Skip to content

Commit 6759721

Browse files
committed
move errata to end of c file
1 parent 19b6cbc commit 6759721

File tree

1 file changed

+65
-39
lines changed

1 file changed

+65
-39
lines changed

src/portable/raspberrypi/rp2040/rp2040_usb.c

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
#include <stdlib.h>
3333
#include "rp2040_usb.h"
3434

35+
//--------------------------------------------------------------------+
36+
// MACRO CONSTANT TYPEDEF PROTOTYPE
37+
//--------------------------------------------------------------------+
38+
3539
// Direction strings for debug
3640
const char *ep_dir_string[] = {
3741
"out",
@@ -40,54 +44,24 @@ const char *ep_dir_string[] = {
4044

4145
static void _hw_endpoint_xfer_sync(struct hw_endpoint *ep);
4246

47+
#if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX
48+
static bool e15_is_bulkin_ep(struct hw_endpoint *ep);
49+
static bool e15_is_critical_frame_period(struct hw_endpoint *ep);
50+
#else
51+
#define e15_is_bulkin_ep(x) (false)
52+
#define e15_is_critical_frame_period(x) (false)
53+
#endif
54+
4355
// if usb hardware is in host mode
4456
TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void)
4557
{
4658
return (usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) ? true : false;
4759
}
4860

4961
//--------------------------------------------------------------------+
50-
//
62+
// Implementation
5163
//--------------------------------------------------------------------+
5264

53-
#if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX
54-
// Errata 15 Walkaround for Device Bulk-In endpoint to avoid schedule an transfer
55-
// within last 20% of an USB frame.
56-
57-
volatile uint32_t e15_last_sof = 0;
58-
59-
// check if Errata 15 walkround is needed for this endpoint
60-
static bool __tusb_irq_path_func(e15_is_bulkin_ep) (struct hw_endpoint *ep)
61-
{
62-
return (!is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN &&
63-
ep->transfer_type == TUSB_XFER_BULK);
64-
}
65-
66-
// check if we need to apply Errata 15 workaround: ie.g
67-
// Enpoint is BULK IN and is currently in critical frame period i.e 20% of last usb frame
68-
static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoint *ep)
69-
{
70-
TU_VERIFY(e15_is_bulkin_ep(ep));
71-
72-
/* Avoid the last 200us (uframe 6.5-7) of a frame, up to the EOF2 point.
73-
* The device state machine cannot recover from receiving an incorrect PID
74-
* when it is expecting an ACK.
75-
*/
76-
uint32_t delta = time_us_32() - e15_last_sof;
77-
if (delta < 800 || delta > 998) {
78-
return false;
79-
}
80-
TU_LOG(3, "Avoiding sof %u now %lu last %lu\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof);
81-
return true;
82-
}
83-
84-
#else
85-
86-
#define e15_is_bulkin_ep(x) false
87-
#define e15_is_critical_frame_period(x) false
88-
89-
#endif
90-
9165
void rp2040_usb_init(void)
9266
{
9367
// Reset usb controller
@@ -396,4 +370,56 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep)
396370
return false;
397371
}
398372

373+
//--------------------------------------------------------------------+
374+
// Errata 15
375+
//--------------------------------------------------------------------+
376+
377+
#if TUD_OPT_RP2040_USB_DEVICE_UFRAME_FIX
378+
379+
/* Don't mark IN buffers as available during the last 200us of a full-speed
380+
frame. This avoids a situation seen with the USB2.0 hub on a Raspberry
381+
Pi 4 where a late IN token before the next full-speed SOF can cause port
382+
babble and a corrupt ACK packet. The nature of the data corruption has a
383+
chance to cause device lockup.
384+
385+
Use the next SOF to mark delayed buffers as available. This reduces
386+
available Bulk IN bandwidth by approximately 20%, and requires that the
387+
SOF interrupt is enabled while these transfers are ongoing.
388+
389+
Inherit the top-level enable from the corresponding Pico-SDK flag.
390+
Applications that will not use the device in a situation where it could
391+
be plugged into a Pi 4 or Pi 400 (for example, when directly connected
392+
to a commodity hub or other host) can turn off the flag in the SDK.
393+
*/
394+
395+
volatile uint32_t e15_last_sof = 0;
396+
397+
// check if Errata 15 is needed for this endpoint i.e device bulk-in
398+
static bool __tusb_irq_path_func(e15_is_bulkin_ep) (struct hw_endpoint *ep)
399+
{
400+
return (!is_host_mode() && tu_edpt_dir(ep->ep_addr) == TUSB_DIR_IN &&
401+
ep->transfer_type == TUSB_XFER_BULK);
402+
}
403+
404+
// check if we need to apply Errata 15 walk-around : i.e
405+
// Endpoint is BULK IN and is currently in critical frame period i.e 20% of last usb frame
406+
static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoint *ep)
407+
{
408+
TU_VERIFY(e15_is_bulkin_ep(ep));
409+
410+
/* Avoid the last 200us (uframe 6.5-7) of a frame, up to the EOF2 point.
411+
* The device state machine cannot recover from receiving an incorrect PID
412+
* when it is expecting an ACK.
413+
*/
414+
uint32_t delta = time_us_32() - e15_last_sof;
415+
if (delta < 800 || delta > 998) {
416+
return false;
417+
}
418+
TU_LOG(3, "Avoiding sof %u now %lu last %lu\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof);
419+
return true;
420+
}
421+
422+
#endif
423+
424+
399425
#endif

0 commit comments

Comments
 (0)