Search code examples
embeddedstm32stm32f4discoverystm32f4nucleo

STM32 USB CDC Rx Interrupt


I have implemented USB CDC (VCP) on STM32-F446re(Nucleo). I am using int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) in loop to receive data. But lot of data is also being sent over, hence I want reception interrupt based.

Can anyone help me understand how to setup USB CDC Rx interrupt?


Solution

  • As commented, CDC_Receive_FS is a call-back that is invoked by the USB stack interrupt handler and already it runs in the interrupt context. You should not be calling that in a loop - it is called by the stack and you are expected to implement the function to process the data.

    An implementation might look like:

    static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
    {
        // Process Len bytes from Buf
        YOUR_CODE_HERE
    
        // Set the RX buffer
        USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]);
        
        // Ready to receive the next packet
        USBD_CDC_ReceivePacket(hUsbDevice_0);
    
        return USBD_OK ;
    }
    

    Then most obvious thing to do at YOUR_CODE_HERE is place the data into a FIFO queue or ring buffer that is then consumed in the main thread context. Or if you are using an RTOS place the data in a queue for processing in a task context.

    Critically you should grab the data and return as soon as possible, because further data will be blocked until you do that, and it is an interrupt context so you don't want to hang around - the ST code is already a bit heavyweight for an ISR IMO. In their earlier (pre-STM32Cube) USB library, I moved the entire stack into an RTOS task, so the ISR simply triggered an event received by the task. That was necessary to prevent time critical tasks being delayed by the USB interrupt.