Commit 79742c5d authored by Dean Camera's avatar Dean Camera
Browse files

Make software USART used in the XPLAINBridge project directly check and store...

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.
parent 9b29d1dc
...@@ -53,13 +53,15 @@ ...@@ -53,13 +53,15 @@
RingBuff_Data_t Buffer[BUFFER_SIZE]; RingBuff_Data_t Buffer[BUFFER_SIZE];
RingBuff_Data_t* In; RingBuff_Data_t* In;
RingBuff_Data_t* Out; RingBuff_Data_t* Out;
uint8_t Count;
} RingBuff_t; } RingBuff_t;
/* Inline Functions: */ /* Inline Functions: */
static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer) static inline void RingBuffer_InitBuffer(RingBuff_t* const Buffer)
{ {
Buffer->In = Buffer->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) static inline void RingBuffer_Insert(RingBuff_t* const Buffer, RingBuff_Data_t Data)
...@@ -68,6 +70,8 @@ ...@@ -68,6 +70,8 @@
if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE]) if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE])
Buffer->In = Buffer->Buffer; Buffer->In = Buffer->Buffer;
Buffer->Count++;
} }
static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer) static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer)
...@@ -77,12 +81,9 @@ ...@@ -77,12 +81,9 @@
if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE]) if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE])
Buffer->Out = Buffer->Buffer; Buffer->Out = Buffer->Buffer;
return Data; Buffer->Count--;
}
static inline bool RingBuffer_Empty(RingBuff_t* const Buffer) return Data;
{
return (Buffer->In == Buffer->Out);
} }
#endif #endif
...@@ -30,27 +30,16 @@ ...@@ -30,27 +30,16 @@
this software. this software.
*/ */
#include "SoftUART.h" /** \file
*
volatile bool srx_done; * Software UART for both data transmission and reception. This
volatile uint8_t stx_count; * code continuously monitors the ring buffers set up by the main
static uint8_t srx_data, srx_mask, srx_tmp, stx_data; * project source file and reads/writes data as it becomes available.
*/
void SoftUART_TxByte(uint8_t Byte)
{
while (stx_count);
stx_data = ~Byte; #include "SoftUART.h"
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) void SoftUART_Init(void)
{ {
...@@ -61,8 +50,7 @@ void SoftUART_Init(void) ...@@ -61,8 +50,7 @@ void SoftUART_Init(void)
EICRA = (1 << ISC01); // -ve edge EICRA = (1 << ISC01); // -ve edge
EIMSK = (1 << INT0); // enable INT0 interrupt EIMSK = (1 << INT0); // enable INT0 interrupt
stx_count = 0; // nothing to send TX_BitsRemaining = 0; // nothing to send
srx_done = false; // nothing received
STXPORT |= (1 << STX); // TX output STXPORT |= (1 << STX); // TX output
STXDDR |= (1 << STX); // TX output STXDDR |= (1 << STX); // TX output
SRXPORT |= (1 << SRX); // pullup on INT0 SRXPORT |= (1 << SRX); // pullup on INT0
...@@ -73,8 +61,8 @@ ISR(INT0_vect) ...@@ -73,8 +61,8 @@ ISR(INT0_vect)
{ {
OCR2A = TCNT2 + (BIT_TIME / 8 * 3 / 2); // scan 1.5 bits after start OCR2A = TCNT2 + (BIT_TIME / 8 * 3 / 2); // scan 1.5 bits after start
srx_tmp = 0; // clear bit storage RX_Data = 0; // clear bit storage
srx_mask = 1; // bit mask RX_BitMask = (1 << 0); // bit mask
TIFR2 = (1 << OCF2A); // clear pending interrupt TIFR2 = (1 << OCF2A); // clear pending interrupt
...@@ -88,19 +76,19 @@ ISR(INT0_vect) ...@@ -88,19 +76,19 @@ ISR(INT0_vect)
/* ISR to manage the reception of bits to the transmitter. */ /* ISR to manage the reception of bits to the transmitter. */
ISR(TIMER2_COMPA_vect) ISR(TIMER2_COMPA_vect)
{ {
if (srx_mask) if (RX_BitMask)
{ {
if (SRXPIN & (1 << SRX)) 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 OCR2A += BIT_TIME / 8; // next bit slice
} }
else else
{ {
srx_done = true; // mark rx data valid RingBuffer_Insert(&UARTtoUSB_Buffer, RX_Data);
srx_data = srx_tmp; // store rx data
TIMSK2 = (1 << OCIE2B); // enable tx and wait for start TIMSK2 = (1 << OCIE2B); // enable tx and wait for start
EIMSK |= (1 << INT0); // enable START irq EIMSK |= (1 << INT0); // enable START irq
EIFR = (1 << INTF0); // clear any pending EIFR = (1 << INTF0); // clear any pending
...@@ -112,20 +100,25 @@ ISR(TIMER2_COMPB_vect) ...@@ -112,20 +100,25 @@ ISR(TIMER2_COMPB_vect)
{ {
OCR2B += BIT_TIME / 8; // next bit slice 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 if (TX_Data & (1 << 0)) // test inverted data
TCCR2A = (1 << COM2B1) | (1 << COM2B0);
else
TCCR2A = (1 << COM2B1); 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 else
{ {
TCCR2A = (1 << COM2B1); // START bit TCCR2A = (1 << COM2B1); // START bit
} }
} }
else if (USBtoUART_Buffer.Count)
{
TX_Data = ~RingBuffer_Remove(&USBtoUART_Buffer);
TX_BitsRemaining = 10;
}
} }
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdbool.h> #include <stdbool.h>
#include "../XPLAINBridge.h"
#include "LightweightRingBuff.h"
/* Macros: */ /* Macros: */
#define BAUD 9600 #define BAUD 9600
...@@ -50,24 +53,7 @@ ...@@ -50,24 +53,7 @@
#define STXPORT PORTD #define STXPORT PORTD
#define STXDDR DDRD #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: */ /* Function Prototypes: */
void SoftUART_TxByte(uint8_t c);
uint8_t SoftUART_RxByte(void);
void SoftUART_Init(void); void SoftUART_Init(void);
#endif #endif
\ No newline at end of file
...@@ -125,17 +125,9 @@ void USARTBridge_Task(void) ...@@ -125,17 +125,9 @@ void USARTBridge_Task(void)
RingBuffer_Insert(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface)); RingBuffer_Insert(&USBtoUART_Buffer, CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));
/* Read bytes from the UART receive buffer into the USB IN endpoint */ /* 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)); 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); CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
} }
......
...@@ -77,7 +77,9 @@ ...@@ -77,7 +77,9 @@
#define MODE_PDI_PROGRAMMER true #define MODE_PDI_PROGRAMMER true
/* External Variables: */ /* External Variables: */
extern bool CurrentFirmwareMode; extern bool CurrentFirmwareMode;
extern RingBuff_t UARTtoUSB_Buffer;
extern RingBuff_t USBtoUART_Buffer;
/* Function Prototypes: */ /* Function Prototypes: */
void SetupHardware(void); void SetupHardware(void);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment