Skip to content

Commit

Permalink
work around possible RP2040 erratum
Browse files Browse the repository at this point in the history
RP2040 device controller does not seem to clear pending transactions
configured in EP0 buffer controls when the host aborts a control
transfer. This causes assertion failures, including when a buffer
AVAILABLE flag set for a previous transfer causes an unexpected
transaction completion.
  • Loading branch information
tlyu committed Feb 25, 2024
1 parent f21b792 commit dc8cb27
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/portable/raspberrypi/rp2040/dcd_rp2040.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,33 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void)

TU_ATTR_ALWAYS_INLINE static inline void reset_ep0_pid(void)
{
// Abort any transactions from a prior control transfer (HW erratum?)
usb_hw_set->abort = 0x3;
while ((usb_hw->abort_done & 0x3) != 0x3)
;
// If we have finished this transfer on EP0 set pid back to 1 for next
// setup transfer. Also clear a stall in case
uint8_t addrs[] = {0x0, 0x80};
for (uint i = 0 ; i < TU_ARRAY_SIZE(addrs); i++)
{
struct hw_endpoint *ep = hw_endpoint_get_by_addr(addrs[i]);
ep->next_pid = 1u;
// Reset the buffer control now to minimize race conditions
_hw_endpoint_buffer_control_set_value32(ep, USB_BUF_CTRL_DATA1_PID | USB_BUF_CTRL_SEL);
// Explicit delay, because the one in
// _hw_endpoint_buffer_control_set_value32 is only to set AVAILABLE
__asm volatile (
"b 1f\n"
"1: b 1f\n"
"1: b 1f\n"
"1: b 1f\n"
"1: b 1f\n"
"1: b 1f\n"
"1:\n"
: : : "memory");
hw_endpoint_reset_transfer(ep);
}
usb_hw_clear->abort = 0x3;
}

static void __tusb_irq_path_func(reset_non_control_endpoints)(void)
Expand Down

0 comments on commit dc8cb27

Please sign in to comment.