From 2cd73ca60234748a15b74a2c346778fcb4f4ee61 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 3 Mar 2022 16:53:22 -0800 Subject: [PATCH] Add host string descriptor functions Plus typo fixes, GCC11 array bounds fix, snprintf for malloc-free debug and pragmas for alignment checks. --- src/common/tusb_common.h | 2 +- src/host/usbh.c | 57 +++++++++++++++++++- src/host/usbh.h | 12 +++++ src/portable/chipidea/ci_hs/hcd_ci_hs.c | 1 + src/portable/ehci/ehci.c | 3 ++ src/portable/ehci/ehci.h | 4 +- src/portable/raspberrypi/rp2040/rp2040_usb.c | 3 ++ 7 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 9b9e2b007..80bb40f77 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -349,7 +349,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3 } // not found return the key value in hex - sprintf(not_found, "0x%08lX", (unsigned long) key); + snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key); return not_found; } diff --git a/src/host/usbh.c b/src/host/usbh.c index 130aba40e..a3c6c3a04 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -258,6 +258,60 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid) return true; } +uint8_t tuh_i_manufacturer_get(uint8_t dev_addr) { + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + return dev->i_manufacturer; +} + +uint8_t tuh_i_serial_get(uint8_t dev_addr) { + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + return dev->i_serial; +} + +uint8_t tuh_i_product_get(uint8_t dev_addr) { + TU_VERIFY(tuh_mounted(dev_addr)); + usbh_device_t const* dev = get_device(dev_addr); + + return dev->i_product; +} + +static tuh_complete_cb_t string_get_cb; + +static bool string_get_complete (uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) { + if (string_get_cb != NULL) { + TU_LOG2("string get done %d\r\n", result); + string_get_cb(result); + } + string_get_cb = NULL; + return true; +} + +bool tuh_string_get(uint8_t dev_addr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb) { + if (string_get_cb != NULL) { + return false; + } + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = TUSB_DESC_STRING << 8 | string_index, + .wIndex = 0, + .wLength = len * sizeof(uint16_t) + }; + string_get_cb = complete_cb; + TU_ASSERT( tuh_control_xfer(dev_addr, &request, buf, string_get_complete) ); + return true; +} + tusb_speed_t tuh_speed_get (uint8_t dev_addr) { return (tusb_speed_t) (dev_addr ? get_device(dev_addr)->speed : _dev0.speed); @@ -561,6 +615,7 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port tu_memclr(dev->ep_status, sizeof(dev->ep_status)); dev->state = TUSB_DEVICE_STATE_UNPLUG; + dev->configured = false; } } } @@ -609,7 +664,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) //--------------------------------------------------------------------+ // Enumeration Process -// is a lengthy process with a seires of control transfer to configure +// is a lengthy process with a series of control transfer to configure // newly attached device. Each step is handled by a function in this // section // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating diff --git a/src/host/usbh.h b/src/host/usbh.h index 8411cad28..98e83fc3c 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -38,6 +38,7 @@ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +typedef bool (*tuh_complete_cb_t)(xfer_result_t result); typedef bool (*tuh_control_complete_cb_t)(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result); //--------------------------------------------------------------------+ @@ -58,6 +59,17 @@ extern void hcd_int_handler(uint8_t rhport); #define tuh_int_handler hcd_int_handler bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t* vid, uint16_t* pid); + +// Gets the string indices for common device descriptor data. +uint8_t tuh_i_manufacturer_get(uint8_t dev_addr); +uint8_t tuh_i_serial_get(uint8_t dev_addr); +uint8_t tuh_i_product_get(uint8_t dev_addr); + +// Reads the string descriptor at the string index into the buffer. This is the +// full response so the first entry is the length and the constant 0x03 for +// string descriptor type. +bool tuh_string_get(uint8_t dev_addr, uint8_t string_index, uint16_t* buf, size_t len, tuh_complete_cb_t complete_cb); + tusb_speed_t tuh_speed_get(uint8_t dev_addr); // Check if device is connected and configured diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 0754b477e..221721b0f 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -35,6 +35,7 @@ // INCLUDE //--------------------------------------------------------------------+ #include "common/tusb_common.h" +#include "host/hcd.h" #include "portable/ehci/ehci_api.h" #include "ci_hs_type.h" diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index e2d51dc4b..6723e99e9 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -189,7 +189,10 @@ static void list_remove_qhd_by_addr(ehci_link_t* list_head, uint8_t dev_addr) prev = list_next(prev) ) { // TODO check type for ISO iTD and siTD + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" ehci_qhd_t* qhd = (ehci_qhd_t*) list_next(prev); + #pragma GCC diagnostic pop if ( qhd->dev_addr == dev_addr ) { // TODO deactive all TD, wait for QHD to inactive before removal diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h index c2bee67a5..ff9ae12e7 100644 --- a/src/portable/ehci/ehci.h +++ b/src/portable/ehci/ehci.h @@ -101,8 +101,8 @@ typedef struct // Word 2: qTQ Token volatile uint32_t ping_err : 1 ; ///< For Highspeed: 0 Out, 1 Ping. Full/Slow used as error indicator - volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of slipt transaction - volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete slip transaction + volatile uint32_t non_hs_split_state : 1 ; ///< Used by HC to track the state of split transaction + volatile uint32_t non_hs_missed_uframe : 1 ; ///< HC misses a complete split transaction volatile uint32_t xact_err : 1 ; ///< Error (Timeout, CRC, Bad PID ... ) volatile uint32_t babble_err : 1 ; ///< Babble detected, also set Halted bit to 1 volatile uint32_t buffer_err : 1 ; ///< Data overrun/underrun error diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 293cefaf6..be02493f0 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -58,8 +58,11 @@ void rp2040_usb_init(void) unreset_block_wait(RESETS_RESET_USBCTRL_BITS); // Clear any previous state just in case +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); +#pragma GCC diagnostic pop // Mux the controller to the onboard usb phy usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;