diff options
Diffstat (limited to 'examples/host')
47 files changed, 673 insertions, 572 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 95f9f1d82..dcdaf41c7 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -15,3 +15,5 @@ mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:STM32H7RS +mcu:STM32N6 diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index f582f4f5a..0c76ff0c9 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -55,16 +55,15 @@ 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 tusb_rhport_init_t host_init = { - .role = TUSB_ROLE_HOST, - .speed = TUSB_SPEED_AUTO + .role = TUSB_ROLE_HOST, + .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); @@ -72,8 +71,7 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { // tinyusb host task tuh_task(); led_blinking_task(); @@ -85,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 @@ -95,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); } @@ -104,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; } @@ -131,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); } } @@ -171,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); } @@ -210,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; } @@ -246,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 @@ -299,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"); @@ -329,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]; } @@ -345,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; } } @@ -356,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 95f9f1d82..dcdaf41c7 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -15,3 +15,5 @@ mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:STM32H7RS +mcu:STM32N6 diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c index 4a13f8b27..97f1a96d6 100644 --- a/examples/host/cdc_msc_hid/src/cdc_app.c +++ b/examples/host/cdc_msc_hid/src/cdc_app.c @@ -27,12 +27,11 @@ #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(); - if (ch <= 0) break; - + if (ch <= 0) { break; } buf[count] = (uint8_t) ch; count++; } @@ -69,10 +68,15 @@ void tuh_cdc_rx_cb(uint8_t idx) { uint32_t const bufsize = sizeof(buf) - 1; // forward cdc interfaces -> console - uint32_t count = tuh_cdc_read(idx, buf, bufsize); - buf[count] = 0; + const uint32_t count = tuh_cdc_read(idx, buf, bufsize); + if (count) { + buf[count] = 0; + printf("%s", (char*) buf); - printf("%s", (char*) buf); + #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? + fflush(stdout);// flush right away, else nanolib will wait for newline + #endif + } } // Invoked when a device with CDC interface is mounted @@ -88,7 +92,7 @@ void tuh_cdc_mount_cb(uint8_t idx) { // If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack // while eneumerating new cdc device cdc_line_coding_t line_coding = {0}; - if (tuh_cdc_get_local_line_coding(idx, &line_coding)) { + if (tuh_cdc_get_line_coding_local(idx, &line_coding)) { printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits); printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits); } diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 3f98ec89f..6f01d6f45 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -29,28 +29,21 @@ //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ +#define MAX_REPORT 4 -// If your host terminal support ansi escape code such as TeraTerm -// it can be use to simulate mouse cursor movement within terminal -#define USE_ANSI_ESCAPE 0 - -#define MAX_REPORT 4 - -static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII }; +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); +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 +56,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. + // By default, host stack will use 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,7 +116,7 @@ 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) { +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; @@ -139,28 +125,25 @@ static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8 return false; } -static void process_kbd_report(hid_keyboard_report_t const *report) -{ - static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released +static void process_kbd_report(hid_keyboard_report_t const *report) { + static hid_keyboard_report_t prev_report = {0, 0, {0}};// previous report to check key released //------------- example code ignore control (non-printable) key affects -------------// - for(uint8_t i=0; i<6; i++) - { - if ( report->keycode[i] ) - { - if ( find_key_in_report(&prev_report, report->keycode[i]) ) - { + for (uint8_t i = 0; i < 6; i++) { + if (report->keycode[i]) { + if (find_key_in_report(&prev_report, report->keycode[i])) { // exist in previous report means the current key is holding - }else - { + } else { // not existed in previous report means the current key is pressed bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT); uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0]; putchar(ch); - if ( ch == '\r' ) putchar('\n'); // added new line for enter key + if (ch == '\r') { + putchar('\n'); + } - #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? - fflush(stdout); // flush right away, else nanolib will wait for newline + #ifndef __ICCARM__ // TODO IAR doesn't support stream control ? + fflush(stdout);// flush right away, else nanolib will wait for newline #endif } } @@ -174,86 +157,47 @@ static void process_kbd_report(hid_keyboard_report_t const *report) // Mouse //--------------------------------------------------------------------+ -void cursor_movement(int8_t x, int8_t y, int8_t wheel) -{ -#if USE_ANSI_ESCAPE - // Move X using ansi escape - if ( x < 0) - { - printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left - }else if ( x > 0) - { - printf(ANSI_CURSOR_FORWARD(%d), x); // move right - } - - // Move Y using ansi escape - if ( y < 0) - { - printf(ANSI_CURSOR_UP(%d), (-y)); // move up - }else if ( y > 0) - { - printf(ANSI_CURSOR_DOWN(%d), y); // move down - } - - // Scroll using ansi escape - if (wheel < 0) - { - printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up - }else if (wheel > 0) - { - printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down - } - - printf("\r\n"); -#else +static void cursor_movement(int8_t x, int8_t y, int8_t wheel) { printf("(%d %d %d)\r\n", x, y, wheel); -#endif } -static void process_mouse_report(hid_mouse_report_t const * report) -{ - static hid_mouse_report_t prev_report = { 0 }; +static void process_mouse_report(hid_mouse_report_t const *report) { + static hid_mouse_report_t prev_report = {0}; - //------------- button state -------------// + // button state uint8_t button_changed_mask = report->buttons ^ prev_report.buttons; - if ( button_changed_mask & report->buttons) - { + if (button_changed_mask & report->buttons) { printf(" %c%c%c ", - report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', - report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', - report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); + report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-', + report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-', + report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-'); } - //------------- cursor movement -------------// + // cursor movement cursor_movement(report->x, report->y, report->wheel); } //--------------------------------------------------------------------+ // 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; } @@ -263,8 +207,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; } @@ -276,23 +219,27 @@ 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"); + TU_LOG2("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"); + TU_LOG2("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: + printf("report[%u] ", rpt_info->report_id); + for (uint8_t i = 0; i < len; i++) { + printf("%02X ", report[i]); + } + printf("\r\n"); + break; } } } diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 71257c0fe..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(); @@ -82,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); } @@ -101,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/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index 1d7e18e6e..0e9c99766 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -30,13 +30,11 @@ //--------------------------------------------------------------------+ static scsi_inquiry_resp_t inquiry_resp; -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; - if (csw->status != 0) - { + if (csw->status != 0) { printf("Inquiry failed\r\n"); return false; } @@ -55,16 +53,14 @@ bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_da } //------------- IMPLEMENTATION -------------// -void tuh_msc_mount_cb(uint8_t dev_addr) -{ +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); } -void tuh_msc_umount_cb(uint8_t dev_addr) -{ +void tuh_msc_umount_cb(uint8_t dev_addr) { (void) dev_addr; printf("A MassStorage device is unmounted\r\n"); } diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index a59a0ffb9..2f8cb5e03 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) @@ -102,10 +103,11 @@ #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // number of supported hubs -#define CFG_TUH_CDC 1 // CDC ACM +#define CFG_TUH_CDC 2 // number of supported CDC devices. also activates CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_PL2303 1 // PL2303 Serial. PL2303 is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 @@ -121,7 +123,7 @@ // Set Line Control state on enumeration/mounted: // DTR ( bit 0), RTS (bit 1) -#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM (CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS) // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width diff --git a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt index b4004f8d7..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) 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 67fbb9af3..178341f81 100644 --- a/examples/host/cdc_msc_hid_freertos/Makefile +++ b/examples/host/cdc_msc_hid_freertos/Makefile @@ -1,14 +1,9 @@ +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 = \ @@ -19,15 +14,4 @@ EXAMPLE_SOURCE = \ 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 e3ae25260..d939d4e7b 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -13,3 +13,5 @@ mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:STM32H7RS +mcu:STM32N6 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 6a886adec..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 TUSB_MCU_VENDOR_ESPRESSIF - #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 7cbe1e03a..d99760a02 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -27,7 +27,7 @@ #include "tusb.h" #include "bsp/board_api.h" -#if TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM #define CDC_STACK_SZIE 2048 #else #define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2) @@ -52,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/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index 10d1b120b..0bcb355ec 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -30,7 +30,7 @@ #include "bsp/board_api.h" #include "tusb.h" -#if TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM #define USBH_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled @@ -69,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(); @@ -92,15 +86,15 @@ int main(void) { xTimerStart(blinky_tm, 0); - // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TUSB_MCU_VENDOR_ESPRESSIF + // only start scheduler for non-espressif mcu +#ifndef ESP_PLATFORM vTaskStartScheduler(); #endif return 0; } -#if TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM void app_main(void) { main(); } 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 6b9cdab85..6439495a8 100644 --- a/examples/host/cdc_msc_hid_freertos/src/msc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c @@ -34,7 +34,7 @@ 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; 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 02de4197b..3cdb227e2 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 TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM #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) @@ -107,10 +108,11 @@ #define CFG_TUH_ENUMERATION_BUFSIZE 256 #define CFG_TUH_HUB 1 // number of supported hubs -#define CFG_TUH_CDC 1 // CDC ACM +#define CFG_TUH_CDC 1 // number of supported CDC devices. also activates CDC ACM #define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API +#define CFG_TUH_CDC_PL2303 1 // PL2303 Serial. PL2303 is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 @@ -126,7 +128,7 @@ // Set Line Control state on enumeration/mounted: // DTR ( bit 0), RTS (bit 1) -#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03 +#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM (CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS) // Set Line Coding on enumeration/mounted, value for cdc_line_coding_t // bit rate = 115200, 1 stop bit, no parity, 8 bit data width diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt index 6a16155ec..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) 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 b6f87f423..b5a4b6739 100644 --- a/examples/host/device_info/only.txt +++ b/examples/host/device_info/only.txt @@ -18,3 +18,5 @@ mcu:RAXXX mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:STM32H7RS +mcu:STM32N6 diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index 775968c16..7189972d6 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -81,7 +81,7 @@ void init_freertos_task(void); //-------------------------------------------------------------------- // Main //-------------------------------------------------------------------- -void init_tinyusb(void) { +static void init_tinyusb(void) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, @@ -124,13 +124,18 @@ void tuh_mount_cb(uint8_t daddr) { } printf("Device %u: ID %04x:%04x SN ", daddr, desc.device.idVendor, desc.device.idProduct); - xfer_result = tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, desc.serial, sizeof(desc.serial)); + + 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] = 'n'; - serial[1] = '/'; - serial[2] = 'a'; - serial[3] = 0; + 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"); @@ -150,16 +155,20 @@ void tuh_mount_cb(uint8_t daddr) { // Get String descriptor using Sync API printf(" iManufacturer %u ", desc.device.iManufacturer); - 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); + 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, desc.buf, sizeof(desc.buf)); - if (XFER_RESULT_SUCCESS == xfer_result) { - print_utf16((uint16_t*)(uintptr_t) desc.buf, sizeof(desc.buf)/2); + 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"); @@ -259,7 +268,7 @@ void led_blinking_task(void* param) { #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE -#if TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM #define USB_STACK_SIZE 4096 #else // Increase stack size when debug log is enabled @@ -276,7 +285,7 @@ StackType_t usb_stack[USB_STACK_SIZE]; StaticTask_t usb_taskdef; #endif -#if TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM void app_main(void) { main(); } @@ -299,8 +308,8 @@ void init_freertos_task(void) { 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 + // only start scheduler for non-espressif mcu +#ifndef ESP_PLATFORM vTaskStartScheduler(); #endif } diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h index 5190b5b1f..e4ca2528e 100644 --- a/examples/host/device_info/src/tusb_config.h +++ b/examples/host/device_info/src/tusb_config.h @@ -40,7 +40,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TUSB_MCU_VENDOR_ESPRESSIF +#ifdef ESP_PLATFORM #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) @@ -109,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 95f9f1d82..dcdaf41c7 100644 --- a/examples/host/hid_controller/only.txt +++ b/examples/host/hid_controller/only.txt @@ -15,3 +15,5 @@ mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:STM32H7RS +mcu:STM32N6 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/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..b5a4b6739 --- /dev/null +++ b/examples/host/midi_rx/only.txt @@ -0,0 +1,22 @@ +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 +mcu:STM32H7RS +mcu:STM32N6 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..76bdf87f3 --- /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 +#ifdef ESP_PLATFORM +#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/Makefile b/examples/host/msc_file_explorer/Makefile index c7d6a7cae..f0872376f 100644 --- a/examples/host/msc_file_explorer/Makefile +++ b/examples/host/msc_file_explorer/Makefile @@ -22,6 +22,6 @@ SRC_C += \ $(FATFS_PATH)/ffunicode.c \ # suppress warning caused by fatfs -CFLAGS += -Wno-error=cast-qual +CFLAGS_GCC += -Wno-error=cast-qual include ../../build_system/make/rules.mk diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt index 95f9f1d82..dcdaf41c7 100644 --- a/examples/host/msc_file_explorer/only.txt +++ b/examples/host/msc_file_explorer/only.txt @@ -15,3 +15,5 @@ mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:STM32H7RS +mcu:STM32N6 diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c index 9509035b4..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(); diff --git a/examples/host/msc_file_explorer/src/msc_app.c b/examples/host/msc_file_explorer/src/msc_app.c index 035d74689..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 @@ -67,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 ? @@ -81,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 ) @@ -99,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; @@ -294,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) |
