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);