Skip to main content
PHolt.1
Senior
September 4, 2022
Question

32F4 USB CDC - any way to tell if Host has retrieved the data sent to it?

The Cube IDE code flow is

CDC_Transmit_FS

USBD_CDC_TransmitPacket

USBD_LL_Transmit

HAL_PCD_EP_Transmit

USB_WritePacket

and the last one does 16 32 bit word transfers to the USB FIFO

HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma)
{
 uint32_t USBx_BASE = (uint32_t)USBx;
 uint32_t *pSrc = (uint32_t *)src;
 uint32_t count32b, i;
 
 if (dma == 0U)
 {
 count32b = ((uint32_t)len + 3U) / 4U;
 for (i = 0U; i < count32b; i++)
 {
 USBx_DFIFO((uint32_t)ch_ep_num) = *((__packed uint32_t *)pSrc);
 pSrc++;
 }
 }
 
 return HAL_OK;
}

My Q is whether there is any way to tell when that data has been consumed.

I have been doing tests and found

  • there is a ~10kHz rate limit on calling CDC_Transmit_FS
  • the max CDC_Transmit_FS packet size is 800 bytes

I am sure these are both system dependent, so I am rate limiting to 1kHz and size limiting to 256 bytes.

There are various return codes from various functions but none of these appear to relate to whether you can shove more data out.

Is USB really "open loop" like that? I know it is all polled by the PC, seemingly at ~10kHz

This topic has been closed for replies.

11 replies

Piranha
Principal III
November 5, 2022

A system tick (hardware with ISR) and the timer thread are related but different things. The timer thread manages all software timers. If the IDLE thread is not the only one at the lowest priority, it cannot be used to put the CPU into sleep mode, which is an unnecessary waste of energy and heating of the MCU without any gain. The ETH Rx thread typically doesn't need to be set at the highest priorities because typically it has several Rx buffers for packets and it's DMA can fill those completely autonomously. It could be that some thread processing UART or similar data has to be at a higher priority because that communication is more timing sensitive. But, of course, it depends on protocols, hardware buffers and the project specifics.

Running (almost) everything at a single priority is not an achievement. It's a deliberate crippling of the system for no reason. Except for a few bytes of RAM, you don't gain anything from that. That's true for up to 32 priority levels, which is plenty for almost anything. Going for more is indeed not recommended as it will loose more resources.

> Is TxState an int or a boolean?

It doesn't matter. What I mean is that this is enough:

while (hcdc->TxState)