Skip to content

Commit 9496740

Browse files
authored
Merge pull request #528 from adafruit/fix-esp32-max3421e
fix compiling hcd max3421e with arduino-esp32 and arduino-pico due to missing atomic_flag function
2 parents f05bd09 + 6fa11c4 commit 9496740

22 files changed

+415
-197
lines changed

.github/workflows/githubci.yml

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
run: bash ci/doxy_gen_and_deploy.sh
3939

4040
# ---------------------------------------
41-
# Main
41+
# build
4242
# ---------------------------------------
4343
build:
4444
runs-on: ubuntu-latest
@@ -83,53 +83,3 @@ jobs:
8383
8484
- name: test platforms
8585
run: python3 ci/build_platform.py ${{ matrix.arduino-platform }}
86-
87-
# ---------------------------------------
88-
# Build ESP32 v2
89-
# ---------------------------------------
90-
build-esp32-v2:
91-
if: false
92-
runs-on: ubuntu-latest
93-
needs: pre-commit
94-
strategy:
95-
fail-fast: false
96-
matrix:
97-
arduino-platform:
98-
- 'feather_esp32s2'
99-
- 'feather_esp32s3'
100-
esp32-version:
101-
- '2.0.17'
102-
103-
steps:
104-
- name: Checkout code
105-
uses: actions/checkout@v4
106-
107-
- name: Checkout adafruit/ci-arduino
108-
uses: actions/checkout@v4
109-
with:
110-
repository: adafruit/ci-arduino
111-
path: ci
112-
113-
- name: pre-install
114-
run: bash ci/actions_install.sh
115-
116-
- name: Install arduino-esp32 v2 and Libraries
117-
env:
118-
BSP_URLS: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
119-
run: |
120-
arduino-cli core install esp32:esp32@${{ matrix.esp32-version }} --additional-urls $BSP_URLS
121-
arduino-cli lib install ${{ env.ARDUINO_LIBS }}
122-
arduino-cli core list
123-
arduino-cli lib list
124-
125-
- name: Create custom build script
126-
working-directory: ${{ github.workspace }}/ci
127-
run: |
128-
echo 'import build_platform' > build_esp32_v2.py
129-
echo 'build_platform.test_examples_in_folder("'${{ matrix.arduino-platform }}'", build_platform.BUILD_DIR)' >> build_esp32_v2.py
130-
echo 'exit(build_platform.success)' >> build_esp32_v2.py
131-
cat build_esp32_v2.py
132-
133-
- name: test platforms
134-
run: |
135-
python3 ci/build_esp32_v2.py

