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.

pull/1469/head
Dean Camera 15 years ago
parent 9b29d1dc50
commit 79742c5d24

@ -53,6 +53,7 @@
RingBuff_Data_t Buffer[BUFFER_SIZE];
RingBuff_Data_t* In;
RingBuff_Data_t* Out;
uint8_t Count;
} RingBuff_t;
/* Inline Functions: */
@ -60,6 +61,7 @@
{
Buffer->In = 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

@ -30,27 +30,16 @@
this software.
*/
#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);
/** \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.
*/
stx_data = ~Byte;
stx_count = 10;
}
uint8_t SoftUART_RxByte(void)
{
while (!(srx_done));
srx_done = false;
#include "SoftUART.h"
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;
}
}

@ -38,6 +38,9 @@
#include <avr/interrupt.h>
#include <stdbool.h>
#include "../XPLAINBridge.h"
#include "LightweightRingBuff.h"
/* Macros: */
#define BAUD 9600
#define BIT_TIME (uint16_t)((F_CPU + (BAUD / 2)) / BAUD)
@ -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

@ -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);
}

@ -78,6 +78,8 @@
/* External Variables: */
extern bool CurrentFirmwareMode;
extern RingBuff_t UARTtoUSB_Buffer;
extern RingBuff_t USBtoUART_Buffer;
/* Function Prototypes: */
void SetupHardware(void);

Loading…
Cancel
Save