mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-01-30 14:13:07 +01:00
pendingPacket overwrite protection busy wait test
This commit is contained in:
parent
0476b9c1d8
commit
14cc2c71c7
2
DCC.cpp
2
DCC.cpp
@ -309,6 +309,7 @@ void DCC::setAccessory(int address, byte port, bool gate, byte onoff /*= 2*/) {
|
|||||||
b[0] = address % 64 + 128;
|
b[0] = address % 64 + 128;
|
||||||
b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
|
b[1] = ((((address / 64) % 8) << 4) + (port % 4 << 1) + gate % 2) ^ 0xF8;
|
||||||
if (onoff != 0) {
|
if (onoff != 0) {
|
||||||
|
DIAG(F("DCC::setAccessory(%d,%d,%d) ON"), address, port, gate);
|
||||||
DCCWaveform::mainTrack.schedulePacket(b, 2, 3); // Repeat on packet three times
|
DCCWaveform::mainTrack.schedulePacket(b, 2, 3); // Repeat on packet three times
|
||||||
#if defined(EXRAIL_ACTIVE)
|
#if defined(EXRAIL_ACTIVE)
|
||||||
RMFT2::activateEvent(address<<2|port,gate);
|
RMFT2::activateEvent(address<<2|port,gate);
|
||||||
@ -316,6 +317,7 @@ void DCC::setAccessory(int address, byte port, bool gate, byte onoff /*= 2*/) {
|
|||||||
}
|
}
|
||||||
if (onoff != 1) {
|
if (onoff != 1) {
|
||||||
b[1] &= ~0x08; // set C to 0
|
b[1] &= ~0x08; // set C to 0
|
||||||
|
DIAG(F("DCC::setAccessory(%d,%d,%d) OFF"), address, port, gate);
|
||||||
DCCWaveform::mainTrack.schedulePacket(b, 2, 3); // Repeat off packet three times
|
DCCWaveform::mainTrack.schedulePacket(b, 2, 3); // Repeat off packet three times
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
DCCRMT.cpp
28
DCCRMT.cpp
@ -86,6 +86,14 @@ void setDCCBit0Long(rmt_item32_t* item) {
|
|||||||
item->duration1 = DCC_0_HALFPERIOD + DCC_0_HALFPERIOD/10;
|
item->duration1 = DCC_0_HALFPERIOD + DCC_0_HALFPERIOD/10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// special short one to trigger scope
|
||||||
|
void setDCCBit1Short(rmt_item32_t* item) {
|
||||||
|
item->level0 = 1;
|
||||||
|
item->duration0 = DCC_1_HALFPERIOD/2;
|
||||||
|
item->level1 = 0;
|
||||||
|
item->duration1 = DCC_1_HALFPERIOD/2;
|
||||||
|
}
|
||||||
|
|
||||||
void setEOT(rmt_item32_t* item) {
|
void setEOT(rmt_item32_t* item) {
|
||||||
item->val = 0;
|
item->val = 0;
|
||||||
}
|
}
|
||||||
@ -135,11 +143,17 @@ RMTChannel::RMTChannel(pinpair pins, bool isMain) {
|
|||||||
// preamble
|
// preamble
|
||||||
preambleLen = plen+2; // plen 1 bits, one 0 bit and one EOF marker
|
preambleLen = plen+2; // plen 1 bits, one 0 bit and one EOF marker
|
||||||
preamble = (rmt_item32_t*)malloc(preambleLen*sizeof(rmt_item32_t));
|
preamble = (rmt_item32_t*)malloc(preambleLen*sizeof(rmt_item32_t));
|
||||||
for (byte n=0; n<plen; n++)
|
|
||||||
setDCCBit1(preamble + n); // preamble bits
|
|
||||||
#ifdef SCOPE
|
#ifdef SCOPE
|
||||||
|
for (byte n=0; n<plen; n++) {
|
||||||
|
if (n == 0)
|
||||||
|
setDCCBit1Short(preamble + n); // start of preamble 1 bit short version
|
||||||
|
else
|
||||||
|
setDCCBit1(preamble + n);
|
||||||
|
}
|
||||||
setDCCBit0Long(preamble + plen); // start of packet 0 bit long version
|
setDCCBit0Long(preamble + plen); // start of packet 0 bit long version
|
||||||
#else
|
#else
|
||||||
|
for (byte n=0; n<plen; n++) {
|
||||||
|
setDCCBit1(preamble + n); // preamble bits
|
||||||
setDCCBit0(preamble + plen); // start of packet 0 bit normal version
|
setDCCBit0(preamble + plen); // start of packet 0 bit normal version
|
||||||
#endif
|
#endif
|
||||||
setEOT(preamble + plen + 1); // EOT marker
|
setEOT(preamble + plen + 1); // EOT marker
|
||||||
@ -204,6 +218,7 @@ void RMTChannel::RMTprefill() {
|
|||||||
const byte transmitMask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
const byte transmitMask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||||
|
|
||||||
int RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCount=0) {
|
int RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCount=0) {
|
||||||
|
int ret = 0;
|
||||||
//int RMTChannel::RMTfillData(dccPacket packet) {
|
//int RMTChannel::RMTfillData(dccPacket packet) {
|
||||||
// dataReady: Signals to then interrupt routine. It is set when
|
// dataReady: Signals to then interrupt routine. It is set when
|
||||||
// we have data in the channel buffer which can be copied out
|
// we have data in the channel buffer which can be copied out
|
||||||
@ -211,9 +226,14 @@ int RMTChannel::RMTfillData(const byte buffer[], byte byteCount, byte repeatCoun
|
|||||||
// the caller of this function if the data has been sent enough
|
// the caller of this function if the data has been sent enough
|
||||||
// times (0 to 3 means 1 to 4 times in total).
|
// times (0 to 3 means 1 to 4 times in total).
|
||||||
if (dataRepeat > 0) // we have still old work to do
|
if (dataRepeat > 0) // we have still old work to do
|
||||||
return dataRepeat;
|
ret = dataRepeat;
|
||||||
if (dataReady == true) // the packet is not copied out yet
|
if (dataReady == true) // the packet is not copied out yet
|
||||||
return 1000;
|
ret = 1000;
|
||||||
|
if (buffer[0] == 129) {
|
||||||
|
DIAG(F("RMTfillData 129 %d %d"), buffer[1], ret);
|
||||||
|
}
|
||||||
|
if (ret > 0)
|
||||||
|
return ret;
|
||||||
if (DATA_LEN(byteCount) > maxDataLen) { // this would overun our allocated memory for data
|
if (DATA_LEN(byteCount) > maxDataLen) { // this would overun our allocated memory for data
|
||||||
DIAG(F("Can not convert DCC bytes # %d to DCC bits %d, buffer too small"), byteCount, maxDataLen);
|
DIAG(F("Can not convert DCC bytes # %d to DCC bits %d, buffer too small"), byteCount, maxDataLen);
|
||||||
return -1; // something very broken, can not convert packet
|
return -1; // something very broken, can not convert packet
|
||||||
|
7
DCCRMT.h
7
DCCRMT.h
@ -39,6 +39,13 @@ class RMTChannel {
|
|||||||
void RMTprefill();
|
void RMTprefill();
|
||||||
//int RMTfillData(dccPacket packet);
|
//int RMTfillData(dccPacket packet);
|
||||||
int RMTfillData(const byte buffer[], byte byteCount, byte repeatCount);
|
int RMTfillData(const byte buffer[], byte byteCount, byte repeatCount);
|
||||||
|
inline void waitForDataCopy() {
|
||||||
|
while(1) {
|
||||||
|
if (dataReady == false)
|
||||||
|
break;
|
||||||
|
//DIAG(F("%d %d"), dataReady, dataRepeat);
|
||||||
|
} //do nothing and wait for interrupt to happen
|
||||||
|
};
|
||||||
inline bool busy() {
|
inline bool busy() {
|
||||||
if (dataRepeat > 0) // we have still old work to do
|
if (dataRepeat > 0) // we have still old work to do
|
||||||
return true;
|
return true;
|
||||||
|
@ -280,6 +280,13 @@ void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repea
|
|||||||
if (byteCount > MAX_PACKET_SIZE) return; // allow for chksum
|
if (byteCount > MAX_PACKET_SIZE) return; // allow for chksum
|
||||||
|
|
||||||
byte checksum = 0;
|
byte checksum = 0;
|
||||||
|
if(isMainTrack) {
|
||||||
|
if (rmtMainChannel != NULL)
|
||||||
|
rmtMainChannel->waitForDataCopy();
|
||||||
|
} else {
|
||||||
|
if (rmtProgChannel != NULL)
|
||||||
|
rmtProgChannel->waitForDataCopy();
|
||||||
|
}
|
||||||
for (byte b = 0; b < byteCount; b++) {
|
for (byte b = 0; b < byteCount; b++) {
|
||||||
checksum ^= buffer[b];
|
checksum ^= buffer[b];
|
||||||
pendingPacket[b] = buffer[b];
|
pendingPacket[b] = buffer[b];
|
||||||
|
@ -1 +1 @@
|
|||||||
#define GITHUB_SHA "c389fe9"
|
#define GITHUB_SHA "master-packetloss-202501161204Z"
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
#define VERSION "5.4.0"
|
#define VERSION "5.4.X"
|
||||||
|
// 5.4.X - bugfix branch
|
||||||
// 5.4.0 - New version on master
|
// 5.4.0 - New version on master
|
||||||
// 5.2.96 - EXRAIL additions XFWD() and XREV()
|
// 5.2.96 - EXRAIL additions XFWD() and XREV()
|
||||||
// 5.2.95 - Release candidate for 5.4
|
// 5.2.95 - Release candidate for 5.4
|
||||||
|
Loading…
Reference in New Issue
Block a user