summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--stmhal/usbd_cdc_interface.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c
index 8a2470c853..a62f8a801f 100644
--- a/stmhal/usbd_cdc_interface.c
+++ b/stmhal/usbd_cdc_interface.c
@@ -46,7 +46,7 @@
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
-#define APP_RX_DATA_SIZE 1024 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE (was 2048)
+#define APP_RX_DATA_SIZE 1024 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE=64 (APP_RX_DATA_SIZE was 2048)
#define APP_TX_DATA_SIZE 1024 // I think this can be any value (was 2048)
/* Private macro -------------------------------------------------------------*/
@@ -138,8 +138,13 @@ static int8_t CDC_Itf_Init(void)
UserRxBufCur = 0;
UserRxBufLen = 0;
+ /* NOTE: we cannot reset these here, because USBD_CDC_SetInterrupt
+ * may be called before this init function to set these values.
+ * This can happen if the USB enumeration occurs after the call to
+ * USBD_CDC_SetInterrupt.
user_interrupt_char = VCP_CHAR_NONE;
user_interrupt_data = NULL;
+ */
return (USBD_OK);
}
@@ -252,7 +257,7 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void) {
{
if(UserTxBufPtrOut > UserTxBufPtrIn) /* rollback */
{
- buffsize = APP_RX_DATA_SIZE - UserTxBufPtrOut;
+ buffsize = APP_TX_DATA_SIZE - UserTxBufPtrOut;
}
else
{
@@ -266,7 +271,7 @@ void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void) {
if(USBD_CDC_TransmitPacket(&hUSBDDevice) == USBD_OK)
{
UserTxBufPtrOut += buffsize;
- if (UserTxBufPtrOut == APP_RX_DATA_SIZE)
+ if (UserTxBufPtrOut == APP_TX_DATA_SIZE)
{
UserTxBufPtrOut = 0;
}
@@ -289,9 +294,20 @@ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) {
HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
#endif
+ // TODO improve this function to implement a circular buffer
+
+ // if we have processed all the characters, reset the buffer counters
+ if (UserRxBufCur > 0 && UserRxBufCur >= UserRxBufLen) {
+ memmove(UserRxBuffer, UserRxBuffer + UserRxBufLen, *Len);
+ UserRxBufCur = 0;
+ UserRxBufLen = 0;
+ }
+
+ uint32_t delta_len;
+
if (user_interrupt_char == VCP_CHAR_NONE) {
// no special interrupt character
- UserRxBufLen = *Len;
+ delta_len = *Len;
} else {
// filter out sepcial interrupt character from the buffer
@@ -310,25 +326,29 @@ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) {
}
}
- // set length of remaining characters
- UserRxBufLen = dest - Buf;
-
if (char_found) {
// raise exception when interrupts are finished
user_interrupt_char = VCP_CHAR_NONE;
pendsv_nlr_jump(user_interrupt_data);
}
- }
- // there are new characters at the start of the buffer, so point there
- UserRxBufCur = 0;
+ // length of remaining characters
+ delta_len = dest - Buf;
+ }
- if (UserRxBufLen == 0) {
- // initiate next USB packet transfer now that UserRxBuffer has been drained
- USBD_CDC_ReceivePacket(&hUSBDDevice);
+ if (UserRxBufLen + delta_len + CDC_DATA_FS_MAX_PACKET_SIZE > APP_RX_DATA_SIZE) {
+ // if we keep this data then the buffer can overflow on the next USB rx
+ // so we don't increment the length, and throw this data away
+ } else {
+ // data fits, leaving room for another CDC_DATA_FS_OUT_PACKET_SIZE
+ UserRxBufLen += delta_len;
}
- return (USBD_OK);
+ // initiate next USB packet transfer, to append to existing data in buffer
+ USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer + UserRxBufLen);
+ USBD_CDC_ReceivePacket(&hUSBDDevice);
+
+ return USBD_OK;
}
int USBD_CDC_IsConnected(void) {
@@ -366,9 +386,6 @@ int USBD_CDC_RxGet(void) {
// get next character
int c = UserRxBuffer[UserRxBufCur++];
- if (UserRxBufCur >= UserRxBufLen) {
- // initiate next USB packet transfer now that UserRxBuffer has been drained
- USBD_CDC_ReceivePacket(&hUSBDDevice);
- }
+
return c;
}