cancel
Showing results for 
Search instead for 
Did you mean: 

CDC_Transmit_FS() is giving me a headache (USB CDC Device mode)

Javier1
Principal

Hello everyone and i hope youre having a great embedded morning.

CDC_Transmit_FS() bricks itself when i check status of the ongoing transmission

is there any mechanism to know when a CDC_Transmit_FS transaction is finished?

When i try to CDC_Transmit_FS before the previous CDC_Transmit_FS is done retval=USBD_BUSY which is to be expected, well after that CDC_Transmit_FS doesnt work anymore always returning USBD_BUSY.

This code bricks the usb peripheral and can only be used again after system reset:

do {
//HAL_Delay(100);
retval=CDC_Transmit_FS(&buffer, receivedbytes);
} while (retval!=USBD_OK);//
 
retval=CDC_Transmit_FS("finished transmission", sizeof("finished transmission"));//this will return HAL_OK but no transaction will be done

If i place a dirty delay big enough for the first transaction to be done everything works.

retval=CDC_Transmit_FS(&buffer, receivedbytes);
HAL_Delay(1000);
retval=CDC_Transmit_FS("finished transmission", sizeof("finished transmission"));

im using STM32f205ret6

CubeMX Version 6.1.1

0693W000008zjjjQAA.png 

we dont need to firmware by ourselves, lets talk
1 ACCEPTED SOLUTION

Accepted Solutions

So i didnt find a solution after 2 weeks struggle...

What ive done is just transmitt data in smaller chunks of 4kB data and place small hal_delay(300); in between.

uint8_t aux=receivedbytesUSB/0x800;//how many full 4kb pages we want to transmitt	
for(uint8_t i=0;i<aux;++i){			//transmitt full 4kb pages
CDC_Transmit_FS(&txBufferUSB68K[i*0x800], 0x800);			
HAL_Delay(300);
}
//transmitt the last less than 4kb page
CDC_Transmit_FS(&rxBufferUSB68K[aux*0x800], receivedbytesUSB%(aux*0x800));
HAL_Delay(300);

This is not ideal but it works

we dont need to firmware by ourselves, lets talk

View solution in original post

12 REPLIES 12
Javier1
Principal

@leogarberoglio​ had the same issue, the answer provided by @Amel NASRI​ didnt helped me.

https://community.st.com/s/question/0D50X00009XkfqgSAB/how-to-wait-until-cdctransmitfs-finish

we dont need to firmware by ourselves, lets talk

Hi Javier,

Did you have a look at the STM32CubeF2 Firmware ? Under directory Projects/$board_name$/Applications/USB_Device/CDC_Standalone

Best Regards,

Ons.

Hi @Ons KOOLI​ , thanks for your reply.

Yes i looked in those examples but i could only find examples for USB cdc host mode

C:\Users\myuser\STM32Cube\Repository\STM32Cube_FW_F2_V1.9.2\Projects\STM322xG_EVAL\Applications\USB_Host\CDC_Standalone\

Im using usb cdc device mode and the issue is my CDC_Transmit_FS blocks the preipheral/process when you check the status of the ongoing transaction.

All other examples and youtube videos ive seen everyone is just sending very small bursts of data, not minding if the previous transmission is over yet.

I trying to send 64kB bursts of data , so the time it takes to finish the tx is very important to me.

we dont need to firmware by ourselves, lets talk

Is this EXACTLY 64K bytes of data in one call to CDC_Transmit_FS()? For example, is your call to CDC_Transmit_FS() have the "len" param set to 65536? If so, note that the "Len" param is uin16_t, so 64K (i.e. 65536) will truncate/wrap to a 16-bit value of zero. And I have no idea how the ST/HAL USB code deals with being told to send zero bytes. This may not be the issue since you say our code works with a 1 second delay between the two CDC_Transmit_FS() calls.

Hi Javier,

What MCU/Board are you using ?

Best Regards,

Ons.

@Ons KOOLI​ STM32f205ret6 with custom board (8Mhz external xtal) but i could also replicate the problemm in a NUCLEO-F207ZG

we dont need to firmware by ourselves, lets talk

@Bob S​ not exactly 64k it can be less, right now im dealing with hex files of around 35kB.

I dont think my problem is an integer overflow... as you said it works if i just let enough time between transactions.

Im trying to code a bootloader so the stm32f205 receives a .bin via USB (correctly), but when i echo the same .bin back to my pc is when this problem appears.

we dont need to firmware by ourselves, lets talk

Hi Javier,

Can you refer to the STM32CubeF2 V1.9.0 available on the official site of ST ?

I checked the package and I found a CDC_Standalone project under the following directory:

STM32Cube_FW_F2_V1.9.0\Projects\STM322xG_EVAL\Applications\USB_Device\CDC_Standalone

Best Regards,

Ons.

@Ons KOOLI​ thanks for your help but I have been taking a long look to the example you pointed to, and im even more confused than before.

Their CDC generated code has a completely different structure, there is not CDC_Transmit_FS() because usbd_cdc_if.c is not there.

I see your example uses USBD_CDC_TransmitPacket() to check if the transmission is completed?

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  uint32_t buffptr;
  uint32_t buffsize;
  
  if(UserTxBufPtrOut != UserTxBufPtrIn)
  {
    if(UserTxBufPtrOut > UserTxBufPtrIn) /* Rollback */
    {
      buffsize = APP_TX_DATA_SIZE - UserTxBufPtrOut;
    }
    else 
    {
      buffsize = UserTxBufPtrIn - UserTxBufPtrOut;
    }
    
    buffptr = UserTxBufPtrOut;
    
    USBD_CDC_SetTxBuffer(&USBD_Device, (uint8_t*)&UserTxBuffer[buffptr], buffsize);
    
    if(USBD_CDC_TransmitPacket(&USBD_Device) == USBD_OK)
    {
      UserTxBufPtrOut += buffsize;
      if (UserTxBufPtrOut == APP_RX_DATA_SIZE)
      {
        UserTxBufPtrOut = 0;
      }
    }
  }
}

USBD_CDC_TransmitPacket() also can be found inside my CDC_Transmit_FS()

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
  /* USER CODE BEGIN 7 */
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  if (hcdc->TxState != 0){
    return USBD_BUSY;
  }
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);///<-----Here
  /* USER CODE END 7 */
  return result;
}

So ill try to use it instead of the glitchy CDC_Transmit_FS().....

we dont need to firmware by ourselves, lets talk