From f2b23c137c13be1d5264c3225466d2da312685e1 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sat, 23 Sep 2023 15:31:52 -0400 Subject: [PATCH] stm32: Add usbfs double buffer support for bulk tx messages 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 --- src/stm32/usbfs.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/stm32/usbfs.c b/src/stm32/usbfs.c index 661aa1b1585d..d166fbb7ace9 100644 --- a/src/stm32/usbfs.c +++ b/src/stm32/usbfs.c @@ -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 @@ -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; } @@ -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); } @@ -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; @@ -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);