src/class/cdc/cdc_host.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ void cdch_close(uint8_t daddr) {
672672

673673
bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) {
674674
// TODO handle stall response, retry failed transfer ...
675-
TU_ASSERT(event == XFER_RESULT_SUCCESS);
675+
TU_VERIFY(event == XFER_RESULT_SUCCESS);
676676

677677
uint8_t const idx = get_idx_by_ep_addr(daddr, ep_addr);
678678
cdch_interface_t * p_cdc = get_itf(idx);

src/class/hid/hid_host.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ bool hidh_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t
444444
hidh_epbuf_t* epbuf = get_hid_epbuf(idx);
445445

446446
if (dir == TUSB_DIR_IN) {
447-
TU_LOG_DRV(" Get Report callback (%u, %u)\r\n", daddr, idx);
447+
TU_LOG_DRV(" [idx=%u] Get Report callback\r\n", idx);
448448
TU_LOG3_MEM(epbuf->epin, xferred_bytes, 2);
449449
tuh_hid_report_received_cb(daddr, idx, epbuf->epin, (uint16_t) xferred_bytes);
450450
} else {
@@ -461,7 +461,9 @@ void hidh_close(uint8_t daddr) {
461461
hidh_interface_t* p_hid = &_hidh_itf[i];
462462
if (p_hid->daddr == daddr) {
463463
TU_LOG_DRV(" HIDh close addr = %u index = %u\r\n", daddr, i);
464-
if (tuh_hid_umount_cb) tuh_hid_umount_cb(daddr, i);
464+
if (tuh_hid_umount_cb) {
465+
tuh_hid_umount_cb(daddr, i);
466+
}
465467
tu_memclr(p_hid, sizeof(hidh_interface_t));
466468
}
467469
}

src/class/vendor/vendor_device.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ void vendord_reset(uint8_t rhport) {
196196

197197
uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) {
198198
TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0);
199+
const uint8_t* desc_end = (const uint8_t*)desc_itf + max_len;
199200
const uint8_t* p_desc = tu_desc_next(desc_itf);
200-
const uint8_t* desc_end = (uint8_t const*)desc_itf + max_len;
201201

202202
// Find available interface
203203
vendord_interface_t* p_vendor = NULL;
@@ -210,26 +210,26 @@ uint16_t vendord_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uin
210210
TU_VERIFY(p_vendor, 0);
211211

212212
p_vendor->itf_num = desc_itf->bInterfaceNumber;
213-
uint8_t found_ep = 0;
214-
while (found_ep < desc_itf->bNumEndpoints) {
215-
// skip non-endpoint descriptors
216-
while ( (TUSB_DESC_ENDPOINT != tu_desc_type(p_desc)) && (p_desc < desc_end) ) {
217-
p_desc = tu_desc_next(p_desc);
218-
}
219-
if (p_desc >= desc_end) {
220-
break;
221-
}
222-
223-
const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc;
224-
TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
225-
found_ep++;
226-
227-
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
228-
tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep);
229-
tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
230-
} else {
231-
tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep);
232-
TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data
213+
while (tu_desc_is_valid(p_desc, desc_end)) {
214+
const uint8_t desc_type = tu_desc_type(p_desc);
215+
if (desc_type == TUSB_DESC_INTERFACE || desc_type == TUSB_DESC_INTERFACE_ASSOCIATION) {
216+
break; // end of this interface
217+
} else if (desc_type == TUSB_DESC_ENDPOINT) {
218+
const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc;
219+
TU_ASSERT(usbd_edpt_open(rhport, desc_ep));
220+
221+
// open endpoint stream, skip if already opened
222+
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
223+
if (p_vendor->tx.stream.ep_addr == 0) {
224+
tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep);
225+
tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf));
226+
}
227+
} else {
228+
if (p_vendor->rx.stream.ep_addr == 0) {
229+
tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep);
230+
TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data
231+
}
232+
}
233233
}
234234

235235
p_desc = tu_desc_next(p_desc);

src/common/tusb_mcu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,10 @@
369369
#define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN
370370
#define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/
371371

372+
#if CFG_TUSB_MCU == OPT_MCU_ESP32S3
373+
#define TUP_MCU_MULTIPLE_CORE 1
374+
#endif
375+
372376
// Disable slave if DMA is enabled
373377
#define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE
374378
#define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE
@@ -381,6 +385,8 @@
381385

382386
#define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/
383387

388+
#define TUP_MCU_MULTIPLE_CORE 1
389+
384390
// Disable slave if DMA is enabled
385391
#define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE
386392
#define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE
@@ -410,6 +416,7 @@
410416
#elif TU_CHECK_MCU(OPT_MCU_RP2040)
411417
#define TUP_DCD_EDPT_ISO_ALLOC
412418
#define TUP_DCD_ENDPOINT_MAX 16
419+
#define TUP_MCU_MULTIPLE_CORE 1
413420

414421
#define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb")))
415422

src/common/tusb_types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) {
586586
return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE];
587587
}
588588

589+
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_is_valid(void const* desc, uint8_t const* desc_end) {
590+
const uint8_t* desc8 = (uint8_t const*) desc;
591+
return (desc8 < desc_end) && (tu_desc_next(desc) <= desc_end);
592+
}
593+
594+
589595
// find descriptor that match byte1 (type)
590596
uint8_t const * tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1);
591597

src/device/usbd.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -342,15 +342,16 @@ TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8
342342
enum { RHPORT_INVALID = 0xFFu };
343343
tu_static uint8_t _usbd_rhport = RHPORT_INVALID;
344344

