From 4c9425c0d52fbfe45f6697d9124b022842049af6 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Sun, 25 Jul 2010 11:59:55 +0000
Subject: [PATCH] Added periodic flush timer to the Benito project. Alter the
 serial transmission code so that sent bytes do not block the remainder of the
 main program code from running.

---
 LUFA/ManPages/ChangeLog.txt   |  2 +-
 Projects/Benito/Benito.c      | 33 +++++++++++++++++++++------------
 Projects/Benito/Benito.txt    |  5 +++++
 Projects/Benito/Descriptors.h |  2 +-
 Projects/Benito/makefile      |  1 +
 5 files changed, 29 insertions(+), 14 deletions(-)

diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 423d7af74..c4f0f9401 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -32,7 +32,7 @@
   *  - Rewrote the implementation of the SwapEndian_16() and SwapEndian_32() functions so that they compile down in most instances to
   *    minimal loads and stores rather than complicated shifts
   *  - The software UART in the XPLAINBridge has been largely altered to try to improve upon its performance and reliability
-  *  - The USBtoSerial project now flushes received data via a flush timer, so that several bytes can be transmitted at once
+  *  - The USBtoSerial and Benito projects now flushes received data via a flush timer, so that several bytes can be transmitted at once
   *  - Removed the automated checking of event names in the demo, project and bootloader makefiles due to inconsistancies between the
   *    behaviour of the command line tools used to perform the check on each platform
   *  - Internal USB driver source files renamed and moved to ease future possible architecture ports
diff --git a/Projects/Benito/Benito.c b/Projects/Benito/Benito.c
index 32c663cb6..71b187bfb 100644
--- a/Projects/Benito/Benito.c
+++ b/Projects/Benito/Benito.c
@@ -51,6 +51,9 @@ volatile struct
 /** Previous state of the virtual DTR control line from the host */
 bool PreviousDTRState = false;
 
+/** Milliseconds remaining until the receive buffer is flushed to the USB host */
+uint8_t FlushPeriodRemaining = RECEIVE_BUFFER_FLUSH_MS;
+
 /** LUFA CDC Class driver interface configuration and state information. This structure is
  *  passed to all CDC Class driver functions, so that multiple instances of the same class
  *  within a device can be differentiated from one another.
@@ -89,23 +92,14 @@ int main(void)
 	for (;;)
 	{
 		/* Echo bytes from the host to the target via the hardware USART */
-		while (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface) > 0)
+		if (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface) && (UCSR1A & (1 << UDRE1)))
 		{
-			Serial_TxByte(CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));
+			UDR1 = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface);
 
 			LEDs_TurnOnLEDs(LEDMASK_TX);
 			PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;			
 		}
 		
-		/* Echo bytes from the target to the host via the virtual serial port */
-		while (Tx_Buffer.Count)
-		{
-			CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_AtomicRemove(&Tx_Buffer));
-
-			LEDs_TurnOnLEDs(LEDMASK_RX);
-			PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
-		}
-		
 		/* Check if the millisecond timer has elapsed */
 		if (TIFR0 & (1 << OCF0A))
 		{
@@ -131,6 +125,22 @@ int main(void)
 			if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
 			  LEDs_TurnOffLEDs(LEDMASK_RX);
 
+			/* Check if the receive buffer flush period has expired */
+			if (!(--FlushPeriodRemaining) || (Tx_Buffer.Count > 200))
+			{
+				/* Echo bytes from the target to the host via the virtual serial port */
+				if (Tx_Buffer.Count)
+				{
+					while (Tx_Buffer.Count)
+					  CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_AtomicRemove(&Tx_Buffer));
+
+					LEDs_TurnOnLEDs(LEDMASK_RX);
+					PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
+				}
+				
+				FlushPeriodRemaining = RECEIVE_BUFFER_FLUSH_MS;
+			}
+
 			/* Clear the millisecond timer CTC flag (cleared by writing logic one to the register) */
 			TIFR0 |= (1 << OCF0A);		
 		}
@@ -148,7 +158,6 @@ void SetupHardware(void)
 	wdt_disable();
 
 	/* Hardware Initialization */
-	Serial_Init(9600, false);
 	LEDs_Init();
 	USB_Init();
 
diff --git a/Projects/Benito/Benito.txt b/Projects/Benito/Benito.txt
index dc10cadf6..ab3098392 100644
--- a/Projects/Benito/Benito.txt
+++ b/Projects/Benito/Benito.txt
@@ -96,5 +96,10 @@
  *    <td>Makefile LUFA_OPTS</td>
  *    <td>Pulse length in milliseconds for the enumeration LED ping-poning between toggles.</td>
  *   </tr>
+ *   <tr>
+ *    <td>RECEIVE_BUFFER_FLUSH_MS</td>
+ *    <td>Makefile LUFA_OPTS</td>
+ *    <td>Period between flushings of received data buffer to the attached USB host.</td>
+ *   </tr>
  *  </table>
  */
diff --git a/Projects/Benito/Descriptors.h b/Projects/Benito/Descriptors.h
index 8012ebdde..a670563cf 100644
--- a/Projects/Benito/Descriptors.h
+++ b/Projects/Benito/Descriptors.h
@@ -56,7 +56,7 @@
 		#define CDC_NOTIFICATION_EPSIZE        8
 
 		/** Size in bytes of the CDC data IN and OUT endpoints. */
-		#define CDC_TXRX_EPSIZE                16	
+		#define CDC_TXRX_EPSIZE                16
 
 	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
diff --git a/Projects/Benito/makefile b/Projects/Benito/makefile
index c08f1557f..3e0311e89 100644
--- a/Projects/Benito/makefile
+++ b/Projects/Benito/makefile
@@ -128,6 +128,7 @@ LUFA_OPTS += -D AVR_RESET_LINE_MASK="(1 << 4)"
 LUFA_OPTS += -D AVR_RESET_PULSE_MS=10
 LUFA_OPTS += -D TX_RX_LED_PULSE_MS=30
 LUFA_OPTS += -D PING_PONG_LED_PULSE_MS=100
+LUFA_OPTS += -D RECEIVE_BUFFER_FLUSH_MS=20
 
 
 # Create the LUFA source path variables by including the LUFA root makefile
-- 
GitLab