Skip to content

Commit 3fd7854

Browse files
authored
Merge pull request #3081 from hathach/usbh-enum-get-string-desc-first
usbh enum get string descriptor length first
2 parents edbea21 + ba45625 commit 3fd7854

File tree

7 files changed

+90
-64
lines changed

7 files changed

+90
-64
lines changed

.github/workflows/build.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
- 'msp430-gcc'
8686
- 'riscv-gcc'
8787
- 'rx-gcc'
88-
- 'esp-idf' # build-system is ignored
88+
- 'esp-idf'
8989
with:
9090
build-system: 'make'
9191
toolchain: ${{ matrix.toolchain }}
@@ -115,7 +115,8 @@ jobs:
115115
# cmake is built by circle-ci. Due to IAR limit capacity, only build oe per family
116116
# ---------------------------------------
117117
arm-iar:
118-
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false
118+
if: false # disable for now since we got reach capacity limit too often
119+
#if: github.event_name == 'push' && github.repository_owner == 'hathach'
119120
needs: set-matrix
120121
uses: ./.github/workflows/build_util.yml
121122
secrets: inherit

.github/workflows/ci_set_matrix.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@
4444
"stm32l0 stm32l4": ["arm-gcc", "arm-clang", "arm-iar"],
4545
"stm32u5 stm32wb": ["arm-gcc", "arm-clang", "arm-iar"],
4646
"xmc4000": ["arm-gcc"],
47-
"-bespressif_kaluga_1": ["esp-idf"],
48-
"-bespressif_s3_devkitm": ["esp-idf"],
49-
"-bespressif_p4_function_ev": ["esp-idf"],
47+
"-bespressif_s2_devkitc": ["esp-idf"],
48+
# S3, P4 will be built by hil test
49+
# "-bespressif_s3_devkitm": ["esp-idf"],
50+
# "-bespressif_p4_function_ev": ["esp-idf"],
5051
}
5152

5253

hw/bsp/espressif/boards/espressif_s2_devkitc/board.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,19 @@
3636
extern "C" {
3737
#endif
3838

39-
// Note: On the production version (v1.2) WS2812 is connected to GPIO 18,
40-
// however earlier revision v1.1 WS2812 is connected to GPIO 17
4139
#define NEOPIXEL_PIN 18
4240

4341
#define BUTTON_PIN 0
4442
#define BUTTON_STATE_ACTIVE 0
4543

44+
// SPI for USB host shield
45+
#define MAX3421_SPI_HOST SPI2_HOST
46+
#define MAX3421_SCK_PIN 36
47+
#define MAX3421_MOSI_PIN 35
48+
#define MAX3421_MISO_PIN 37
49+
#define MAX3421_CS_PIN 15
50+
#define MAX3421_INTR_PIN 14
51+
4652
#ifdef __cplusplus
4753
}
4854
#endif

hw/bsp/espressif/boards/espressif_s3_devkitc/board.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
extern "C" {
3737
#endif
3838

39-
#define NEOPIXEL_PIN 48
39+
#define NEOPIXEL_PIN 38
4040

4141
#define BUTTON_PIN 0
4242
#define BUTTON_STATE_ACTIVE 0

hw/bsp/espressif/family.cmake

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ endif ()
3434
set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components")
3535

3636
# set SDKCONFIG for each IDF Target
37-
set(SDKCONFIG ${CMAKE_SOURCE_DIR}/sdkconfig.${IDF_TARGET})
37+
set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig)
3838

3939
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

src/common/tusb_debug.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,13 @@ typedef struct {
108108
} tu_lookup_table_t;
109109

110110
static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) {
111-
tu_static char not_found[11];
112-
113111
for(uint16_t i=0; i<p_table->count; i++) {
114-
if (p_table->items[i].key == key) return p_table->items[i].data;
112+
if (p_table->items[i].key == key) { return p_table->items[i].data; }
115113
}
116114

117115
// not found return the key value in hex
116+
static char not_found[11];
118117
snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key);
119-
120118
return not_found;
121119
}
122120

src/host/usbh.c

