From a49cb957957a2b6fca9fe006e88a95de4120eb5d Mon Sep 17 00:00:00 2001 From: Asbelos Date: Thu, 17 Oct 2024 21:48:30 +0100 Subject: [PATCH] detection happening! --- DCCWaveform.cpp | 2 ++ DCCWaveform.h | 4 ++++ IO_I2CRailcom.h | 45 ++++++++++++++++++++++++++------------------- Railcom.cpp | 15 ++++++++++----- Railcom.h | 4 +++- 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index b4c812d..211aac3 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -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) { diff --git a/DCCWaveform.h b/DCCWaveform.h index 6bdbe15..97cf94b 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -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; diff --git a/IO_I2CRailcom.h b/IO_I2CRailcom.h index b46c32a..28c62e2 100644 --- a/IO_I2CRailcom.h +++ b/IO_I2CRailcom.h @@ -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); diff --git a/Railcom.cpp b/Railcom.cpp index dabdced..7d21cf4 100644 --- a/Railcom.cpp +++ b/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 diff --git a/Railcom.h b/Railcom.h index d1ab5d4..6c00a7b 100644 --- a/Railcom.h +++ b/Railcom.h @@ -34,7 +34,9 @@ class Railcom { private: uint8_t holdoverHigh,holdoverLow; -bool haveHigh,haveLow; + bool haveHigh,haveLow; + uint8_t packetsWithNoData; + static const byte MAX_WAIT_FOR_GLITCH=10; // number of dead or empty packets before assuming loco=0 }; #endif \ No newline at end of file