diff --git a/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c b/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c index 2533cdb877..b5bf16b0d9 100644 --- a/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c +++ b/lib/main/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c @@ -184,9 +184,9 @@ __ALIGN_BEGIN uint8_t APP_Rx_Buffer [APP_RX_DATA_SIZE] __ALIGN_END ; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ __ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ; -uint32_t APP_Rx_ptr_in = 0; -uint32_t APP_Rx_ptr_out = 0; -uint32_t APP_Rx_length = 0; +volatile uint32_t APP_Rx_ptr_in = 0; +volatile uint32_t APP_Rx_ptr_out = 0; +volatile uint32_t APP_Rx_length = 0; uint8_t USB_Tx_State = USB_CDC_IDLE; @@ -482,8 +482,8 @@ uint8_t usbd_cdc_Init (void *pdev, uint8_t usbd_cdc_DeInit (void *pdev, uint8_t cfgidx) { - (void)pdev; - (void)cfgidx; + (void)pdev; + (void)cfgidx; /* Open EP IN */ DCD_EP_Close(pdev, CDC_IN_EP); @@ -594,7 +594,7 @@ uint8_t usbd_cdc_Setup (void *pdev, */ uint8_t usbd_cdc_EP0_RxReady (void *pdev) { - (void)pdev; + (void)pdev; if (cdcCmd != NO_CMD) { /* Process the data */ @@ -617,60 +617,45 @@ uint8_t usbd_cdc_EP0_RxReady (void *pdev) */ uint8_t usbd_cdc_DataIn (void *pdev, uint8_t epnum) { - (void)pdev; - (void)epnum; - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if (USB_Tx_State == USB_CDC_BUSY) - { - if (APP_Rx_length == 0) + (void)pdev; + (void)epnum; + uint16_t USB_Tx_length; + + if (USB_Tx_State == USB_CDC_BUSY) { - USB_Tx_State = USB_CDC_IDLE; - } - else - { - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){ - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - if(USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) + if (APP_Rx_length == 0) { - USB_Tx_State = USB_CDC_ZLP; + USB_Tx_State = USB_CDC_IDLE; + } else { + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + } else { + USB_Tx_length = APP_Rx_length; + + if (USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_State = USB_CDC_ZLP; + } + } + + /* Prepare the available data buffer to be sent on IN endpoint */ + DCD_EP_Tx(pdev, CDC_IN_EP, (uint8_t*)&APP_Rx_Buffer[APP_Rx_ptr_out], USB_Tx_length); + + // Advance the out pointer + APP_Rx_ptr_out = (APP_Rx_ptr_out + USB_Tx_length) % APP_RX_DATA_SIZE;; + APP_Rx_length -= USB_Tx_length; + + return USBD_OK; } - } - - /* Prepare the available data buffer to be sent on IN endpoint */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - return USBD_OK; } - } - - /* Avoid any asynchronous transfer during ZLP */ - if (USB_Tx_State == USB_CDC_ZLP) - { - /*Send ZLP to indicate the end of the current transfer */ - DCD_EP_Tx (pdev, - CDC_IN_EP, - NULL, - 0); - - USB_Tx_State = USB_CDC_IDLE; - } - return USBD_OK; + + /* Avoid any asynchronous transfer during ZLP */ + if (USB_Tx_State == USB_CDC_ZLP) { + /*Send ZLP to indicate the end of the current transfer */ + DCD_EP_Tx(pdev, CDC_IN_EP, NULL, 0); + + USB_Tx_State = USB_CDC_IDLE; + } + return USBD_OK; } /** @@ -731,67 +716,49 @@ uint8_t usbd_cdc_SOF (void *pdev) */ static void Handle_USBAsynchXfer (void *pdev) { - uint16_t USB_Tx_ptr; - uint16_t USB_Tx_length; - - if(USB_Tx_State == USB_CDC_IDLE) - { - if (APP_Rx_ptr_out == APP_RX_DATA_SIZE) - { - APP_Rx_ptr_out = 0; - } - - if(APP_Rx_ptr_out == APP_Rx_ptr_in) - { - USB_Tx_State = USB_CDC_IDLE; - return; - } - - if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */ - { - APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; - - } - else - { - APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; - - } + uint16_t USB_Tx_length; + + if (USB_Tx_State == USB_CDC_IDLE) { + if (APP_Rx_ptr_out == APP_Rx_ptr_in) { + // Ring buffer is empty + return; + } + + if (APP_Rx_ptr_out > APP_Rx_ptr_in) { + // Transfer bytes up to the end of the ring buffer + APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out; + } else { + // Transfer all bytes in ring buffer + APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out; + } + #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED - APP_Rx_length &= ~0x03; + // Only transfer whole 32 bit words of data + APP_Rx_length &= ~0x03; #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ + + if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; + + USB_Tx_State = USB_CDC_BUSY; + } else { + USB_Tx_length = APP_Rx_length; + + if (USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) { + USB_Tx_State = USB_CDC_ZLP; + } else { + USB_Tx_State = USB_CDC_BUSY; + } + } - if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = CDC_DATA_IN_PACKET_SIZE; - - APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE; - APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE; - USB_Tx_State = USB_CDC_BUSY; + DCD_EP_Tx (pdev, + CDC_IN_EP, + (uint8_t*)&APP_Rx_Buffer[APP_Rx_ptr_out], + USB_Tx_length); + + APP_Rx_ptr_out = (APP_Rx_ptr_out + USB_Tx_length) % APP_RX_DATA_SIZE; + APP_Rx_length -= USB_Tx_length; } - else - { - USB_Tx_ptr = APP_Rx_ptr_out; - USB_Tx_length = APP_Rx_length; - - APP_Rx_ptr_out += APP_Rx_length; - APP_Rx_length = 0; - if(USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) - { - USB_Tx_State = USB_CDC_ZLP; - } - else - { - USB_Tx_State = USB_CDC_BUSY; - } - } - - DCD_EP_Tx (pdev, - CDC_IN_EP, - (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr], - USB_Tx_length); - } } /** @@ -803,7 +770,7 @@ static void Handle_USBAsynchXfer (void *pdev) */ static uint8_t *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length) { - (void)speed; + (void)speed; *length = sizeof (usbd_cdc_CfgDesc); return usbd_cdc_CfgDesc; } diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index c4e7d3d928..730b7d1777 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -183,7 +183,7 @@ static serialPort_t *cliPort = NULL; static bufWriter_t *cliWriter = NULL; static bufWriter_t *cliErrorWriter = NULL; -static uint8_t cliWriteBuffer[sizeof(*cliWriter) + CLI_OUT_BUFFER_SIZE]; +static uint8_t cliWriteBuffer[sizeof(bufWriter_t) + CLI_OUT_BUFFER_SIZE]; static char cliBuffer[CLI_IN_BUFFER_SIZE]; static uint32_t bufferIndex = 0; diff --git a/src/main/vcp_hal/usbd_cdc_interface.c b/src/main/vcp_hal/usbd_cdc_interface.c index b44576f8a1..f1577643b1 100644 --- a/src/main/vcp_hal/usbd_cdc_interface.c +++ b/src/main/vcp_hal/usbd_cdc_interface.c @@ -409,17 +409,11 @@ uint32_t CDC_Receive_BytesAvailable(void) uint32_t CDC_Send_FreeBytes(void) { - /* - return the bytes free in the circular buffer - - functionally equivalent to: - (APP_Rx_ptr_out > APP_Rx_ptr_in ? APP_Rx_ptr_out - APP_Rx_ptr_in : APP_RX_DATA_SIZE - APP_Rx_ptr_in + APP_Rx_ptr_in) - but without the impact of the condition check. - */ + // return the bytes free in the circular buffer uint32_t freeBytes; ATOMIC_BLOCK(NVIC_BUILD_PRIORITY(6, 0)) { - freeBytes = ((UserTxBufPtrOut - UserTxBufPtrIn) + (-((int)(UserTxBufPtrOut <= UserTxBufPtrIn)) & APP_TX_DATA_SIZE)) - 1; + freeBytes = APP_RX_DATA_SIZE - rxAvailable; } return freeBytes; diff --git a/src/main/vcpf4/usbd_cdc_vcp.c b/src/main/vcpf4/usbd_cdc_vcp.c index 6a0aaa60f4..7c8718e623 100644 --- a/src/main/vcpf4/usbd_cdc_vcp.c +++ b/src/main/vcpf4/usbd_cdc_vcp.c @@ -25,8 +25,11 @@ #include "platform.h" +#include "build/atomic.h" + #include "usbd_cdc_vcp.h" #include "stm32f4xx_conf.h" +#include "drivers/nvic.h" #include "drivers/time.h" #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED @@ -44,11 +47,11 @@ __IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */ /* This is the buffer for data received from the MCU to APP (i.e. MCU TX, APP RX) */ extern uint8_t APP_Rx_Buffer[]; -extern uint32_t APP_Rx_ptr_out; +extern volatile uint32_t APP_Rx_ptr_out; /* Increment this buffer position or roll it back to start address when writing received data in the buffer APP_Rx_Buffer. */ -extern uint32_t APP_Rx_ptr_in; +extern volatile uint32_t APP_Rx_ptr_in; /* APP TX is the circular buffer for data that is transmitted from the APP (host) @@ -188,14 +191,7 @@ uint32_t CDC_Send_DATA(const uint8_t *ptrBuffer, uint32_t sendLength) uint32_t CDC_Send_FreeBytes(void) { - /* - return the bytes free in the circular buffer - - functionally equivalent to: - (APP_Rx_ptr_out > APP_Rx_ptr_in ? APP_Rx_ptr_out - APP_Rx_ptr_in : APP_RX_DATA_SIZE - APP_Rx_ptr_in + APP_Rx_ptr_in) - but without the impact of the condition check. - */ - return ((APP_Rx_ptr_out - APP_Rx_ptr_in) + (-((int)(APP_Rx_ptr_out <= APP_Rx_ptr_in)) & APP_RX_DATA_SIZE)) - 1; + return APP_RX_DATA_SIZE - CDC_Receive_BytesAvailable();; } /** @@ -215,12 +211,13 @@ static uint16_t VCP_DataTx(const uint8_t* Buf, uint32_t Len) while (USB_Tx_State != 0); for (uint32_t i = 0; i < Len; i++) { - APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i]; - APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE; - - while (CDC_Send_FreeBytes() == 0) { + // Stall if the ring buffer is full + while (((APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE) == APP_Rx_ptr_out) { delay(1); } + + APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i]; + APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) % APP_RX_DATA_SIZE; } return USBD_OK; @@ -237,7 +234,7 @@ uint32_t CDC_Receive_DATA(uint8_t* recvBuf, uint32_t len) { uint32_t count = 0; - while (APP_Tx_ptr_out != APP_Tx_ptr_in && count < len) { + while (APP_Tx_ptr_out != APP_Tx_ptr_in && (count < len)) { recvBuf[count] = APP_Tx_Buffer[APP_Tx_ptr_out]; APP_Tx_ptr_out = (APP_Tx_ptr_out + 1) % APP_TX_DATA_SIZE; count++; @@ -248,7 +245,7 @@ uint32_t CDC_Receive_DATA(uint8_t* recvBuf, uint32_t len) uint32_t CDC_Receive_BytesAvailable(void) { /* return the bytes available in the receive circular buffer */ - return APP_Tx_ptr_out > APP_Tx_ptr_in ? APP_TX_DATA_SIZE - APP_Tx_ptr_out + APP_Tx_ptr_in : APP_Tx_ptr_in - APP_Tx_ptr_out; + return (APP_Tx_ptr_in + APP_TX_DATA_SIZE - APP_Tx_ptr_out) % APP_TX_DATA_SIZE; } /**