cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Receive for the STM32F103C8 using CubeMX?

Nathan Conrad
Associate II
Posted on September 06, 2017 at 02:55

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.
  1. Do I process/copy the buffer on line 5 or line 10?
  2. Why does it need to

    SetRxBuffer

    ? It shouldn't change, should it? Isn't it always stored into

    UserRxBufferFS

    ?Or is this function passing a pointer to some other buffer internal to the USB driver, and

    UserRxBufferFS

    is never used?
  3. What does

    USB_CDC_RecivePacket

    do? Since it does LL stuff, why wouldn't it be called by the function that calls

    CDC_Receive_FS

    ?
  4. My understanding is that the max packet length for full-speed USB is 512 bytes. Do I need to change

    APP_RX_DATA_SIZE

    to be 512?
  5. Are there still concerns with read/write locking? (See

    https://community.st.com/thread/10392

    ).
  6. Is there a way to cancel the previous USB transmit, or append data to its buffer?

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
3 REPLIES 3
Nathan Conrad
Associate II
Posted on September 10, 2017 at 05:32

(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;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Vitor Pereira
Associate II
Posted on November 14, 2017 at 12:39

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

Posted on November 29, 2017 at 13:45

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.