+71-51
Original file line numberDiff line numberDiff line change
@@ -1372,9 +1372,13 @@ enum {
13721372
ENUM_HUB_CLEAR_RESET_2,
13731373
ENUM_SET_ADDR,
13741374
ENUM_GET_DEVICE_DESC,
1375+
ENUM_GET_STRING_LANGUAGE_ID_LEN,
13751376
ENUM_GET_STRING_LANGUAGE_ID,
1377+
ENUM_GET_STRING_MANUFACTURER_LEN,
13761378
ENUM_GET_STRING_MANUFACTURER,
1379+
ENUM_GET_STRING_PRODUCT_LEN,
13771380
ENUM_GET_STRING_PRODUCT,
1381+
ENUM_GET_STRING_SERIAL_LEN,
13781382
ENUM_GET_STRING_SERIAL,
13791383
ENUM_GET_9BYTE_CONFIG_DESC,
13801384
ENUM_GET_FULL_CONFIG_DESC,
@@ -1416,6 +1420,9 @@ static void process_enumeration(tuh_xfer_t* xfer) {
14161420
uint8_t const daddr = xfer->daddr;
14171421
uintptr_t const state = xfer->user_data;
14181422
usbh_device_t* dev = get_device(daddr);
1423+
if (daddr > 0) {
1424+
TU_ASSERT(dev,);
1425+
}
14191426
uint16_t langid = 0x0409; // default is English
14201427

14211428
switch (state) {
@@ -1474,30 +1481,6 @@ static void process_enumeration(tuh_xfer_t* xfer) {
14741481
break;
14751482
}
14761483

1477-
#if 0
1478-
case ENUM_RESET_2:
1479-
// TODO not used by now, but may be needed for some devices !?
1480-
// Reset device again before Set Address
1481-
TU_LOG_USBH("Port reset2 \r\n");
1482-
if (_dev0.hub_addr == 0) {
1483-
// connected directly to roothub
1484-
hcd_port_reset( _dev0.rhport );
1485-
tusb_time_delay_ms_api(RESET_DELAY); // TODO may not work for no-OS on MCU that require reset_end() since
1486-
// sof of controller may not running while resetting
1487-
hcd_port_reset_end(_dev0.rhport);
1488-
// TODO: fall through to SET ADDRESS, refactor later
1489-
}
1490-
#if CFG_TUH_HUB
1491-
else {
1492-
// after RESET_DELAY the hub_port_reset() already complete
1493-
TU_ASSERT( hub_port_reset(_dev0.hub_addr, _dev0.hub_port,
1494-
process_enumeration, ENUM_HUB_GET_STATUS_2), );
1495-
break;
1496-
}
1497-
#endif
1498-
TU_ATTR_FALLTHROUGH;
1499-
#endif
1500-
15011484
case ENUM_SET_ADDR:
15021485
enum_request_set_addr((tusb_desc_device_t*) _usbh_epbuf.ctrl);
15031486
break;
@@ -1520,65 +1503,104 @@ static void process_enumeration(tuh_xfer_t* xfer) {
15201503
// Get full device descriptor
15211504
TU_LOG_USBH("Get Device Descriptor\r\n");
15221505
TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t),
1523-
process_enumeration, ENUM_GET_STRING_LANGUAGE_ID),);
1506+
process_enumeration, ENUM_GET_STRING_LANGUAGE_ID_LEN),);
15241507
break;
15251508
}
15261509

1527-
case ENUM_GET_STRING_LANGUAGE_ID: {
1510+
// For string descriptor (langid, manufacturer, product, serila): always get the first 2 bytes
1511+
// to determine the length first. otherwise, some device may have buffer overflow.
1512+
case ENUM_GET_STRING_LANGUAGE_ID_LEN: {
15281513
// save the received device descriptor
1529-
TU_ASSERT(dev,);
1530-
tusb_desc_device_t const* desc_device = (tusb_desc_device_t const*) _usbh_epbuf.ctrl;
1514+
tusb_desc_device_t const *desc_device = (tusb_desc_device_t const *) _usbh_epbuf.ctrl;
15311515
dev->vid = desc_device->idVendor;
15321516
dev->pid = desc_device->idProduct;
15331517
dev->i_manufacturer = desc_device->iManufacturer;
15341518
dev->i_product = desc_device->iProduct;
15351519
dev->i_serial = desc_device->iSerialNumber;
15361520
dev->bNumConfigurations = desc_device->bNumConfigurations;
15371521

1538-
tuh_enum_descriptor_device_cb(daddr, desc_device); // callback
1522+
tuh_enum_descriptor_device_cb(daddr, desc_device);// callback
15391523

1540-
tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, CFG_TUH_ENUMERATION_BUFSIZE,
1541-
process_enumeration, ENUM_GET_STRING_MANUFACTURER);
1524+
tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, 2,
1525+
process_enumeration, ENUM_GET_STRING_LANGUAGE_ID);
15421526
break;
15431527
}
15441528

