Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RS485 Data Dropping #52

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions src/DcsBios.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "internal/ExportStreamListener.h"
#include "internal/PollingInput.h"
#include "internal/Protocol.h"
#include "internal/Protocol.cpp.inc" // Needs to be a .cpp.inc to allow DCSBIOS_INCOMING_DATA_BUFFER_SIZE
#include "internal/Addresses.h"


Expand Down
15 changes: 14 additions & 1 deletion src/internal/DcsBiosNgRS485Slave.cpp.inc
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ namespace DcsBios {
case RX_WAIT_DATA:
rxtx_len--;
if (rx_datatype == RXDATA_DCSBIOS_EXPORT) {
parser.processCharISR(c);
if (rxtx_len <= parser.incomingDataBuffer.availableForWrite()) {
parser.processCharISR(c);
} else {
last_rx_time = micros();
state = SYNC;
}
}
if (rxtx_len == 0) {
state = RX_WAIT_CHECKSUM;
Expand Down Expand Up @@ -240,6 +245,14 @@ namespace DcsBios {
void loop() {
PollingInput::pollInputs();
ExportStreamListener::loopAll();

// Process incoming data outside of ISR
#ifdef DCSBIOS_DEFER_RS485_PROCESSING
if (!parser.incomingDataBuffer.isEmpty()) {
unsigned char nextByte = parser.incomingDataBuffer.get();
parser.processChar(nextByte);
}
#endif
}
}
#endif
7 changes: 4 additions & 3 deletions src/internal/Protocol.cpp → src/internal/Protocol.cpp.inc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace DcsBios {
*/
void ProtocolParser::processCharISR(unsigned char c) {
incomingDataBuffer.put(c);

// For some reason RS485 slaves cannot process data here, while it works over USB. Perhaps due to the additonal overhead of the RS485 state machine? If DCSBIOS_RS485_SLAVE is defined, the processing is deferred to loop().
#ifndef DCSBIOS_DEFER_RS485_PROCESSING
if (processingData) return;

processingData = true;
Expand All @@ -31,10 +34,8 @@ namespace DcsBios {
unsigned char nextByte = incomingDataBuffer.get();
interrupts();
processChar(nextByte);
#ifdef DCSBIOS_RS485_SLAVE
noInterrupts();
#endif
}
#endif
}

void ProtocolParser::processChar(unsigned char c) {
Expand Down
7 changes: 6 additions & 1 deletion src/internal/Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#define DCSBIOS_STATE_DATA_LOW 5
#define DCSBIOS_STATE_DATA_HIGH 6

#ifndef DCSBIOS_INCOMING_DATA_BUFFER_SIZE
#define DCSBIOS_INCOMING_DATA_BUFFER_SIZE 64
#endif

#include "ExportStreamListener.h"
#include "RingBuffer.h"

Expand All @@ -23,9 +27,10 @@ namespace DcsBios {
volatile unsigned char sync_byte_count;

ExportStreamListener* startESL;
RingBuffer<64> incomingDataBuffer;
volatile bool processingData;
public:
RingBuffer<DCSBIOS_INCOMING_DATA_BUFFER_SIZE> incomingDataBuffer;

void processChar(unsigned char c);
void processCharISR(unsigned char c);
ProtocolParser();
Expand Down
1 change: 1 addition & 0 deletions src/internal/RingBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace DcsBios {
__attribute__((always_inline)) uint8_t get() { uint8_t ret = buffer[readpos]; readpos = ++readpos % SIZE; return ret; }
__attribute__((always_inline)) uint8_t getLength() { return (uint8_t)(writepos - readpos) % SIZE; }
__attribute__((always_inline)) void clear() { readpos = 0; writepos = 0; }
__attribute__((always_inline)) uint8_t availableForWrite() { return SIZE - getLength() - 1; }
};
}

Expand Down