summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-06-18 23:35:44 +0700
committerhathach <[email protected]>2025-06-18 23:44:03 +0700
commit9503883ba7f99523a14082ce68a5f900585747b0 (patch)
tree795dd2947c3b94f28e4163df8a3819edc6b07d60 /src
parent506edc626709ca92dd9c38d6c6f5813f30a27692 (diff)
usbh: add new API tuh_descriptor_get_device_local()
cdc host: remove the local desc_dev and the get_device descriptor call for ftdi and pl2303
Diffstat (limited to 'src')
-rw-r--r--src/class/cdc/cdc_host.c141
-rw-r--r--src/common/tusb_types.h1
-rw-r--r--src/host/usbh.c58
-rw-r--r--src/host/usbh.h3
4 files changed, 91 insertions, 112 deletions
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 3be61e654..d704d82d7 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -123,10 +123,6 @@ typedef struct {
static cdch_interface_t cdch_data[CFG_TUH_CDC];
CFG_TUH_MEM_SECTION static cdch_epbuf_t cdch_epbuf[CFG_TUH_CDC];
-#if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_PL2303
- static tusb_desc_device_t desc_dev[CFG_TUH_ENUMERATION_BUFSIZE];
-#endif
-
//--------------------------------------------------------------------+
// Serial Driver
//--------------------------------------------------------------------+
@@ -189,8 +185,6 @@ static bool ch34x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complet
static uint16_t const pl2303_vid_pid_list[][2] = {CFG_TUH_CDC_PL2303_VID_PID_LIST};
static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {PL2303_TYPE_DATA};
-CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN
-
static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
static bool pl2303_process_set_config(tuh_xfer_t *xfer);
@@ -331,7 +325,7 @@ TU_ATTR_ALWAYS_INLINE static inline cdch_interface_t * get_itf(uint8_t idx) {
}
TU_ATTR_ALWAYS_INLINE static inline uint8_t get_idx_by_ptr(cdch_interface_t* p_cdc) {
- return p_cdc - cdch_data;
+ return (uint8_t) (p_cdc - cdch_data);
}
static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) {
@@ -434,7 +428,7 @@ bool tuh_cdc_itf_get_info(uint8_t idx, tuh_itf_info_t * info) {
info->daddr = p_cdc->daddr;
- // re-construct descriptor
+ // re-construct interface descriptor
tusb_desc_interface_t * desc = &info->desc;
desc->bLength = sizeof(tusb_desc_interface_t);
desc->bDescriptorType = TUSB_DESC_INTERFACE;
@@ -975,8 +969,6 @@ bool cdch_set_config(uint8_t daddr, uint8_t itf_num) {
// ACM
//--------------------------------------------------------------------+
-//------------- Driver API -------------//
-
// internal control complete to update state such as line state, encoding
static void acm_internal_control_complete(tuh_xfer_t *xfer) {
uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
@@ -1089,7 +1081,6 @@ static bool acm_set_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb,
}
//------------- Enumeration -------------//
-
enum {
CONFIG_ACM_SET_CONTROL_LINE_STATE = 0,
CONFIG_ACM_SET_LINE_CODING,
@@ -1339,8 +1330,7 @@ static bool ftdi_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_
//------------- Enumeration -------------//
enum {
- CONFIG_FTDI_GET_DESC = 0,
- CONFIG_FTDI_DETERMINE_TYPE,
+ CONFIG_FTDI_DETERMINE_TYPE = 0,
CONFIG_FTDI_WRITE_LATENCY,
CONFIG_FTDI_SIO_RESET,
CONFIG_FTDI_SET_DATA,
@@ -1383,15 +1373,6 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) {
switch (state) {
// from here sequence overtaken from Linux Kernel function ftdi_port_probe()
- case CONFIG_FTDI_GET_DESC:
- // get device descriptor
- if (itf_num == 0) { // only necessary for 1st interface. other interface overtake type from interface 0
- TU_ASSERT(tuh_descriptor_get_device(xfer->daddr, &desc_dev, sizeof(tusb_desc_device_t),
- cdch_process_set_config, CONFIG_FTDI_DETERMINE_TYPE));
- break;
- }
- TU_ATTR_FALLTHROUGH;
-
case CONFIG_FTDI_DETERMINE_TYPE:
// determine type
if (itf_num == 0) {
@@ -1472,7 +1453,9 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) {
//------------- Helper -------------//
static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
- uint16_t const version = desc_dev->bcdDevice;
+ tusb_desc_device_t desc_dev;
+ TU_VERIFY(tuh_descriptor_get_device_local(p_cdc->daddr, &desc_dev));
+ uint16_t const version = desc_dev.bcdDevice;
uint8_t const itf_num = p_cdc->bInterfaceNumber;
p_cdc->ftdi.chip_type = UNKNOWN;
@@ -1482,8 +1465,7 @@ static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
switch (version) {
case 0x200:
- // FT232A not supported to keep it simple (no extra _read_latency_timer())
- // not testable
+ // FT232A not supported to keep it simple (no extra _read_latency_timer()) not testable
// p_cdc->ftdi.chip_type = FT232A;
// p_cdc->ftdi.baud_base = 48000000 / 2;
// p_cdc->ftdi.channel = 0;
@@ -1497,50 +1479,20 @@ static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
// p_cdc->ftdi.chip_type = FT232B;
// }
break;
- case 0x400:
- p_cdc->ftdi.chip_type = FT232B;
- p_cdc->ftdi.channel = 0;
- break;
- case 0x500:
- p_cdc->ftdi.chip_type = FT2232C;
- break;
- case 0x600:
- p_cdc->ftdi.chip_type = FT232R;
- p_cdc->ftdi.channel = 0;
- break;
- case 0x700:
- p_cdc->ftdi.chip_type = FT2232H;
- break;
- case 0x800:
- p_cdc->ftdi.chip_type = FT4232H;
- break;
- case 0x900:
- p_cdc->ftdi.chip_type = FT232H;
- break;
- case 0x1000:
- p_cdc->ftdi.chip_type = FTX;
- break;
- case 0x2800:
- p_cdc->ftdi.chip_type = FT2233HP;
- break;
- case 0x2900:
- p_cdc->ftdi.chip_type = FT4233HP;
- break;
- case 0x3000:
- p_cdc->ftdi.chip_type = FT2232HP;
- break;
- case 0x3100:
- p_cdc->ftdi.chip_type = FT4232HP;
- break;
- case 0x3200:
- p_cdc->ftdi.chip_type = FT233HP;
- break;
- case 0x3300:
- p_cdc->ftdi.chip_type = FT232HP;
- break;
- case 0x3600:
- p_cdc->ftdi.chip_type = FT4232HA;
- break;
+ case 0x400: p_cdc->ftdi.chip_type = FT232B; p_cdc->ftdi.channel = 0; break;
+ case 0x500: p_cdc->ftdi.chip_type = FT2232C; break;
+ case 0x600: p_cdc->ftdi.chip_type = FT232R; p_cdc->ftdi.channel = 0; break;
+ case 0x700: p_cdc->ftdi.chip_type = FT2232H; break;
+ case 0x800: p_cdc->ftdi.chip_type = FT4232H; break;
+ case 0x900: p_cdc->ftdi.chip_type = FT232H; break;
+ case 0x1000: p_cdc->ftdi.chip_type = FTX; break;
+ case 0x2800: p_cdc->ftdi.chip_type = FT2233HP; break;
+ case 0x2900: p_cdc->ftdi.chip_type = FT4233HP; break;
+ case 0x3000: p_cdc->ftdi.chip_type = FT2232HP; break;
+ case 0x3100: p_cdc->ftdi.chip_type = FT4232HP; break;
+ case 0x3200: p_cdc->ftdi.chip_type = FT233HP; break;
+ case 0x3300: p_cdc->ftdi.chip_type = FT232HP; break;
+ case 0x3600: p_cdc->ftdi.chip_type = FT4232HA; break;
default:
if (version < 0x200) {
p_cdc->ftdi.chip_type = SIO;
@@ -1550,7 +1502,7 @@ static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
}
TU_LOG_P_CDC("%s detected (bcdDevice = 0x%04x)",
- ftdi_chip_name[p_cdc->ftdi.chip_type], desc_dev->bcdDevice);
+ ftdi_chip_name[p_cdc->ftdi.chip_type], version);
return (p_cdc->ftdi.chip_type != UNKNOWN);
}
@@ -2025,7 +1977,8 @@ static bool ch34x_write_reg_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t comp
}
static bool ch34x_modem_ctrl_request(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
- uint8_t control = ~((p_cdc->requested_line_state.rts ? CH34X_BIT_RTS : 0) |// CH34x signals are inverted
+ // CH34x signals are inverted
+ uint8_t control = ~((p_cdc->requested_line_state.rts ? CH34X_BIT_RTS : 0) |
(p_cdc->requested_line_state.dtr ? CH34X_BIT_DTR : 0));
return ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, complete_cb, user_data);
}
@@ -2506,8 +2459,7 @@ static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complet
//------------- Enumeration -------------//
enum {
- CONFIG_PL2303_GET_DESC = 0,
- CONFIG_PL2303_DETECT_TYPE,
+ CONFIG_PL2303_DETECT_TYPE = 0,
CONFIG_PL2303_READ1,
CONFIG_PL2303_WRITE1,
CONFIG_PL2303_READ2,
@@ -2568,14 +2520,8 @@ static bool pl2303_process_set_config(tuh_xfer_t *xfer) {
TU_ASSERT(p_cdc && (xfer->result == XFER_RESULT_SUCCESS || xfer->user_data == CONFIG_PL2303_READ1));
switch (state) {
// from here sequence overtaken from Linux Kernel function pl2303_startup()
- case CONFIG_PL2303_GET_DESC:
- p_cdc->user_control_cb = cdch_process_set_config;// set once for whole process config
- // get device descriptor
- TU_ASSERT(tuh_descriptor_get_device(xfer->daddr, &desc_dev, sizeof(tusb_desc_device_t),
- cdch_process_set_config, CONFIG_PL2303_DETECT_TYPE));
- break;
-
case CONFIG_PL2303_DETECT_TYPE:
+ p_cdc->user_control_cb = cdch_process_set_config;// set once for whole process config
// get type and quirks (step 1)
type = pl2303_detect_type(p_cdc, 1, cdch_process_set_config, CONFIG_PL2303_READ1);
TU_ASSERT(type != PL2303_DETECT_TYPE_FAILED);
@@ -2784,39 +2730,39 @@ static bool pl2303_process_set_config(tuh_xfer_t *xfer) {
static int8_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step,
tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
- /*
- * Legacy PL2303H, variants 0 and 1 (difference unknown).
- */
- if (desc_dev->bDeviceClass == 0x02) {
+ tusb_desc_device_t desc_dev;
+ TU_VERIFY(tuh_descriptor_get_device_local(p_cdc->daddr, &desc_dev), PL2303_DETECT_TYPE_FAILED);
+
+ // Legacy PL2303H, variants 0 and 1 (difference unknown).
+ if (desc_dev.bDeviceClass == 0x02) {
return TYPE_H; /* variant 0 */
}
- if (desc_dev->bMaxPacketSize0 != 0x40) {
- if (desc_dev->bDeviceClass == 0x00 || desc_dev->bDeviceClass == 0xff) {
+ if (desc_dev.bMaxPacketSize0 != 0x40) {
+ if (desc_dev.bDeviceClass == 0x00 || desc_dev.bDeviceClass == 0xff) {
return TYPE_H; /* variant 1 */
}
return TYPE_H; /* variant 0 */
}
- switch (desc_dev->bcdUSB) {
+ switch (desc_dev.bcdUSB) {
case 0x101:
/* USB 1.0.1? Let's assume they meant 1.1... */
TU_ATTR_FALLTHROUGH;
case 0x110:
- switch (desc_dev->bcdDevice) {
- case 0x300:
- return TYPE_HX;
- case 0x400:
- return TYPE_HXD;
- default:
- return TYPE_HX;
+ switch (desc_dev.bcdDevice) {
+ case 0x300: return TYPE_HX;
+ case 0x400: return TYPE_HXD;
+ default: return TYPE_HX;
}
break;
+
case 0x200:
- switch (desc_dev->bcdDevice) {
+ switch (desc_dev.bcdDevice) {
case 0x100: /* GC */
case 0x105:
return TYPE_HXN;
+
case 0x300: /* GT / TA */
if (step == 1) {
// step 1 trigger pl2303_supports_hx_status() request
@@ -2833,6 +2779,7 @@ static int8_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step,
case 0x400: /* GL */
case 0x405:
return TYPE_HXN;
+
case 0x500: /* GE / TB */
if (step == 1) {
// step 1 trigger pl2303_supports_hx_status() request
@@ -2851,6 +2798,7 @@ static int8_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step,
case 0x700: /* GR */
case 0x705:
return TYPE_HXN;
+
default:
break;
}
@@ -2858,8 +2806,7 @@ static int8_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step,
default: break;
}
- TU_LOG_P_CDC("unknown device type bcdUSB = 0x%04x", desc_dev->bcdUSB);
-
+ TU_LOG_P_CDC("unknown device type bcdUSB = 0x%04x", desc_dev.bcdUSB);
return PL2303_DETECT_TYPE_FAILED;
}
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index fd7f01b67..ff5d8b66a 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -345,7 +345,6 @@ typedef struct TU_ATTR_PACKED {
uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer.
uint8_t iProduct ; ///< Index of string descriptor describing product.
uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number.
-
uint8_t bNumConfigurations ; ///< Number of possible configurations.
} tusb_desc_device_t;
diff --git a/src/host/usbh.c b/src/host/usbh.c
index f2e5c1f0e..08c362171 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -94,26 +94,28 @@ TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(const void* addr, uint32_t data_si
typedef struct {
tuh_bus_info_t bus_info;
- // Device State
- struct TU_ATTR_PACKED {
- volatile uint8_t connected : 1; // After 1st transfer
- volatile uint8_t addressed : 1; // After SET_ADDR
- volatile uint8_t configured : 1; // After SET_CONFIG and all drivers are configured
- volatile uint8_t suspended : 1; // Bus suspended
- // volatile uint8_t removing : 1; // Physically disconnected, waiting to be processed by usbh
- };
-
// Device Descriptor
- uint8_t ep0_size;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
+ uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
- // Configuration Descriptor
- // uint8_t interface_count; // bNumInterfaces alias
+ // Device State
+ struct TU_ATTR_PACKED {
+ volatile uint8_t connected : 1; // After 1st transfer
+ volatile uint8_t addressed : 1; // After SET_ADDR
+ volatile uint8_t configured : 1; // After SET_CONFIG and all drivers are configured
+ volatile uint8_t suspended : 1; // Bus suspended
+ // volatile uint8_t removing : 1; // Physically disconnected, waiting to be processed by usbh
+ };
// Endpoint & Interface
uint8_t itf2drv[CFG_TUH_INTERFACE_MAX]; // map interface number to driver (0xff is invalid)
@@ -373,6 +375,28 @@ bool tuh_vid_pid_get(uint8_t dev_addr, uint16_t *vid, uint16_t *pid) {
return true;
}
+bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device) {
+ usbh_device_t *dev = get_device(daddr);
+ TU_VERIFY(dev && desc_device);
+
+ desc_device->bLength = sizeof(tusb_desc_device_t);
+ desc_device->bDescriptorType = TUSB_DESC_DEVICE;
+ desc_device->bcdUSB = dev->bcdUSB;
+ desc_device->bDeviceClass = dev->bDeviceClass;
+ desc_device->bDeviceSubClass = dev->bDeviceSubClass;
+ desc_device->bDeviceProtocol = dev->bDeviceProtocol;
+ desc_device->bMaxPacketSize0 = dev->bMaxPacketSize0;
+ desc_device->idVendor = dev->idVendor;
+ desc_device->idProduct = dev->idProduct;
+ desc_device->bcdDevice = dev->bcdDevice;
+ desc_device->iManufacturer = dev->iManufacturer;
+ desc_device->iProduct = dev->iProduct;
+ desc_device->iSerialNumber = dev->iSerialNumber;
+ desc_device->bNumConfigurations = dev->bNumConfigurations;
+
+ return true;
+}
+
tusb_speed_t tuh_speed_get(uint8_t daddr) {
tuh_bus_info_t bus_info;
tuh_bus_info_get(daddr, &bus_info);
@@ -1579,7 +1603,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
usbh_device_t* new_dev = get_device(new_addr);
new_dev->bus_info = *dev0_bus;
new_dev->connected = 1;
- new_dev->ep0_size = desc_device->bMaxPacketSize0;
+ new_dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0;
TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC),);
break;
@@ -1596,7 +1620,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
usbh_device_close(dev0_bus->rhport, 0); // close dev0
- TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->ep0_size),); // open new control endpoint
+ TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0),); // open new control endpoint
TU_LOG_USBH("Get Device Descriptor\r\n");
TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t),
@@ -1609,8 +1633,14 @@ static void process_enumeration(tuh_xfer_t* xfer) {
case ENUM_GET_STRING_LANGUAGE_ID_LEN: {
// save the received device descriptor
tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl;
+ dev->bcdUSB = desc_device->bcdUSB;
+ dev->bDeviceClass = desc_device->bDeviceClass;
+ dev->bDeviceSubClass = desc_device->bDeviceSubClass;
+ dev->bDeviceProtocol = desc_device->bDeviceProtocol;
+ dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0;
dev->idVendor = desc_device->idVendor;
dev->idProduct = desc_device->idProduct;
+ dev->bcdDevice = desc_device->bcdDevice;
dev->iManufacturer = desc_device->iManufacturer;
dev->iProduct = desc_device->iProduct;
dev->iSerialNumber = desc_device->iSerialNumber;
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 13eede869..1ee511722 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -204,6 +204,9 @@ bool tuh_rhport_reset_bus(uint8_t rhport, bool active);
// Get VID/PID of device
bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid);
+// Get local (cached) device descriptor once device is enumerated
+bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device);
+
// Get speed of device
tusb_speed_t tuh_speed_get(uint8_t daddr);