1545-
case ENUM_GET_STRING_MANUFACTURER: {
1546-
TU_ASSERT(dev,);
1547-
const tusb_desc_string_t* desc_langid = (tusb_desc_string_t const*) _usbh_epbuf.ctrl;
1529+
case ENUM_GET_STRING_LANGUAGE_ID: {
1530+
const uint8_t str_len = xfer->buffer[0];
1531+
tuh_descriptor_get_string_langid(daddr, _usbh_epbuf.ctrl, str_len,
1532+
process_enumeration, ENUM_GET_STRING_MANUFACTURER_LEN);
1533+
break;
1534+
}
1535+
1536+
case ENUM_GET_STRING_MANUFACTURER_LEN: {
1537+
const tusb_desc_string_t* desc_langid = (const tusb_desc_string_t *) _usbh_epbuf.ctrl;
15481538
if (desc_langid->bLength >= 4) {
1549-
langid = tu_le16toh(desc_langid->utf16le[0]);
1539+
langid = tu_le16toh(desc_langid->utf16le[0]); // previous request is langid
15501540
}
15511541
if (dev->i_manufacturer != 0) {
1552-
tuh_descriptor_get_string(daddr, dev->i_manufacturer, langid, _usbh_epbuf.ctrl, CFG_TUH_ENUMERATION_BUFSIZE,
1553-
process_enumeration, ENUM_GET_STRING_PRODUCT);
1542+
tuh_descriptor_get_string(daddr, dev->i_manufacturer, langid, _usbh_epbuf.ctrl, 2,
1543+
process_enumeration, ENUM_GET_STRING_MANUFACTURER);
1544+
break;
1545+
}else {
1546+
TU_ATTR_FALLTHROUGH;
1547+
}
1548+
}
1549+
1550+
case ENUM_GET_STRING_MANUFACTURER: {
1551+
if (dev->i_manufacturer != 0) {
1552+
langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
1553+
const uint8_t str_len = xfer->buffer[0];
1554+
tuh_descriptor_get_string(daddr, dev->i_manufacturer, langid, _usbh_epbuf.ctrl, str_len,
1555+
process_enumeration, ENUM_GET_STRING_PRODUCT_LEN);
15541556
break;
15551557
} else {
15561558
TU_ATTR_FALLTHROUGH;
15571559
}
15581560
}
15591561

1560-
case ENUM_GET_STRING_PRODUCT: {
1561-
TU_ASSERT(dev,);
1562-
if (state == ENUM_GET_STRING_PRODUCT) {
1563-
langid = tu_le16toh(xfer->setup->wIndex); // if not fall through, get langid from previous setup packet
1562+
case ENUM_GET_STRING_PRODUCT_LEN:
1563+
if (dev->i_product != 0) {
1564+
if (state == ENUM_GET_STRING_PRODUCT_LEN) {
1565+
langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through
1566+
}
1567+
tuh_descriptor_get_string(daddr, dev->i_product, langid, _usbh_epbuf.ctrl, 2,
1568+
process_enumeration, ENUM_GET_STRING_PRODUCT);
1569+
break;
1570+
} else {
1571+
TU_ATTR_FALLTHROUGH;
15641572
}
1573+
1574+
case ENUM_GET_STRING_PRODUCT: {
15651575
if (dev->i_product != 0) {
1566-
tuh_descriptor_get_string(daddr, dev->i_product, 0x0409, _usbh_epbuf.ctrl, CFG_TUH_ENUMERATION_BUFSIZE,
1567-
process_enumeration, ENUM_GET_STRING_SERIAL);
1576+
langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
1577+
const uint8_t str_len = xfer->buffer[0];
1578+
tuh_descriptor_get_string(daddr, dev->i_product, langid, _usbh_epbuf.ctrl, str_len,
1579+
process_enumeration, ENUM_GET_STRING_SERIAL_LEN);
15681580
break;
15691581
} else {
15701582
TU_ATTR_FALLTHROUGH;
15711583
}
15721584
}
15731585

1574-
case ENUM_GET_STRING_SERIAL: {
1575-
TU_ASSERT(dev,);
1576-
if (state == ENUM_GET_STRING_SERIAL) {
1577-
langid = tu_le16toh(xfer->setup->wIndex); // if not fall through, get langid from previous setup packet
1586+
case ENUM_GET_STRING_SERIAL_LEN:
1587+
if (dev->i_serial != 0) {
1588+
if (state == ENUM_GET_STRING_SERIAL_LEN) {
1589+
langid = tu_le16toh(xfer->setup->wIndex); // get langid from previous setup packet if not fall through
1590+
}
1591+
tuh_descriptor_get_string(daddr, dev->i_serial, langid, _usbh_epbuf.ctrl, 2,
1592+
process_enumeration, ENUM_GET_STRING_SERIAL);
1593+
break;
1594+
} else {
1595+
TU_ATTR_FALLTHROUGH;
15781596
}
1597+
1598+
case ENUM_GET_STRING_SERIAL: {
15791599
if (dev->i_serial != 0) {
1580-
tuh_descriptor_get_string(daddr, dev->i_serial, langid, _usbh_epbuf.ctrl, CFG_TUH_ENUMERATION_BUFSIZE,
1581-
process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC);
1600+
langid = tu_le16toh(xfer->setup->wIndex); // langid from length's request
1601+
const uint8_t str_len = xfer->buffer[0];
1602+
tuh_descriptor_get_string(daddr, dev->i_serial, langid, _usbh_epbuf.ctrl, str_len,
1603+
process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC);
15821604
break;
15831605
} else {
15841606
TU_ATTR_FALLTHROUGH;
@@ -1627,8 +1649,6 @@ static void process_enumeration(tuh_xfer_t* xfer) {
16271649

16281650
case ENUM_CONFIG_DRIVER: {
16291651
TU_LOG_USBH("Device configured\r\n");
1630-
TU_ASSERT(dev,);
1631-
16321652
dev->configured = 1;
16331653

16341654
// Parse configuration & set up drivers

0 commit comments

Comments
 (0)