Fixed possible lost data in the XPLAINBridge, USBtoSerial and Benito projects when the host exceeds the packet timeout period on received packets as set by USB_STREAM_TIMEOUT_MS (thanks to Justin Rajewski).

pull/1469/head
Dean Camera 14 years ago
parent b67f9f3669
commit 46677b4589

@ -31,6 +31,8 @@
* - Fixed Benito project discarding incoming data from the USB virtual serial port when the USART is busy * - Fixed Benito project discarding incoming data from the USB virtual serial port when the USART is busy
* - Fixed broken DFU bootloader, added XPLAIN support for bootloader start when XCK jumpered to ground * - Fixed broken DFU bootloader, added XPLAIN support for bootloader start when XCK jumpered to ground
* - Fixed broken HID_REQ_GetReport request handler in the Low Level GenericHID demo * - Fixed broken HID_REQ_GetReport request handler in the Low Level GenericHID demo
* - Fixed possible lost data in the XPLAINBridge, USBtoSerial and Benito projects when the host exceeds the packet
* timeout period on received packets as set by USB_STREAM_TIMEOUT_MS (thanks to Justin Rajewski)
* *
* \section Sec_ChangeLog101122 Version 101122 * \section Sec_ChangeLog101122 Version 101122
* <b>New:</b> * <b>New:</b>

@ -37,7 +37,7 @@
#include "Benito.h" #include "Benito.h"
/** Circular buffer to hold data from the serial port before it is sent to the host. */ /** Circular buffer to hold data from the serial port before it is sent to the host. */
RingBuff_t Tx_Buffer; RingBuff_t USARTtoUSB_Buffer;
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
volatile struct volatile struct
@ -85,7 +85,7 @@ int main(void)
{ {
SetupHardware(); SetupHardware();
RingBuffer_InitBuffer(&Tx_Buffer); RingBuffer_InitBuffer(&USARTtoUSB_Buffer);
sei(); sei();
@ -126,14 +126,24 @@ int main(void)
LEDs_TurnOffLEDs(LEDMASK_RX); LEDs_TurnOffLEDs(LEDMASK_RX);
/* Check if the receive buffer flush period has expired */ /* Check if the receive buffer flush period has expired */
RingBuff_Count_t BufferCount = RingBuffer_GetCount(&Tx_Buffer); RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);
if (!(--FlushPeriodRemaining) || (BufferCount > 200)) if (!(--FlushPeriodRemaining) || (BufferCount > 200))
{ {
/* Echo bytes from the target to the host via the virtual serial port */ /* Echo bytes from the target to the host via the virtual serial port */
if (BufferCount) if (BufferCount)
{ {
while (BufferCount--) while (BufferCount--)
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&Tx_Buffer)); {
/* 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);
}
LEDs_TurnOnLEDs(LEDMASK_RX); LEDs_TurnOnLEDs(LEDMASK_RX);
PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS; PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
@ -263,7 +273,7 @@ ISR(USART1_RX_vect, ISR_BLOCK)
uint8_t ReceivedByte = UDR1; uint8_t ReceivedByte = UDR1;
if (USB_DeviceState == DEVICE_STATE_Configured) if (USB_DeviceState == DEVICE_STATE_Configured)
RingBuffer_Insert(&Tx_Buffer, ReceivedByte); RingBuffer_Insert(&USARTtoUSB_Buffer, ReceivedByte);
} }
/** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event. /** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event.

@ -100,7 +100,17 @@ int main(void)
/* Read bytes from the USART receive buffer into the USB IN endpoint */ /* Read bytes from the USART receive buffer into the USB IN endpoint */
while (BufferCount--) while (BufferCount--)
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&USARTtoUSB_Buffer)); {
/* 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);
}
} }
/* Load the next byte from the USART transmit buffer into the USART */ /* Load the next byte from the USART transmit buffer into the USART */

@ -136,9 +136,19 @@ void UARTBridge_Task(void)
/* Clear flush timer expiry flag */ /* Clear flush timer expiry flag */
TIFR0 |= (1 << TOV0); TIFR0 |= (1 << TOV0);
/* Read bytes from the UART receive buffer into the USB IN endpoint */ /* Read bytes from the USART receive buffer into the USB IN endpoint */
while (BufferCount--) while (BufferCount--)
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&UARTtoUSB_Buffer)); {
/* 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(&UARTtoUSB_Buffer)) != ENDPOINT_READYWAIT_NoError)
{
break;
}
/* Dequeue the already sent byte from the buffer now we have confirmed that no transmission error occurred */
RingBuffer_Remove(&UARTtoUSB_Buffer);
}
} }
CDC_Device_USBTask(&VirtualSerial_CDC_Interface); CDC_Device_USBTask(&VirtualSerial_CDC_Interface);

Loading…
Cancel
Save