2021-04-09 04:24 AM
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
Solved! Go to Solution.
2021-04-28 01:39 AM
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
2021-04-09 04:29 AM
@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
2021-04-16 06:34 AM
Hi Javier,
Did you have a look at the STM32CubeF2 Firmware ? Under directory Projects/$board_name$/Applications/USB_Device/CDC_Standalone
Best Regards,
Ons.
2021-04-18 11:59 PM
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.
2021-04-20 06:29 AM
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.
2021-04-20 06:32 AM
Hi Javier,
What MCU/Board are you using ?
Best Regards,
Ons.
2021-04-20 06:40 AM
@Ons KOOLI STM32f205ret6 with custom board (8Mhz external xtal) but i could also replicate the problemm in a NUCLEO-F207ZG
2021-04-20 07:41 AM
@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.
2021-04-21 02:56 AM
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.
2021-04-26 06:26 AM
@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().....