mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-22 23:56:13 +01:00
railcom tidy
This commit is contained in:
parent
a49cb95795
commit
fae713eae7
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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 @@ private:
|
|||
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 @@ 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
|
||||
|
@ -131,32 +128,9 @@ public:
|
|||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
50
Railcom.cpp
50
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
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user