cancel
Showing results for 
Search instead for 
Did you mean: 

STM32Cube/HAL USB CDC - TX Complete Callback?

mwp
Senior
Posted on December 14, 2016 at 06:10

Hi all,

Does anyone know of the 'correct' way to get a call back when the previous transfer has been completed?

The USB CDC has the TxState status variable which is cleared when a transmission is complete, but i don't really want to poll this.

TxState is cleared in USBD_CDC_DataIn() which is in usbd_cdc.c (Middlewares/USB), so i also dont want to modify this file to add a callback as any changes will be cleared when STM32Cube re-gen's the code.

Im really looking forward to the new LL drivers are properly supported by STM32CubeMX.

HAL is terrible

:(

Thanks in advance.

#usb #cdc #stm32 #hal
3 REPLIES 3
stm322399
Senior
Posted on December 18, 2016 at 16:15

IMHO, it is worth to modify the generated code. Only a single line in USBD_CDC_DataIn() and another in usbd_cdc.h to declare the 'Sent' callback in USBD_CDC_ItfTypeDef.

To work around code re-generation, i rebase my own code onto CubeMX code (with git, of course!).

Hopefully CubeMX will be enhanced this way, the sooner, the better.

tm3341
Associate II
Posted on December 18, 2016 at 21:17

This is actually very good purpose since now we have to poll for data to be sent if anything available.

Hope ST adds 5th callback in CDC class (usb_cdc_if file) to nofity user about Transmit().

Williams.Mark.001 wrote:

Im really looking forward to the new LL drivers are properly supported by STM32CubeMX.

HAL is terrible

HAL is terrible for very advanced users. For beginners, it is very good tool.

Brendan McDonnell
Associate II
Posted on February 02, 2017 at 16:48

Does anyone know of the 'correct' way to get a call back when the previous transfer has been completed?

You're asking about IN Transfers (device to host), right?

I'm using code generated by STM32CubeMX against

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubef0.html

firmware v 1.7.0. (USB CDC, of course.) In

PCD_EP_ISR_Handler()

, you have

        /* Zero Length Packet? */

        if (ep->xfer_len == 0U)

        {

          /* TX COMPLETE */

          HAL_PCD_DataInStageCallback(hpcd, ep->num);

        }

        else

        {

          HAL_PCD_EP_Transmit(hpcd, ep->num, ep->xfer_buff, ep->xfer_len);

        }

My understanding of this is that it'll handle the packet-wise transmission internally (by repeatedly calling

HAL_PCD_EP_Transmit

()), and not do the callback until all the data has been sent. That is, after the transmission is sent, this sequence of calls occurs:

HAL_PCD_DataInStageCallback()

-->

USBD_LL_DataInStage()

-->

pdev->pClass->DataIn()

which is

USBD_CDC_DataIn()

. It doesn't look to me like you have to poll

TxState

in the class driver.

However, it doesn't send a ZLP to terminate if (transmission_length % wMaxPacketSize == 0); it's letting the class do that if it wants in its callback.

I recently suggested to ST in a tech support ticket that they add a flag as to whether to send ZLPs to terminate such transfers

http://libusb.org/ticket/6

, since this optional functionality is described in the USB 2.0 spec, so it belongs in the core driver, not the class. (I don't know in which module specifically it makes the most sense, like LL vs. PCD, but definitely in the core, below the class level.)

Feel free to echo my suggestion to them.