345-
// Event queue
346-
// usbd_int_set() is used as mutex in OS NONE config
345+
static OSAL_SPINLOCK_DEF(_usbd_spin, usbd_int_set);
346+
347+
// Event queue: usbd_int_set() is used as mutex in OS NONE config
347348
OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t);
348-
tu_static osal_queue_t _usbd_q;
349+
static osal_queue_t _usbd_q;
349350

350351
// Mutex for claiming endpoint
351352
#if OSAL_MUTEX_REQUIRED
352-
tu_static osal_mutex_def_t _ubsd_mutexdef;
353-
tu_static osal_mutex_t _usbd_mutex;
353+
static osal_mutex_def_t _ubsd_mutexdef;
354+
static osal_mutex_t _usbd_mutex;
354355
#else
355356
#define _usbd_mutex NULL
356357
#endif
@@ -468,7 +469,7 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
468469
TU_ASSERT(rh_init);
469470

470471
TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport,
471-
rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full");
472+
rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full");
472473
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
473474
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t));
474475
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
@@ -477,6 +478,8 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
477478
tu_varclr(&_usbd_dev);
478479
_usbd_queued_setup = 0;
479480

481+
osal_spin_init(&_usbd_spin);
482+
480483
#if OSAL_MUTEX_REQUIRED
481484
// Init device mutex
482485
_usbd_mutex = osal_mutex_create(&_ubsd_mutexdef);
@@ -1248,17 +1251,21 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr)
12481251
// USBD API For Class Driver
12491252
//--------------------------------------------------------------------+
12501253

