Skip to content

Commit

Permalink
rp2040: Add support for double buffering on USB bulk tx packets
Browse files Browse the repository at this point in the history
Signed-off-by: Kevin O'Connor <[email protected]>
  • Loading branch information
KevinOConnor committed Sep 25, 2023
1 parent 98872c9 commit fd7372e
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/rp2040/usbserial.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,22 +101,26 @@ usb_read_bulk_out(void *data, uint_fast8_t max_len)
return c;
}

static uint32_t bulk_in_pop_count;

int_fast8_t
usb_send_bulk_in(void *data, uint_fast8_t len)
{
// Check if there is room for this packet
uint32_t bipc = bulk_in_pop_count, bufnum = bipc & 1;
uint32_t ep = USB_CDC_EP_BULK_IN;
volatile uint16_t *epbp = lookup_epbufctrl(ep, 0, 0);
volatile uint16_t *epbp = lookup_epbufctrl(ep, 0, bufnum);
uint32_t epb = *epbp;
if (epb & (USB_BUF_CTRL_AVAIL|USB_BUF_CTRL_FULL))
return -1;
// Determine the next packet header
uint32_t pid = next_data_pid(epb);
bulk_in_pop_count = bipc + 1;
uint32_t pid = bufnum ? USB_BUF_CTRL_DATA1_PID : 0;
uint32_t new_epb = USB_BUF_CTRL_FULL | USB_BUF_CTRL_LAST | pid | len;
*epbp = new_epb;
barrier();
// Copy the packet to the hw buffer
memcpy(usb_buf_addr(ep, 0), data, len);
memcpy(usb_buf_addr(ep, bufnum), data, len);
// Inform the USB hardware of the available packet
barrier();
*epbp = new_epb | USB_BUF_CTRL_AVAIL;
Expand Down Expand Up @@ -219,7 +223,8 @@ usb_set_address(uint_fast8_t addr)
void
usb_set_configure(void)
{
usb_dpram->ep_buf_ctrl[USB_CDC_EP_BULK_IN].in = USB_BUF_CTRL_DATA1_PID;
bulk_in_pop_count = 0;
usb_dpram->ep_buf_ctrl[USB_CDC_EP_BULK_IN].in = 0;

bulk_out_push_count = 0;
uint32_t epb0 = USB_BUF_CTRL_AVAIL | USB_BUF_CTRL_LAST | DPBUF_SIZE;
Expand Down Expand Up @@ -361,6 +366,7 @@ endpoint_setup(void)
| (USB_ENDPOINT_XFER_BULK << EP_CTRL_BUFFER_TYPE_LSB));
usb_dpram->ep_ctrl[USB_CDC_EP_BULK_OUT-1].out = ep_out;
uint32_t ep_in = (EP_CTRL_ENABLE_BITS | usb_buf_offset(USB_CDC_EP_BULK_IN)
| EP_CTRL_DOUBLE_BUFFERED_BITS
| EP_CTRL_INTERRUPT_PER_BUFFER
| (USB_ENDPOINT_XFER_BULK << EP_CTRL_BUFFER_TYPE_LSB));
usb_dpram->ep_ctrl[USB_CDC_EP_BULK_IN-1].in = ep_in;
Expand Down

0 comments on commit fd7372e

Please sign in to comment.