aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);