mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 15:46:14 +01:00
detection happening!
This commit is contained in:
parent
7bd790dfbf
commit
a49cb95795
|
@ -77,6 +77,7 @@ void DCCWaveform::interruptHandler() {
|
|||
if (cutoutNextTime) {
|
||||
cutoutNextTime=false;
|
||||
railcomSampleWindow=false; // about to cutout, stop reading railcom data.
|
||||
railcomCutoutCounter++;
|
||||
DCCTimer::startRailcomTimer(9);
|
||||
}
|
||||
byte sigMain=signalTransform[mainTrack.state];
|
||||
|
@ -125,6 +126,7 @@ bool DCCWaveform::railcomPossible=false; // High accuracy only
|
|||
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
|
||||
|
||||
bool DCCWaveform::setRailcom(bool on, bool debug) {
|
||||
if (on && railcomPossible) {
|
||||
|
|
|
@ -87,6 +87,9 @@ class DCCWaveform {
|
|||
inline static bool isRailcom() {
|
||||
return railcomActive;
|
||||
};
|
||||
inline static byte getRailcomCutoutCounter() {
|
||||
return railcomCutoutCounter;
|
||||
};
|
||||
inline static bool isRailcomSampleWindow() {
|
||||
return railcomSampleWindow;
|
||||
};
|
||||
|
@ -125,6 +128,7 @@ class DCCWaveform {
|
|||
static volatile bool railcomActive; // switched on by user
|
||||
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 bool cutoutNextTime; // railcom
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
static RMTChannel *rmtMainChannel;
|
||||
|
|
|
@ -54,14 +54,15 @@
|
|||
|
||||
// Debug and diagnostic defines, enable too many will result in slowing the driver
|
||||
#define DIAG_I2CRailcom
|
||||
#define DIAG_I2CRailcom_data
|
||||
//#define DIAG_I2CRailcom_data
|
||||
|
||||
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 _outbuf[2];
|
||||
byte _outbuf[2];
|
||||
byte cutoutCounter[2];
|
||||
Railcom _channelMonitors[2];
|
||||
int16_t _locoInBlock[2];
|
||||
public:
|
||||
|
@ -87,7 +88,9 @@ public:
|
|||
DIAG(F("I2CRailcom: %s UART%S detected"),
|
||||
_I2CAddress.toString(), exists?F(""):F(" NOT"));
|
||||
if (!exists) return;
|
||||
|
||||
_locoInBlock[0]=0;
|
||||
_locoInBlock[1]=0;
|
||||
|
||||
_UART_CH=0;
|
||||
Init_SC16IS752(); // Initialize UART0
|
||||
if (_nPins>1) {
|
||||
|
@ -106,43 +109,47 @@ public:
|
|||
|
||||
// return if in cutout or cutout very soon.
|
||||
if (!DCCWaveform::isRailcomSampleWindow()) return;
|
||||
|
||||
|
||||
// IF we have 2 channels, flip channels each loop
|
||||
if (_nPins>1) _UART_CH=_UART_CH?0:1;
|
||||
|
||||
// have we read this cutout already?
|
||||
auto cut=DCCWaveform::getRailcomCutoutCounter();
|
||||
if (cutoutCounter[_UART_CH]==cut) return;
|
||||
cutoutCounter[_UART_CH]=cut;
|
||||
|
||||
// Read incoming raw Railcom data, and process accordingly
|
||||
|
||||
auto inlength = UART_ReadRegister(REG_RXLV);
|
||||
if (inlength==0) return;
|
||||
|
||||
#ifdef DIAG_I2CRailcom
|
||||
DIAG(F("Railcom: %s/%d RX Fifo length: %d"),_I2CAddress.toString(), _UART_CH, inlength);
|
||||
#endif
|
||||
|
||||
// Read data buffer from UART
|
||||
_outbuf[0]=(byte)(REG_RHR << 3 | _UART_CH << 1);
|
||||
I2CManager.read(_I2CAddress, _inbuf, inlength, _outbuf, 1);
|
||||
|
||||
if (inlength> sizeof(_inbuf)) inlength=sizeof(_inbuf);
|
||||
_inbuf[0]=0;
|
||||
if (inlength>0) {
|
||||
// Read data buffer from UART
|
||||
_outbuf[0]=(byte)(REG_RHR << 3 | _UART_CH << 1);
|
||||
I2CManager.read(_I2CAddress, _inbuf, inlength, _outbuf, 1);
|
||||
}
|
||||
// HK: Reset FIFO at end of read cycle
|
||||
UART_WriteRegister(REG_FCR, 0x07,false);
|
||||
//if (inlength<2) return;
|
||||
|
||||
#ifdef DIAG_I2CRailcom_data
|
||||
DIAG(F("Railcom %s/%d RX FIFO Data"), _I2CAddress.toString(), _UART_CH);
|
||||
DIAG(F("Railcom %s/%d RX FIFO Data, %d"), _I2CAddress.toString(), _UART_CH,inlength);
|
||||
for (int i = 0; i < inlength; i++){
|
||||
DIAG(F("[0x%x]: 0x%x"), i, _inbuf[i]);
|
||||
if (_inbuf[i])DIAG(F("[0x%x]: 0x%x"), i, _inbuf[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ask Railcom to interpret the channel1 loco
|
||||
auto locoid=_channelMonitors[_UART_CH].getChannel1Loco(_inbuf);
|
||||
#ifdef DIAG_I2CRailcom
|
||||
DIAG(F("Railcom Channel1=%d"), locoid);
|
||||
#endif
|
||||
if (locoid<0) return; // -1 indicates Railcom needs another packet
|
||||
|
||||
|
||||
// determine if loco in this block has changed
|
||||
auto prevLoco=_locoInBlock[_UART_CH];
|
||||
if (locoid==prevLoco) return;
|
||||
#ifdef DIAG_I2CRailcom
|
||||
DIAG(F("Railcom vpin %d was %d is %d "), _firstVpin+_UART_CH, prevLoco, locoid);
|
||||
#endif
|
||||
|
||||
// Previous loco (if any) is exiting block
|
||||
if (prevLoco) RMFT3::blockEvent(_firstVpin+_UART_CH,prevLoco,false);
|
||||
|
|
15
Railcom.cpp
15
Railcom.cpp
|
@ -133,6 +133,7 @@ const uint8_t HIGHFLASH decode[256] =
|
|||
Railcom::Railcom() {
|
||||
haveHigh=false;
|
||||
haveLow=false;
|
||||
packetsWithNoData=0;
|
||||
}
|
||||
|
||||
/* returns -1: Call again next packet
|
||||
|
@ -141,9 +142,7 @@ Railcom::Railcom() {
|
|||
*/
|
||||
int16_t Railcom::getChannel1Loco(uint8_t * inbound) {
|
||||
auto v1=GETHIGHFLASH(decode,inbound[0]);
|
||||
if (v1>MAX_VALID) return -1;
|
||||
auto v2=GETHIGHFLASH(decode,inbound[1]);
|
||||
if (v2>MAX_VALID) return -1;
|
||||
auto packet=(v1<<6) | v2;
|
||||
// packet is 12 bits TTTTDDDDDDDD
|
||||
auto type=packet>>8;
|
||||
|
@ -151,18 +150,24 @@ int16_t Railcom::getChannel1Loco(uint8_t * inbound) {
|
|||
if (type==RMOB_ADRHIGH) {
|
||||
holdoverHigh=data;
|
||||
haveHigh=true;
|
||||
packetsWithNoData=0;
|
||||
}
|
||||
else if (type==RMOB_ADRLOW) {
|
||||
holdoverLow=data;
|
||||
haveLow=true;
|
||||
packetsWithNoData=0;
|
||||
}
|
||||
else if (type==RMOB_EXT) {
|
||||
return -1; /* ignore*/
|
||||
}
|
||||
else {
|
||||
haveHigh=false;
|
||||
haveLow=false;
|
||||
return 0; // treat as no loco
|
||||
if (packetsWithNoData>MAX_WAIT_FOR_GLITCH) {
|
||||
haveHigh=false;
|
||||
haveLow=false;
|
||||
return 0; // treat as no loco
|
||||
}
|
||||
packetsWithNoData++;
|
||||
return -1; // need more data
|
||||
}
|
||||
if (haveHigh && haveLow) return ((holdoverHigh<<8)| holdoverLow);
|
||||
return -1; // call again, need next packet
|
||||
|
|
Loading…
Reference in New Issue
Block a user