Skip to content

Commit 1e998ce

Browse files
committed
usbd: fix control transfer issue for chipidea hs when previous status and new setup complete in the same isr frame
change usbd edpt busy/stalled/claimed value to 0/1 instead of (true/false) since they are 1-bit field.
1 parent 2c48050 commit 1e998ce

File tree

4 files changed

+39
-38
lines changed

4 files changed

+39
-38
lines changed

.idea/runConfigurations/rt1010.xml

Lines changed: 0 additions & 10 deletions
This file was deleted.

.idea/runConfigurations/rt1010_nxplink.xml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/device/usbd.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,9 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
516516
_usbd_dev.connected = 1;
517517

518518
// mark both in & out control as free
519-
_usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = false;
519+
_usbd_dev.ep_status[0][TUSB_DIR_OUT].busy = 0;
520520
_usbd_dev.ep_status[0][TUSB_DIR_OUT].claimed = 0;
521-
_usbd_dev.ep_status[0][TUSB_DIR_IN ].busy = false;
521+
_usbd_dev.ep_status[0][TUSB_DIR_IN ].busy = 0;
522522
_usbd_dev.ep_status[0][TUSB_DIR_IN ].claimed = 0;
523523

524524
// Process control request
@@ -540,20 +540,21 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
540540

541541
TU_LOG(USBD_DBG, "on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
542542

543-
_usbd_dev.ep_status[epnum][ep_dir].busy = false;
543+
_usbd_dev.ep_status[epnum][ep_dir].busy = 0;
544544
_usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
545545

546546
if ( 0 == epnum )
547547
{
548-
usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len);
548+
usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete
549+
.len);
549550
}
550551
else
551552
{
552553
usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] );
553554
TU_ASSERT(driver, );
554555

555556
TU_LOG(USBD_DBG, " %s xfer callback\r\n", driver->name);
556-
driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t)event.xfer_complete.result, event.xfer_complete.len);
557+
driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
557558
}
558559
}
559560
break;
@@ -1244,15 +1245,15 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
12441245

12451246
// Set busy first since the actual transfer can be complete before dcd_edpt_xfer()
12461247
// could return and USBD task can preempt and clear the busy
1247-
_usbd_dev.ep_status[epnum][dir].busy = true;
1248+
_usbd_dev.ep_status[epnum][dir].busy = 1;
12481249

12491250
if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) )
12501251
{
12511252
return true;
12521253
}else
12531254
{
12541255
// DCD error, mark endpoint as ready to allow next transfer
1255-
_usbd_dev.ep_status[epnum][dir].busy = false;
1256+
_usbd_dev.ep_status[epnum][dir].busy = 0;
12561257
_usbd_dev.ep_status[epnum][dir].claimed = 0;
12571258
TU_LOG(USBD_DBG, "FAILED\r\n");
12581259
TU_BREAKPOINT();
@@ -1278,7 +1279,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
12781279

12791280
// Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
12801281
// and usbd task can preempt and clear the busy
1281-
_usbd_dev.ep_status[epnum][dir].busy = true;
1282+
_usbd_dev.ep_status[epnum][dir].busy = 1;
12821283

12831284
if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
12841285
{
@@ -1287,7 +1288,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
12871288
}else
12881289
{
12891290
// DCD error, mark endpoint as ready to allow next transfer
1290-
_usbd_dev.ep_status[epnum][dir].busy = false;
1291+
_usbd_dev.ep_status[epnum][dir].busy = 0;
12911292
_usbd_dev.ep_status[epnum][dir].claimed = 0;
12921293
TU_LOG(USBD_DBG, "failed\r\n");
12931294
TU_BREAKPOINT();
@@ -1317,8 +1318,8 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
13171318
{
13181319
TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr);
13191320
dcd_edpt_stall(rhport, ep_addr);
1320-
_usbd_dev.ep_status[epnum][dir].stalled = true;
1321-
_usbd_dev.ep_status[epnum][dir].busy = true;
1321+
_usbd_dev.ep_status[epnum][dir].stalled = 1;
1322+
_usbd_dev.ep_status[epnum][dir].busy = 1;
13221323
}
13231324
}
13241325

@@ -1334,8 +1335,8 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
13341335
{
13351336
TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr);
13361337
dcd_edpt_clear_stall(rhport, ep_addr);
1337-
_usbd_dev.ep_status[epnum][dir].stalled = false;
1338-
_usbd_dev.ep_status[epnum][dir].busy = false;
1338+
_usbd_dev.ep_status[epnum][dir].stalled = 0;
1339+
_usbd_dev.ep_status[epnum][dir].busy = 0;
13391340
}
13401341
}
13411342

@@ -1366,9 +1367,9 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
13661367
uint8_t const dir = tu_edpt_dir(ep_addr);
13671368

13681369
dcd_edpt_close(rhport, ep_addr);
1369-
_usbd_dev.ep_status[epnum][dir].stalled = false;
1370-
_usbd_dev.ep_status[epnum][dir].busy = false;
1371-
_usbd_dev.ep_status[epnum][dir].claimed = false;
1370+
_usbd_dev.ep_status[epnum][dir].stalled = 0;
1371+
_usbd_dev.ep_status[epnum][dir].busy = 0;
1372+
_usbd_dev.ep_status[epnum][dir].claimed = 0;
13721373

13731374
return;
13741375
}
@@ -1403,9 +1404,9 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep
14031404
TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX);
14041405
TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed));
14051406

1406-
_usbd_dev.ep_status[epnum][dir].stalled = false;
1407-
_usbd_dev.ep_status[epnum][dir].busy = false;
1408-
_usbd_dev.ep_status[epnum][dir].claimed = false;
1407+
_usbd_dev.ep_status[epnum][dir].stalled = 0;
1408+
_usbd_dev.ep_status[epnum][dir].busy = 0;
1409+
_usbd_dev.ep_status[epnum][dir].claimed = 0;
14091410
return dcd_edpt_iso_activate(rhport, desc_ep);
14101411
}
14111412

src/portable/chipidea/ci_hs/dcd_ci_hs.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -616,15 +616,6 @@ void dcd_int_handler(uint8_t rhport)
616616
uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE;
617617
dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge
618618

619-
if (dcd_reg->ENDPTSETUPSTAT)
620-
{
621-
//------------- Set up Received -------------//
622-
// 23.10.10.2 Operational model for setup transfers
623-
dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;
624-
625-
dcd_event_setup_received(rhport, (uint8_t*)(uintptr_t) &_dcd_data.qhd[0][0].setup_request, true);
626-
}
627-
628619
// 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set
629620
// nothing to do, we will submit xfer as error to usbd
630621
// if (int_status & INTR_ERROR) { }
@@ -637,6 +628,15 @@ void dcd_int_handler(uint8_t rhport)
637628
if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN);
638629
}
639630
}
631+
632+
// Set up Received
633+
// 23.10.10.2 Operational model for setup transfers
634+
// Must be after normal transfer complete since it is possible to have both previous control status + new setup
635+
// in the same frame and we should handle previous status first.
636+
if (dcd_reg->ENDPTSETUPSTAT) {
637+
dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;
638+
dcd_event_setup_received(rhport, (uint8_t *) (uintptr_t) &_dcd_data.qhd[0][0].setup_request, true);
639+
}
640640
}
641641

642642
if (int_status & INTR_SOF)

0 commit comments

Comments
 (0)