32F417: can one detect when a USB Host is connected?
Can anyone suggest a way of bypassing this USB OUT function ("OUT" means to Host i.e. the opposite of the correct USB terminology) if no USB cable is plugged in?
This is a fairly common bit of code from the ST Cube USB CDC (VCP) library, with additions from me to make it thread-safe, and a timeout in case a USB Host (with a USB VCP application running) is not connected.
I would like to achieve this without the timeout.
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function. Note that "IN" in USB terminology means
* product-> PC.
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* *
* This function had a call rate limit of about 10kHz, and had a packet length limit
* of about 800 bytes - until the flow control mod below. These limits still apply if
* flow_control=false.
*
* This function is BLOCKING if flow_control=true. That means that if there is no Host
* application receiving the data (e.g. Teraterm) it will block output.
* The problem is that if no USB device is connected from startup, the while() loop
* would block for ever, hence the timeout.
*
* Flow control is normally disabled for the debugging output functions.
*
* If called before USB thread starts, all output is dumped - for obvious reasons!
*
* Mutexed to enable multiple RTOS tasks to output to port 0.
*
*/
#define USB_TX_TIMEOUT 100 // 100ms
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, bool flow_control)
{
if ( g_USB_started && (Len>0) )
{
uint32_t counter = 0;
bool timeout = false;
osMutexAcquire(g_CDC_transmit_mutex, osWaitForever);
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassDataCDC;
// Wait on USB Host accepting the data.
if ( flow_control )
{
// Loop around until USB Host has picked up the last data
// This rarely holds things up - 20us typ. delay
while (hcdc->TxState != 0) // This gets changed by USB thread, hence the g_USB_started test
{
osDelay(1);
counter++;
if (counter>USB_TX_TIMEOUT)
{
timeout=true;
break;
}
}
}
if (!timeout)
{
// Output the data to USB
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
USBD_CDC_TransmitPacket(&hUsbDeviceFS);
}
osMutexRelease(g_CDC_transmit_mutex);
g_comms_act[0]=LED_COM_TC; // indicate data flow on LED 0
// If flow control is selected OFF, we do a crude wait to make CDC output work
// even with a slow Host. This actually needs to be only a ~100-200us wait, but
// is host dependent.
if ( !flow_control )
{
osDelay(2);
}
}
return USBD_OK;
}