mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-26 09:36:13 +01:00
Prep last packet id
This commit is contained in:
parent
fae713eae7
commit
dd42390ae9
|
@ -127,10 +127,11 @@ volatile bool DCCWaveform::railcomActive=false; // switched on by user
|
|||
volatile bool DCCWaveform::railcomDebug=false; // switched on by user
|
||||
volatile bool DCCWaveform::railcomSampleWindow=false; // true during packet transmit
|
||||
volatile byte DCCWaveform::railcomCutoutCounter=0; // cyclic cutout
|
||||
volatile byte DCCWaveform::railcomLastAddressHigh=0;
|
||||
volatile byte DCCWaveform::railcomLastAddressLow=0;
|
||||
|
||||
bool DCCWaveform::setRailcom(bool on, bool debug) {
|
||||
if (on && railcomPossible) {
|
||||
// TODO check possible
|
||||
railcomActive=true;
|
||||
railcomDebug=debug;
|
||||
}
|
||||
|
@ -233,6 +234,12 @@ void DCCWaveform::promotePendingPacket() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Remember address bytes of last sent packet so that Railcom can
|
||||
// work out where the channel2 data came from.
|
||||
railcomLastAddressHigh=transmitPacket[0];
|
||||
railcomLastAddressLow =transmitPacket[1];
|
||||
|
||||
|
||||
if (packetPending) {
|
||||
// Copy pending packet to transmit packet
|
||||
// a fixed length memcpy is faster than a variable length loop for these small lengths
|
||||
|
|
|
@ -100,6 +100,14 @@ class DCCWaveform {
|
|||
railcomPossible=yes;
|
||||
if (!yes) setRailcom(false,false);
|
||||
};
|
||||
inline static uint16_t getRailcomLastLocoAddress() {
|
||||
// first 2 bits 00=short loco, 11=long loco , 01/10 = accessory
|
||||
byte addressType=railcomLastAddressHigh & 0xC0;
|
||||
if (addressType==0xC0) return ((railcomLastAddressHigh & 0x3f)<<8) | railcomLastAddressLow;
|
||||
if (addressType==0x00) return railcomLastAddressHigh & 0x3F;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
#ifndef ARDUINO_ARCH_ESP32
|
||||
volatile bool packetPending;
|
||||
|
@ -129,6 +137,7 @@ class DCCWaveform {
|
|||
static volatile bool railcomDebug; // switched on by user
|
||||
static volatile bool railcomSampleWindow; // when safe to sample
|
||||
static volatile byte railcomCutoutCounter; // incremented for each cutout
|
||||
static volatile byte railcomLastAddressHigh,railcomLastAddressLow;
|
||||
static bool cutoutNextTime; // railcom
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
static RMTChannel *rmtMainChannel;
|
||||
|
|
|
@ -58,7 +58,7 @@ class I2CRailcom : public IODevice {
|
|||
private:
|
||||
// SC16IS752 defines
|
||||
uint8_t _UART_CH=0x00; // channel 0 or 1 flips each loop if npins>1
|
||||
byte _inbuf[65];
|
||||
byte _inbuf[12];
|
||||
byte _outbuf[2];
|
||||
byte cutoutCounter[2];
|
||||
Railcom * _channelMonitors[2];
|
||||
|
@ -118,7 +118,7 @@ public:
|
|||
// Read incoming raw Railcom data, and process accordingly
|
||||
|
||||
auto inlength = UART_ReadRegister(REG_RXLV);
|
||||
if (inlength==0) return;
|
||||
|
||||
if (inlength> sizeof(_inbuf)) inlength=sizeof(_inbuf);
|
||||
_inbuf[0]=0;
|
||||
if (inlength>0) {
|
||||
|
|
60
Railcom.cpp
60
Railcom.cpp
|
@ -54,7 +54,7 @@
|
|||
#include "EXRAIL3.h"
|
||||
#include "DIAG.h"
|
||||
|
||||
//#define DIAG_I2CRailcom_data
|
||||
#define DIAG_I2CRailcom_data
|
||||
|
||||
|
||||
/** Table for 8-to-6 decoding of railcom data. This table can be indexed by the
|
||||
|
@ -135,6 +135,10 @@ const uint8_t HIGHFLASH decode[256] =
|
|||
RMOB_LOGON_ENABLE_FEEDBACK = 15,
|
||||
};
|
||||
|
||||
// each railcom block is represented by an instance of this class.
|
||||
// The blockvpin is the vpin associated with this block for the purposes of
|
||||
// a HAL driver for the railcom detection and the EXRAIL ONBLOCKENTER/ONBLOCKEXIT
|
||||
|
||||
Railcom::Railcom(uint16_t blockvpin) {
|
||||
haveHigh=false;
|
||||
haveLow=false;
|
||||
|
@ -143,23 +147,33 @@ Railcom::Railcom(uint16_t blockvpin) {
|
|||
vpin=blockvpin;
|
||||
}
|
||||
|
||||
/* returns -1: Call again next packet
|
||||
0: No loco on track
|
||||
>0: loco id
|
||||
*/
|
||||
void Railcom::process(uint8_t * inbound, uint8_t length) {
|
||||
|
||||
|
||||
#ifdef DIAG_I2CRailcom_data
|
||||
DIAG(F("Railcom %d RX FIFO Data, %d"), vpin,length);
|
||||
for (int i = 0; i < 2; i++){
|
||||
if (inbound[i]) DIAG(F("[0x%x]: 0x%x"), i, inbound[i]);
|
||||
static const char hexchars[]="0123456789ABCDEF";
|
||||
if (length>2) {
|
||||
Serial.print("R ");
|
||||
for (byte i=0;i<length;i++) {
|
||||
if (i==2) Serial.write(' ');
|
||||
Serial.write(hexchars[inbound[i]>>4]);
|
||||
Serial.write(hexchars[inbound[i]& 0x0F ]);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#endif
|
||||
if (length<2 || (inbound[0]==0 && inbound[1]==0)) {
|
||||
noData();
|
||||
return;
|
||||
}
|
||||
|
||||
auto v1=GETHIGHFLASH(decode,inbound[0]);
|
||||
auto v2=(length>2) ? GETHIGHFLASH(decode,inbound[1]):0x0;
|
||||
auto v2=(length>1) ? GETHIGHFLASH(decode,inbound[1]):INV;
|
||||
uint16_t packet=(v1<<6) | (v2 & 0x3f);
|
||||
// packet is 12 bits TTTTDDDDDDDD
|
||||
auto type=packet>>8;
|
||||
auto data= packet & 0xFF;
|
||||
byte type=(packet>>8) & 0x0F;
|
||||
byte data= packet & 0xFF;
|
||||
if (type==RMOB_ADRHIGH) {
|
||||
holdoverHigh=data;
|
||||
haveHigh=true;
|
||||
|
@ -174,16 +188,7 @@ void Railcom::process(uint8_t * inbound, uint8_t length) {
|
|||
return; /* ignore*/
|
||||
}
|
||||
else {
|
||||
if (packetsWithNoData>MAX_WAIT_FOR_GLITCH) {
|
||||
// treat as no loco
|
||||
haveHigh=false;
|
||||
haveLow=false;
|
||||
// Previous loco (if any) is exiting block
|
||||
blockEvent(false);
|
||||
locoOnTrack=0;
|
||||
return ;
|
||||
}
|
||||
packetsWithNoData++;
|
||||
noData();
|
||||
return; // need more data
|
||||
}
|
||||
if (haveHigh && haveLow) {
|
||||
|
@ -202,3 +207,16 @@ void Railcom::blockEvent(bool entering) {
|
|||
if (locoOnTrack) RMFT3::blockEvent(vpin,locoOnTrack,entering);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Railcom::noData() {
|
||||
if (packetsWithNoData>MAX_WAIT_FOR_GLITCH) return;
|
||||
if (packetsWithNoData==MAX_WAIT_FOR_GLITCH) {
|
||||
// treat as no loco
|
||||
haveHigh=false;
|
||||
haveLow=false;
|
||||
// Previous loco (if any) is exiting block
|
||||
blockEvent(false);
|
||||
locoOnTrack=0;
|
||||
}
|
||||
packetsWithNoData++;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user