From 1b338b288c3e1b91f8b2b77ef3305142188f922e Mon Sep 17 00:00:00 2001 From: caleb crome Date: Tue, 1 Mar 2022 17:24:28 -0800 Subject: in TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR, _nitfs should be 3. I believe that there is a mistake in the definition of TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR. The nitfs in the audio descriptor is always 3 regardless of ITF_NUM_TOTAL. --- examples/device/uac2_headset/src/usb_descriptors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h index d9510ea4f..342b4fac1 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.h +++ b/examples/device/uac2_headset/src/usb_descriptors.h @@ -86,7 +86,7 @@ enum #define TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(_stridx, _epout, _epin) \ /* Standard Interface Association Descriptor (IAD) */\ - TUD_AUDIO_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ ITF_NUM_TOTAL, /*_stridx*/ 0x00),\ + TUD_AUDIO_DESC_IAD(/*_firstitfs*/ ITF_NUM_AUDIO_CONTROL, /*_nitfs*/ 3, /*_stridx*/ 0x00),\ /* Standard AC Interface Descriptor(4.7.1) */\ TUD_AUDIO_DESC_STD_AC(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_nEPs*/ 0x00, /*_stridx*/ _stridx),\ /* Class-Specific AC Interface Header Descriptor(4.7.2) */\ -- cgit v1.3.1 From db9d97c9473f29ad59a87d641e6d41a27a00f332 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 11:03:29 +0700 Subject: add tuh_descriptor_hid_report_get() --- examples/host/bare_api/src/main.c | 48 +++++++++++++++++++++++++++++++++------ src/class/hid/hid_host.c | 17 +------------- src/host/usbh.c | 22 ++++++++++++++++++ src/host/usbh.h | 3 +++ 4 files changed, 67 insertions(+), 23 deletions(-) (limited to 'examples') diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index b6b1527c0..2fe5999bc 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -64,23 +64,57 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -void print_device_descriptor(uint8_t dev_addr) +uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); + +tusb_desc_device_t desc_device; + +bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result) { - (void) dev_addr; + (void) request; + + if ( XFER_RESULT_SUCCESS != result ) + { + printf("Failed to get device descriptor\r\n"); + return false; + } + + printf("Rhport %u Device %u: ID %04x:%04x\r\n", 0, 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(" iManufacturer %u\r\n", desc_device.iManufacturer); + printf(" iProduct %u\r\n", desc_device.iProduct); + printf(" iSerialNumber %u\r\n", desc_device.iSerialNumber); + + printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations); + + return true; } // Invoked when device is mounted (configured) -void tuh_mount_cb (uint8_t dev_addr) +void tuh_mount_cb (uint8_t daddr) { - printf("Device attached, address = %d\r\n", dev_addr); - print_device_descriptor(dev_addr); + printf("Device attached, address = %d\r\n", daddr); + + // get device descriptor + tuh_descriptor_device_get(daddr, &desc_device, 18, print_device_descriptor); } /// Invoked when device is unmounted (bus reset/unplugged) -void tuh_umount_cb(uint8_t dev_addr) +void tuh_umount_cb(uint8_t daddr) { - printf("Device removed, address = %d\r\n", dev_addr); + printf("Device removed, address = %d\r\n", daddr); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 9190642c6..32bb775b0 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -409,22 +409,7 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_LOG2("HID Get Report Descriptor\r\n"); - tusb_control_request_t const new_request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_u16(hid_itf->report_desc_type, 0), - .wIndex = itf_num, - .wLength = hid_itf->report_desc_len - }; - - TU_ASSERT(tuh_control_xfer(dev_addr, &new_request, usbh_get_enum_buf(), config_get_report_desc_complete)); + TU_ASSERT(tuh_descriptor_hid_report_get(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); } return true; diff --git a/src/host/usbh.c b/src/host/usbh.c index 192979ce6..b047179c5 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -299,6 +299,7 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { + len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); } @@ -361,6 +362,27 @@ bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); } +// Get HID report descriptor +bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +{ + TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, 0)), + .wIndex = itf_num, + .wLength = len + }; + + return tuh_control_xfer(daddr, &request, buffer, complete_cb); +} + bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_complete_cb_t complete_cb) { TU_LOG2("Set Configuration = %d\r\n", config_num); diff --git a/src/host/usbh.h b/src/host/usbh.h index 9465d1d1b..6fea2fac5 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -112,6 +112,9 @@ bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void // Get serial string descriptor bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +// Get HID report descriptor +bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); + //--------------------------------------------------------------------+ // APPLICATION CALLBACK //--------------------------------------------------------------------+ -- cgit v1.3.1 From f920e1c17102cac04b20ad3908efff24d96d8e7c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Mar 2022 11:21:13 +0700 Subject: rename host descriptor function --- examples/host/bare_api/src/main.c | 2 +- src/class/hid/hid_host.c | 2 +- src/host/usbh.c | 28 ++++++++++++++-------------- src/host/usbh.h | 14 +++++++------- 4 files changed, 23 insertions(+), 23 deletions(-) (limited to 'examples') diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 2fe5999bc..5f8f886c8 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -108,7 +108,7 @@ void tuh_mount_cb (uint8_t daddr) printf("Device attached, address = %d\r\n", daddr); // get device descriptor - tuh_descriptor_device_get(daddr, &desc_device, 18, print_device_descriptor); + tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor); } /// Invoked when device is unmounted (bus reset/unplugged) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 32bb775b0..323debe69 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -409,7 +409,7 @@ static bool config_get_report_desc(uint8_t dev_addr, tusb_control_request_t cons config_driver_mount_complete(dev_addr, instance, NULL, 0); }else { - TU_ASSERT(tuh_descriptor_hid_report_get(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); + TU_ASSERT(tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, usbh_get_enum_buf(), hid_itf->report_desc_len, config_get_report_desc_complete)); } return true; diff --git a/src/host/usbh.c b/src/host/usbh.c index b047179c5..74c763552 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -297,18 +297,18 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer return true; } -bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { len = tu_min16(len, sizeof(tusb_desc_device_t)); return tuh_descriptor_get(daddr, TUSB_DESC_DEVICE, 0, buffer, len, complete_cb); } -bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { return tuh_descriptor_get(daddr, TUSB_DESC_CONFIGURATION, index, buffer, len, complete_cb); } -bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, +bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { tusb_control_request_t const request = @@ -330,40 +330,40 @@ bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t inde } // Get manufacturer string descriptor -bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_manufacturer == 0) { return false; } - return tuh_descriptor_string_get(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_manufacturer, buffer, len, complete_cb); } // Get product string descriptor -bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_product == 0) { return false; } - return tuh_descriptor_string_get(daddr, language_id, dev->i_product, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_product, buffer, len, complete_cb); } // Get serial string descriptor -bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_VERIFY(tuh_mounted(daddr)); usbh_device_t const* dev = get_device(daddr); if (dev->i_serial == 0) { return false; } - return tuh_descriptor_string_get(daddr, language_id, dev->i_serial, buffer, len, complete_cb); + return tuh_descriptor_get_string(daddr, language_id, dev->i_serial, buffer, len, complete_cb); } // Get HID report descriptor -bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb) { TU_LOG2("HID Get Report Descriptor\r\n"); tusb_control_request_t const request = @@ -868,7 +868,7 @@ static bool enum_request_addr0_device_desc(void) // Get first 8 bytes of device descriptor for Control Endpoint size TU_LOG2("Get 8 byte of Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_device_get(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); + TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, enum_get_addr0_device_desc_complete)); return true; } @@ -977,7 +977,7 @@ static bool enum_set_address_complete(uint8_t dev_addr, tusb_control_request_t c // Get full device descriptor TU_LOG2("Get Device Descriptor\r\n"); - TU_ASSERT(tuh_descriptor_device_get(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); + TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), enum_get_device_desc_complete)); return true; } @@ -1000,7 +1000,7 @@ static bool enum_get_device_desc_complete(uint8_t dev_addr, tusb_control_request // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, enum_get_9byte_config_desc_complete) ); return true; } @@ -1020,7 +1020,7 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_configuration_get(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); + TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, enum_get_config_desc_complete) ); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 6fea2fac5..31d63d6a7 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -94,26 +94,26 @@ bool tuh_descriptor_get(uint8_t daddr, uint8_t type, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get device descriptor -bool tuh_descriptor_device_get(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_device(uint8_t daddr, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get configuration descriptor -bool tuh_descriptor_configuration_get(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_configuration(uint8_t daddr, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get string descriptor -bool tuh_descriptor_string_get(uint8_t daddr, uint16_t language_id, uint8_t index, +bool tuh_descriptor_get_string(uint8_t daddr, uint16_t language_id, uint8_t index, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get manufacturer string descriptor -bool tuh_descriptor_string_manufacturer_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_manufacturer_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get product string descriptor -bool tuh_descriptor_string_product_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_product_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get serial string descriptor -bool tuh_descriptor_string_serial_get(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); // Get HID report descriptor -bool tuh_descriptor_hid_report_get(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); +bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, void* buffer, uint16_t len, tuh_control_complete_cb_t complete_cb); //--------------------------------------------------------------------+ // APPLICATION CALLBACK -- cgit v1.3.1 From 22f682c37879a38aa662c2205d411b2246d0639c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 9 Mar 2022 15:22:31 -0800 Subject: Add host example that prints out info of connected devices --- examples/host/device_info/CMakeLists.txt | 27 +++++ examples/host/device_info/Makefile | 28 +++++ examples/host/device_info/only.txt | 9 ++ examples/host/device_info/src/main.c | 175 ++++++++++++++++++++++++++++ examples/host/device_info/src/tusb_config.h | 96 +++++++++++++++ 5 files changed, 335 insertions(+) create mode 100644 examples/host/device_info/CMakeLists.txt create mode 100644 examples/host/device_info/Makefile create mode 100644 examples/host/device_info/only.txt create mode 100644 examples/host/device_info/src/main.c create mode 100644 examples/host/device_info/src/tusb_config.h (limited to 'examples') diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt new file mode 100644 index 000000000..bff281a8c --- /dev/null +++ b/examples/host/device_info/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.5) + +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}) + +# Checks this example is valid for the family and initializes the project +family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) + +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... see the corresponding function +# in hw/bsp/FAMILY/family.cmake for details. +family_configure_host_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/device_info/Makefile b/examples/host/device_info/Makefile new file mode 100644 index 000000000..c59369ffa --- /dev/null +++ b/examples/host/device_info/Makefile @@ -0,0 +1,28 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += \ + src/main.c + +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# TODO: suppress warning caused by host stack +CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference + +# TinyUSB Host Stack source +SRC_C += \ + src/class/cdc/cdc_host.c \ + src/class/hid/hid_host.c \ + src/class/msc/msc_host.c \ + src/host/hub.c \ + src/host/usbh.c \ + src/host/usbh_control.c \ + src/portable/ohci/ohci.c \ + src/portable/nxp/lpc17_40/hcd_lpc17_40.c + +include ../../rules.mk diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt new file mode 100644 index 000000000..7fe4e3f5c --- /dev/null +++ b/examples/host/device_info/only.txt @@ -0,0 +1,9 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 +mcu:RX65X diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c new file mode 100644 index 000000000..45b616af0 --- /dev/null +++ b/examples/host/device_info/src/main.c @@ -0,0 +1,175 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries + * + * 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 example prints out info about the enumerated devices. */ + + +#include +#include +#include + +#include "bsp/board.h" +#include "tusb.h" + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ +void led_blinking_task(void); + +static xfer_result_t _get_string_result; + +static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { + (void)daddr; + (void)request; + _get_string_result = result; + return true; +} + +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. + + for (size_t i = 0; i < utf16_len; i++) { + uint16_t chr = utf16[i]; + if (chr < 0x80) { + *utf8++ = chr & 0xff; + } 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. + } + return total_bytes; +} + +static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { + while (_get_string_result == 0xff) { + tuh_task(); + } + size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = _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'; +} + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + printf("TinyUSB Host Device Info Example\r\n"); + + tusb_init(); + + uint32_t interval_ms = 5000; + uint32_t start_time = 0; + + while (1) + { + // tinyusb host task + tuh_task(); + led_blinking_task(); + + if (board_millis() - start_time < interval_ms) { + continue; + } + start_time = board_millis(); + // Brute force check every device address to see if it is active. + for (int i = 1; i < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1; i++) { + if (!tuh_ready(i)) { + continue; + } + uint16_t vid; + uint16_t pid; + tuh_vid_pid_get(i, &vid, &pid); + printf("%d vid %04x pid %04x\r\n", i, vid, pid); + + _get_string_result = 0xff; + uint16_t temp_buf[127]; + if (tuh_descriptor_string_serial_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf("Serial: %s\r\n", (const char*) temp_buf); + } + + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_string_product_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf("Product: %s\r\n", (const char*) temp_buf); + } + + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_string_manufacturer_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf("Manufacturer: %s\r\n", (const char*) temp_buf); + } + } + printf("\n"); + } + + 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 +} diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h new file mode 100644 index 000000000..6b413e46f --- /dev/null +++ b/examples/host/device_info/src/tusb_config.h @@ -0,0 +1,96 @@ +/* + * 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 + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) +#else + #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST +#endif + +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* 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_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// CONFIGURATION +//-------------------------------------------------------------------- + +// Size of buffer to hold descriptors and other data used for enumeration +#define CFG_TUH_ENUMERATION_BUFSIZE 256 + +// only hub class is enabled +#define CFG_TUH_HUB 1 + +// max device support (excluding hub device) +// 1 hub typically has 4 ports +#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) + +#define CFG_TUH_ENDPOINT_MAX 8 + +#define CFG_TUH_TASK_QUEUE_SZ 64 + +//------------- HID -------------// + +#define CFG_TUH_HID_EP_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ -- cgit v1.3.1 From 37960990a5fb0a42a5faa19230f0051efaa4e6c0 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 10 Mar 2022 11:01:44 -0800 Subject: Print speed. Don't crash if string get fails --- examples/host/device_info/src/main.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'examples') diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index 45b616af0..e6149db89 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -90,6 +90,10 @@ static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { while (_get_string_result == 0xff) { tuh_task(); } + if (_get_string_result != XFER_RESULT_SUCCESS) { + temp_buf[0] = 0; + return; + } size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); size_t utf8_len = _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); @@ -128,6 +132,21 @@ int main(void) tuh_vid_pid_get(i, &vid, &pid); printf("%d vid %04x pid %04x\r\n", i, vid, pid); + tusb_speed_t speed = tuh_speed_get(i); + switch (speed) { + case TUSB_SPEED_FULL: + printf("Full speed\r\n"); + break; + case TUSB_SPEED_LOW: + printf("Low speed\r\n"); + break; + case TUSB_SPEED_HIGH: + printf("High speed\r\n"); + break; + default: + break; + } + _get_string_result = 0xff; uint16_t temp_buf[127]; if (tuh_descriptor_string_serial_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { -- cgit v1.3.1 From a715077b1079993f4cd01bbf54b8166a6612b29b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Mar 2022 09:57:35 +0700 Subject: remove usbh_control.c --- examples/host/bare_api/Makefile | 1 - examples/host/cdc_msc_hid/Makefile | 1 - examples/host/hid_controller/Makefile | 1 - examples/host/hid_to_cdc/Makefile | 3 +- hw/bsp/rp2040/family.cmake | 1 - src/host/usbh_control.c | 85 ----------------------------------- 6 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 src/host/usbh_control.c (limited to 'examples') diff --git a/examples/host/bare_api/Makefile b/examples/host/bare_api/Makefile index c59369ffa..13e14df53 100644 --- a/examples/host/bare_api/Makefile +++ b/examples/host/bare_api/Makefile @@ -21,7 +21,6 @@ SRC_C += \ src/class/msc/msc_host.c \ src/host/hub.c \ src/host/usbh.c \ - src/host/usbh_control.c \ src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile index ce0dd1a40..272acbac8 100644 --- a/examples/host/cdc_msc_hid/Makefile +++ b/examples/host/cdc_msc_hid/Makefile @@ -19,7 +19,6 @@ SRC_C += \ src/class/msc/msc_host.c \ src/host/hub.c \ src/host/usbh.c \ - src/host/usbh_control.c \ src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index c58df562b..06dc56914 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -22,7 +22,6 @@ SRC_C += \ src/class/msc/msc_host.c \ src/host/hub.c \ src/host/usbh.c \ - src/host/usbh_control.c \ src/portable/ohci/ohci.c \ src/portable/nxp/lpc17_40/hcd_lpc17_40.c diff --git a/examples/host/hid_to_cdc/Makefile b/examples/host/hid_to_cdc/Makefile index b62a383eb..3fe9b0888 100644 --- a/examples/host/hid_to_cdc/Makefile +++ b/examples/host/hid_to_cdc/Makefile @@ -14,7 +14,6 @@ CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference SRC_C += \ src/class/hid/hid_host.c \ src/host/hub.c \ - src/host/usbh.c \ - src/host/usbh_control.c + src/host/usbh.c include ../../rules.mk diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index 1aa180ef8..e832c0756 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -83,7 +83,6 @@ if (NOT TARGET _rp2040_family_inclusion_marker) ${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c ${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c ${TOP}/src/host/usbh.c - ${TOP}/src/host/usbh_control.c ${TOP}/src/host/hub.c ${TOP}/src/class/cdc/cdc_host.c ${TOP}/src/class/hid/hid_host.c diff --git a/src/host/usbh_control.c b/src/host/usbh_control.c deleted file mode 100644 index 38f03a8d2..000000000 --- a/src/host/usbh_control.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2020, 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. - */ - -#include "tusb_option.h" - -#if CFG_TUH_ENABLED && 0 - -#include "tusb.h" -#include "usbh_classdriver.h" - -typedef struct -{ - tusb_control_request_t request TU_ATTR_ALIGNED(4); - uint8_t* buffer; - tuh_control_complete_cb_t complete_cb; - - uint8_t daddr; -} usbh_control_xfer_t; - -static usbh_control_xfer_t _xfer; -static uint8_t _stage = CONTROL_STAGE_IDLE; - -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -uint8_t usbh_control_xfer_stage(void) -{ - return _stage; -} - -bool usbh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request, void* buffer, tuh_control_complete_cb_t complete_cb) -{ - // TODO need to claim the endpoint first - const uint8_t rhport = usbh_get_rhport(dev_addr); - - _ctrl_xfer.xfer.daddr = dev_addr; - _ctrl_xfer.xfer.request = (*request); - _ctrl_xfer.xfer.buffer = buffer; - _ctrl_xfer.xfer.complete_cb = complete_cb; - - _stage = CONTROL_STAGE_SETUP; - - // Send setup packet - TU_ASSERT( hcd_setup_send(rhport, dev_addr, (uint8_t const*) &_ctrl_xfer.xfer.request) ); - - return true; -} - -void usbh_control_xfer_abort(uint8_t dev_addr) -{ - if (_ctrl_xfer.xfer.daddr == dev_addr) _stage = CONTROL_STAGE_IDLE; -} - -static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) -{ - TU_LOG2("\r\n"); - if (_ctrl_xfer.xfer.complete_cb) _ctrl_xfer.xfer.complete_cb(dev_addr, &_ctrl_xfer.xfer.request, result); -} - - -#endif -- cgit v1.3.1 From 6b5490ced687ba44ede9a0dd1dd62b4b67eedf59 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Mar 2022 13:12:36 +0700 Subject: merge device_info into bare_api example --- examples/host/bare_api/src/main.c | 129 ++++++++++++++---- examples/host/device_info/CMakeLists.txt | 27 ---- examples/host/device_info/Makefile | 28 ---- examples/host/device_info/only.txt | 9 -- examples/host/device_info/src/main.c | 194 ---------------------------- examples/host/device_info/src/tusb_config.h | 96 -------------- src/host/usbh.c | 4 +- 7 files changed, 110 insertions(+), 377 deletions(-) delete mode 100644 examples/host/device_info/CMakeLists.txt delete mode 100644 examples/host/device_info/Makefile delete mode 100644 examples/host/device_info/only.txt delete mode 100644 examples/host/device_info/src/main.c delete mode 100644 examples/host/device_info/src/tusb_config.h (limited to 'examples') diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index 5f8f886c8..73e97c390 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -46,8 +46,6 @@ int main(void) board_init(); printf("TinyUSB Host HID Controller Example\r\n"); - printf("Note: Events only displayed for explictly supported controllers\r\n"); - tusb_init(); while (1) @@ -64,10 +62,74 @@ int main(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); +// English +#define LANGUAGE_ID 0x0409 +//uint8_t usb_buf[256] TU_ATTR_ALIGNED(4); tusb_desc_device_t desc_device; +static volatile xfer_result_t _get_string_result; + +static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { + (void)daddr; + (void)request; + _get_string_result = result; + return true; +} + +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. + + for (size_t i = 0; i < utf16_len; i++) { + uint16_t chr = utf16[i]; + if (chr < 0x80) { + *utf8++ = chr & 0xff; + } 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. + } + return total_bytes; +} + +static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { + while (_get_string_result == 0xff) { + tuh_task(); + } + if (_get_string_result != XFER_RESULT_SUCCESS) { + temp_buf[0] = 0; + return; + } + size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); + size_t utf8_len = _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'; +} + bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result) { (void) request; @@ -78,26 +140,49 @@ bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * reque return false; } - printf("Rhport %u Device %u: ID %04x:%04x\r\n", 0, daddr, desc_device.idVendor, desc_device.idProduct); + 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(" iManufacturer %u\r\n", desc_device.iManufacturer); - printf(" iProduct %u\r\n", desc_device.iProduct); - printf(" iSerialNumber %u\r\n", desc_device.iSerialNumber); + 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_result = 0xff; + uint16_t temp_buf[128]; + + printf(" iManufacturer %u " , desc_device.iManufacturer); + temp_buf[0] = 0; + if (tuh_descriptor_get_manufacturer_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf((const char*) temp_buf); + } + printf("\r\n"); + + printf(" iProduct %u " , desc_device.iProduct); + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_get_product_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf((const char*) temp_buf); + } + printf("\r\n"); + + printf(" iSerialNumber %u " , desc_device.iSerialNumber); + _get_string_result = 0xff; + temp_buf[0] = 0; + if (tuh_descriptor_get_serial_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { + _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); + printf((const char*) temp_buf); + } + printf("\r\n"); - printf(" bNumConfigurations %u\r\n", desc_device.bNumConfigurations); + printf(" bNumConfigurations %u\r\n" , desc_device.bNumConfigurations); return true; } @@ -107,7 +192,7 @@ void tuh_mount_cb (uint8_t daddr) { printf("Device attached, address = %d\r\n", daddr); - // get device descriptor + // Get Device Descriptor tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor); } diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt deleted file mode 100644 index bff281a8c..000000000 --- a/examples/host/device_info/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.5) - -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}) - -# Checks this example is valid for the family and initializes the project -family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) - -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... see the corresponding function -# in hw/bsp/FAMILY/family.cmake for details. -family_configure_host_example(${PROJECT}) \ No newline at end of file diff --git a/examples/host/device_info/Makefile b/examples/host/device_info/Makefile deleted file mode 100644 index c59369ffa..000000000 --- a/examples/host/device_info/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -include ../../../tools/top.mk -include ../../make.mk - -INC += \ - src \ - $(TOP)/hw \ - -# Example source -EXAMPLE_SOURCE += \ - src/main.c - -SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) - -# TODO: suppress warning caused by host stack -CFLAGS += -Wno-error=cast-align -Wno-error=null-dereference - -# TinyUSB Host Stack source -SRC_C += \ - src/class/cdc/cdc_host.c \ - src/class/hid/hid_host.c \ - src/class/msc/msc_host.c \ - src/host/hub.c \ - src/host/usbh.c \ - src/host/usbh_control.c \ - src/portable/ohci/ohci.c \ - src/portable/nxp/lpc17_40/hcd_lpc17_40.c - -include ../../rules.mk diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt deleted file mode 100644 index 7fe4e3f5c..000000000 --- a/examples/host/device_info/only.txt +++ /dev/null @@ -1,9 +0,0 @@ -mcu:LPC175X_6X -mcu:LPC177X_8X -mcu:LPC18XX -mcu:LPC40XX -mcu:LPC43XX -mcu:MIMXRT10XX -mcu:RP2040 -mcu:MSP432E4 -mcu:RX65X diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c deleted file mode 100644 index e6149db89..000000000 --- a/examples/host/device_info/src/main.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2022 Scott Shawcroft for Adafruit Industries - * - * 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 example prints out info about the enumerated devices. */ - - -#include -#include -#include - -#include "bsp/board.h" -#include "tusb.h" - -//--------------------------------------------------------------------+ -// MACRO CONSTANT TYPEDEF PROTYPES -//--------------------------------------------------------------------+ -void led_blinking_task(void); - -static xfer_result_t _get_string_result; - -static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) { - (void)daddr; - (void)request; - _get_string_result = result; - return true; -} - -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. - - for (size_t i = 0; i < utf16_len; i++) { - uint16_t chr = utf16[i]; - if (chr < 0x80) { - *utf8++ = chr & 0xff; - } 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. - } - return total_bytes; -} - -static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) { - while (_get_string_result == 0xff) { - tuh_task(); - } - if (_get_string_result != XFER_RESULT_SUCCESS) { - temp_buf[0] = 0; - return; - } - size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t); - size_t utf8_len = _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'; -} - -/*------------- MAIN -------------*/ -int main(void) -{ - board_init(); - - printf("TinyUSB Host Device Info Example\r\n"); - - tusb_init(); - - uint32_t interval_ms = 5000; - uint32_t start_time = 0; - - while (1) - { - // tinyusb host task - tuh_task(); - led_blinking_task(); - - if (board_millis() - start_time < interval_ms) { - continue; - } - start_time = board_millis(); - // Brute force check every device address to see if it is active. - for (int i = 1; i < CFG_TUH_DEVICE_MAX + CFG_TUH_HUB + 1; i++) { - if (!tuh_ready(i)) { - continue; - } - uint16_t vid; - uint16_t pid; - tuh_vid_pid_get(i, &vid, &pid); - printf("%d vid %04x pid %04x\r\n", i, vid, pid); - - tusb_speed_t speed = tuh_speed_get(i); - switch (speed) { - case TUSB_SPEED_FULL: - printf("Full speed\r\n"); - break; - case TUSB_SPEED_LOW: - printf("Low speed\r\n"); - break; - case TUSB_SPEED_HIGH: - printf("High speed\r\n"); - break; - default: - break; - } - - _get_string_result = 0xff; - uint16_t temp_buf[127]; - if (tuh_descriptor_string_serial_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf("Serial: %s\r\n", (const char*) temp_buf); - } - - _get_string_result = 0xff; - temp_buf[0] = 0; - if (tuh_descriptor_string_product_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf("Product: %s\r\n", (const char*) temp_buf); - } - - _get_string_result = 0xff; - temp_buf[0] = 0; - if (tuh_descriptor_string_manufacturer_get(i, 0, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) { - _wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf)); - printf("Manufacturer: %s\r\n", (const char*) temp_buf); - } - } - printf("\n"); - } - - 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 -} diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h deleted file mode 100644 index 6b413e46f..000000000 --- a/examples/host/device_info/src/tusb_config.h +++ /dev/null @@ -1,96 +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. - * - */ - -#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 - -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX - #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#else - #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST -#endif - -#ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE -#endif - -// CFG_TUSB_DEBUG is defined by compiler in DEBUG build -// #define CFG_TUSB_DEBUG 0 - -/* 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_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION -#endif - -#ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) -#endif - -//-------------------------------------------------------------------- -// CONFIGURATION -//-------------------------------------------------------------------- - -// Size of buffer to hold descriptors and other data used for enumeration -#define CFG_TUH_ENUMERATION_BUFSIZE 256 - -// only hub class is enabled -#define CFG_TUH_HUB 1 - -// max device support (excluding hub device) -// 1 hub typically has 4 ports -#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) - -#define CFG_TUH_ENDPOINT_MAX 8 - -#define CFG_TUH_TASK_QUEUE_SZ 64 - -//------------- HID -------------// - -#define CFG_TUH_HID_EP_BUFSIZE 64 - -#ifdef __cplusplus - } -#endif - -#endif /* _TUSB_CONFIG_H_ */ diff --git a/src/host/usbh.c b/src/host/usbh.c index 11bf2f997..617aff79a 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -535,7 +535,7 @@ void tuh_task(void) break; case HCD_EVENT_DEVICE_REMOVE: - TU_LOG2("USBH DEVICE REMOVED\r\n"); + TU_LOG2("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); process_device_unplugged(event.rhport, event.connection.hub_addr, event.connection.hub_port); #if CFG_TUH_HUB @@ -924,6 +924,8 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h (hub_port == 0 || dev->hub_port == hub_port) && dev->connected) { + TU_LOG2(" Address = %u\r\n", dev_addr); + // Invoke callback before close driver if (tuh_umount_cb) tuh_umount_cb(dev_addr); -- cgit v1.3.1