From fae713eae7967028943dc8649edd0c1201541144 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sat, 19 Oct 2024 12:24:14 +0100 Subject: [PATCH] railcom tidy --- EXRAIL3.cpp | 1 + IO_I2CRailcom.h | 36 +++++------------------------------ Railcom.cpp | 50 +++++++++++++++++++++++++++++++++++++++---------- Railcom.h | 11 +++++++---- 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/EXRAIL3.cpp b/EXRAIL3.cpp index f9554dac..bf654990 100644 --- a/EXRAIL3.cpp +++ b/EXRAIL3.cpp @@ -1,5 +1,6 @@ // file exists to break #include dependency loop #include "EXRAIL2.h" +#include "EXRAIL3.h" void RMFT3::blockEvent(int16_t block, int16_t loco, bool entering) { RMFT2::blockEvent(block,loco,entering); }; diff --git a/IO_I2CRailcom.h b/IO_I2CRailcom.h index 28c62e26..0daa3681 100644 --- a/IO_I2CRailcom.h +++ b/IO_I2CRailcom.h @@ -45,7 +45,6 @@ #ifndef IO_I2CRailcom_h #define IO_I2CRailcom_h -#include "EXRAIL3.h" #include "IODevice.h" #include "I2CManager.h" #include "DIAG.h" @@ -54,7 +53,6 @@ // Debug and diagnostic defines, enable too many will result in slowing the driver #define DIAG_I2CRailcom -//#define DIAG_I2CRailcom_data class I2CRailcom : public IODevice { private: @@ -63,14 +61,15 @@ class I2CRailcom : public IODevice { byte _inbuf[65]; byte _outbuf[2]; byte cutoutCounter[2]; - Railcom _channelMonitors[2]; - int16_t _locoInBlock[2]; + Railcom * _channelMonitors[2]; public: // Constructor I2CRailcom(VPIN firstVpin, int nPins, I2CAddress i2cAddress){ _firstVpin = firstVpin; _nPins = nPins; _I2CAddress = i2cAddress; + _channelMonitors[0]=new Railcom(firstVpin); + if (nPins>1) _channelMonitors[1]=new Railcom(firstVpin+1); addDevice(this); } @@ -88,8 +87,6 @@ class I2CRailcom : public IODevice { 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 @@ -131,32 +128,9 @@ class I2CRailcom : public IODevice { } // 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, %d"), _I2CAddress.toString(), _UART_CH,inlength); - for (int i = 0; i < inlength; 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); - 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); - // new loco, if any, is entering block - _locoInBlock[_UART_CH]=locoid; - if (locoid) RMFT3::blockEvent(_firstVpin+_UART_CH,locoid,true); + // Ask Railcom to interpret the raw data + _channelMonitors[_UART_CH]->process(_inbuf,inlength); } diff --git a/Railcom.cpp b/Railcom.cpp index 7d21cf4a..ef7b7f14 100644 --- a/Railcom.cpp +++ b/Railcom.cpp @@ -49,7 +49,13 @@ **/ #include "Railcom.h" +#include "defines.h" #include "FSH.h" +#include "EXRAIL3.h" +#include "DIAG.h" + +//#define DIAG_I2CRailcom_data + /** Table for 8-to-6 decoding of railcom data. This table can be indexed by the * 8-bit value read from the railcom channel, and the return value will be @@ -129,21 +135,28 @@ const uint8_t HIGHFLASH decode[256] = RMOB_LOGON_ENABLE_FEEDBACK = 15, }; - -Railcom::Railcom() { +Railcom::Railcom(uint16_t blockvpin) { haveHigh=false; haveLow=false; packetsWithNoData=0; + locoOnTrack=0; + vpin=blockvpin; } /* returns -1: Call again next packet 0: No loco on track >0: loco id */ -int16_t Railcom::getChannel1Loco(uint8_t * inbound) { +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]); + } + #endif auto v1=GETHIGHFLASH(decode,inbound[0]); - auto v2=GETHIGHFLASH(decode,inbound[1]); - auto packet=(v1<<6) | v2; + auto v2=(length>2) ? GETHIGHFLASH(decode,inbound[1]):0x0; + uint16_t packet=(v1<<6) | (v2 & 0x3f); // packet is 12 bits TTTTDDDDDDDD auto type=packet>>8; auto data= packet & 0xFF; @@ -158,17 +171,34 @@ int16_t Railcom::getChannel1Loco(uint8_t * inbound) { packetsWithNoData=0; } else if (type==RMOB_EXT) { - return -1; /* ignore*/ + return; /* ignore*/ } else { if (packetsWithNoData>MAX_WAIT_FOR_GLITCH) { + // treat as no loco haveHigh=false; haveLow=false; - return 0; // treat as no loco + // Previous loco (if any) is exiting block + blockEvent(false); + locoOnTrack=0; + return ; } packetsWithNoData++; - return -1; // need more data + return; // need more data } - if (haveHigh && haveLow) return ((holdoverHigh<<8)| holdoverLow); - return -1; // call again, need next packet + if (haveHigh && haveLow) { + uint16_t thisLoco=((holdoverHigh<<8)| holdoverLow); + if (locoOnTrack!=thisLoco) { + // Previous loco (if any) is exiting block + blockEvent(false); + locoOnTrack=thisLoco; + blockEvent(true); + } + } +} + +void Railcom::blockEvent(bool entering) { + #ifdef EXRAIL_ACTIVE + if (locoOnTrack) RMFT3::blockEvent(vpin,locoOnTrack,entering); + #endif } diff --git a/Railcom.h b/Railcom.h index 6c00a7ba..b16945ec 100644 --- a/Railcom.h +++ b/Railcom.h @@ -24,19 +24,22 @@ class Railcom { public: - Railcom(); + Railcom(uint16_t vpin); /* returns -1: Call again next packet 0: No loco on track >0: loco id */ - int16_t getChannel1Loco(uint8_t * inbound); - + void process(uint8_t * inbound,uint8_t length); + private: + void blockEvent(bool entering); + uint16_t locoOnTrack; + uint16_t vpin; uint8_t holdoverHigh,holdoverLow; bool haveHigh,haveLow; uint8_t packetsWithNoData; - static const byte MAX_WAIT_FOR_GLITCH=10; // number of dead or empty packets before assuming loco=0 + static const byte MAX_WAIT_FOR_GLITCH=20; // number of dead or empty packets before assuming loco=0 }; #endif \ No newline at end of file