Skip to content

Commit

Permalink
stm32: Add usbfs double buffer support for bulk tx messages
Browse files Browse the repository at this point in the history
Implement the usbfs fast buffer switching mechanism on the "bulk in"
endpoint.  This can improve the overall USB throughput and bus
utilization.

Signed-off-by: Kevin O'Connor <[email protected]>
  • Loading branch information
KevinOConnor committed Oct 4, 2023
1 parent b1361d9 commit cd8d57c
Showing 1 changed file with 28 additions and 8 deletions.
36 changes: 28 additions & 8 deletions src/stm32/usbfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ btable_configure(void)
epm_ep_desc_setup(USB_CDC_EP_ACM, BUFRX, 0);
epm_ep_desc_setup(USB_CDC_EP_BULK_OUT, 0, USB_CDC_EP_BULK_OUT_SIZE);
epm_ep_desc_setup(USB_CDC_EP_BULK_OUT, 1, USB_CDC_EP_BULK_OUT_SIZE);
epm_ep_desc_setup(USB_CDC_EP_BULK_IN, BUFTX, 0);
epm_ep_desc_setup(USB_CDC_EP_BULK_IN, BUFRX, 0);
epm_ep_desc_setup(USB_CDC_EP_BULK_IN, 0, 0);
epm_ep_desc_setup(USB_CDC_EP_BULK_IN, 1, 0);
}

// Read a packet stored in dedicated usb memory
Expand Down Expand Up @@ -236,15 +236,27 @@ usb_read_bulk_out(void *data, uint_fast8_t max_len)
return count;
}

static uint32_t bulk_in_push_count, bulk_in_pop_flag;

int_fast8_t
usb_send_bulk_in(void *data, uint_fast8_t len)
{
uint32_t ep = USB_CDC_EP_BULK_IN, epr = USB_EPR[ep];
if ((epr & USB_EPTX_STAT) != USB_EP_TX_NAK)
if (readl(&bulk_in_pop_flag))
// No buffer space available
return -1;
btable_write_packet(ep, BUFTX, data, len);
USB_EPR[ep] = calc_epr_bits(epr, USB_EPTX_STAT, USB_EP_TX_VALID);
uint32_t ep = USB_CDC_EP_BULK_IN;
int bufnum = bulk_in_push_count & 1;
bulk_in_push_count++;
btable_write_packet(ep, bufnum, data, len);
writel(&bulk_in_pop_flag, USB_EP_DTOG_RX);

// Check if hardware needs to be notified
uint32_t epr = USB_EPR[ep];
if (epr_is_dbuf_blocking(epr) && readl(&bulk_in_pop_flag)) {
writel(&bulk_in_pop_flag, 0);
USB_EPR[ep] = calc_epr_bits(epr, 0, 0) | USB_EP_DTOG_RX;
}

return len;
}

Expand Down Expand Up @@ -305,6 +317,11 @@ usb_set_configure(void)
uint32_t ep = USB_CDC_EP_BULK_OUT;
bulk_out_pop_count = 0;
USB_EPR[ep] = calc_epr_bits(USB_EPR[ep], USB_EPRX_STAT, USB_EP_RX_VALID);

ep = USB_CDC_EP_BULK_IN;
bulk_in_push_count = 0;
writel(&bulk_in_pop_flag, 0);
USB_EPR[ep] = calc_epr_bits(USB_EPR[ep], USB_EPTX_STAT, USB_EP_TX_VALID);
}


Expand All @@ -329,8 +346,9 @@ usb_reset(void)
bulk_out_push_flag = USB_EP_DTOG_TX;

ep = USB_CDC_EP_BULK_IN;
USB_EPR[ep] = (USB_CDC_EP_BULK_IN | USB_EP_BULK
USB_EPR[ep] = (USB_CDC_EP_BULK_IN | USB_EP_BULK | USB_EP_KIND
| USB_EP_RX_NAK | USB_EP_TX_NAK);
bulk_in_pop_flag = USB_EP_DTOG_RX;

USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM;
USB->DADDR = USB_DADDR_EF;
Expand All @@ -350,7 +368,9 @@ USB_IRQHandler(void)
bulk_out_push_flag = 0;
usb_notify_bulk_out();
} else if (ep == USB_CDC_EP_BULK_IN) {
USB_EPR[ep] = calc_epr_bits(epr, USB_EP_CTR_RX | USB_EP_CTR_TX, 0);
USB_EPR[ep] = (calc_epr_bits(epr, USB_EP_CTR_RX | USB_EP_CTR_TX, 0)
| bulk_in_pop_flag);
bulk_in_pop_flag = 0;
usb_notify_bulk_in();
} else if (ep == 0) {
USB_EPR[ep] = calc_epr_bits(epr, USB_EP_CTR_RX | USB_EP_CTR_TX, 0);
Expand Down

0 comments on commit cd8d57c

Please sign in to comment.