diff --git a/src/platforms/common/usb_serial.c b/src/platforms/common/usb_serial.c index 2387ec0..920804e 100644 --- a/src/platforms/common/usb_serial.c +++ b/src/platforms/common/usb_serial.c @@ -52,6 +52,7 @@ #include #include #include +#include static bool gdb_uart_dtr = true; @@ -211,6 +212,73 @@ size_t debug_uart_write(const char *buf, const size_t len) return len; } +/* + * Copy data from fifo into continuous buffer. Return copied length. + */ +static uint32_t copy_from_fifo(char *dst, const char *src, uint32_t start, uint32_t end, uint32_t len, uint32_t fifo_sz) +{ + uint32_t out_len = 0; + for (uint32_t buf_out = start; buf_out != end && out_len < len; buf_out %= fifo_sz) + dst[out_len++] = src[buf_out++]; + + return out_len; +} + +/* + * Runs deferred processing for USBUSART RX, draining RX FIFO by sending + * characters to host PC via CDCACM. Allowed to write to FIFO OUT pointer. + */ +void usbuart_send_rx_packet(void) +{ + rx_usb_trfr_cplt = false; + /* Calculate writing position in the FIFO */ + const uint32_t buf_rx_in = (RX_FIFO_SIZE - dma_get_number_of_data(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN)) % RX_FIFO_SIZE; + + /* Forcibly empty fifo if no USB endpoint. + * If fifo empty, nothing further to do. */ + if (usb_get_config() != 1 || (buf_rx_in == buf_rx_out +#ifdef ENABLE_DEBUG + && usb_dbg_in == usb_dbg_out +#endif + )) + { +#ifdef ENABLE_DEBUG + usb_dbg_out = usb_dbg_in; +#endif + buf_rx_out = buf_rx_in; + /* Turn off LED */ + usbuart_set_led_state(RX_LED_ACT, false); + rx_usb_trfr_cplt = true; + } + else + { + /* To avoid the need of sending ZLP don't transmit full packet. + * Also reserve space for copy function overrun. + */ + char packet_buf[CDCACM_PACKET_SIZE - 1 + sizeof(uint64_t)]; + uint32_t packet_size; + +#ifdef ENABLE_DEBUG + /* Copy data from DEBUG FIFO into local usb packet buffer */ + packet_size = copy_from_fifo(packet_buf, usb_dbg_buf, usb_dbg_out, usb_dbg_in, CDCACM_PACKET_SIZE - 1, RX_FIFO_SIZE); + /* Send if buffer not empty */ + if (packet_size) + { + const uint16_t written = usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); + usb_dbg_out = (usb_dbg_out + written) % RX_FIFO_SIZE; + return; + } +#endif + + /* Copy data from uart RX FIFO into local usb packet buffer */ + packet_size = copy_from_fifo(packet_buf, buf_rx, buf_rx_out, buf_rx_in, CDCACM_PACKET_SIZE - 1, RX_FIFO_SIZE); + + /* Advance fifo out pointer by amount written */ + const uint16_t written = usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); + buf_rx_out = (buf_rx_out + written) % RX_FIFO_SIZE; + } +} + void debug_uart_run(void) { nvic_disable_irq(USB_IRQ); diff --git a/src/platforms/common/usbuart.h b/src/platforms/common/usbuart.h index a9b3f18..cb6b0d4 100644 --- a/src/platforms/common/usbuart.h +++ b/src/platforms/common/usbuart.h @@ -41,7 +41,13 @@ void debug_uart_run(void); #define RX_FIFO_SIZE (USART_DMA_BUF_SIZE) #define TX_BUF_SIZE (USART_DMA_BUF_SIZE) +/* TX transfer complete */ extern bool tx_trfr_cplt; +/* RX Fifo buffer with space for copy fn overrun */ +extern char buf_rx[RX_FIFO_SIZE + sizeof(uint64_t)]; +/* RX Fifo out pointer, writes assumed to be atomic */ +extern uint8_t buf_rx_out; +/* RX usb transfer complete */ extern bool rx_usb_trfr_cplt; #ifdef ENABLE_DEBUG diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 55eb0ff..d55a2dc 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -58,9 +58,9 @@ static uint8_t buf_tx_act_sz; /* TX transfer complete */ bool tx_trfr_cplt = true; /* RX Fifo buffer with space for copy fn overrun */ -static uint8_t buf_rx[RX_FIFO_SIZE + sizeof(uint64_t)]; +char buf_rx[RX_FIFO_SIZE + sizeof(uint64_t)]; /* RX Fifo out pointer, writes assumed to be atomic */ -static uint8_t buf_rx_out; +uint8_t buf_rx_out; /* RX usb transfer complete */ bool rx_usb_trfr_cplt = true; @@ -182,18 +182,6 @@ void aux_serial_init(void) usart_enable_rx_dma(USBUSART); } -/* - * Copy data from fifo into continuous buffer. Return copied length. - */ -static uint32_t copy_from_fifo(uint8_t *dst, const uint8_t *src, uint32_t start, uint32_t end, uint32_t len, uint32_t fifo_sz) -{ - uint32_t out_len = 0; - for (uint32_t buf_out = start; buf_out != end && out_len < len; buf_out %= fifo_sz) - dst[out_len++] = src[buf_out++]; - - return out_len; -} - /* * Changes USBUSART TX buffer in which data is accumulated from USB. * Filled buffer is submitted to DMA for transfer. @@ -258,61 +246,6 @@ void usbuart_usb_out_cb(usbd_device *dev, uint8_t ep) } #endif -/* - * Runs deferred processing for USBUSART RX, draining RX FIFO by sending - * characters to host PC via CDCACM. Allowed to write to FIFO OUT pointer. - */ -void usbuart_send_rx_packet(void) -{ - rx_usb_trfr_cplt = false; - /* Calculate writing position in the FIFO */ - const uint32_t buf_rx_in = (RX_FIFO_SIZE - dma_get_number_of_data(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN)) % RX_FIFO_SIZE; - - /* Forcibly empty fifo if no USB endpoint. - * If fifo empty, nothing further to do. */ - if (usb_get_config() != 1 || (buf_rx_in == buf_rx_out -#ifdef ENABLE_DEBUG - && usb_dbg_in == usb_dbg_out -#endif - )) - { -#ifdef ENABLE_DEBUG - usb_dbg_out = usb_dbg_in; -#endif - buf_rx_out = buf_rx_in; - /* Turn off LED */ - usbuart_set_led_state(RX_LED_ACT, false); - rx_usb_trfr_cplt = true; - } - else - { - /* To avoid the need of sending ZLP don't transmit full packet. - * Also reserve space for copy function overrun. - */ - uint8_t packet_buf[CDCACM_PACKET_SIZE - 1 + sizeof(uint64_t)]; - uint32_t packet_size; - -#ifdef ENABLE_DEBUG - /* Copy data from DEBUG FIFO into local usb packet buffer */ - packet_size = copy_from_fifo(packet_buf, (uint8_t *)usb_dbg_buf, usb_dbg_out, usb_dbg_in, CDCACM_PACKET_SIZE - 1, RX_FIFO_SIZE); - /* Send if buffer not empty */ - if (packet_size) - { - const uint16_t written = usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); - usb_dbg_out = (usb_dbg_out + written) % RX_FIFO_SIZE; - return; - } -#endif - - /* Copy data from uart RX FIFO into local usb packet buffer */ - packet_size = copy_from_fifo(packet_buf, buf_rx, buf_rx_out, buf_rx_in, CDCACM_PACKET_SIZE - 1, RX_FIFO_SIZE); - - /* Advance fifo out pointer by amount written */ - const uint16_t written = usbd_ep_write_packet(usbdev, CDCACM_UART_ENDPOINT, packet_buf, packet_size); - buf_rx_out = (buf_rx_out + written) % RX_FIFO_SIZE; - } -} - void usbuart_usb_in_cb(usbd_device *dev, uint8_t ep) { (void) ep;