186 Zeilen
6.4 KiB
C
186 Zeilen
6.4 KiB
C
//Z21 DCC RailCom Decoder
|
|
//Dekodierung globaler Railcomdaten am Serial3 (MEGA only!)
|
|
//
|
|
//Copyright (c) by Philipp Gahtow, year 2021
|
|
|
|
//--------------------------------------------------------------
|
|
#if defined(DCCGLOBALDETECTOR) && defined(DCC)
|
|
|
|
uint16_t RailcomCVAdr = 0; //init global RailCom detector for POM
|
|
|
|
//--------------------------------------------------------------
|
|
#if defined(MEGA_MCU)
|
|
/*
|
|
void notifyCVPOMRead(uint16_t Adr, uint8_t value) {
|
|
#if defined(LAN) || defined(WIFI) || defined(ESP_WIFI)
|
|
z21.setCVPOMBYTE(Adr, value);
|
|
#endif
|
|
}
|
|
*/
|
|
|
|
#define RCSerial Serial3 //Serial Port that we will listen to for RailCom Data
|
|
|
|
//--------------------------------------------------------------
|
|
byte RailComGetCV = false; //try to receive a CV value
|
|
byte RailComReadFirst = true;
|
|
byte RailComReadData = 0; //Save the first 2 bit data
|
|
byte RailComReadLastCV = 0xFF; //Save the last read CV value
|
|
byte RailComCVRead = false; //receive a CV value
|
|
byte RailComCVTime = 0; //cycle time
|
|
uint16_t RailComReadAdr = 0; //Adress read over RailCom
|
|
|
|
//--------------------------------------------------------------
|
|
//init the Serial interface for receiving RailCom
|
|
void RailComSetup(void) {
|
|
RCSerial.begin(250000); //Read Railcom Message at 250KBit
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
//Decoding RailCom Received Data
|
|
byte RailComDecodeInData (void) {
|
|
switch (RCSerial.read()) {
|
|
case B10101100: return 0x00;
|
|
case B10110010: return 0x10;
|
|
case B01010110: return 0x20;
|
|
case B11000110: return 0x30;
|
|
case B10101010: return 0x01;
|
|
case B10110100: return 0x11;
|
|
case B01001110: return 0x21;
|
|
case B11001100: return 0x31;
|
|
case B10101001: return 0x02;
|
|
case B10111000: return 0x12;
|
|
case B01001101: return 0x22;
|
|
case B01111000: return 0x32;
|
|
case B10100101: return 0x03;
|
|
case B01110100: return 0x13;
|
|
case B01001011: return 0x23;
|
|
case B00010111: return 0x33;
|
|
case B10100011: return 0x04;
|
|
case B01110010: return 0x14;
|
|
case B01000111: return 0x24;
|
|
case B00011011: return 0x34;
|
|
case B10100110: return 0x05;
|
|
case B01101100: return 0x15;
|
|
case B01110001: return 0x25;
|
|
case B00011101: return 0x35;
|
|
case B10011100: return 0x06;
|
|
case B01101010: return 0x16;
|
|
case B11101000: return 0x26;
|
|
case B00011110: return 0x36;
|
|
case B10011010: return 0x07;
|
|
case B01101001: return 0x17;
|
|
case B11100100: return 0x27;
|
|
case B00101110: return 0x37;
|
|
case B10011001: return 0x08;
|
|
case B01100101: return 0x18;
|
|
case B11100010: return 0x28;
|
|
case B00110110: return 0x38;
|
|
case B10010101: return 0x09;
|
|
case B01100011: return 0x19;
|
|
case B11010001: return 0x29;
|
|
case B00111010: return 0x39;
|
|
case B10010011: return 0x0A;
|
|
case B01100110: return 0x1A;
|
|
case B11001001: return 0x2A;
|
|
case B00100111: return 0x3A;
|
|
case B10010110: return 0x0B;
|
|
case B01011100: return 0x1B;
|
|
case B11000101: return 0x2B;
|
|
case B00101011: return 0x3B;
|
|
case B10001110: return 0x0C;
|
|
case B01011010: return 0x1C;
|
|
case B11011000: return 0x2C;
|
|
case B00101101: return 0x3C;
|
|
case B10001101: return 0x0D;
|
|
case B01011001: return 0x1D;
|
|
case B11010100: return 0x2D;
|
|
case B00110101: return 0x3D;
|
|
case B10001011: return 0x0E;
|
|
case B01010101: return 0x1E;
|
|
case B11010010: return 0x2E;
|
|
case B00111001: return 0x3E;
|
|
case B10110001: return 0x0F;
|
|
case B01010011: return 0x1F;
|
|
case B11001010: return 0x2F;
|
|
case B00110011: return 0x3F;
|
|
case 0x0F: return 0xF0; //ACK
|
|
}
|
|
return 0xFF;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
//Check if we receive data?
|
|
void RailComRead(void) {
|
|
if (RailComGetCV) { //need to read data?
|
|
RailComCVTime++;
|
|
while (RCSerial.available()) { //is there serial data in buffer?
|
|
byte data = RailComDecodeInData(); //read Railcom Data and decode Railcom Data
|
|
if (data < 0x40) { //gültige Railcom Message empfangen
|
|
if (RailComReadFirst) {
|
|
RailComReadData = data; //Save first Byte of Data
|
|
if ((data >> 2) < 3) //app:pom, app:adr_low, app:adr_high -> read only 12 Bit!
|
|
RailComReadFirst = false;
|
|
}
|
|
else {
|
|
RailComReadFirst = true;
|
|
byte RailComID = RailComReadData >> 2; //Save ID
|
|
RailComReadData = (RailComReadData << 6) | data; //first 2 Bit and add next 6 Bit
|
|
if (RailComID == 0) { //app:pom
|
|
RailComCVTime = 25; //Reset Timer!
|
|
RailComReadLastCV = RailComReadData;
|
|
RailComCVRead = true;
|
|
}
|
|
else if (RailComID == 1) { //app:adr_high
|
|
RailComReadAdr = (RailComReadData << 8) | (RailComReadAdr & 0xFF);
|
|
}
|
|
else if (RailComID == 2) { //app:adr_low
|
|
RailComReadAdr = (RailComReadAdr & 0xFF00) | RailComReadData;
|
|
}
|
|
}
|
|
}
|
|
else RailComReadFirst = true;
|
|
}
|
|
if (RailComCVTime == 0) { //TIMEOUT?
|
|
RailComGetCV = false; //Stop reading! ERROR!
|
|
if (RailComCVRead == true) {
|
|
RailComCVRead = false;
|
|
#if defined(LAN) || defined(WIFI) || defined(ESP_WIFI)
|
|
z21.setCVPOMBYTE(RailcomCVAdr, RailComReadLastCV);
|
|
#endif
|
|
#if defined(RCDEB)
|
|
Debug.print(F(" result: A"));
|
|
Debug.print(RailComReadAdr);
|
|
Debug.print(" CV");
|
|
Debug.print(RailcomCVAdr+1);
|
|
Debug.print(" = ");
|
|
Debug.println(RailComReadLastCV);
|
|
#endif
|
|
}
|
|
else {
|
|
#if defined(LAN) || defined(WIFI) || defined(ESP_WIFI)
|
|
z21.setCVNack(); //Antwort: LAN_X_CV_NACK
|
|
#endif
|
|
#if defined(RCDEB)
|
|
Debug.println(" RC ERROR");
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
//Start Reading Data!
|
|
void RailComStart(void) {
|
|
while(RCSerial.available()){RCSerial.read();} //remove all rubish data
|
|
RailComGetCV = true; //start reading RailCom Data
|
|
RailComReadLastCV = 0xFF; //Reset the last Value
|
|
RailComCVTime = 0; //Reset the cycle time
|
|
RailComReadAdr = 0;
|
|
RailComRead(); //Try to read data...
|
|
}
|
|
|
|
#endif //End MEGA Serial
|
|
|
|
//--------------------------------------------------------------
|
|
#endif
|