Skip to content

Commit

Permalink
usb_device.c: Fix EP buffer size limitation for isochronous endpoints
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
maximus64 committed Jul 17, 2024
1 parent 09c64d5 commit 6f54e2f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/rp2_common/usb_device/include/pico/usb_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ typedef void (*usb_transfer_completed_func)(struct usb_endpoint *ep, struct usb_

struct usb_buffer {
uint8_t *data;
uint8_t data_len;
uint8_t data_max;
uint16_t data_len;
uint16_t data_max;
// then...
bool valid; // aka user owned
};
Expand Down
14 changes: 10 additions & 4 deletions src/rp2_common/usb_device/usb_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ static volatile uint32_t trace_i;
#define usb_hw_set hw_set_alias(usb_hw)
#define usb_hw_clear hw_clear_alias(usb_hw)

#define ROUND_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))

void _usb_transfer_current_packet_only(struct usb_endpoint *ep);

const struct usb_transfer_type usb_current_packet_only_transfer_type = {
Expand Down Expand Up @@ -229,9 +231,12 @@ static void _usb_endpoint_hw_init(struct usb_endpoint *ep, __unused uintptr_t da
ep->dpram_buffer_offset = _device.next_buffer_offset;
usb_debug("endpoint %d %s buf at %04x %04xx%d\n", ep_num, usb_endpoint_dir_string(ep), ep->dpram_buffer_offset,
ep->buffer_size, _ep_buffer_count(ep));
uint32_t stride = _usb_endpoint_stride(ep);
if (ep->double_buffered) stride <<= 1u;
_device.next_buffer_offset += stride;
uint16_t stride = _usb_endpoint_stride(ep);
uint16_t buf_size_align = ROUND_UP(ep->buffer_size, stride);

if (ep->double_buffered) buf_size_align <<= 1u;

_device.next_buffer_offset += buf_size_align;
assert(_device.next_buffer_offset <= USB_DPRAM_MAX);
if (ep_num) {
uint32_t reg = EP_CTRL_ENABLE_BITS
Expand Down Expand Up @@ -1137,10 +1142,11 @@ struct usb_interface *usb_interface_init(struct usb_interface *interface, const
#if !PICO_USBDEV_BULK_ONLY_EP1_THRU_16
if (USB_TRANSFER_TYPE_ISOCHRONOUS == (ep_desc->bmAttributes & USB_TRANSFER_TYPE_BITS)) {
endpoints[i]->buffer_stride = 128 << PICO_USBDEV_ISOCHRONOUS_BUFFER_STRIDE_TYPE;
assert(ep_desc->wMaxPacketSize < 1024);
} else {
endpoints[i]->buffer_stride = 64;
assert(ep_desc->wMaxPacketSize <= endpoints[i]->buffer_stride);
}
assert(ep_desc->wMaxPacketSize <= endpoints[i]->buffer_stride);
#endif
}
return interface;
Expand Down

0 comments on commit 6f54e2f

Please sign in to comment.