Просмотр исходного кода

Add host string descriptor functions

Plus typo fixes, GCC11 array bounds fix, snprintf for malloc-free
debug and pragmas for alignment checks.
Scott Shawcroft 4 лет назад
Родитель
Сommit
2cd73ca602

+ 1 - 1
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;
 }

+ 56 - 1
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

+ 12 - 0
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

+ 1 - 0
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"
 

+ 3 - 0
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

+ 2 - 2
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

+ 3 - 0
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;