Skip to content

Commit d829ccd

Browse files
committed
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
1 parent 506edc6 commit d829ccd

File tree

4 files changed

+89
-110
lines changed

4 files changed

+89
-110
lines changed

src/class/cdc/cdc_host.c

Lines changed: 42 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,6 @@ typedef struct {
123123
static cdch_interface_t cdch_data[CFG_TUH_CDC];
124124
CFG_TUH_MEM_SECTION static cdch_epbuf_t cdch_epbuf[CFG_TUH_CDC];
125125

126-
#if CFG_TUH_CDC_FTDI || CFG_TUH_CDC_PL2303
127-
static tusb_desc_device_t desc_dev[CFG_TUH_ENUMERATION_BUFSIZE];
128-
#endif
129-
130126
//--------------------------------------------------------------------+
131127
// Serial Driver
132128
//--------------------------------------------------------------------+
@@ -189,8 +185,6 @@ static bool ch34x_set_modem_ctrl(cdch_interface_t * p_cdc, tuh_xfer_cb_t complet
189185
static uint16_t const pl2303_vid_pid_list[][2] = {CFG_TUH_CDC_PL2303_VID_PID_LIST};
190186
static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {PL2303_TYPE_DATA};
191187

192-
CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN
193-
194188
static bool pl2303_open(uint8_t daddr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
195189
static bool pl2303_process_set_config(tuh_xfer_t *xfer);
196190

@@ -975,8 +969,6 @@ bool cdch_set_config(uint8_t daddr, uint8_t itf_num) {
975969
// ACM
976970
//--------------------------------------------------------------------+
977971

978-
//------------- Driver API -------------//
979-
980972
// internal control complete to update state such as line state, encoding
981973
static void acm_internal_control_complete(tuh_xfer_t *xfer) {
982974
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,
10891081
}
10901082

10911083
//------------- Enumeration -------------//
1092-
10931084
enum {
10941085
CONFIG_ACM_SET_CONTROL_LINE_STATE = 0,
10951086
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_
13391330
//------------- Enumeration -------------//
13401331

13411332
enum {
1342-
CONFIG_FTDI_GET_DESC = 0,
1343-
CONFIG_FTDI_DETERMINE_TYPE,
1333+
CONFIG_FTDI_DETERMINE_TYPE = 0,
13441334
CONFIG_FTDI_WRITE_LATENCY,
13451335
CONFIG_FTDI_SIO_RESET,
13461336
CONFIG_FTDI_SET_DATA,
@@ -1383,15 +1373,6 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) {
13831373

13841374
switch (state) {
13851375
// from here sequence overtaken from Linux Kernel function ftdi_port_probe()
1386-
case CONFIG_FTDI_GET_DESC:
1387-
// get device descriptor
1388-
if (itf_num == 0) { // only necessary for 1st interface. other interface overtake type from interface 0
1389-
TU_ASSERT(tuh_descriptor_get_device(xfer->daddr, &desc_dev, sizeof(tusb_desc_device_t),
1390-
cdch_process_set_config, CONFIG_FTDI_DETERMINE_TYPE));
1391-
break;
1392-
}
1393-
TU_ATTR_FALLTHROUGH;
1394-
13951376
case CONFIG_FTDI_DETERMINE_TYPE:
13961377
// determine type
13971378
if (itf_num == 0) {
@@ -1472,7 +1453,9 @@ static bool ftdi_proccess_set_config(tuh_xfer_t *xfer) {
14721453
//------------- Helper -------------//
14731454

14741455
static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
1475-
uint16_t const version = desc_dev->bcdDevice;
1456+
tusb_desc_device_t desc_dev;
1457+
TU_VERIFY(tuh_descriptor_get_device_local(p_cdc->daddr, &desc_dev));
1458+
uint16_t const version = desc_dev.bcdDevice;
14761459
uint8_t const itf_num = p_cdc->bInterfaceNumber;
14771460

14781461
p_cdc->ftdi.chip_type = UNKNOWN;
@@ -1482,8 +1465,7 @@ static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
14821465

14831466
switch (version) {
14841467
case 0x200:
1485-
// FT232A not supported to keep it simple (no extra _read_latency_timer())
1486-
// not testable
1468+
// FT232A not supported to keep it simple (no extra _read_latency_timer()) not testable
14871469
// p_cdc->ftdi.chip_type = FT232A;
14881470
// p_cdc->ftdi.baud_base = 48000000 / 2;
14891471
// p_cdc->ftdi.channel = 0;
@@ -1497,50 +1479,20 @@ static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
14971479
// p_cdc->ftdi.chip_type = FT232B;
14981480
// }
14991481
break;
1500-
case 0x400:
1501-
p_cdc->ftdi.chip_type = FT232B;
1502-
p_cdc->ftdi.channel = 0;
1503-
break;
1504-
case 0x500:
1505-
p_cdc->ftdi.chip_type = FT2232C;
1506-
break;
1507-
case 0x600:
1508-
p_cdc->ftdi.chip_type = FT232R;
1509-
p_cdc->ftdi.channel = 0;
1510-
break;
1511-
case 0x700:
1512-
p_cdc->ftdi.chip_type = FT2232H;
1513-
break;
1514-
case 0x800:
1515-
p_cdc->ftdi.chip_type = FT4232H;
1516-
break;
1517-
case 0x900:
1518-
p_cdc->ftdi.chip_type = FT232H;
1519-
break;
1520-
case 0x1000:
1521-
p_cdc->ftdi.chip_type = FTX;
1522-
break;
1523-
case 0x2800:
1524-
p_cdc->ftdi.chip_type = FT2233HP;
1525-
break;
1526-
case 0x2900:
1527-
p_cdc->ftdi.chip_type = FT4233HP;
1528-
break;
1529-
case 0x3000:
1530-
p_cdc->ftdi.chip_type = FT2232HP;
1531-
break;
1532-
case 0x3100:
1533-
p_cdc->ftdi.chip_type = FT4232HP;
1534-
break;
1535-
case 0x3200:
1536-
p_cdc->ftdi.chip_type = FT233HP;
1537-
break;
1538-
case 0x3300:
1539-
p_cdc->ftdi.chip_type = FT232HP;
1540-
break;
1541-
case 0x3600:
1542-
p_cdc->ftdi.chip_type = FT4232HA;
1543-
break;
1482+
case 0x400: p_cdc->ftdi.chip_type = FT232B; p_cdc->ftdi.channel = 0; break;
1483+
case 0x500: p_cdc->ftdi.chip_type = FT2232C; break;
1484+
case 0x600: p_cdc->ftdi.chip_type = FT232R; p_cdc->ftdi.channel = 0; break;
1485+
case 0x700: p_cdc->ftdi.chip_type = FT2232H; break;
1486+
case 0x800: p_cdc->ftdi.chip_type = FT4232H; break;
1487+
case 0x900: p_cdc->ftdi.chip_type = FT232H; break;
1488+
case 0x1000: p_cdc->ftdi.chip_type = FTX; break;
1489+
case 0x2800: p_cdc->ftdi.chip_type = FT2233HP; break;
1490+
case 0x2900: p_cdc->ftdi.chip_type = FT4233HP; break;
1491+
case 0x3000: p_cdc->ftdi.chip_type = FT2232HP; break;
1492+
case 0x3100: p_cdc->ftdi.chip_type = FT4232HP; break;
1493+
case 0x3200: p_cdc->ftdi.chip_type = FT233HP; break;
1494+
case 0x3300: p_cdc->ftdi.chip_type = FT232HP; break;
1495+
case 0x3600: p_cdc->ftdi.chip_type = FT4232HA; break;
15441496
default:
15451497
if (version < 0x200) {
15461498
p_cdc->ftdi.chip_type = SIO;
@@ -1550,7 +1502,7 @@ static bool ftdi_determine_type(cdch_interface_t *p_cdc) {
15501502
}
15511503

15521504
TU_LOG_P_CDC("%s detected (bcdDevice = 0x%04x)",
1553-
ftdi_chip_name[p_cdc->ftdi.chip_type], desc_dev->bcdDevice);
1505+
ftdi_chip_name[p_cdc->ftdi.chip_type], version);
15541506

15551507
return (p_cdc->ftdi.chip_type != UNKNOWN);
15561508
}
@@ -2025,7 +1977,8 @@ static bool ch34x_write_reg_baudrate(cdch_interface_t *p_cdc, tuh_xfer_cb_t comp
20251977
}
20261978

20271979
static bool ch34x_modem_ctrl_request(cdch_interface_t *p_cdc, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
2028-
uint8_t control = ~((p_cdc->requested_line_state.rts ? CH34X_BIT_RTS : 0) |// CH34x signals are inverted
1980+
// CH34x signals are inverted
1981+
uint8_t control = ~((p_cdc->requested_line_state.rts ? CH34X_BIT_RTS : 0) |
20291982
(p_cdc->requested_line_state.dtr ? CH34X_BIT_DTR : 0));
20301983
return ch34x_control_out(p_cdc, CH34X_REQ_MODEM_CTRL, control, 0, complete_cb, user_data);
20311984
}
@@ -2506,8 +2459,7 @@ static bool pl2303_set_modem_ctrl(cdch_interface_t *p_cdc, tuh_xfer_cb_t complet
25062459
//------------- Enumeration -------------//
25072460

25082461
enum {
2509-
CONFIG_PL2303_GET_DESC = 0,
2510-
CONFIG_PL2303_DETECT_TYPE,
2462+
CONFIG_PL2303_DETECT_TYPE = 0,
25112463
CONFIG_PL2303_READ1,
25122464
CONFIG_PL2303_WRITE1,
25132465
CONFIG_PL2303_READ2,
@@ -2568,14 +2520,8 @@ static bool pl2303_process_set_config(tuh_xfer_t *xfer) {
25682520
TU_ASSERT(p_cdc && (xfer->result == XFER_RESULT_SUCCESS || xfer->user_data == CONFIG_PL2303_READ1));
25692521
switch (state) {
25702522
// from here sequence overtaken from Linux Kernel function pl2303_startup()
2571-
case CONFIG_PL2303_GET_DESC:
2572-
p_cdc->user_control_cb = cdch_process_set_config;// set once for whole process config
2573-
// get device descriptor
2574-
TU_ASSERT(tuh_descriptor_get_device(xfer->daddr, &desc_dev, sizeof(tusb_desc_device_t),
2575-
cdch_process_set_config, CONFIG_PL2303_DETECT_TYPE));
2576-
break;
2577-
25782523
case CONFIG_PL2303_DETECT_TYPE:
2524+
p_cdc->user_control_cb = cdch_process_set_config;// set once for whole process config
25792525
// get type and quirks (step 1)
25802526
type = pl2303_detect_type(p_cdc, 1, cdch_process_set_config, CONFIG_PL2303_READ1);
25812527
TU_ASSERT(type != PL2303_DETECT_TYPE_FAILED);
@@ -2784,39 +2730,39 @@ static bool pl2303_process_set_config(tuh_xfer_t *xfer) {
27842730

27852731
static int8_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step,
27862732
tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
2787-
/*
2788-
* Legacy PL2303H, variants 0 and 1 (difference unknown).
2789-
*/
2790-
if (desc_dev->bDeviceClass == 0x02) {
2733+
tusb_desc_device_t desc_dev;
2734+
TU_VERIFY(tuh_descriptor_get_device_local(p_cdc->daddr, &desc_dev), PL2303_DETECT_TYPE_FAILED);
2735+
2736+
// Legacy PL2303H, variants 0 and 1 (difference unknown).
2737+
if (desc_dev.bDeviceClass == 0x02) {
27912738
return TYPE_H; /* variant 0 */
27922739
}
27932740

2794-
if (desc_dev->bMaxPacketSize0 != 0x40) {
2795-
if (desc_dev->bDeviceClass == 0x00 || desc_dev->bDeviceClass == 0xff) {
2741+
if (desc_dev.bMaxPacketSize0 != 0x40) {
2742+
if (desc_dev.bDeviceClass == 0x00 || desc_dev.bDeviceClass == 0xff) {
27962743
return TYPE_H; /* variant 1 */
27972744
}
27982745
return TYPE_H; /* variant 0 */
27992746
}
28002747

2801-
switch (desc_dev->bcdUSB) {
2748+
switch (desc_dev.bcdUSB) {
28022749
case 0x101:
28032750
/* USB 1.0.1? Let's assume they meant 1.1... */
28042751
TU_ATTR_FALLTHROUGH;
28052752
case 0x110:
2806-
switch (desc_dev->bcdDevice) {
2807-
case 0x300:
2808-
return TYPE_HX;
2809-
case 0x400:
2810-
return TYPE_HXD;
2811-
default:
2812-
return TYPE_HX;
2753+
switch (desc_dev.bcdDevice) {
2754+
case 0x300: return TYPE_HX;
2755+
case 0x400: return TYPE_HXD;
2756+
default: return TYPE_HX;
28132757
}
28142758
break;
2759+
28152760
case 0x200:
2816-
switch (desc_dev->bcdDevice) {
2761+
switch (desc_dev.bcdDevice) {
28172762
case 0x100: /* GC */
28182763
case 0x105:
28192764
return TYPE_HXN;
2765+
28202766
case 0x300: /* GT / TA */
28212767
if (step == 1) {
28222768
// 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,
28332779
case 0x400: /* GL */
28342780
case 0x405:
28352781
return TYPE_HXN;
2782+
28362783
case 0x500: /* GE / TB */
28372784
if (step == 1) {
28382785
// step 1 trigger pl2303_supports_hx_status() request
@@ -2851,15 +2798,15 @@ static int8_t pl2303_detect_type(cdch_interface_t *p_cdc, uint8_t step,
28512798
case 0x700: /* GR */
28522799
case 0x705:
28532800
return TYPE_HXN;
2801+
28542802
default:
28552803
break;
28562804
}
28572805
break;
28582806
default: break;
28592807
}
28602808

2861-
TU_LOG_P_CDC("unknown device type bcdUSB = 0x%04x", desc_dev->bcdUSB);
2862-
2809+
TU_LOG_P_CDC("unknown device type bcdUSB = 0x%04x", desc_dev.bcdUSB);
28632810
return PL2303_DETECT_TYPE_FAILED;
28642811
}
28652812

src/common/tusb_types.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,6 @@ typedef struct TU_ATTR_PACKED {
345345
uint8_t iManufacturer ; ///< Index of string descriptor describing manufacturer.
346346
uint8_t iProduct ; ///< Index of string descriptor describing product.
347347
uint8_t iSerialNumber ; ///< Index of string descriptor describing the device's serial number.
348-
349348
uint8_t bNumConfigurations ; ///< Number of possible configurations.
350349
} tusb_desc_device_t;
351350

src/host/usbh.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -94,26 +94,28 @@ TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(const void* addr, uint32_t data_si
9494
typedef struct {
9595
tuh_bus_info_t bus_info;
9696

97-
// Device State
98-
struct TU_ATTR_PACKED {
99-
volatile uint8_t connected : 1; // After 1st transfer
100-
volatile uint8_t addressed : 1; // After SET_ADDR
101-
volatile uint8_t configured : 1; // After SET_CONFIG and all drivers are configured
102-
volatile uint8_t suspended : 1; // Bus suspended
103-
// volatile uint8_t removing : 1; // Physically disconnected, waiting to be processed by usbh
104-
};
105-
10697
// Device Descriptor
107-
uint8_t ep0_size;
98+
uint16_t bcdUSB;
99+
uint8_t bDeviceClass;
100+
uint8_t bDeviceSubClass;
101+
uint8_t bDeviceProtocol;
102+
uint8_t bMaxPacketSize0;
108103
uint16_t idVendor;
109104
uint16_t idProduct;
105+
uint16_t bcdDevice;
110106
uint8_t iManufacturer;
111107
uint8_t iProduct;
112108
uint8_t iSerialNumber;
113109
uint8_t bNumConfigurations;
114110

115-
// Configuration Descriptor
116-
// uint8_t interface_count; // bNumInterfaces alias
111+
// Device State
112+
struct TU_ATTR_PACKED {
113+
volatile uint8_t connected : 1; // After 1st transfer
114+
volatile uint8_t addressed : 1; // After SET_ADDR
115+
volatile uint8_t configured : 1; // After SET_CONFIG and all drivers are configured
116+
volatile uint8_t suspended : 1; // Bus suspended
117+
// volatile uint8_t removing : 1; // Physically disconnected, waiting to be processed by usbh
118+
};
117119

118120
// Endpoint & Interface
119121
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) {
373375
return true;
374376
}
375377

378+
bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device) {
379+
usbh_device_t *dev = get_device(daddr);
380+
TU_VERIFY(dev && desc_device);
381+
382+
desc_device->bLength = sizeof(tusb_desc_device_t);
383+
desc_device->bDescriptorType = TUSB_DESC_DEVICE;
384+
desc_device->bcdUSB = dev->bcdUSB;
385+
desc_device->bDeviceClass = dev->bDeviceClass;
386+
desc_device->bDeviceSubClass = dev->bDeviceSubClass;
387+
desc_device->bDeviceProtocol = dev->bDeviceProtocol;
388+
desc_device->bMaxPacketSize0 = dev->bMaxPacketSize0;
389+
desc_device->idVendor = dev->idVendor;
390+
desc_device->idProduct = dev->idProduct;
391+
desc_device->bcdDevice = dev->bcdDevice;
392+
desc_device->iManufacturer = dev->iManufacturer;
393+
desc_device->iProduct = dev->iProduct;
394+
desc_device->iSerialNumber = dev->iSerialNumber;
395+
desc_device->bNumConfigurations = dev->bNumConfigurations;
396+
397+
return true;
398+
}
399+
376400
tusb_speed_t tuh_speed_get(uint8_t daddr) {
377401
tuh_bus_info_t bus_info;
378402
tuh_bus_info_get(daddr, &bus_info);
@@ -1579,7 +1603,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
15791603
usbh_device_t* new_dev = get_device(new_addr);
15801604
new_dev->bus_info = *dev0_bus;
15811605
new_dev->connected = 1;
1582-
new_dev->ep0_size = desc_device->bMaxPacketSize0;
1606+
new_dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0;
15831607

15841608
TU_ASSERT(tuh_address_set(0, new_addr, process_enumeration, ENUM_GET_DEVICE_DESC),);
15851609
break;
@@ -1596,7 +1620,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
15961620

15971621
usbh_device_close(dev0_bus->rhport, 0); // close dev0
15981622

1599-
TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->ep0_size),); // open new control endpoint
1623+
TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0),); // open new control endpoint
16001624

16011625
TU_LOG_USBH("Get Device Descriptor\r\n");
16021626
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) {
16091633
case ENUM_GET_STRING_LANGUAGE_ID_LEN: {
16101634
// save the received device descriptor
16111635
tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl;
1636+
dev->bcdUSB = desc_device->bcdUSB;
1637+
dev->bDeviceClass = desc_device->bDeviceClass;
1638+
dev->bDeviceSubClass = desc_device->bDeviceSubClass;
1639+
dev->bDeviceProtocol = desc_device->bDeviceProtocol;
1640+
dev->bMaxPacketSize0 = desc_device->bMaxPacketSize0;
16121641
dev->idVendor = desc_device->idVendor;
16131642
dev->idProduct = desc_device->idProduct;
1643+
dev->bcdDevice = desc_device->bcdDevice;
16141644
dev->iManufacturer = desc_device->iManufacturer;
16151645
dev->iProduct = desc_device->iProduct;
16161646
dev->iSerialNumber = desc_device->iSerialNumber;

src/host/usbh.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ bool tuh_rhport_reset_bus(uint8_t rhport, bool active);
204204
// Get VID/PID of device
205205
bool tuh_vid_pid_get(uint8_t daddr, uint16_t* vid, uint16_t* pid);
206206

207+
// Get local (cached) device descriptor once device is enumerated
208+
bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_device);
209+
207210
// Get speed of device
208211
tusb_speed_t tuh_speed_get(uint8_t daddr);
209212

0 commit comments

Comments
 (0)