diff options
| author | Gordon McNab <[email protected]> | 2021-12-08 08:36:43 +0000 |
|---|---|---|
| committer | Gordon McNab <[email protected]> | 2021-12-08 08:36:43 +0000 |
| commit | 9a7db985931ae215e808d40e7bacd52535d45305 (patch) | |
| tree | a4d75e2c3823766da53a006280c0d805630d996e /src/host | |
| parent | edf3f3501656b010ad4a9e1d0a0d62573dd0b3fb (diff) | |
| parent | cde824f17f73b5ce4fcec8c176827297854a76c2 (diff) | |
Merge branch 'master' into port-ft90x
Diffstat (limited to 'src/host')
| -rw-r--r-- | src/host/hcd_attr.h | 46 | ||||
| -rw-r--r-- | src/host/usbh.c | 110 |
2 files changed, 86 insertions, 70 deletions
diff --git a/src/host/hcd_attr.h b/src/host/hcd_attr.h index 729fc407b..06011c63c 100644 --- a/src/host/hcd_attr.h +++ b/src/host/hcd_attr.h @@ -34,64 +34,64 @@ // - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on. //------------- NXP -------------// -#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX) +#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) #define HCD_ATTR_OHCI -#elif TU_CHECK_MCU(LPC18XX) || TU_CHECK_MCU(LPC43XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #define HCD_ATTR_EHCI_TRANSDIMENSION -#elif TU_CHECK_MCU(LPC54XXX) +#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) // #define HCD_ATTR_EHCI_NXP_PTD -#elif TU_CHECK_MCU(LPC55XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) // #define HCD_ATTR_EHCI_NXP_PTD -#elif TU_CHECK_MCU(MIMXRT10XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) #define HCD_ATTR_EHCI_TRANSDIMENSION -#elif TU_CHECK_MCU(MKL25ZXX) +#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX) //------------- Microchip -------------// -#elif TU_CHECK_MCU(SAMD21) || TU_CHECK_MCU(SAMD51) || TU_CHECK_MCU(SAME5X) || \ - TU_CHECK_MCU(SAMD11) || TU_CHECK_MCU(SAML21) || TU_CHECK_MCU(SAML22) +#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ + TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) -#elif TU_CHECK_MCU(SAMG) +#elif TU_CHECK_MCU(OPT_MCU_SAMG) -#elif TU_CHECK_MCU(SAMX7X) +#elif TU_CHECK_MCU(OPT_MCU_SAMX7X) //------------- ST -------------// -#elif TU_CHECK_MCU(STM32F0) || TU_CHECK_MCU(STM32F1) || TU_CHECK_MCU(STM32F3) || \ - TU_CHECK_MCU(STM32L0) || TU_CHECK_MCU(STM32L1) || TU_CHECK_MCU(STM32L4) +#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1, OPT_MCU_STM32F3) || \ + TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32L4) -#elif TU_CHECK_MCU(STM32F2) || TU_CHECK_MCU(STM32F4) || TU_CHECK_MCU(STM32F3) +#elif TU_CHECK_MCU(OPT_MCU_STM32F2, OPT_MCU_STM32F3, OPT_MCU_STM32F4) -#elif TU_CHECK_MCU(STM32F7) +#elif TU_CHECK_MCU(OPT_MCU_STM32F7) -#elif TU_CHECK_MCU(STM32H7) +#elif TU_CHECK_MCU(OPT_MCU_STM32H7) //------------- Sony -------------// -#elif TU_CHECK_MCU(CXD56) +#elif TU_CHECK_MCU(OPT_MCU_CXD56) //------------- Nuvoton -------------// -#elif TU_CHECK_MCU(NUC505) +#elif TU_CHECK_MCU(OPT_MCU_NUC505) //------------- Espressif -------------// -#elif TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) //------------- Raspberry Pi -------------// -#elif TU_CHECK_MCU(RP2040) +#elif TU_CHECK_MCU(OPT_MCU_RP2040) //------------- Silabs -------------// -#elif TU_CHECK_MCU(EFM32GG) || TU_CHECK_MCU(EFM32GG11) || TU_CHECK_MCU(EFM32GG12) +#elif TU_CHECK_MCU(OPT_MCU_EFM32GG) //------------- Renesas -------------// -#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X) || TU_CHECK_MCU(RX72N) +#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) -//#elif TU_CHECK_MCU(MM32F327X) +//#elif TU_CHECK_MCU(OPT_MCU_MM32F327X) // #define DCD_ATTR_ENDPOINT_MAX not known yet //------------- GigaDevice -------------// -#elif TU_CHECK_MCU(GD32VF103) +#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #else // #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" diff --git a/src/host/usbh.c b/src/host/usbh.c index 51b8f85b6..b8439addc 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -53,13 +53,39 @@ // USBH-HCD common data structure //--------------------------------------------------------------------+ +// device0 struct must be strictly a subset of normal device struct +typedef struct +{ + // port + uint8_t rhport; + uint8_t hub_addr; + uint8_t hub_port; + uint8_t speed; + + volatile struct TU_ATTR_PACKED + { + uint8_t connected : 1; + uint8_t addressed : 1; + uint8_t configured : 1; + uint8_t suspended : 1; + }; +} usbh_dev0_t; + typedef struct { - //------------- port -------------// + // port uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; uint8_t speed; + volatile struct TU_ATTR_PACKED + { + uint8_t connected : 1; + uint8_t addressed : 1; + uint8_t configured : 1; + uint8_t suspended : 1; + }; + //------------- device descriptor -------------// uint16_t vid; uint16_t pid; @@ -73,14 +99,6 @@ typedef struct { // uint8_t interface_count; // bNumInterfaces alias //------------- device -------------// - struct TU_ATTR_PACKED - { - uint8_t connected : 1; - uint8_t addressed : 1; - uint8_t configured : 1; - uint8_t suspended : 1; - }; - volatile uint8_t state; // device state, value from enum tusbh_device_state_t uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) @@ -103,16 +121,6 @@ typedef struct { } usbh_device_t; -typedef struct -{ - uint8_t rhport; - uint8_t hub_addr; - uint8_t hub_port; - uint8_t speed; - - volatile uint8_t connected; -} usbh_dev0_t; - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -533,10 +541,12 @@ void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port usbh_class_drivers[drv_id].close(dev_addr); } + hcd_device_close(rhport, dev_addr); + + // release all endpoints associated with the device memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping - - hcd_device_close(rhport, dev_addr); + tu_memclr(dev->ep_status, sizeof(dev->ep_status)); dev->state = TUSB_DEVICE_STATE_UNPLUG; } @@ -894,11 +904,10 @@ static bool enum_get_9byte_config_desc_complete(uint8_t dev_addr, tusb_control_r TU_ASSERT(XFER_RESULT_SUCCESS == result); // TODO not enough buffer to hold configuration descriptor - tusb_desc_configuration_t const * desc_config = (tusb_desc_configuration_t const*) _usbh_ctrl_buf; - uint16_t total_len; + uint8_t const * desc_config = _usbh_ctrl_buf; // Use offsetof to avoid pointer to the odd/misaligned address - memcpy(&total_len, (uint8_t*) desc_config + offsetof(tusb_desc_configuration_t, wTotalLength), 2); + uint16_t const total_len = tu_le16toh( tu_unaligned_read16(desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) ); TU_ASSERT(total_len <= CFG_TUH_ENUMERATION_BUFSIZE); @@ -982,25 +991,38 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura // parse each interfaces while( p_desc < desc_end ) { - // TODO Do we need to use IAD - tusb_desc_interface_assoc_t const * desc_iad = NULL; + 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) ) { - desc_iad = (tusb_desc_interface_assoc_t const *) p_desc; - p_desc = tu_desc_next(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 + + // IAD's first interface number and class should match with opened interface + //TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber && + // desc_iad->bFunctionClass == desc_itf->bInterfaceClass); } TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); - tusb_desc_interface_t const* desc_itf = (tusb_desc_interface_t const*) p_desc; - // Interface number must not be used already - TU_ASSERT( dev->itf2drv[desc_itf->bInterfaceNumber] == DRVID_INVALID ); +#if CFG_TUH_MIDI + // MIDI has 2 interfaces (Audio Control v1 + MIDIStreaming) but does not have IAD + // manually increase the associated count + if (1 == assoc_itf_count && + TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && + AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) + { + assoc_itf_count = 2; + } +#endif - uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, desc_iad ? desc_iad->bInterfaceCount : 1, desc_end-p_desc); - TU_ASSERT(drv_len); + uint16_t const drv_len = tu_desc_get_interface_total_len(desc_itf, assoc_itf_count, desc_end-p_desc); + TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t)); if (desc_itf->bInterfaceClass == TUSB_CLASS_HUB && dev->hub_addr != 0) { @@ -1019,22 +1041,16 @@ static bool parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configura if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) ) { // open successfully - TU_LOG2(" Opened successfully\r\n"); - - // bind interface to found driver - dev->itf2drv[desc_itf->bInterfaceNumber] = drv_id; + TU_LOG2(" %s opened\r\n", driver->name); - // If using IAD, bind all interfaces to the same driver - if (desc_iad) + // bind (associated) interfaces to found driver + for(uint8_t i=0; i<assoc_itf_count; i++) { - // IAD's first interface number and class should match with opened interface - TU_ASSERT(desc_iad->bFirstInterface == desc_itf->bInterfaceNumber && - desc_iad->bFunctionClass == desc_itf->bInterfaceClass); + uint8_t const itf_num = desc_itf->bInterfaceNumber+i; - for(uint8_t i=1; i<desc_iad->bInterfaceCount; i++) - { - dev->itf2drv[desc_itf->bInterfaceNumber+i] = drv_id; - } + // Interface number must not be used already + TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] ); + dev->itf2drv[itf_num] = drv_id; } // bind all endpoints to found driver @@ -1158,7 +1174,7 @@ static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size) .bDescriptorType = TUSB_DESC_ENDPOINT, .bEndpointAddress = 0, .bmAttributes = { .xfer = TUSB_XFER_CONTROL }, - .wMaxPacketSize = { .size = max_packet_size }, + .wMaxPacketSize = max_packet_size, .bInterval = 0 }; |
