2017-09-05 05:55 PM
How should I implement USB CDC Receive for the STM32F103C8 using CubeMX? I could not find any examples.
I have a partially working implementation of a USB CDC for this IC, but I have a few occasional issues with missed data.
First, I don't understand the
CDC_Receive_FS(...)
function.SetRxBuffer
? It shouldn't change, should it? Isn't it always stored intoUserRxBufferFS
?Or is this function passing a pointer to some other buffer internal to the USB driver, andUserRxBufferFS
is never used?USB_CDC_RecivePacket
do? Since it does LL stuff, why wouldn't it be called by the function that callsCDC_Receive_FS
?APP_RX_DATA_SIZE
to be 512?static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
/**** Do I process the buffer here? ****/
/* Can the next line be removed, unless the RX buffer needs to change? */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); /*<-- Change buffer for next RX? */
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
/**** Or do I process it here? ****/
return (USBD_OK);
/* USER CODE END 6 */
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
I'm currently detecting if the USB CDC is connected by seeing if the previous transmission succeeded in a timely fashion. I'm using FreeRTOS. Is this proper, or is there a better way? Since I don't know how to cancel the previous transmit, I don't want to overwrite the buffer while it may still be transmitting.
static void usbTx(char *msg) {
static TickType_t lastXmit = 0;
/* If still transmitting, and it has been more than 200 ms, give up */
while(CDC_Busy() && (xTaskGetTickCount()-lastXmit < (200/portTICK_PERIOD_MS ))) {
osDelay(1);
}
// Last transmission failed, so lets skip this one.
if(CDC_Busy())
return;
size_t len = strlen(msg);
uint8_t result = CDC_Transmit_FS((uint8_t*)msg,len);
if(result == USBD_OK)
lastXmit = xTaskGetTickCount();
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
#freertos-stm32cube #stm32f103 #cdc #usb
2017-09-09 08:32 PM
(I'm replying to my own post, though I'd still appreciate answers to the questions I posed.)
I found that I had a memory-management bug in my code while transmitting. The issue was that after calling the transmit function, the TX buffer may not change until the transmission is complete. I've not done thorough testing, but my CDC implementation seems to be reliable now.
To solve my bug, I added a memcpy(...) to the TX function:
// Use 65, just to be safe. I dislike buffer overruns.
#define APP_TX_DATA_SIZE 65
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
if(hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
return USBD_FAIL;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
// I've read that lengths of 64 can confuse Windows, as it interprets it as a reset.
configASSERT(Len > 0 && Len < 63);
memcpy(UserTxBufferFS, Buf, Len);
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
2017-11-14 03:39 AM
Hi, I'm sorry that I don't have any answers for you your questions, but I have a question myself. How are we supposed to use the CDC_Receive_FS function if it's satic on main.c or any other file? Same thing to the other static functions in the 'usbd_cdc_if.c' file.
Thanks
VÃtor Pereira
2017-11-29 05:45 AM
Replying to myself, hoping to be usefull for someone else: CDC_Receive_FS/HS is a callback function. When data is received on USB port, this function is called. You have to implement what you wnat to do with data received in this function. Data received will be in Buf pointer.