summaryrefslogtreecommitdiff
path: root/examples/host
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-04-18 11:13:15 +0200
committerHiFiPhile <[email protected]>2025-04-18 11:13:15 +0200
commitb6abc9022a4beae98cc206d8fbeefb4700deef2f (patch)
treebdd12bb710caa9d161edc1488a37911de0931a3d /examples/host
parent713410997326269b4072dce906933f8f44fd0efe (diff)
parent865e3488f99209c57b73953428dccf2bc666f0be (diff)
Merge remote-tracking branch 'upstream/master' into hcd-template-comments
Signed-off-by: HiFiPhile <[email protected]>
Diffstat (limited to 'examples/host')
-rw-r--r--examples/host/CMakeLists.txt3
-rw-r--r--examples/host/CMakePresets.json6
-rw-r--r--examples/host/bare_api/CMakeLists.txt2
-rw-r--r--examples/host/bare_api/CMakePresets.json6
-rw-r--r--examples/host/bare_api/only.txt3
-rw-r--r--examples/host/bare_api/src/main.c246
-rw-r--r--examples/host/bare_api/src/tusb_config.h3
-rw-r--r--examples/host/cdc_msc_hid/CMakeLists.txt2
-rw-r--r--examples/host/cdc_msc_hid/CMakePresets.json6
-rw-r--r--examples/host/cdc_msc_hid/only.txt3
-rw-r--r--examples/host/cdc_msc_hid/src/cdc_app.c2
-rw-r--r--examples/host/cdc_msc_hid/src/hid_app.c94
-rw-r--r--examples/host/cdc_msc_hid/src/main.c22
-rw-r--r--examples/host/cdc_msc_hid/src/tusb_config.h3
-rw-r--r--examples/host/cdc_msc_hid_freertos/CMakeLists.txt3
-rw-r--r--examples/host/cdc_msc_hid_freertos/CMakePresets.json6
-rw-r--r--examples/host/cdc_msc_hid_freertos/Makefile19
-rw-r--r--examples/host/cdc_msc_hid_freertos/only.txt4
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h199
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/cdc_app.c18
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/freertos_hook.c111
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/main.c33
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/msc_app.c11
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/tusb_config.h5
-rw-r--r--examples/host/device_info/CMakeLists.txt10
-rw-r--r--examples/host/device_info/CMakePresets.json6
-rw-r--r--examples/host/device_info/only.txt10
-rw-r--r--examples/host/device_info/src/CMakeLists.txt4
-rw-r--r--examples/host/device_info/src/main.c223
-rw-r--r--examples/host/device_info/src/tusb_config.h11
-rw-r--r--examples/host/hid_controller/CMakeLists.txt2
-rw-r--r--examples/host/hid_controller/CMakePresets.json6
-rw-r--r--examples/host/hid_controller/only.txt3
-rw-r--r--examples/host/hid_controller/src/hid_app.c17
-rw-r--r--examples/host/hid_controller/src/main.c6
-rw-r--r--examples/host/hid_controller/src/tusb_config.h3
-rw-r--r--examples/host/midi_rx/CMakeLists.txt32
-rw-r--r--examples/host/midi_rx/Makefile13
-rw-r--r--examples/host/midi_rx/only.txt20
-rw-r--r--examples/host/midi_rx/src/main.c123
-rw-r--r--examples/host/midi_rx/src/tusb_config.h118
-rw-r--r--examples/host/msc_file_explorer/CMakeLists.txt2
-rw-r--r--examples/host/msc_file_explorer/CMakePresets.json6
-rw-r--r--examples/host/msc_file_explorer/only.txt3
-rw-r--r--examples/host/msc_file_explorer/src/main.c12
-rw-r--r--examples/host/msc_file_explorer/src/msc_app.c32
-rw-r--r--examples/host/msc_file_explorer/src/msc_app.h35
-rw-r--r--examples/host/msc_file_explorer/src/tusb_config.h3
48 files changed, 823 insertions, 687 deletions
diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt
index 793f6ab08..2783dd84e 100644
--- a/examples/host/CMakeLists.txt
+++ b/examples/host/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake)
@@ -11,4 +11,5 @@ family_add_subdirectory(cdc_msc_hid)
family_add_subdirectory(cdc_msc_hid_freertos)
family_add_subdirectory(device_info)
family_add_subdirectory(hid_controller)
+family_add_subdirectory(midi_rx)
family_add_subdirectory(msc_file_explorer)
diff --git a/examples/host/CMakePresets.json b/examples/host/CMakePresets.json
new file mode 100644
index 000000000..c22e8c0ec
--- /dev/null
+++ b/examples/host/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt
index 76182d6fa..0efe84b60 100644
--- a/examples/host/bare_api/CMakeLists.txt
+++ b/examples/host/bare_api/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
diff --git a/examples/host/bare_api/CMakePresets.json b/examples/host/bare_api/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/host/bare_api/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt
index fee10f9e2..95f9f1d82 100644
--- a/examples/host/bare_api/only.txt
+++ b/examples/host/bare_api/only.txt
@@ -12,3 +12,6 @@ mcu:MSP432E4
mcu:RX65X
mcu:RAXXX
mcu:MAX3421
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c
index ae574c078..0c76ff0c9 100644
--- a/examples/host/bare_api/src/main.c
+++ b/examples/host/bare_api/src/main.c
@@ -55,21 +55,23 @@ uint8_t* get_hid_buf(uint8_t daddr);
void free_hid_buf(uint8_t daddr);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
printf("TinyUSB Bare API Example\r\n");
// init host stack on configured roothub port
- tuh_init(BOARD_TUH_RHPORT);
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUH_RHPORT, &host_init);
if (board_init_after_tusb) {
board_init_after_tusb();
}
- while (1)
- {
+ while (1) {
// tinyusb host task
tuh_task();
led_blinking_task();
@@ -81,8 +83,7 @@ int main(void)
/*------------- TinyUSB Callbacks -------------*/
// Invoked when device is mounted (configured)
-void tuh_mount_cb (uint8_t daddr)
-{
+void tuh_mount_cb(uint8_t daddr) {
printf("Device attached, address = %d\r\n", daddr);
// Get Device Descriptor
@@ -91,8 +92,7 @@ void tuh_mount_cb (uint8_t daddr)
}
/// Invoked when device is unmounted (bus reset/unplugged)
-void tuh_umount_cb(uint8_t daddr)
-{
+void tuh_umount_cb(uint8_t daddr) {
printf("Device removed, address = %d\r\n", daddr);
free_hid_buf(daddr);
}
@@ -100,11 +100,8 @@ void tuh_umount_cb(uint8_t daddr)
//--------------------------------------------------------------------+
// Device Descriptor
//--------------------------------------------------------------------+
-
-void print_device_descriptor(tuh_xfer_t* xfer)
-{
- if ( XFER_RESULT_SUCCESS != xfer->result )
- {
+void print_device_descriptor(tuh_xfer_t *xfer) {
+ if (XFER_RESULT_SUCCESS != xfer->result) {
printf("Failed to get device descriptor\r\n");
return;
}
@@ -127,33 +124,29 @@ void print_device_descriptor(tuh_xfer_t* xfer)
// Get String descriptor using Sync API
uint16_t temp_buf[128];
- printf(" iManufacturer %u " , desc_device.iManufacturer);
- if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf)) )
- {
+ printf(" iManufacturer %u ", desc_device.iManufacturer);
+ if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) {
print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf));
}
printf("\r\n");
- printf(" iProduct %u " , desc_device.iProduct);
- if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf)))
- {
+ printf(" iProduct %u ", desc_device.iProduct);
+ if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) {
print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf));
}
printf("\r\n");
- printf(" iSerialNumber %u " , desc_device.iSerialNumber);
- if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf)))
- {
+ printf(" iSerialNumber %u ", desc_device.iSerialNumber);
+ if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, sizeof(temp_buf))) {
print_utf16(temp_buf, TU_ARRAY_SIZE(temp_buf));
}
printf("\r\n");
- printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations);
+ printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations);
// Get configuration descriptor with sync API
- if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf)))
- {
- parse_config_descriptor(daddr, (tusb_desc_configuration_t*) temp_buf);
+ if (XFER_RESULT_SUCCESS == tuh_descriptor_get_configuration_sync(daddr, 0, temp_buf, sizeof(temp_buf))) {
+ parse_config_descriptor(daddr, (tusb_desc_configuration_t *) temp_buf);
}
}
@@ -167,37 +160,33 @@ uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_
void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len);
// simple configuration parser to open and listen to HID Endpoint IN
-void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg)
-{
- uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
- uint8_t const* p_desc = tu_desc_next(desc_cfg);
+void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const *desc_cfg) {
+ uint8_t const *desc_end = ((uint8_t const *) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
+ uint8_t const *p_desc = tu_desc_next(desc_cfg);
// parse each interfaces
- while( p_desc < desc_end )
- {
+ while (p_desc < desc_end) {
uint8_t assoc_itf_count = 1;
// Class will always starts with Interface Association (if any) and then Interface descriptor
- if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc) )
- {
- tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const *) p_desc;
+ if (TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type(p_desc)) {
+ tusb_desc_interface_assoc_t const *desc_iad = (tusb_desc_interface_assoc_t const *) p_desc;
assoc_itf_count = desc_iad->bInterfaceCount;
- p_desc = tu_desc_next(p_desc); // next to Interface
+ p_desc = tu_desc_next(p_desc);// next to Interface
}
// must be interface from now
- if( TUSB_DESC_INTERFACE != tu_desc_type(p_desc) ) return;
- tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc;
+ if (TUSB_DESC_INTERFACE != tu_desc_type(p_desc)) { return; }
+ tusb_desc_interface_t const *desc_itf = (tusb_desc_interface_t const *) p_desc;
- uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end-p_desc));
+ uint16_t const drv_len = count_interface_total_len(desc_itf, assoc_itf_count, (uint16_t) (desc_end - p_desc));
// probably corrupted descriptor
- if(drv_len < sizeof(tusb_desc_interface_t)) return;
+ if (drv_len < sizeof(tusb_desc_interface_t)) { return; }
// only open and listen to HID endpoint IN
- if (desc_itf->bInterfaceClass == TUSB_CLASS_HID)
- {
+ if (desc_itf->bInterfaceClass == TUSB_CLASS_HID) {
open_hid_interface(dev_addr, desc_itf, drv_len);
}
@@ -206,25 +195,21 @@ void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const*
}
}
-uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len)
-{
- uint8_t const* p_desc = (uint8_t const*) desc_itf;
+uint16_t count_interface_total_len(tusb_desc_interface_t const *desc_itf, uint8_t itf_count, uint16_t max_len) {
+ uint8_t const *p_desc = (uint8_t const *) desc_itf;
uint16_t len = 0;
- while (itf_count--)
- {
+ while (itf_count--) {
// Next on interface desc
len += tu_desc_len(desc_itf);
p_desc = tu_desc_next(p_desc);
- while (len < max_len)
- {
+ while (len < max_len) {
// return on IAD regardless of itf count
- if ( tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len;
+ if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE_ASSOCIATION) { return len; }
- if ( (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
- ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0 )
- {
+ if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
+ ((tusb_desc_interface_t const *) p_desc)->bAlternateSetting == 0) {
break;
}
@@ -242,46 +227,45 @@ uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_
void hid_report_received(tuh_xfer_t* xfer);
-void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
-{
+void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) {
// len = interface + hid + n*endpoints
uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) +
desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
// corrupted descriptor
- if (max_len < drv_len) return;
+ if (max_len < drv_len) { return; }
uint8_t const *p_desc = (uint8_t const *) desc_itf;
// HID descriptor
p_desc = tu_desc_next(p_desc);
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
- if(HID_DESC_TYPE_HID != desc_hid->bDescriptorType) return;
+ if (HID_DESC_TYPE_HID != desc_hid->bDescriptorType) { return; }
// Endpoint descriptor
p_desc = tu_desc_next(p_desc);
- tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc;
+ tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc;
- for(int i = 0; i < desc_itf->bNumEndpoints; i++)
- {
- if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) return;
+ for (int i = 0; i < desc_itf->bNumEndpoints; i++) {
+ if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) { return; }
- if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN)
- {
- // skip if failed to open endpoint
- if ( ! tuh_edpt_open(daddr, desc_ep) ) return;
+ if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
+ if (!tuh_edpt_open(daddr, desc_ep)) {
+ return; // skip if failed to open endpoint
+ }
- uint8_t* buf = get_hid_buf(daddr);
- if (!buf) return; // out of memory
+ uint8_t *buf = get_hid_buf(daddr);
+ if (!buf) {
+ return;// out of memory
+ }
- tuh_xfer_t xfer =
- {
- .daddr = daddr,
- .ep_addr = desc_ep->bEndpointAddress,
- .buflen = 64,
- .buffer = buf,
- .complete_cb = hid_report_received,
- .user_data = (uintptr_t) buf, // since buffer is not available in callback, use user data to store the buffer
+ tuh_xfer_t xfer = {
+ .daddr = daddr,
+ .ep_addr = desc_ep->bEndpointAddress,
+ .buflen = 64,
+ .buffer = buf,
+ .complete_cb = hid_report_received,
+ .user_data = (uintptr_t) buf,// since buffer is not available in callback, use user data to store the buffer
};
// submit transfer for this EP
@@ -295,18 +279,17 @@ void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, ui
}
}
-void hid_report_received(tuh_xfer_t* xfer)
-{
+void hid_report_received(tuh_xfer_t *xfer) {
// Note: not all field in xfer is available for use (i.e filled by tinyusb stack) in callback to save sram
// For instance, xfer->buffer is NULL. We have used user_data to store buffer when submitted callback
- uint8_t* buf = (uint8_t*) xfer->user_data;
+ uint8_t *buf = (uint8_t *) xfer->user_data;
- if (xfer->result == XFER_RESULT_SUCCESS)
- {
+ if (xfer->result == XFER_RESULT_SUCCESS) {
printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr);
- for(uint32_t i=0; i<xfer->actual_len; i++)
- {
- if (i%16 == 0) printf("\r\n ");
+ for (uint32_t i = 0; i < xfer->actual_len; i++) {
+ if (i % 16 == 0) {
+ printf("\r\n ");
+ }
printf("%02X ", buf[i]);
}
printf("\r\n");
@@ -325,12 +308,9 @@ void hid_report_received(tuh_xfer_t* xfer)
//--------------------------------------------------------------------+
// get an buffer from pool
-uint8_t* get_hid_buf(uint8_t daddr)
-{
- for(size_t i=0; i<BUF_COUNT; i++)
- {
- if (buf_owner[i] == 0)
- {
+uint8_t *get_hid_buf(uint8_t daddr) {
+ for (size_t i = 0; i < BUF_COUNT; i++) {
+ if (buf_owner[i] == 0) {
buf_owner[i] = daddr;
return buf_pool[i];
}
@@ -341,10 +321,8 @@ uint8_t* get_hid_buf(uint8_t daddr)
}
// free all buffer owned by device
-void free_hid_buf(uint8_t daddr)
-{
- for(size_t i=0; i<BUF_COUNT; i++)
- {
+void free_hid_buf(uint8_t daddr) {
+ for (size_t i = 0; i < BUF_COUNT; i++) {
if (buf_owner[i] == daddr) buf_owner[i] = 0;
}
}
@@ -352,70 +330,70 @@ void free_hid_buf(uint8_t daddr)
//--------------------------------------------------------------------+
// Blinking Task
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
const uint32_t interval_ms = 1000;
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every interval ms
- if ( board_millis() - start_ms < interval_ms) return; // not enough time
+ if (board_millis() - start_ms < interval_ms) {
+ return; // not enough time
+ }
start_ms += interval_ms;
board_led_write(led_state);
- led_state = 1 - led_state; // toggle
+ led_state = 1 - led_state;// toggle
}
//--------------------------------------------------------------------+
// String Descriptor Helper
//--------------------------------------------------------------------+
-
static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) {
- // TODO: Check for runover.
- (void)utf8_len;
- // Get the UTF-16 length out of the data itself.
+ // TODO: Check for runover.
+ (void) utf8_len;
+ // Get the UTF-16 length out of the data itself.
- for (size_t i = 0; i < utf16_len; i++) {
- uint16_t chr = utf16[i];
- if (chr < 0x80) {
- *utf8++ = chr & 0xffu;
- } else if (chr < 0x800) {
- *utf8++ = (uint8_t)(0xC0 | (chr >> 6 & 0x1F));
- *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F));
- } else {
- // TODO: Verify surrogate.
- *utf8++ = (uint8_t)(0xE0 | (chr >> 12 & 0x0F));
- *utf8++ = (uint8_t)(0x80 | (chr >> 6 & 0x3F));
- *utf8++ = (uint8_t)(0x80 | (chr >> 0 & 0x3F));
- }
- // TODO: Handle UTF-16 code points that take two entries.
+ for (size_t i = 0; i < utf16_len; i++) {
+ uint16_t chr = utf16[i];
+ if (chr < 0x80) {
+ *utf8++ = chr & 0xffu;
+ } else if (chr < 0x800) {
+ *utf8++ = (uint8_t) (0xC0 | (chr >> 6 & 0x1F));
+ *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
+ } else {
+ // TODO: Verify surrogate.
+ *utf8++ = (uint8_t) (0xE0 | (chr >> 12 & 0x0F));
+ *utf8++ = (uint8_t) (0x80 | (chr >> 6 & 0x3F));
+ *utf8++ = (uint8_t) (0x80 | (chr >> 0 & 0x3F));
}
+ // TODO: Handle UTF-16 code points that take two entries.
+ }
}
// Count how many bytes a utf-16-le encoded string will take in utf-8.
static int _count_utf8_bytes(const uint16_t *buf, size_t len) {
- size_t total_bytes = 0;
- for (size_t i = 0; i < len; i++) {
- uint16_t chr = buf[i];
- if (chr < 0x80) {
- total_bytes += 1;
- } else if (chr < 0x800) {
- total_bytes += 2;
- } else {
- total_bytes += 3;
- }
- // TODO: Handle UTF-16 code points that take two entries.
+ size_t total_bytes = 0;
+ for (size_t i = 0; i < len; i++) {
+ uint16_t chr = buf[i];
+ if (chr < 0x80) {
+ total_bytes += 1;
+ } else if (chr < 0x800) {
+ total_bytes += 2;
+ } else {
+ total_bytes += 3;
}
- return (int) total_bytes;
+ // TODO: Handle UTF-16 code points that take two entries.
+ }
+ return (int) total_bytes;
}
static void print_utf16(uint16_t *temp_buf, size_t buf_len) {
- if ((temp_buf[0] & 0xff) == 0) return; // empty
- size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
- size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len);
- _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len);
- ((uint8_t*) temp_buf)[utf8_len] = '\0';
+ if ((temp_buf[0] & 0xff) == 0) return;// empty
+ size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
+ size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len);
+ _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len);
+ ((uint8_t *) temp_buf)[utf8_len] = '\0';
- printf("%s", (char*)temp_buf);
+ printf("%s", (char *) temp_buf);
}
diff --git a/examples/host/bare_api/src/tusb_config.h b/examples/host/bare_api/src/tusb_config.h
index fab233be0..a03675c5f 100644
--- a/examples/host/bare_api/src/tusb_config.h
+++ b/examples/host/bare_api/src/tusb_config.h
@@ -69,9 +69,10 @@
// Enable Host stack
#define CFG_TUH_ENABLED 1
+// #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
- // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
// host roothub port is 1 if using either pio-usb or max3421
#if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)
diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt
index a7c372a34..e8928cda5 100644
--- a/examples/host/cdc_msc_hid/CMakeLists.txt
+++ b/examples/host/cdc_msc_hid/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
diff --git a/examples/host/cdc_msc_hid/CMakePresets.json b/examples/host/cdc_msc_hid/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/host/cdc_msc_hid/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt
index fee10f9e2..95f9f1d82 100644
--- a/examples/host/cdc_msc_hid/only.txt
+++ b/examples/host/cdc_msc_hid/only.txt
@@ -12,3 +12,6 @@ mcu:MSP432E4
mcu:RX65X
mcu:RAXXX
mcu:MAX3421
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c
index 4a13f8b27..e68ec383b 100644
--- a/examples/host/cdc_msc_hid/src/cdc_app.c
+++ b/examples/host/cdc_msc_hid/src/cdc_app.c
@@ -27,7 +27,7 @@
#include "tusb.h"
#include "bsp/board_api.h"
-size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
+static size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
size_t count = 0;
while (count < bufsize) {
int ch = board_getchar();
diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c
index 6bb3a2072..a751c9c80 100644
--- a/examples/host/cdc_msc_hid/src/hid_app.c
+++ b/examples/host/cdc_msc_hid/src/hid_app.c
@@ -39,18 +39,16 @@
static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII };
// Each HID instance can has multiple reports
-static struct
-{
+static struct {
uint8_t report_count;
tuh_hid_report_info_t report_info[MAX_REPORT];
-}hid_info[CFG_TUH_HID];
+} hid_info[CFG_TUH_HID];
static void process_kbd_report(hid_keyboard_report_t const *report);
static void process_mouse_report(hid_mouse_report_t const * report);
static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
-void hid_app_task(void)
-{
+void hid_app_task(void) {
// nothing to do
}
@@ -63,64 +61,57 @@ void hid_app_task(void)
// can be used to parse common/simple enough descriptor.
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
// therefore report_desc = NULL, desc_len = 0
-void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len)
-{
+void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) {
printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);
// Interface protocol (hid_interface_protocol_enum_t)
- const char* protocol_str[] = { "None", "Keyboard", "Mouse" };
+ const char *protocol_str[] = {"None", "Keyboard", "Mouse"};
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]);
// By default host stack will use activate boot protocol on supported interface.
// Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser)
- if ( itf_protocol == HID_ITF_PROTOCOL_NONE )
- {
+ if (itf_protocol == HID_ITF_PROTOCOL_NONE) {
hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len);
printf("HID has %u reports \r\n", hid_info[instance].report_count);
}
// request to receive report
// tuh_hid_report_received_cb() will be invoked when report is available
- if ( !tuh_hid_receive_report(dev_addr, instance) )
- {
+ if (!tuh_hid_receive_report(dev_addr, instance)) {
printf("Error: cannot request to receive report\r\n");
}
}
// Invoked when device with hid interface is un-mounted
-void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
-{
+void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
}
// Invoked when received report from device via interrupt endpoint
-void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
-{
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
- switch (itf_protocol)
- {
+ switch (itf_protocol) {
case HID_ITF_PROTOCOL_KEYBOARD:
TU_LOG2("HID receive boot keyboard report\r\n");
- process_kbd_report( (hid_keyboard_report_t const*) report );
- break;
+ process_kbd_report((hid_keyboard_report_t const *) report);
+ break;
case HID_ITF_PROTOCOL_MOUSE:
TU_LOG2("HID receive boot mouse report\r\n");
- process_mouse_report( (hid_mouse_report_t const*) report );
- break;
+ process_mouse_report((hid_mouse_report_t const *) report);
+ break;
default:
// Generic report requires matching ReportID and contents with previous parsed report info
process_generic_report(dev_addr, instance, report, len);
- break;
+ break;
}
// continue to request to receive report
- if ( !tuh_hid_receive_report(dev_addr, instance) )
- {
+ if (!tuh_hid_receive_report(dev_addr, instance)) {
printf("Error: cannot request to receive report\r\n");
}
}
@@ -130,13 +121,12 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
//--------------------------------------------------------------------+
// look up new key in previous keys
-static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode)
-{
- for(uint8_t i=0; i<6; i++)
- {
- if (report->keycode[i] == keycode) return true;
+static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8_t keycode) {
+ for (uint8_t i = 0; i < 6; i++) {
+ if (report->keycode[i] == keycode) {
+ return true;
+ }
}
-
return false;
}
@@ -175,8 +165,7 @@ static void process_kbd_report(hid_keyboard_report_t const *report)
// Mouse
//--------------------------------------------------------------------+
-void cursor_movement(int8_t x, int8_t y, int8_t wheel)
-{
+static void cursor_movement(int8_t x, int8_t y, int8_t wheel) {
#if USE_ANSI_ESCAPE
// Move X using ansi escape
if ( x < 0)
@@ -232,29 +221,24 @@ static void process_mouse_report(hid_mouse_report_t const * report)
//--------------------------------------------------------------------+
// Generic Report
//--------------------------------------------------------------------+
-static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
-{
+static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
(void) dev_addr;
(void) len;
uint8_t const rpt_count = hid_info[instance].report_count;
- tuh_hid_report_info_t* rpt_info_arr = hid_info[instance].report_info;
- tuh_hid_report_info_t* rpt_info = NULL;
+ tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info;
+ tuh_hid_report_info_t *rpt_info = NULL;
- if ( rpt_count == 1 && rpt_info_arr[0].report_id == 0)
- {
+ if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) {
// Simple report without report ID as 1st byte
rpt_info = &rpt_info_arr[0];
- }else
- {
+ } else {
// Composite report, 1st byte is report ID, data starts from 2nd byte
uint8_t const rpt_id = report[0];
// Find report id in the array
- for(uint8_t i=0; i<rpt_count; i++)
- {
- if (rpt_id == rpt_info_arr[i].report_id )
- {
+ for (uint8_t i = 0; i < rpt_count; i++) {
+ if (rpt_id == rpt_info_arr[i].report_id) {
rpt_info = &rpt_info_arr[i];
break;
}
@@ -264,8 +248,7 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c
len--;
}
- if (!rpt_info)
- {
+ if (!rpt_info) {
printf("Couldn't find report info !\r\n");
return;
}
@@ -277,23 +260,22 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c
// - Consumer Control (Media Key) : Consumer, Consumer Control
// - System Control (Power key) : Desktop, System Control
// - Generic (vendor) : 0xFFxx, xx
- if ( rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP )
- {
- switch (rpt_info->usage)
- {
+ if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) {
+ switch (rpt_info->usage) {
case HID_USAGE_DESKTOP_KEYBOARD:
TU_LOG1("HID receive keyboard report\r\n");
// Assume keyboard follow boot report layout
- process_kbd_report( (hid_keyboard_report_t const*) report );
- break;
+ process_kbd_report((hid_keyboard_report_t const *) report);
+ break;
case HID_USAGE_DESKTOP_MOUSE:
TU_LOG1("HID receive mouse report\r\n");
// Assume mouse follow boot report layout
- process_mouse_report( (hid_mouse_report_t const*) report );
- break;
+ process_mouse_report((hid_mouse_report_t const *) report);
+ break;
- default: break;
+ default:
+ break;
}
}
}
diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c
index a3b80e030..7b02e238e 100644
--- a/examples/host/cdc_msc_hid/src/main.c
+++ b/examples/host/cdc_msc_hid/src/main.c
@@ -31,18 +31,12 @@
#include "tusb.h"
//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF PROTYPES
+// MACRO CONSTANT TYPEDEF PROTOTYPES
//--------------------------------------------------------------------+
void led_blinking_task(void);
extern void cdc_app_task(void);
extern void hid_app_task(void);
-#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
-// API to read/rite MAX3421's register. Implemented by TinyUSB
-extern uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr);
-extern bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr);
-#endif
-
/*------------- MAIN -------------*/
int main(void) {
board_init();
@@ -50,7 +44,11 @@ int main(void) {
printf("TinyUSB Host CDC MSC HID Example\r\n");
// init host stack on configured roothub port
- tuh_init(BOARD_TUH_RHPORT);
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUH_RHPORT, &host_init);
if (board_init_after_tusb) {
board_init_after_tusb();
@@ -78,12 +76,12 @@ int main(void) {
void tuh_mount_cb(uint8_t dev_addr) {
// application set-up
- printf("A device with address %d is mounted\r\n", dev_addr);
+ printf("A device with address %u is mounted\r\n", dev_addr);
}
void tuh_umount_cb(uint8_t dev_addr) {
// application tear-down
- printf("A device with address %d is unmounted \r\n", dev_addr);
+ printf("A device with address %u is unmounted \r\n", dev_addr);
}
@@ -97,7 +95,9 @@ void led_blinking_task(void) {
static bool led_state = false;
// Blink every interval ms
- if (board_millis() - start_ms < interval_ms) return; // not enough time
+ if (board_millis() - start_ms < interval_ms) {
+ return;// not enough time
+ }
start_ms += interval_ms;
board_led_write(led_state);
diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h
index a59a0ffb9..cc8d6e5c4 100644
--- a/examples/host/cdc_msc_hid/src/tusb_config.h
+++ b/examples/host/cdc_msc_hid/src/tusb_config.h
@@ -69,9 +69,10 @@
// Enable Host stack
#define CFG_TUH_ENABLED 1
+// #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
- // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
// host roothub port is 1 if using either pio-usb or max3421
#if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)
diff --git a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
index 2e95a18e0..78b2784fe 100644
--- a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
+++ b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
@@ -20,7 +20,6 @@ add_executable(${PROJECT})
# Example source
target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c
${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c
diff --git a/examples/host/cdc_msc_hid_freertos/CMakePresets.json b/examples/host/cdc_msc_hid_freertos/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/cdc_msc_hid_freertos/Makefile b/examples/host/cdc_msc_hid_freertos/Makefile
index bf4725f47..178341f81 100644
--- a/examples/host/cdc_msc_hid_freertos/Makefile
+++ b/examples/host/cdc_msc_hid_freertos/Makefile
@@ -1,34 +1,17 @@
+RTOS = freertos
include ../../build_system/make/make.mk
-FREERTOS_SRC = lib/FreeRTOS-Kernel
-FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(findstring iar,$(TOOLCHAIN)),IAR,GCC)
-
INC += \
src \
- src/FreeRTOSConfig \
$(TOP)/hw \
- $(TOP)/$(FREERTOS_SRC)/include \
- $(TOP)/$(FREERTOS_PORTABLE_SRC) \
# Example source
EXAMPLE_SOURCE = \
src/cdc_app.c \
- src/freertos_hook.c \
src/hid_app.c \
src/main.c \
src/msc_app.c \
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
-# FreeRTOS source, all files in port folder
-SRC_C += \
- $(FREERTOS_SRC)/list.c \
- $(FREERTOS_SRC)/queue.c \
- $(FREERTOS_SRC)/tasks.c \
- $(FREERTOS_SRC)/timers.c \
- $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c))
-
-SRC_S += \
- $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s))
-
include ../../build_system/make/rules.mk
diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt
index 1e0e60075..e3ae25260 100644
--- a/examples/host/cdc_msc_hid_freertos/only.txt
+++ b/examples/host/cdc_msc_hid_freertos/only.txt
@@ -1,3 +1,4 @@
+mcu:ESP32P4
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
@@ -9,3 +10,6 @@ mcu:MIMXRT11XX
mcu:MSP432E4
mcu:RX65X
mcu:MAX3421
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h
deleted file mode 100644
index bd754518d..000000000
--- a/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * FreeRTOS Kernel V10.0.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software. If you wish to use our Amazon
- * FreeRTOS name, please do so in a fair use way that does not cause confusion.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
- * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
- *
- * See http://www.freertos.org/a00110.html.
- *----------------------------------------------------------*/
-
-// skip if included from IAR assembler
-#ifndef __IASMARM__
-
-// Include MCU header
-#include "bsp/board_mcu.h"
-
-#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
- #error "ESP32-Sx should use IDF's FreeRTOSConfig.h"
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wredundant-decls"
-#endif
-
-// TODO fix later
-// FIXME cause redundant-decls warnings
-#if CFG_TUSB_MCU == OPT_MCU_MM32F327X
- extern u32 SystemCoreClock;
-#else
- extern uint32_t SystemCoreClock;
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
-#endif
-
-/* Cortex M23/M33 port configuration. */
-#define configENABLE_MPU 0
-#define configENABLE_FPU 1
-#define configENABLE_TRUSTZONE 0
-#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
-
-#define configUSE_PREEMPTION 1
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
-#define configCPU_CLOCK_HZ SystemCoreClock
-#define configTICK_RATE_HZ ( 1000 )
-#define configMAX_PRIORITIES ( 5 )
-#define configMINIMAL_STACK_SIZE ( 128 )
-#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
-#define configMAX_TASK_NAME_LEN 16
-#define configUSE_16_BIT_TICKS 0
-#define configIDLE_SHOULD_YIELD 1
-#define configUSE_MUTEXES 1
-#define configUSE_RECURSIVE_MUTEXES 1
-#define configUSE_COUNTING_SEMAPHORES 1
-#define configQUEUE_REGISTRY_SIZE 4
-#define configUSE_QUEUE_SETS 0
-#define configUSE_TIME_SLICING 0
-#define configUSE_NEWLIB_REENTRANT 0
-#define configENABLE_BACKWARD_COMPATIBILITY 1
-#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
-
-#define configSUPPORT_STATIC_ALLOCATION 1
-#define configSUPPORT_DYNAMIC_ALLOCATION 0
-
-/* Hook function related definitions. */
-#define configUSE_IDLE_HOOK 0
-#define configUSE_TICK_HOOK 0
-#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
-#define configCHECK_FOR_STACK_OVERFLOW 2
-#define configCHECK_HANDLER_INSTALLATION 0
-
-/* Run time and task stats gathering related definitions. */
-#define configGENERATE_RUN_TIME_STATS 0
-#define configUSE_TRACE_FACILITY 1 // legacy trace
-#define configUSE_STATS_FORMATTING_FUNCTIONS 0
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
-#define configMAX_CO_ROUTINE_PRIORITIES 2
-
-/* Software timer related definitions. */
-#define configUSE_TIMERS 1
-#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
-#define configTIMER_QUEUE_LENGTH 32
-#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
-
-/* Optional functions - most linkers will remove unused functions anyway. */
-#define INCLUDE_vTaskPrioritySet 0
-#define INCLUDE_uxTaskPriorityGet 0
-#define INCLUDE_vTaskDelete 0
-#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
-#define INCLUDE_xResumeFromISR 0
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_xTaskGetSchedulerState 0
-#define INCLUDE_xTaskGetCurrentTaskHandle 0
-#define INCLUDE_uxTaskGetStackHighWaterMark 0
-#define INCLUDE_xTaskGetIdleTaskHandle 0
-#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
-#define INCLUDE_pcTaskGetTaskName 0
-#define INCLUDE_eTaskGetState 0
-#define INCLUDE_xEventGroupSetBitFromISR 0
-#define INCLUDE_xTimerPendFunctionCall 0
-
-#ifdef __RX__
-/* Renesas RX series */
-#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
-#define vTickISR INT_Excep_CMT0_CMI0
-#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
-#define configKERNEL_INTERRUPT_PRIORITY 1
-#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
-
-#else
-
-/* FreeRTOS hooks to NVIC vectors */
-#define xPortPendSVHandler PendSV_Handler
-#define xPortSysTickHandler SysTick_Handler
-#define vPortSVCHandler SVC_Handler
-
-//--------------------------------------------------------------------+
-// Interrupt nesting behavior configuration.
-//--------------------------------------------------------------------+
-#if defined(__NVIC_PRIO_BITS)
- // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
- #define configPRIO_BITS __NVIC_PRIO_BITS
-
-#elif defined(__ECLIC_INTCTLBITS)
- // RISC-V Bumblebee core from nuclei
- #define configPRIO_BITS __ECLIC_INTCTLBITS
-
-#elif defined(__IASMARM__)
- // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
- // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
- // IAR user must update this to correct value of the target MCU
- #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
- #define configPRIO_BITS 2
-
-#else
- #error "FreeRTOS configPRIO_BITS to be defined"
-#endif
-
-/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
-#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
-
-/* The highest interrupt priority that can be used by any interrupt service
-routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
-INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
-PRIORITY THAN THIS! (higher priorities are lower numeric values. */
-#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
-
-/* Interrupt priorities used by the kernel port layer itself. These are generic
-to all Cortex-M ports, and do not rely on any particular library functions. */
-#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-
-/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
-See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
-#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
-
-#endif
-
-#endif /* __FREERTOS_CONFIG__H */
diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
index f3495ab28..e279ad509 100644
--- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
+++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
@@ -27,23 +27,9 @@
#include "tusb.h"
#include "bsp/board_api.h"
-#if TUP_MCU_ESPRESSIF
-// ESP-IDF need "freertos/" prefix in include path.
-// CFG_TUSB_OS_INC_PATH should be defined accordingly.
- #include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
- #include "freertos/queue.h"
- #include "freertos/task.h"
- #include "freertos/timers.h"
-
+#if TUSB_MCU_VENDOR_ESPRESSIF
#define CDC_STACK_SZIE 2048
#else
- #include "FreeRTOS.h"
- #include "semphr.h"
- #include "queue.h"
- #include "task.h"
- #include "timers.h"
-
#define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2)
#endif
@@ -66,7 +52,7 @@ void cdc_app_init(void) {
}
// helper
-size_t get_console_inputs(uint8_t *buf, size_t bufsize) {
+static size_t get_console_inputs(uint8_t *buf, size_t bufsize) {
size_t count = 0;
while (count < bufsize) {
int ch = board_getchar();
diff --git a/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c
deleted file mode 100644
index 07d159fd5..000000000
--- a/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
-
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include "FreeRTOS.h"
-#include "task.h"
-#include "common/tusb_common.h"
-
-void vApplicationMallocFailedHook(void) {
- taskDISABLE_INTERRUPTS();
- TU_ASSERT(false,);
-}
-
-void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) {
- (void) pxTask;
- (void) pcTaskName;
-
- taskDISABLE_INTERRUPTS();
- TU_ASSERT(false,);
-}
-
-/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
- * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
- * used by the Idle task. */
-void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer,
- uint32_t *pulIdleTaskStackSize) {
- /* If the buffers to be provided to the Idle task are declared inside this
- * function then they must be declared static - otherwise they will be allocated on
- * the stack and so not exists after this function exits. */
- static StaticTask_t xIdleTaskTCB;
- static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
-
- /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
- state will be stored. */
- *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
-
- /* Pass out the array that will be used as the Idle task's stack. */
- *ppxIdleTaskStackBuffer = uxIdleTaskStack;
-
- /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
- Note that, as the array is necessarily of type StackType_t,
- configMINIMAL_STACK_SIZE is specified in words, not bytes. */
- *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
-}
-
-/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
- * application must provide an implementation of vApplicationGetTimerTaskMemory()
- * to provide the memory that is used by the Timer service task. */
-void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer,
- uint32_t *pulTimerTaskStackSize) {
- /* If the buffers to be provided to the Timer task are declared inside this
- * function then they must be declared static - otherwise they will be allocated on
- * the stack and so not exists after this function exits. */
- static StaticTask_t xTimerTaskTCB;
- static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
-
- /* Pass out a pointer to the StaticTask_t structure in which the Timer
- task's state will be stored. */
- *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
-
- /* Pass out the array that will be used as the Timer task's stack. */
- *ppxTimerTaskStackBuffer = uxTimerTaskStack;
-
- /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
- Note that, as the array is necessarily of type StackType_t,
- configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
- *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
-}
-
-#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X
-#include "iodefine.h"
-void vApplicationSetupTimerInterrupt(void)
-{
- /* Enable CMT0 */
- SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1);
- MSTP(CMT0) = 0;
- SYSTEM.PRCR.WORD = (0xA5u<<8);
-
- CMT0.CMCNT = 0;
- CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128);
- CMT0.CMCR.WORD = TU_BIT(6) | 2;
- IR(CMT0, CMI0) = 0;
- IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY;
- IEN(CMT0, CMI0) = 1;
- CMT.CMSTR0.BIT.STR0 = 1;
-}
-#endif
diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c
index fa799aede..64a108254 100644
--- a/examples/host/cdc_msc_hid_freertos/src/main.c
+++ b/examples/host/cdc_msc_hid_freertos/src/main.c
@@ -30,23 +30,9 @@
#include "bsp/board_api.h"
#include "tusb.h"
-#if TUP_MCU_ESPRESSIF
- // ESP-IDF need "freertos/" prefix in include path.
- // CFG_TUSB_OS_INC_PATH should be defined accordingly.
- #include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
- #include "freertos/queue.h"
- #include "freertos/task.h"
- #include "freertos/timers.h"
-
+#if TUSB_MCU_VENDOR_ESPRESSIF
#define USBH_STACK_SIZE 4096
#else
- #include "FreeRTOS.h"
- #include "semphr.h"
- #include "queue.h"
- #include "task.h"
- #include "timers.h"
-
// Increase stack size when debug log is enabled
#define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
#endif
@@ -83,12 +69,6 @@ extern void cdc_app_init(void);
extern void hid_app_init(void);
extern void msc_app_init(void);
-#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
-// API to read/rite MAX3421's register. Implemented by TinyUSB
-extern uint8_t tuh_max3421_reg_read(uint8_t rhport, uint8_t reg, bool in_isr);
-extern bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr);
-#endif
-
/*------------- MAIN -------------*/
int main(void) {
board_init();
@@ -107,14 +87,14 @@ int main(void) {
xTimerStart(blinky_tm, 0);
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
-#if !TUP_MCU_ESPRESSIF
+#if !TUSB_MCU_VENDOR_ESPRESSIF
vTaskStartScheduler();
#endif
return 0;
}
-#if TUP_MCU_ESPRESSIF
+#if TUSB_MCU_VENDOR_ESPRESSIF
void app_main(void) {
main();
}
@@ -126,7 +106,12 @@ static void usb_host_task(void *param) {
(void) param;
// init host stack on configured roothub port
- if (!tuh_init(BOARD_TUH_RHPORT)) {
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+
+ if (!tusb_init(BOARD_TUH_RHPORT, &host_init)) {
printf("Failed to init USB Host Stack\r\n");
vTaskSuspend(NULL);
}
diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c
index 9ffd5d965..6439495a8 100644
--- a/examples/host/cdc_msc_hid_freertos/src/msc_app.c
+++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c
@@ -25,13 +25,16 @@
#include "tusb.h"
-static scsi_inquiry_resp_t inquiry_resp;
+// define the buffer to be place in USB/DMA memory with correct alignment/cache line size
+CFG_TUH_MEM_SECTION static struct {
+ TUH_EPBUF_TYPE_DEF(scsi_inquiry_resp_t, inquiry);
+} scsi_resp;
void msc_app_init(void) {
// nothing to do
}
-bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) {
+static bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) {
msc_cbw_t const *cbw = cb_data->cbw;
msc_csw_t const *csw = cb_data->csw;
@@ -41,7 +44,7 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_dat
}
// Print out Vendor ID, Product ID and Rev
- printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
+ printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev);
// Get capacity of device
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
@@ -58,7 +61,7 @@ void tuh_msc_mount_cb(uint8_t dev_addr) {
printf("A MassStorage device is mounted\r\n");
uint8_t const lun = 0;
- tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
+ tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0);
}
void tuh_msc_umount_cb(uint8_t dev_addr) {
diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
index 0aab2cd2f..682265f59 100644
--- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
+++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
@@ -44,7 +44,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUP_MCU_ESPRESSIF
+#if TUSB_MCU_VENDOR_ESPRESSIF
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
@@ -74,9 +74,10 @@
// Enable Host stack
#define CFG_TUH_ENABLED 1
+// #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
- // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
// host roothub port is 1 if using either pio-usb or max3421
#if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)
diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt
index 76182d6fa..33953233d 100644
--- a/examples/host/device_info/CMakeLists.txt
+++ b/examples/host/device_info/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
@@ -19,13 +19,13 @@ add_executable(${PROJECT})
# Example source
target_sources(${PROJECT} PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
- )
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
+ )
# Example include
target_include_directories(${PROJECT} PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- )
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ )
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
diff --git a/examples/host/device_info/CMakePresets.json b/examples/host/device_info/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/host/device_info/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt
index fee10f9e2..b6f87f423 100644
--- a/examples/host/device_info/only.txt
+++ b/examples/host/device_info/only.txt
@@ -1,14 +1,20 @@
+mcu:ESP32S2
+mcu:ESP32S3
+mcu:ESP32P4
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
+mcu:MAX3421
mcu:MIMXRT1XXX
mcu:MIMXRT10XX
mcu:MIMXRT11XX
-mcu:RP2040
mcu:MSP432E4
+mcu:RP2040
mcu:RX65X
mcu:RAXXX
-mcu:MAX3421
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/device_info/src/CMakeLists.txt b/examples/host/device_info/src/CMakeLists.txt
new file mode 100644
index 000000000..1908a32c3
--- /dev/null
+++ b/examples/host/device_info/src/CMakeLists.txt
@@ -0,0 +1,4 @@
+# This file is for ESP-IDF only
+idf_component_register(SRCS "main.c"
+ INCLUDE_DIRS "."
+ REQUIRES boards tinyusb_src)
diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c
index 18beea663..e924a137b 100644
--- a/examples/host/device_info/src/main.c
+++ b/examples/host/device_info/src/main.c
@@ -24,7 +24,7 @@
*/
/* Host example will get device descriptors of attached devices and print it out via uart/rtt (logger) as follows:
- * Device 1: ID 046d:c52f
+ * Device 1: ID 046d:c52f SN 11223344
Device Descriptor:
bLength 18
bDescriptorType 1
@@ -56,107 +56,136 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
-void led_blinking_task(void);
-static void print_utf16(uint16_t* temp_buf, size_t buf_len);
+enum {
+ BLINK_NOT_MOUNTED = 250,
+ BLINK_MOUNTED = 1000,
+ BLINK_SUSPENDED = 2500,
+};
+static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
-/*------------- MAIN -------------*/
-int main(void) {
- board_init();
+// Declare for buffer for usb transfer, may need to be in USB/DMA section and
+// multiple of dcache line size if dcache is enabled (for some ports).
+CFG_TUH_MEM_SECTION struct {
+ TUH_EPBUF_TYPE_DEF(tusb_desc_device_t, device);
+ TUH_EPBUF_DEF(serial, 64*sizeof(uint16_t));
+ TUH_EPBUF_DEF(buf, 128*sizeof(uint16_t));
+} desc;
- printf("TinyUSB Device Info Example\r\n");
+void led_blinking_task(void* param);
+static void print_utf16(uint16_t* temp_buf, size_t buf_len);
+
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+void init_freertos_task(void);
+#endif
+//--------------------------------------------------------------------
+// Main
+//--------------------------------------------------------------------
+static void init_tinyusb(void) {
// init host stack on configured roothub port
- tuh_init(BOARD_TUH_RHPORT);
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUH_RHPORT, &host_init);
if (board_init_after_tusb) {
board_init_after_tusb();
}
+}
+
+int main(void) {
+ board_init();
+ printf("TinyUSB Device Info Example\r\n");
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ init_freertos_task();
+#else
+ init_tinyusb();
while (1) {
- // tinyusb host task
- tuh_task();
- led_blinking_task();
+ tuh_task(); // tinyusb host task
+ led_blinking_task(NULL);
}
-
return 0;
+#endif
}
/*------------- TinyUSB Callbacks -------------*/
// Invoked when device is mounted (configured)
void tuh_mount_cb(uint8_t daddr) {
+ blink_interval_ms = BLINK_MOUNTED;
+
// Get Device Descriptor
- tusb_desc_device_t desc_device;
- uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc_device, 18);
+ uint8_t xfer_result = tuh_descriptor_get_device_sync(daddr, &desc.device, 18);
if (XFER_RESULT_SUCCESS != xfer_result) {
printf("Failed to get device descriptor\r\n");
return;
}
- uint16_t buf[256];
+ printf("Device %u: ID %04x:%04x SN ", daddr, desc.device.idVendor, desc.device.idProduct);
+
+ xfer_result = XFER_RESULT_FAILED;
+ if (desc.device.iSerialNumber != 0) {
+ xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, desc.serial, sizeof(desc.serial));
+ }
+ if (XFER_RESULT_SUCCESS != xfer_result) {
+ uint16_t* serial = (uint16_t*)(uintptr_t) desc.serial;
+ serial[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * 3 + 2));
+ serial[1] = 'n';
+ serial[2] = '/';
+ serial[3] = 'a';
+ serial[4] = 0;
+ }
+ print_utf16((uint16_t*)(uintptr_t) desc.serial, sizeof(desc.serial)/2);
+ printf("\r\n");
- printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct);
printf("Device Descriptor:\r\n");
- printf(" bLength %u\r\n", desc_device.bLength);
- printf(" bDescriptorType %u\r\n", desc_device.bDescriptorType);
- printf(" bcdUSB %04x\r\n", desc_device.bcdUSB);
- printf(" bDeviceClass %u\r\n", desc_device.bDeviceClass);
- printf(" bDeviceSubClass %u\r\n", desc_device.bDeviceSubClass);
- printf(" bDeviceProtocol %u\r\n", desc_device.bDeviceProtocol);
- printf(" bMaxPacketSize0 %u\r\n", desc_device.bMaxPacketSize0);
- printf(" idVendor 0x%04x\r\n", desc_device.idVendor);
- printf(" idProduct 0x%04x\r\n", desc_device.idProduct);
- printf(" bcdDevice %04x\r\n", desc_device.bcdDevice);
+ printf(" bLength %u\r\n", desc.device.bLength);
+ printf(" bDescriptorType %u\r\n", desc.device.bDescriptorType);
+ printf(" bcdUSB %04x\r\n", desc.device.bcdUSB);
+ printf(" bDeviceClass %u\r\n", desc.device.bDeviceClass);
+ printf(" bDeviceSubClass %u\r\n", desc.device.bDeviceSubClass);
+ printf(" bDeviceProtocol %u\r\n", desc.device.bDeviceProtocol);
+ printf(" bMaxPacketSize0 %u\r\n", desc.device.bMaxPacketSize0);
+ printf(" idVendor 0x%04x\r\n", desc.device.idVendor);
+ printf(" idProduct 0x%04x\r\n", desc.device.idProduct);
+ printf(" bcdDevice %04x\r\n", desc.device.bcdDevice);
// Get String descriptor using Sync API
- printf(" iManufacturer %u ", desc_device.iManufacturer);
- xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
- if (XFER_RESULT_SUCCESS == xfer_result) {
- print_utf16(buf, TU_ARRAY_SIZE(buf));
+ printf(" iManufacturer %u ", desc.device.iManufacturer);
+ if (desc.device.iManufacturer != 0) {
+ xfer_result = tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, desc.buf, sizeof(desc.buf));
+ if (XFER_RESULT_SUCCESS == xfer_result) {
+ print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2);
+ }
}
printf("\r\n");
- printf(" iProduct %u ", desc_device.iProduct);
- xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
- if (XFER_RESULT_SUCCESS == xfer_result) {
- print_utf16(buf, TU_ARRAY_SIZE(buf));
+ printf(" iProduct %u ", desc.device.iProduct);
+ if (desc.device.iProduct != 0) {
+ xfer_result = tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, desc.buf, sizeof(desc.buf));
+ if (XFER_RESULT_SUCCESS == xfer_result) {
+ print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2);
+ }
}
printf("\r\n");
- printf(" iSerialNumber %u ", desc_device.iSerialNumber);
- xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, buf, sizeof(buf));
- if (XFER_RESULT_SUCCESS == xfer_result) {
- print_utf16(buf, TU_ARRAY_SIZE(buf));
- }
+ printf(" iSerialNumber %u ", desc.device.iSerialNumber);
+ printf((char*)desc.serial); // serial is already to UTF-8
printf("\r\n");
- printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations);
+ printf(" bNumConfigurations %u\r\n", desc.device.bNumConfigurations);
}
-/// Invoked when device is unmounted (bus reset/unplugged)
+// Invoked when device is unmounted (bus reset/unplugged)
void tuh_umount_cb(uint8_t daddr) {
+ blink_interval_ms = BLINK_NOT_MOUNTED;
printf("Device removed, address = %d\r\n", daddr);
}
//--------------------------------------------------------------------+
-// Blinking Task
-//--------------------------------------------------------------------+
-void led_blinking_task(void) {
- const uint32_t interval_ms = 1000;
- static uint32_t start_ms = 0;
-
- static bool led_state = false;
-
- // Blink every interval ms
- if (board_millis() - start_ms < interval_ms) return; // not enough time
- start_ms += interval_ms;
-
- board_led_write(led_state);
- led_state = 1 - led_state; // toggle
-}
-
-//--------------------------------------------------------------------+
// String Descriptor Helper
//--------------------------------------------------------------------+
@@ -208,3 +237,81 @@ static void print_utf16(uint16_t* temp_buf, size_t buf_len) {
printf("%s", (char*) temp_buf);
}
+
+//--------------------------------------------------------------------+
+// Blinking Task
+//--------------------------------------------------------------------+
+void led_blinking_task(void* param) {
+ (void) param;
+ static uint32_t start_ms = 0;
+ static bool led_state = false;
+
+ while (1) {
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+ vTaskDelay(blink_interval_ms / portTICK_PERIOD_MS);
+#else
+ if (board_millis() - start_ms < blink_interval_ms) {
+ return; // not enough time
+ }
+#endif
+
+ start_ms += blink_interval_ms;
+ board_led_write(led_state);
+ led_state = 1 - led_state; // toggle
+ }
+}
+
+//--------------------------------------------------------------------+
+// FreeRTOS
+//--------------------------------------------------------------------+
+#if CFG_TUSB_OS == OPT_OS_FREERTOS
+
+#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
+
+#if TUSB_MCU_VENDOR_ESPRESSIF
+ #define USB_STACK_SIZE 4096
+#else
+ // Increase stack size when debug log is enabled
+ #define USB_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
+#endif
+
+
+// static task
+#if configSUPPORT_STATIC_ALLOCATION
+StackType_t blinky_stack[BLINKY_STACK_SIZE];
+StaticTask_t blinky_taskdef;
+
+StackType_t usb_stack[USB_STACK_SIZE];
+StaticTask_t usb_taskdef;
+#endif
+
+#if TUSB_MCU_VENDOR_ESPRESSIF
+void app_main(void) {
+ main();
+}
+#endif
+
+void usb_host_task(void *param) {
+ (void) param;
+ init_tinyusb();
+ while (1) {
+ tuh_task();
+ }
+}
+
+void init_freertos_task(void) {
+#if configSUPPORT_STATIC_ALLOCATION
+ xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
+ xTaskCreateStatic(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_stack, &usb_taskdef);
+#else
+ xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
+ xTaskCreate(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
+#endif
+
+ // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
+#if !TUSB_MCU_VENDOR_ESPRESSIF
+ vTaskStartScheduler();
+#endif
+}
+
+#endif
diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h
index 2e9731eaf..e12970c12 100644
--- a/examples/host/device_info/src/tusb_config.h
+++ b/examples/host/device_info/src/tusb_config.h
@@ -39,6 +39,11 @@
#error CFG_TUSB_MCU must be defined
#endif
+// Espressif IDF requires "freertos/" prefix in include path
+#if TUSB_MCU_VENDOR_ESPRESSIF
+#define CFG_TUSB_OS_INC_PATH freertos/
+#endif
+
#ifndef CFG_TUSB_OS
#define CFG_TUSB_OS OPT_OS_NONE
#endif
@@ -69,9 +74,10 @@
// Enable Host stack
#define CFG_TUH_ENABLED 1
+// #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
- // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
// host roothub port is 1 if using either pio-usb or max3421
#if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)
@@ -104,8 +110,7 @@
// only hub class is enabled
#define CFG_TUH_HUB 1
-// max device support (excluding hub device)
-// 1 hub typically has 4 ports
+// max device support (excluding hub device): 1 hub typically has 4 ports
#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1)
#ifdef __cplusplus
diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt
index c1b500dd8..fb5faf210 100644
--- a/examples/host/hid_controller/CMakeLists.txt
+++ b/examples/host/hid_controller/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
diff --git a/examples/host/hid_controller/CMakePresets.json b/examples/host/hid_controller/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/host/hid_controller/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt
index fee10f9e2..95f9f1d82 100644
--- a/examples/host/hid_controller/only.txt
+++ b/examples/host/hid_controller/only.txt
@@ -12,3 +12,6 @@ mcu:MSP432E4
mcu:RX65X
mcu:RAXXX
mcu:MAX3421
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c
index 6ffe0b6d4..1d6ca8b07 100644
--- a/examples/host/hid_controller/src/hid_app.c
+++ b/examples/host/hid_controller/src/hid_app.c
@@ -231,14 +231,12 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
}
// check if different than 2
-bool diff_than_2(uint8_t x, uint8_t y)
-{
+static inline bool diff_than_2(uint8_t x, uint8_t y) {
return (x - y > 2) || (y - x > 2);
}
// check if 2 reports are different enough
-bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2)
-{
+static bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2) {
bool result;
// x, y, z, rz must different than 2 to be counted
@@ -251,7 +249,7 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2)
return result;
}
-void process_sony_ds4(uint8_t const* report, uint16_t len)
+static void process_sony_ds4(uint8_t const* report, uint16_t len)
{
(void)len;
const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" };
@@ -310,16 +308,13 @@ void process_sony_ds4(uint8_t const* report, uint16_t len)
}
// Invoked when received report from device via interrupt endpoint
-void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
-{
- if ( is_sony_ds4(dev_addr) )
- {
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
+ if (is_sony_ds4(dev_addr)) {
process_sony_ds4(report, len);
}
// continue to request to receive report
- if ( !tuh_hid_receive_report(dev_addr, instance) )
- {
+ if (!tuh_hid_receive_report(dev_addr, instance)) {
printf("Error: cannot request to receive report\r\n");
}
}
diff --git a/examples/host/hid_controller/src/main.c b/examples/host/hid_controller/src/main.c
index 05a5ae176..ba12774bd 100644
--- a/examples/host/hid_controller/src/main.c
+++ b/examples/host/hid_controller/src/main.c
@@ -52,7 +52,11 @@ int main(void)
printf("Note: Events only displayed for explicit supported controllers\r\n");
// init host stack on configured roothub port
- tuh_init(BOARD_TUH_RHPORT);
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUH_RHPORT, &host_init);
if (board_init_after_tusb) {
board_init_after_tusb();
diff --git a/examples/host/hid_controller/src/tusb_config.h b/examples/host/hid_controller/src/tusb_config.h
index 3ac591d8f..351fe0178 100644
--- a/examples/host/hid_controller/src/tusb_config.h
+++ b/examples/host/hid_controller/src/tusb_config.h
@@ -69,9 +69,10 @@
// Enable Host stack
#define CFG_TUH_ENABLED 1
+// #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
- // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
// host roothub port is 1 if using either pio-usb or max3421
#if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)
diff --git a/examples/host/midi_rx/CMakeLists.txt b/examples/host/midi_rx/CMakeLists.txt
new file mode 100644
index 000000000..33953233d
--- /dev/null
+++ b/examples/host/midi_rx/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.20)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
+
+# gets PROJECT name for the example
+family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
+
+project(${PROJECT} C CXX ASM)
+
+# Checks this example is valid for the family and initializes the project
+family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
+add_executable(${PROJECT})
+
+# Example source
+target_sources(${PROJECT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
+ )
+
+# Example include
+target_include_directories(${PROJECT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ )
+
+# Configure compilation flags and libraries for the example without RTOS.
+# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
+family_configure_host_example(${PROJECT} noos)
diff --git a/examples/host/midi_rx/Makefile b/examples/host/midi_rx/Makefile
new file mode 100644
index 000000000..0235e08c3
--- /dev/null
+++ b/examples/host/midi_rx/Makefile
@@ -0,0 +1,13 @@
+include ../../build_system/make/make.mk
+
+INC += \
+ src \
+ $(TOP)/hw \
+
+# Example source
+EXAMPLE_SOURCE += \
+ src/main.c
+
+SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
+
+include ../../build_system/make/rules.mk
diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt
new file mode 100644
index 000000000..b6f87f423
--- /dev/null
+++ b/examples/host/midi_rx/only.txt
@@ -0,0 +1,20 @@
+mcu:ESP32S2
+mcu:ESP32S3
+mcu:ESP32P4
+mcu:KINETIS_KL
+mcu:LPC175X_6X
+mcu:LPC177X_8X
+mcu:LPC18XX
+mcu:LPC40XX
+mcu:LPC43XX
+mcu:MAX3421
+mcu:MIMXRT1XXX
+mcu:MIMXRT10XX
+mcu:MIMXRT11XX
+mcu:MSP432E4
+mcu:RP2040
+mcu:RX65X
+mcu:RAXXX
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/midi_rx/src/main.c b/examples/host/midi_rx/src/main.c
new file mode 100644
index 000000000..78b1a11b9
--- /dev/null
+++ b/examples/host/midi_rx/src/main.c
@@ -0,0 +1,123 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bsp/board_api.h"
+#include "tusb.h"
+
+//--------------------------------------------------------------------+
+// STATIC GLOBALS DECLARATION
+//--------------------------------------------------------------------+
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF PROTOTYPES
+//--------------------------------------------------------------------+
+void led_blinking_task(void);
+void midi_host_rx_task(void);
+
+/*------------- MAIN -------------*/
+int main(void) {
+ board_init();
+
+ printf("TinyUSB Host MIDI Example\r\n");
+
+ // init host stack on configured roothub port
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUH_RHPORT, &host_init);
+
+ while (1) {
+ tuh_task();
+ led_blinking_task();
+ midi_host_rx_task();
+ }
+
+ return 0;
+}
+
+//--------------------------------------------------------------------+
+// Blinking Task
+//--------------------------------------------------------------------+
+void led_blinking_task(void) {
+ const uint32_t interval_ms = 1000;
+ static uint32_t start_ms = 0;
+
+ static bool led_state = false;
+
+ // Blink every interval ms
+ if (board_millis() - start_ms < interval_ms) return;// not enough time
+ start_ms += interval_ms;
+
+ board_led_write(led_state);
+ led_state = 1 - led_state;// toggle
+}
+
+//--------------------------------------------------------------------+
+// MIDI host receive task
+//--------------------------------------------------------------------+
+void midi_host_rx_task(void) {
+ // nothing to do, we just print out received data in callback
+}
+
+//--------------------------------------------------------------------+
+// TinyUSB Callbacks
+//--------------------------------------------------------------------+
+
+// Invoked when device with MIDI interface is mounted.
+void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data) {
+ printf("MIDI Interface Index = %u, Address = %u, Number of RX cables = %u, Number of TX cables = %u\r\n",
+ idx, mount_cb_data->daddr, mount_cb_data->rx_cable_count, mount_cb_data->tx_cable_count);
+}
+
+// Invoked when device with hid interface is un-mounted
+void tuh_midi_umount_cb(uint8_t idx) {
+ printf("MIDI Interface Index = %u is unmounted\r\n", idx);
+}
+
+void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes) {
+ if (xferred_bytes == 0) {
+ return;
+ }
+
+ uint8_t buffer[48];
+ uint8_t cable_num = 0;
+ uint32_t bytes_read = tuh_midi_stream_read(idx, &cable_num, buffer, sizeof(buffer));
+
+ printf("Cable %u rx: ", cable_num);
+ for (uint32_t i = 0; i < bytes_read; i++) {
+ printf("%02X ", buffer[i]);
+ }
+ printf("\r\n");
+}
+
+void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes) {
+ (void) idx;
+ (void) xferred_bytes;
+}
diff --git a/examples/host/midi_rx/src/tusb_config.h b/examples/host/midi_rx/src/tusb_config.h
new file mode 100644
index 000000000..c9b430388
--- /dev/null
+++ b/examples/host/midi_rx/src/tusb_config.h
@@ -0,0 +1,118 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef TUSB_CONFIG_H_
+#define TUSB_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------
+// Common Configuration
+//--------------------------------------------------------------------
+
+// defined by compiler flags for flexibility
+#ifndef CFG_TUSB_MCU
+#error CFG_TUSB_MCU must be defined
+#endif
+
+// Espressif IDF requires "freertos/" prefix in include path
+#if TUSB_MCU_VENDOR_ESPRESSIF
+#define CFG_TUSB_OS_INC_PATH freertos/
+#endif
+
+#ifndef CFG_TUSB_OS
+#define CFG_TUSB_OS OPT_OS_NONE
+#endif
+
+#ifndef CFG_TUSB_DEBUG
+#define CFG_TUSB_DEBUG 0
+#endif
+
+/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
+ * Tinyusb use follows macros to declare transferring memory so that they can be put
+ * into those specific section.
+ * e.g
+ * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
+ * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
+ */
+#ifndef CFG_TUH_MEM_SECTION
+#define CFG_TUH_MEM_SECTION
+#endif
+
+#ifndef CFG_TUH_MEM_ALIGN
+#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4)))
+#endif
+
+//--------------------------------------------------------------------
+// Host Configuration
+//--------------------------------------------------------------------
+
+// Enable Host stack
+#define CFG_TUH_ENABLED 1
+
+#if CFG_TUSB_MCU == OPT_MCU_RP2040
+ // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
+ // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
+ // host roothub port is 1 if using either pio-usb or max3421
+ #if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)
+ #define BOARD_TUH_RHPORT 1
+ #endif
+#endif
+
+// Default is max speed that hardware controller could support with on-chip PHY
+#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED
+
+//------------------------- Board Specific --------------------------
+
+// RHPort number used for host can be defined by board.mk, default to port 0
+#ifndef BOARD_TUH_RHPORT
+#define BOARD_TUH_RHPORT 0
+#endif
+
+// RHPort max operational speed can defined by board.mk
+#ifndef BOARD_TUH_MAX_SPEED
+#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED
+#endif
+
+//--------------------------------------------------------------------
+// Driver Configuration
+//--------------------------------------------------------------------
+
+// Size of buffer to hold descriptors and other data used for enumeration
+#define CFG_TUH_ENUMERATION_BUFSIZE 256
+
+#define CFG_TUH_HUB 1
+// max device support (excluding hub device): 1 hub typically has 4 ports
+#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1)
+#define CFG_TUH_MIDI CFG_TUH_DEVICE_MAX
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/examples/host/msc_file_explorer/CMakeLists.txt b/examples/host/msc_file_explorer/CMakeLists.txt
index 1a57c7466..5ac75c04a 100644
--- a/examples/host/msc_file_explorer/CMakeLists.txt
+++ b/examples/host/msc_file_explorer/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.17)
+cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
diff --git a/examples/host/msc_file_explorer/CMakePresets.json b/examples/host/msc_file_explorer/CMakePresets.json
new file mode 100644
index 000000000..5cd8971e9
--- /dev/null
+++ b/examples/host/msc_file_explorer/CMakePresets.json
@@ -0,0 +1,6 @@
+{
+ "version": 6,
+ "include": [
+ "../../../hw/bsp/BoardPresets.json"
+ ]
+}
diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt
index fee10f9e2..95f9f1d82 100644
--- a/examples/host/msc_file_explorer/only.txt
+++ b/examples/host/msc_file_explorer/only.txt
@@ -12,3 +12,6 @@ mcu:MSP432E4
mcu:RX65X
mcu:RAXXX
mcu:MAX3421
+mcu:STM32F4
+mcu:STM32F7
+mcu:STM32H7
diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c
index f6b6810f5..8197c3c8d 100644
--- a/examples/host/msc_file_explorer/src/main.c
+++ b/examples/host/msc_file_explorer/src/main.c
@@ -62,15 +62,13 @@
#include "bsp/board_api.h"
#include "tusb.h"
+#include "msc_app.h"
+
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
void led_blinking_task(void);
-// from msc_app.c
-extern bool msc_app_init(void);
-extern void msc_app_task(void);
-
/*------------- MAIN -------------*/
int main(void) {
board_init();
@@ -78,7 +76,11 @@ int main(void) {
printf("TinyUSB Host MassStorage Explorer Example\r\n");
// init host stack on configured roothub port
- tuh_init(BOARD_TUH_RHPORT);
+ tusb_rhport_init_t host_init = {
+ .role = TUSB_ROLE_HOST,
+ .speed = TUSB_SPEED_AUTO
+ };
+ tusb_init(BOARD_TUH_RHPORT, &host_init);
if (board_init_after_tusb) {
board_init_after_tusb();
diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c
index ddd39c674..40a9ef57e 100644
--- a/examples/host/msc_file_explorer/src/msc_app.c
+++ b/examples/host/msc_file_explorer/src/msc_app.c
@@ -34,6 +34,8 @@
#define EMBEDDED_CLI_IMPL
#include "embedded_cli.h"
+#include "msc_app.h"
+
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
@@ -53,7 +55,11 @@ static CLI_UINT cli_buffer[BYTES_TO_CLI_UINTS(CLI_BUFFER_SIZE)];
static FATFS fatfs[CFG_TUH_DEVICE_MAX]; // for simplicity only support 1 LUN per device
static volatile bool _disk_busy[CFG_TUH_DEVICE_MAX];
-static scsi_inquiry_resp_t inquiry_resp;
+// define the buffer to be place in USB/DMA memory with correct alignment/cache line size
+CFG_TUH_MEM_SECTION static struct {
+ TUH_EPBUF_TYPE_DEF(scsi_inquiry_resp_t, inquiry);
+} scsi_resp;
+
//--------------------------------------------------------------------+
//
@@ -63,7 +69,9 @@ bool cli_init(void);
bool msc_app_init(void)
{
- for(size_t i=0; i<CFG_TUH_DEVICE_MAX; i++) _disk_busy[i] = false;
+ for(size_t i=0; i<CFG_TUH_DEVICE_MAX; i++) {
+ _disk_busy[i] = false;
+ }
// disable stdout buffered for echoing typing command
#ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
@@ -77,7 +85,9 @@ bool msc_app_init(void)
void msc_app_task(void)
{
- if (!_cli) return;
+ if (!_cli) {
+ return;
+ }
int ch = board_getchar();
if ( ch > 0 )
@@ -95,8 +105,7 @@ void msc_app_task(void)
//
//--------------------------------------------------------------------+
-bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
-{
+static bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data) {
msc_cbw_t const* cbw = cb_data->cbw;
msc_csw_t const* csw = cb_data->csw;
@@ -107,7 +116,7 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da
}
// Print out Vendor ID, Product ID and Rev
- printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
+ printf("%.8s %.16s rev %.4s\r\n", scsi_resp.inquiry.vendor_id, scsi_resp.inquiry.product_id, scsi_resp.inquiry.product_rev);
// Get capacity of device
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
@@ -145,7 +154,7 @@ void tuh_msc_mount_cb(uint8_t dev_addr)
printf("A MassStorage device is mounted\r\n");
uint8_t const lun = 0;
- tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
+ tuh_msc_inquiry(dev_addr, lun, &scsi_resp.inquiry, inquiry_complete_cb, 0);
}
void tuh_msc_umount_cb(uint8_t dev_addr)
@@ -290,18 +299,11 @@ void cli_cmd_mkdir(EmbeddedCli *cli, char *args, void *context);
void cli_cmd_mv(EmbeddedCli *cli, char *args, void *context);
void cli_cmd_rm(EmbeddedCli *cli, char *args, void *context);
-void cli_write_char(EmbeddedCli *cli, char c)
-{
+static void cli_write_char(EmbeddedCli *cli, char c) {
(void) cli;
putchar((int) c);
}
-void cli_cmd_unknown(EmbeddedCli *cli, CliCommand *command)
-{
- (void) cli;
- printf("%s: command not found\r\n", command->name);
-}
-
bool cli_init(void)
{
EmbeddedCliConfig *config = embeddedCliDefaultConfig();
diff --git a/examples/host/msc_file_explorer/src/msc_app.h b/examples/host/msc_file_explorer/src/msc_app.h
new file mode 100644
index 000000000..3ba03d0dc
--- /dev/null
+++ b/examples/host/msc_file_explorer/src/msc_app.h
@@ -0,0 +1,35 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2025 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+#ifndef MSC_APP_H
+#define MSC_APP_H
+
+#include <stdbool.h>
+
+bool msc_app_init(void);
+void msc_app_task(void);
+
+
+#endif
diff --git a/examples/host/msc_file_explorer/src/tusb_config.h b/examples/host/msc_file_explorer/src/tusb_config.h
index c798b4383..c1829c300 100644
--- a/examples/host/msc_file_explorer/src/tusb_config.h
+++ b/examples/host/msc_file_explorer/src/tusb_config.h
@@ -69,9 +69,10 @@
// Enable Host stack
#define CFG_TUH_ENABLED 1
+// #define CFG_TUH_MAX3421 1 // use max3421 as host controller
+
#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
- // #define CFG_TUH_MAX3421 1 // use max3421 as host controller
// host roothub port is 1 if using either pio-usb or max3421
#if (defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB) || (defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)