From 79742c5d24929442175953c796a1834e45a93d0d Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 26 May 2010 06:59:55 +0000 Subject: [PATCH] Make software USART used in the XPLAINBridge project directly check and store into the ring buffers, rather than polling from the main program loop to avoid added latency. --- .../XPLAINBridge/Lib/LightweightRingBuff.h | 13 ++-- Projects/XPLAINBridge/Lib/SoftUART.c | 61 ++++++++----------- Projects/XPLAINBridge/Lib/SoftUART.h | 20 +----- Projects/XPLAINBridge/XPLAINBridge.c | 12 +--- Projects/XPLAINBridge/XPLAINBridge.h | 4 +- 5 files changed, 42 insertions(+), 68 deletions(-) diff --git a/Projects/XPLAINBridge/Lib/LightweightRingBuff.h b/Projects/XPLAINBridge/Lib/LightweightRingBuff.h index 16e890c072..31430ddd48 100644 --- a/Projects/XPLAINBridge/Lib/LightweightRingBuff.h +++ b/Projects/XPLAINBridge/Lib/LightweightRingBuff.h @@ -53,13 +53,15 @@ RingBuff_Data_t Buffer[BUFFER_SIZE]; RingBuff_Data_t* In; RingBuff_Data_t* Out; + uint8_t Count; } RingBuff_t; /* Inline Functions: */ static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer) { Buffer->In = Buffer->Buffer; - Buffer->Out = Buffer->Buffer; + Buffer->Out = Buffer->Buffer; + Buffer->Count = 0; } static inline void RingBuffer_Insert(RingBuff_t* const Buffer, RingBuff_Data_t Data) @@ -68,6 +70,8 @@ if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) Buffer->In = Buffer->Buffer; + + Buffer->Count++; } static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer) @@ -77,12 +81,9 @@ if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE]) Buffer->Out = Buffer->Buffer; - return Data; - } + Buffer->Count--; - static inline bool RingBuffer_Empty(RingBuff_t* const Buffer) - { - return (Buffer->In == Buffer->Out); + return Data; } #endif diff --git a/Projects/XPLAINBridge/Lib/SoftUART.c b/Projects/XPLAINBridge/Lib/SoftUART.c index 5e589f3d74..18d5c01bd8 100644 --- a/Projects/XPLAINBridge/Lib/SoftUART.c +++ b/Projects/XPLAINBridge/Lib/SoftUART.c @@ -30,27 +30,16 @@ this software. */ +/** \file + * + * Software UART for both data transmission and reception. This + * code continuously monitors the ring buffers set up by the main + * project source file and reads/writes data as it becomes available. + */ + #include "SoftUART.h" -volatile bool srx_done; -volatile uint8_t stx_count; -static uint8_t srx_data, srx_mask, srx_tmp, stx_data; - -void SoftUART_TxByte(uint8_t Byte) -{ - while (stx_count); - - stx_data = ~Byte; - stx_count = 10; -} - -uint8_t SoftUART_RxByte(void) -{ - while (!(srx_done)); - srx_done = false; - - return srx_data; -} +static uint8_t TX_BitsRemaining, TX_Data, RX_BitMask, RX_Data; void SoftUART_Init(void) { @@ -61,8 +50,7 @@ void SoftUART_Init(void) EICRA = (1 << ISC01); // -ve edge EIMSK = (1 << INT0); // enable INT0 interrupt - stx_count = 0; // nothing to send - srx_done = false; // nothing received + TX_BitsRemaining = 0; // nothing to send STXPORT |= (1 << STX); // TX output STXDDR |= (1 << STX); // TX output SRXPORT |= (1 << SRX); // pullup on INT0 @@ -73,8 +61,8 @@ ISR(INT0_vect) { OCR2A = TCNT2 + (BIT_TIME / 8 * 3 / 2); // scan 1.5 bits after start - srx_tmp = 0; // clear bit storage - srx_mask = 1; // bit mask + RX_Data = 0; // clear bit storage + RX_BitMask = (1 << 0); // bit mask TIFR2 = (1 << OCF2A); // clear pending interrupt @@ -88,19 +76,19 @@ ISR(INT0_vect) /* ISR to manage the reception of bits to the transmitter. */ ISR(TIMER2_COMPA_vect) { - if (srx_mask) + if (RX_BitMask) { if (SRXPIN & (1 << SRX)) - srx_tmp |= srx_mask; + RX_Data |= RX_BitMask; - srx_mask <<= 1; + RX_BitMask <<= 1; OCR2A += BIT_TIME / 8; // next bit slice } else { - srx_done = true; // mark rx data valid - srx_data = srx_tmp; // store rx data + RingBuffer_Insert(&UARTtoUSB_Buffer, RX_Data); + TIMSK2 = (1 << OCIE2B); // enable tx and wait for start EIMSK |= (1 << INT0); // enable START irq EIFR = (1 << INTF0); // clear any pending @@ -112,20 +100,25 @@ ISR(TIMER2_COMPB_vect) { OCR2B += BIT_TIME / 8; // next bit slice - if (stx_count) + if (TX_BitsRemaining) { - if (--stx_count != 9) // no start bit + if (--TX_BitsRemaining != 9) // no start bit { - if (!(stx_data & 1)) // test inverted data - TCCR2A = (1 << COM2B1) | (1 << COM2B0); - else + if (TX_Data & (1 << 0)) // test inverted data TCCR2A = (1 << COM2B1); + else + TCCR2A = (1 << COM2B1) | (1 << COM2B0); - stx_data >>= 1; // shift zero in from left + TX_Data >>= 1; // shift zero in from left } else { TCCR2A = (1 << COM2B1); // START bit } } + else if (USBtoUART_Buffer.Count) + { + TX_Data = ~RingBuffer_Remove(&USBtoUART_Buffer); + TX_BitsRemaining = 10; + } } diff --git a/Projects/XPLAINBridge/Lib/SoftUART.h b/Projects/XPLAINBridge/Lib/SoftUART.h index 416490d8d2..e54d4a9ae2 100644 --- a/Projects/XPLAINBridge/Lib/SoftUART.h +++ b/Projects/XPLAINBridge/Lib/SoftUART.h @@ -37,6 +37,9 @@ #include #include #include + + #include "../XPLAINBridge.h" + #include "LightweightRingBuff.h" /* Macros: */ #define BAUD 9600 @@ -50,24 +53,7 @@ #define STXPORT PORTD #define STXDDR DDRD - /* External Variables: */ - extern volatile bool srx_done; - extern volatile uint8_t stx_count; - - /* Inline Functions: */ - static inline bool SoftUART_IsReady(void) - { - return !(stx_count); - } - - static inline bool SoftUART_IsReceived(void) - { - return srx_done; - } - /* Function Prototypes: */ - void SoftUART_TxByte(uint8_t c); - uint8_t SoftUART_RxByte(void); void SoftUART_Init(void); #endif \ No newline at end of file diff --git a/Projects/XPLAINBridge/XPLAINBridge.c b/Projects/XPLAINBridge/XPLAINBridge.c index 5798c21a5c..d92e2b4936 100644 --- a/Projects/XPLAINBridge/XPLAINBridge.c +++ b/Projects/XPLAINBridge/XPLAINBridge.c @@ -125,17 +125,9 @@ void USARTBridge_Task(void) RingBuffer_Insert(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)); /* Read bytes from the UART receive buffer into the USB IN endpoint */ - if (!(RingBuffer_Empty(&UARTtoUSB_Buffer))) + if (UARTtoUSB_Buffer.Count) CDC_Device_SendByte(&VirtualSerial_CDC_Interface, RingBuffer_Remove(&UARTtoUSB_Buffer)); - - /* Load bytes from the UART transmit buffer into the UART */ - if (!(RingBuffer_Empty(&USBtoUART_Buffer)) && SoftUART_IsReady()) - SoftUART_TxByte(RingBuffer_Remove(&USBtoUART_Buffer)); - - /* Load bytes from the UART into the UART receive buffer */ - if (SoftUART_IsReceived()) - RingBuffer_Insert(&UARTtoUSB_Buffer, SoftUART_RxByte()); - + CDC_Device_USBTask(&VirtualSerial_CDC_Interface); } diff --git a/Projects/XPLAINBridge/XPLAINBridge.h b/Projects/XPLAINBridge/XPLAINBridge.h index ddb5b0e0cc..72e90463d3 100644 --- a/Projects/XPLAINBridge/XPLAINBridge.h +++ b/Projects/XPLAINBridge/XPLAINBridge.h @@ -77,7 +77,9 @@ #define MODE_PDI_PROGRAMMER true /* External Variables: */ - extern bool CurrentFirmwareMode; + extern bool CurrentFirmwareMode; + extern RingBuff_t UARTtoUSB_Buffer; + extern RingBuff_t USBtoUART_Buffer; /* Function Prototypes: */ void SetupHardware(void);