Add EOT sentinel and fix race condition when copying rxbuf

This commit is contained in:
2024-10-19 16:00:05 +02:00
parent 84281a61f4
commit 343df15140

View File

@@ -14,21 +14,22 @@
static volatile bool txready; // Aligned with clock? static volatile bool txready; // Aligned with clock?
static volatile int rxstate; // Current decoder state static volatile int rxstate; // Current decoder state
static volatile byte rxbuf[128]; // Data buffer for decoder
static volatile byte * rxhead; // Write position for decoder
static volatile byte * rxtail; // End of decoder buffer
static volatile word edgecap; // Current edge capture time static volatile word edgecap; // Current edge capture time
static volatile word edgedir; // Current edge direction static volatile word edgedir; // Current edge direction
static volatile int lastbit; // Previously read logic value static volatile int lastbit; // Previously read logic value
static volatile word numsync; // Number of preamble bits read static volatile word numsync; // Number of preamble bits read
static volatile word numdata; // Number of data bits read static volatile word numdata; // Number of data bits read
static volatile bool needmid; // Expect short interval next static volatile bool needmid; // Expect short interval next
static volatile byte rxbuf[128]; // Data buffer for decoder
static volatile byte * rxhead; // Write position for decoder
static volatile byte * rxtail; // End of decoder buffer
static volatile bool rxdone; // Finished receiving data
static void SendByte(byte data); static void SendByte(byte data);
static void WaitPulse(void); static void WaitPulse(void);
static void HandleEdge(void); static void HandleEdge(void);
static void Synchronize(void); static void Synchronize(void);
static void ReadPayload(void); static void ReadDataBit(void);
static void ReadShortPeriod(void); static void ReadShortPeriod(void);
static void ReadLongPeriod(void); static void ReadLongPeriod(void);
static void WriteBit(int val); static void WriteBit(int val);
@@ -92,20 +93,25 @@ void RF_Transmit(const byte *data, int size)
while (head < tail) { while (head < tail) {
SendByte(*head++); SendByte(*head++);
} }
// EOT sentinel
SendByte(0x04);
} }
int RF_Receive(byte *data, int size) int RF_Receive(byte *data, int size)
{ {
int n = 0; int n = 0;
while (1) { cli();
if (n == size || n == (int) numdata) { if (rxdone) {
break; // Finished copying rxdone = false;
} while (n < size && n < (int) numdata) {
data[n] = rxbuf[n]; data[n] = rxbuf[n];
n++; n++;
} }
}
sei();
return n; return n;
} }
@@ -146,8 +152,8 @@ static void WaitPulse(void)
static void HandleEdge(void) static void HandleEdge(void)
{ {
if (edgedir != E_RISING) { if (rxdone || edgedir != E_RISING) {
return; // Wrong edge return; // Ignore this edge
} }
rxstate = S_SYNC; rxstate = S_SYNC;
@@ -164,15 +170,15 @@ static void Synchronize(void)
numsync++; numsync++;
if (numsync == 8) { if (numsync == 8) {
rxstate = S_DATA;
rxhead = rxbuf;
needmid = false;
numdata = 0; numdata = 0;
lastbit = 0; lastbit = 0;
needmid = false;
rxhead = rxbuf;
rxstate = S_DATA;
} }
} }
static void ReadPayload(void) static void ReadDataBit(void)
{ {
if (edgecap >= 75 && edgecap <= 175) { if (edgecap >= 75 && edgecap <= 175) {
ReadShortPeriod(); ReadShortPeriod();
@@ -222,7 +228,8 @@ static void WriteBit(int val)
int bit; int bit;
if (rxhead == rxtail) { if (rxhead == rxtail) {
return; // Discard rxstate = S_IDLE;
return;
} }
bit = numdata % 8; bit = numdata % 8;
@@ -232,6 +239,12 @@ static void WriteBit(int val)
*rxhead |= (val << (7 - bit)); *rxhead |= (val << (7 - bit));
if (bit == 7) { if (bit == 7) {
// Check for EOT sentinel
if (*rxhead == 0x04) {
numdata -= 8;
rxdone = true;
rxstate = S_IDLE;
}
rxhead++; rxhead++;
} }
} }
@@ -261,7 +274,7 @@ ISR(TIMER3_CAPT_vect)
} else if (rxstate == S_SYNC) { } else if (rxstate == S_SYNC) {
Synchronize(); Synchronize();
} else if (rxstate == S_DATA) { } else if (rxstate == S_DATA) {
ReadPayload(); ReadDataBit();
} }
} }
@@ -273,7 +286,7 @@ ISR(TIMER3_OVF_vect)
if (rxstate == S_SYNC) { if (rxstate == S_SYNC) {
Synchronize(); Synchronize();
} else if (rxstate == S_DATA) { } else if (rxstate == S_DATA) {
ReadPayload(); ReadDataBit();
} }
} }