2016-03-31 07:14 AM
I have observed in all of the USB-CDC examples I've seen with the STM32Cube libraries, that the transmit buffer is managed with a timer that polls the USB to see if the previous transmission was complete (or rather if the USB is busy) before setting the next chunk of transmit buffer and calling USBD_CDC_TransmitPacket - Is there a way around having to poll this? Is there an interrupt available that indicates with a transmit is complete so I know as soon as possible when I can send the next packet? Or do I have to poll? If I have to poll, what is a good polling interval to get the best possible performance (FS USB, not HS)
#usb #cdc #device #usb-cdc-stm32cube-stm32-pollingSolved! Go to Solution.
2018-07-31 04:46 PM
@Sebastian
> why can not I send a chain after another, my PC only receive the first
Sending takes time.
USBD_CDC_TransmitPacket() only queues the data for sending and returns immediately. Until the data has been sent, TxState flag is set, so your second call to CDC_Transmit_FS() returns USBD_BUSY and the 2nd data is not sent.
The TxState flag is cleared in the USB interrupt callback inside the CDC class module
There is no direct access to this callback unless you modify the source.
-- pa
2016-04-04 01:19 AM
I wonder this as well...
2016-04-04 06:21 AM
Right?! It seems like that's how it should work, but every example I find uses a timer to poll the interface to check if it's busy, which seems like it would introduce needless latency, especially if you didn't want to be taking frequent timer interrupts in your application to check on the USB. I have been hesitant to dip down into the low level USB code to search for a resolution, but I think I'm getting to that point!
2016-04-04 08:51 AM
Hi sturmer,
> Way to be notified on CDC transmit complete? a) Poll ((USBD_CDC_HandleTypeDef*)(USBD_Device.pClassData))->TxState value in your application code - While transfer is going on, TxState is kept in 1 - When transfer completes, TxState goes to 0 (see code below) OR b) Modify CDC class code, to add your custom callback, which is called at transfer completion interrupt.\STM32Cube_FW_F4_V1.11.0\Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src\
usbd_cdc.c // line 664 static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; if(pdev->pClassData != NULL) { hcdc->TxState = 0; // <---------------- add your custom callback here. return USBD_OK; } else { return USBD_FAIL; } } > so I know as soon as possible when I can send the next packet? You don't need to split large buffer into chunks. You may pass ANY size of data buffer to USBD_CDC_SetTxBuffer(), even greater than MPS (Max Packet Size: FS 64 bytes / HS 512 bytes). The device stack automatically splits the buffer into MPS transactions, and it sends them one by one. When you are starting on an existing ''CDC_Standalone'' project, instead of generated code by CubeMX, this project implements a periodic timer to keep TX (device->host) transfer. This timer is good for USB-UART application to keep transfer speed (size) over slow UART with fast USB. But for other applications, this timer ISR causes unexpected result. And then, delete this timer initialization and its ISR (HAL_TIM_PeriodElapsedCallback())usbd_cdc_interface.c
static int8_t CDC_Itf_Init(void) { ... // line 120 Delete these timer setting lines /*##-3- Configure the TIM Base generation #################################*/ TIM_Config(); /*##-4- Start the TIM Base generation in interrupt mode ####################*/ /* Start Channel1 */ if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK) { /* Starting Error */ Error_Handler(); } Tsuneo > to ST web admin, ''Format Code Block'' button doesn't work with ''Web.config registration missing'' error. Please fix it.2016-04-04 09:46 AM
The splitting into chunks comes from wanting to do multiple writes consecutively, and running into the problem of the USB being busy. If I do two USB writes, and the second one is called before the first one is complete, I either have to sleep and wake up with a timer to poll the interface, or I can do as you describe and use a callback to kick off the next write. (Or as a third option, i could poll, but this isn't ideal for me)
Do I have this right?2016-04-08 02:59 AM
Hi chinzei.tsuneo,
Thanks for all your valuable answers in our STM32 forums.> to ST web admin,''Format Code Block'' button doesn't work with ''Web.config registration missing'' error. Please fix it.
==> We are working to fix this issue. Sorry for such inconvenience.-Mayla-
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-04-13 02:10 AM
Hi,
Please note that the issue related to ''Format Code Block'' or picture insert is already fixed.-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-04-21 07:44 AM
2018-07-31 09:34 AM
Hi
why can not I send a chain after another, my PC only receive the first
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM1) {
HAL_IncTick();
}
if (htim->Instance == TIM2)
{
uint8_t text1[] = "Hello World\r\n";
uint8_t text2[] = "I m here\r\n";
CDC_Transmit_FS(text1, 13);
CDC_Transmit_FS(text2, 10);
}
}
if I m place it on the principal loop I need place an Hal_delay beteween CDC_transmit_S, I m using the CubeMx configuration, the code is:
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);
/* USER CODE END 7 */
return result;
}
someone can help me and say what mistake I'm committing
thanks for your help
2018-07-31 04:46 PM
@Sebastian
> why can not I send a chain after another, my PC only receive the first
Sending takes time.
USBD_CDC_TransmitPacket() only queues the data for sending and returns immediately. Until the data has been sent, TxState flag is set, so your second call to CDC_Transmit_FS() returns USBD_BUSY and the 2nd data is not sent.
The TxState flag is cleared in the USB interrupt callback inside the CDC class module
There is no direct access to this callback unless you modify the source.
-- pa