Skip to content

Commit 9e5b9fe

Browse files
committed
usb_device.c: Fix EP buffer size limitation for isochronous endpoints
The buffer size for USB endpoints was previously limited by the endpoints buffer stride, which is 128 bytes * 2 for isochronous endpoints and 64 bytes for bulk transfers. According to the USB full-speed specification, the maximum frame size can go up to 1023 bytes. The RP2040 microcontroller has 4KB of DPSRAM, which can support this maximum frame size. This commit removes the 128 bytes * 2 limitation for isochronous endpoints, allowing support for the full 1023-byte frame size. Signed-off-by: Khoa Hoang <[email protected]>
1 parent 09c64d5 commit 9e5b9fe

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

src/rp2_common/usb_device/include/pico/usb_device.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ typedef void (*usb_transfer_completed_func)(struct usb_endpoint *ep, struct usb_
8787

8888
struct usb_buffer {
8989
uint8_t *data;
90-
uint8_t data_len;
91-
uint8_t data_max;
90+
uint16_t data_len;
91+
uint16_t data_max;
9292
// then...
9393
bool valid; // aka user owned
9494
};

src/rp2_common/usb_device/usb_device.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ static volatile uint32_t trace_i;
5252
#define usb_hw_set hw_set_alias(usb_hw)
5353
#define usb_hw_clear hw_clear_alias(usb_hw)
5454

55+
#define ROUND_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
56+
5557
void _usb_transfer_current_packet_only(struct usb_endpoint *ep);
5658

5759
const struct usb_transfer_type usb_current_packet_only_transfer_type = {
@@ -229,9 +231,12 @@ static void _usb_endpoint_hw_init(struct usb_endpoint *ep, __unused uintptr_t da
229231
ep->dpram_buffer_offset = _device.next_buffer_offset;
230232
usb_debug("endpoint %d %s buf at %04x %04xx%d\n", ep_num, usb_endpoint_dir_string(ep), ep->dpram_buffer_offset,
231233
ep->buffer_size, _ep_buffer_count(ep));
232-
uint32_t stride = _usb_endpoint_stride(ep);
233-
if (ep->double_buffered) stride <<= 1u;
234-
_device.next_buffer_offset += stride;
234+
uint16_t stride = _usb_endpoint_stride(ep);
235+
uint16_t buf_size_align = ROUND_UP(ep->buffer_size, stride);
236+
237+
if (ep->double_buffered) buf_size_align <<= 1u;
238+
239+
_device.next_buffer_offset += buf_size_align;
235240
assert(_device.next_buffer_offset <= USB_DPRAM_MAX);
236241
if (ep_num) {
237242
uint32_t reg = EP_CTRL_ENABLE_BITS
@@ -1137,10 +1142,12 @@ struct usb_interface *usb_interface_init(struct usb_interface *interface, const
11371142
#if !PICO_USBDEV_BULK_ONLY_EP1_THRU_16
11381143
if (USB_TRANSFER_TYPE_ISOCHRONOUS == (ep_desc->bmAttributes & USB_TRANSFER_TYPE_BITS)) {
11391144
endpoints[i]->buffer_stride = 128 << PICO_USBDEV_ISOCHRONOUS_BUFFER_STRIDE_TYPE;
1145+
assert(ep_desc->wMaxPacketSize % endpoints[i]->buffer_stride == 0);
1146+
assert(ep_desc->wMaxPacketSize < 1024);
11401147
} else {
11411148
endpoints[i]->buffer_stride = 64;
1149+
assert(ep_desc->wMaxPacketSize <= endpoints[i]->buffer_stride);
11421150
}
1143-
assert(ep_desc->wMaxPacketSize <= endpoints[i]->buffer_stride);
11441151
#endif
11451152
}
11461153
return interface;

0 commit comments

Comments
 (0)