aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2012-09-16 18:18:07 +0000
committerDean Camera <dean@fourwalledcubicle.com>2012-09-16 18:18:07 +0000
commite186907e393939f1b417f0f7ba7406b46c76bece (patch)
treee3267282ed812b7c07b58faf1546644248e2c7b3
parent3e1f3869c1678fa89c40e9afef06efa2d7f24326 (diff)
downloadlufa-e186907e393939f1b417f0f7ba7406b46c76bece.tar.gz
lufa-e186907e393939f1b417f0f7ba7406b46c76bece.tar.bz2
lufa-e186907e393939f1b417f0f7ba7406b46c76bece.zip
Fixed lengthy timeouts in the USBtoSerial project if no application on the host is consuming data (thanks to Nicolas Saugnier).
Fixed lengthy automatic data flushing in the CDC and MIDI device class drivers.
-rw-r--r--LUFA/DoxygenPages/ChangeLog.txt2
-rw-r--r--LUFA/Drivers/USB/Class/Device/CDCClassDevice.c5
-rw-r--r--LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c5
-rw-r--r--Projects/USBtoSerial/USBtoSerial.c35
4 files changed, 33 insertions, 14 deletions
diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt
index 271c23d10..e92f026cf 100644
--- a/LUFA/DoxygenPages/ChangeLog.txt
+++ b/LUFA/DoxygenPages/ChangeLog.txt
@@ -34,6 +34,8 @@
* - Library Applications:
* - Fixed broken RESET_TOGGLES_LIBUSB_COMPAT compile time option in the AVRISP-MKII project
* - Fixed incompatibility in the CDC class bootloader on some systems (thanks to Sylvain Munaut)
+ * - Fixed lengthy timeouts in the USBtoSerial project if no application on the host is consuming data (thanks to Nicolas Saugnier)
+ * - Fixed lengthy automatic data flushing in the CDC and MIDI device class drivers
*
* \section Sec_ChangeLog120730 Version 120730
* <b>New:</b>
diff --git a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
index ff0f9bb55..61f4be9d7 100644
--- a/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
+++ b/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c
@@ -138,7 +138,10 @@ void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
return;
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
- CDC_Device_Flush(CDCInterfaceInfo);
+ Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address);
+
+ if (Endpoint_IsINReady())
+ CDC_Device_Flush(CDCInterfaceInfo);
#endif
}
diff --git a/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c b/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c
index c9553a413..5defa142a 100644
--- a/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c
+++ b/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c
@@ -59,7 +59,10 @@ void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo)
return;
#if !defined(NO_CLASS_DRIVER_AUTOFLUSH)
- MIDI_Device_Flush(MIDIInterfaceInfo);
+ Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address);
+
+ if (Endpoint_IsINReady())
+ MIDI_Device_Flush(MIDIInterfaceInfo);
#endif
}
diff --git a/Projects/USBtoSerial/USBtoSerial.c b/Projects/USBtoSerial/USBtoSerial.c
index 7fe67da44..a0b8de4c4 100644
--- a/Projects/USBtoSerial/USBtoSerial.c
+++ b/Projects/USBtoSerial/USBtoSerial.c
@@ -108,21 +108,32 @@ int main(void)
uint16_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
if ((TIFR0 & (1 << TOV0)) || (BufferCount > (uint8_t)(sizeof(USARTtoUSB_Buffer_Data) * .75)))
{
- /* Clear flush timer expiry flag */
- TIFR0 |= (1 << TOV0);
-
- /* Read bytes from the USART receive buffer into the USB IN endpoint */
- while (BufferCount--)
+ Endpoint_SelectEndpoint(VirtualSerial_CDC_Interface.Config.DataINEndpoint.Address);
+
+ /* Check if a packet is already enqueued to the host - if so, we shouldn't try to send more data
+ * until it completes as there is a chance nothing is listening and a lengthy timeout could occur */
+ if (Endpoint_IsINReady())
{
- /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
- if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
- RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
+ /* Clear flush timer expiry flag */
+ TIFR0 |= (1 << TOV0);
+
+ /* Never send more than one bank size less one byte to the host at a time, so that we don't block
+ * while a Zero Length Packet (ZLP) to terminate the transfer is sent if the host isn't listening */
+ uint8_t BytesToSend = MIN(BufferCount, (CDC_TXRX_EPSIZE - 1));
+
+ /* Read bytes from the USART receive buffer into the USB IN endpoint */
+ while (BytesToSend--)
{
- break;
- }
+ /* Try to send the next byte of data to the host, abort if there is an error without dequeuing */
+ if (CDC_Device_SendByte(&VirtualSerial_CDC_Interface,
+ RingBuffer_Peek(&USARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
+ {
+ break;
+ }
- /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
- RingBuffer_Remove(&USARTtoUSB_Buffer);
+ /* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
+ RingBuffer_Remove(&USARTtoUSB_Buffer);
+ }
}
}