aboutsummaryrefslogtreecommitdiffstats
path: root/src/stm32/usbfs.c
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2023-09-23 15:31:52 -0400
committerKevin O'Connor <kevin@koconnor.net>2023-10-03 23:26:46 -0400
commitcd8d57c2c68049e8fbbeedd88eba01fe6495c7c5 (patch)
treea9ca487736e86ecee8938223346968e328fa2cdf /src/stm32/usbfs.c
parentb1361d9e5b5191c0c3b49dbe239e769ba23981a8 (diff)
downloadkutter-cd8d57c2c68049e8fbbeedd88eba01fe6495c7c5.tar.gz
kutter-cd8d57c2c68049e8fbbeedd88eba01fe6495c7c5.tar.xz
kutter-cd8d57c2c68049e8fbbeedd88eba01fe6495c7c5.zip
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 <kevin@koconnor.net>
Diffstat (limited to 'src/stm32/usbfs.c')
-rw-r--r--src/stm32/usbfs.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/stm32/usbfs.c b/src/stm32/usbfs.c
index 661aa1b1..d166fbb7 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);