Electronic – Throttling data from USB serial connection on STM32 microcontroller (flow control)

flow controlserialstm32usb

I've just integrated the code from ST's STM32 USB Virtual Com Port example (stm32_usb-fs-device_lib.zip from here) with my project in order to get the STM32 to appear as a Virtual Serial Port.

However the code example throttles the data it receives by having the callback function EP3_OUT_Callback block (in an interrupt) until all data is dealt with. The exact comment in the code is "USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the USART Xfer"

In my project, I need to process the data that has been received in the main loop (outside of an interrupt), so I need a way of throttling the data that I get from USB without blocking in EP3_OUT_Callback.

What I would like is a function:

Do_Not_Call_EP3_OUT_Callback_Right_Now(bool yes_or_no);

Best Answer

I appear to have got this working:

void EP3_OUT_Callback(void) {
 ...
  //SetEPRxValid(ENDP3); //<-- Commented out
  SetEPRxStatus(ENDP3, Do_I_Have_Room_For_More_Data() ? EP_RX_VALID : EP_RX_NAK); //<-- Added this
}

void SOF_Callback(void) {
  if(bDeviceState == CONFIGURED) {
    SetEPRxStatus(ENDP3, Do_I_Have_Room_For_More_Data() ? EP_RX_VALID : EP_RX_NAK); //<-- Added this
    ...
    // Original TX code here
  }
}

What's happening is after getting data, and in the Start of Frame callback (every 1ms), I set whether the endpoint is accepting data.

Note: The docs never seem to say just how much data USB_SIL_Read will read - potentially leading to a buffer overrun. However I believe the maximum is what is in VIRTUAL_COM_PORT_DATA_SIZE - and this seems to work great for me.

This would appear to work - however I have no idea if it is the 'right' way of doing it. Please let me know if it's wrong and I'll update it!