1251-
void usbd_int_set(bool enabled)
1252-
{
1253-
if (enabled)
1254-
{
1254+
void usbd_int_set(bool enabled) {
1255+
if (enabled) {
12551256
dcd_int_enable(_usbd_rhport);
1256-
}else
1257-
{
1257+
} else {
12581258
dcd_int_disable(_usbd_rhport);
12591259
}
12601260
}
12611261

1262+
void usbd_spin_lock(bool in_isr) {
1263+
osal_spin_lock(&_usbd_spin, in_isr);
1264+
}
1265+
void usbd_spin_unlock(bool in_isr) {
1266+
osal_spin_unlock(&_usbd_spin, in_isr);
1267+
}
1268+
12621269
// Parse consecutive endpoint descriptors (IN & OUT)
12631270
bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
12641271
{

src/device/usbd_pvt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR
6868
typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
6969

7070
void usbd_int_set(bool enabled);
71+
void usbd_spin_lock(bool in_isr);
72+
void usbd_spin_unlock(bool in_isr);
7173

7274
//--------------------------------------------------------------------+
7375
// USBD Endpoint API

src/host/hub.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp,
201201

202202
bool hub_port_get_status_local(uint8_t hub_addr, uint8_t hub_port, hub_port_status_response_t* resp) {
203203
(void) hub_port;
204-
TU_VERIFY(hub_addr > CFG_TUH_DEVICE_MAX);
205204
hub_interface_t* p_hub = get_hub_itf(hub_addr);
206205
*resp = p_hub->port_status;
207206
return true;

src/host/usbh.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ static osal_mutex_t _usbh_mutex;
147147
#define _usbh_mutex NULL
148148
#endif
149149

150+
// Spinlock for interrupt handler
151+
static OSAL_SPINLOCK_DEF(_usbh_spin, usbh_int_set);
152+
150153
// Event queue: usbh_int_set() is used as mutex in OS NONE config
151154
OSAL_QUEUE_DEF(usbh_int_set, _usbh_qdef, CFG_TUH_TASK_QUEUE_SZ, hcd_event_t);
152155
static osal_queue_t _usbh_q;
@@ -424,6 +427,8 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
424427
TU_LOG_INT_USBH(sizeof(tu_fifo_t));
425428
TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t));
426429

430+
osal_spin_init(&_usbh_spin);
431+
427432
// Event queue
428433
_usbh_q = osal_queue_create(&_usbh_qdef);
429434
TU_ASSERT(_usbh_q != NULL);
@@ -547,7 +552,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
547552
// TODO better to have an separated queue for newly attached devices
548553
if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) {
549554
// New device attached and we are ready
550-
TU_LOG1("[%u:] USBH Device Attach\r\n", event.rhport);
555+
TU_LOG_USBH("[%u:] USBH Device Attach\r\n", event.rhport);
551556
_usbh_data.enumerating_daddr = 0; // enumerate new device with address 0
552557
enum_new_device(&event);
553558
} else {
@@ -562,7 +567,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
562567
break;
563568

564569
case HCD_EVENT_DEVICE_REMOVE:
565-
TU_LOG1("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
570+
TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
566571
if (_usbh_data.enumerating_daddr == 0 &&
567572
event.rhport == _usbh_data.dev0_bus.rhport &&
568573
event.connection.hub_addr == _usbh_data.dev0_bus.hub_addr &&
@@ -579,7 +584,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
579584
uint8_t const epnum = tu_edpt_number(ep_addr);
580585
uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr);
581586

582-
TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len, tu_str_xfer_result[event.xfer_complete.result]);
587+
TU_LOG_USBH("[:%u] on EP %02X with %u bytes: %s\r\n",
588+
event.dev_addr, ep_addr, (unsigned int) event.xfer_complete.len, tu_str_xfer_result[event.xfer_complete.result]);
583589

584590
if (event.dev_addr == 0) {
585591
// device 0 only has control endpoint
@@ -618,7 +624,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
618624
uint8_t drv_id = dev->ep2drv[epnum][ep_dir];
619625
usbh_class_driver_t const* driver = get_driver(drv_id);
620626
if (driver) {
621-
TU_LOG_USBH("%s xfer callback\r\n", driver->name);
627+
TU_LOG_USBH(" %s xfer callback\r\n", driver->name);
622628
driver->xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result,
623629
event.xfer_complete.len);
624630
} else {
@@ -894,6 +900,14 @@ void usbh_int_set(bool enabled) {
894900
}
895901
}
896902

903+
void usbh_spin_lock(bool in_isr) {
904+
osal_spin_lock(&_usbh_spin, in_isr);
905+
}
906+
907+
void usbh_spin_unlock(bool in_isr) {
908+
osal_spin_unlock(&_usbh_spin, in_isr);
909+
}
910+
897911
void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) {
898912
hcd_event_t event = { 0 };
899913
event.event_id = USBH_EVENT_FUNC_CALL;
@@ -1463,7 +1477,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
14631477
bool retry = (_usbh_data.enumerating_daddr != TUSB_INDEX_INVALID_8) && (failed_count < ATTEMPT_COUNT_MAX);
14641478
if (retry) {
14651479
tusb_time_delay_ms_api(ATTEMPT_DELAY_MS); // delay a bit
1466-
TU_LOG1("Enumeration attempt %u/%u\r\n", failed_count+1, ATTEMPT_COUNT_MAX);
1480+
TU_LOG_USBH("Enumeration attempt %u/%u\r\n", failed_count+1, ATTEMPT_COUNT_MAX);
14671481
retry = tuh_control_xfer(xfer);
14681482
}
14691483

src/host/usbh_pvt.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ void usbh_int_set(bool enabled);
7171

7272
void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr);
7373

74+
void usbh_spin_lock(bool in_isr);
75+
void usbh_spin_unlock(bool in_isr);
76+
7477
//--------------------------------------------------------------------+
7578
// USBH Endpoint API
7679
//--------------------------------------------------------------------+

src/osal/osal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ typedef void (*osal_task_func_t)( void * );
7575
// OSAL Porting API
7676
// Should be implemented as static inline function in osal_port.h header
7777
/*
78+
void osal_spin_init(osal_spinlock_t *ctx);
79+
void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr)
80+
void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr);
81+
7882
osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
7983
bool osal_semaphore_delete(osal_semaphore_t semd_hdl);
8084
bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);

0 commit comments

Comments
 (0)