forked from DCC-EX/CommandStation-EX
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Compile success for Decoder (not tested)
- Loading branch information
Showing
5 changed files
with
247 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include <Arduino.h> | ||
#include "DCCPacket.h" | ||
#include "LocoTable.h" | ||
|
||
class DCCDecoder { | ||
public: | ||
DCCDecoder() {}; | ||
bool parse(DCCPacket p); | ||
private: | ||
}; | ||
|
||
|
||
bool DCCDecoder::parse(DCCPacket p) { | ||
byte *d = p.data(); | ||
byte *instr = 0; | ||
uint16_t addr; | ||
bool locoInfoChanged = 0; | ||
byte decoderType = 0; // use 0 as none | ||
if (d[0] == 0B11111111) { // Idle packet | ||
return false; | ||
} | ||
if (bitRead(d[0],7) == 0) { // bit7 == 0 => loco short addr | ||
decoderType = 1; | ||
instr = d+1; | ||
addr = d[0]; | ||
} else { | ||
if (bitRead(d[0],6) == 1) { // bit7 == 1 and bit6 == 1 => loco long addr | ||
decoderType = 1; | ||
instr = d+2; | ||
addr = 256 * (d[0] & 0B00111111) + d[1]; | ||
} | ||
} | ||
if (decoderType == 1) { | ||
switch (instr[0] & 0xE0) { | ||
case 0x20: // 001x-xxxx Extended commands | ||
if (instr[0] == 0B00111111) { // 128 speed steps | ||
if ((locoInfoChanged = LocoTable::updateLoco(addr, instr[1])) == true) { | ||
// send speed change to DCCEX here | ||
} | ||
} | ||
break; | ||
case 0x40: // 010x-xxxx Speed | ||
case 0x60: // 011x-xxxx | ||
if ((locoInfoChanged = LocoTable::updateLoco(addr, instr[0] & 0B00111111)) == true) { | ||
// send speed change to DCCEX here | ||
} | ||
break; | ||
case 0x80: // 100x-xxxx Function group 1 | ||
break; | ||
case 0xA0: // 101x-xxxx Function group 3 and 2 | ||
break; | ||
case 0xC0: // 110x-xxxx Extended | ||
break; | ||
case 0xE0: // 111x-xxxx Config vars | ||
break; | ||
} | ||
} | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* Copyright (c) 2023 Harald Barth | ||
* | ||
* This source is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This source is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this software. If not, see | ||
* <http://www.gnu.org/licenses/>. | ||
*/ | ||
#include "LocoTable.h" | ||
|
||
LocoTable::LOCO LocoTable::speedTable[MAX_LOCOS] = { {0,0,0,0,0,0} }; | ||
int LocoTable::highestUsedReg = 0; | ||
|
||
int LocoTable::lookupSpeedTable(int locoId, bool autoCreate) { | ||
// determine speed reg for this loco | ||
int firstEmpty = MAX_LOCOS; | ||
int reg; | ||
for (reg = 0; reg < MAX_LOCOS; reg++) { | ||
if (speedTable[reg].loco == locoId) break; | ||
if (speedTable[reg].loco == 0 && firstEmpty == MAX_LOCOS) firstEmpty = reg; | ||
} | ||
|
||
// return -1 if not found and not auto creating | ||
if (reg == MAX_LOCOS && !autoCreate) return -1; | ||
if (reg == MAX_LOCOS) reg = firstEmpty; | ||
if (reg >= MAX_LOCOS) { | ||
//DIAG(F("Too many locos")); | ||
return -1; | ||
} | ||
if (reg==firstEmpty){ | ||
speedTable[reg].loco = locoId; | ||
speedTable[reg].speedCode=128; // default direction forward | ||
speedTable[reg].groupFlags=0; | ||
speedTable[reg].functions=0; | ||
} | ||
if (reg > highestUsedReg) highestUsedReg = reg; | ||
return reg; | ||
} | ||
|
||
// returns false only if loco existed but nothing was changed | ||
bool LocoTable::updateLoco(int loco, byte speedCode) { | ||
if (loco==0) { | ||
/* | ||
// broadcast stop/estop but dont change direction | ||
for (int reg = 0; reg < highestUsedReg; reg++) { | ||
if (speedTable[reg].loco==0) continue; | ||
byte newspeed=(speedTable[reg].speedCode & 0x80) | (speedCode & 0x7f); | ||
if (speedTable[reg].speedCode != newspeed) { | ||
speedTable[reg].speedCode = newspeed; | ||
CommandDistributor::broadcastLoco(reg); | ||
} | ||
} | ||
*/ | ||
return true; | ||
} | ||
|
||
// determine speed reg for this loco | ||
int reg=lookupSpeedTable(loco, false); | ||
if (reg>=0) { | ||
speedTable[reg].speedcounter++; | ||
if (speedTable[reg].speedCode!=speedCode) { | ||
speedTable[reg].speedCode = speedCode; | ||
return true; | ||
} else { | ||
return false; | ||
} | ||
} else { | ||
// new | ||
reg=lookupSpeedTable(loco, true); | ||
if(reg >=0) speedTable[reg].speedCode = speedCode; | ||
return true; | ||
} | ||
} | ||
|
||
bool LocoTable::updateFunc(int loco, byte func, int shift) { | ||
unsigned long previous; | ||
unsigned long newfunc; | ||
bool retval = false; // nothing was touched | ||
int reg = lookupSpeedTable(loco, false); | ||
if (reg < 0) { // not found | ||
retval = true; | ||
reg = lookupSpeedTable(loco, true); | ||
newfunc = previous = 0; | ||
} else { | ||
newfunc = previous = speedTable[reg].functions; | ||
} | ||
|
||
speedTable[reg].funccounter++; | ||
|
||
if(shift == 1) { // special case for light | ||
newfunc &= ~1UL; | ||
newfunc |= ((func & 0B10000) >> 4); | ||
} | ||
newfunc &= ~(0B1111UL << shift); | ||
newfunc |= ((func & 0B1111) << shift); | ||
|
||
if (newfunc != previous) { | ||
speedTable[reg].functions = newfunc; | ||
retval = true; | ||
} | ||
return retval; | ||
} | ||
|
||
void LocoTable::dumpTable(Stream *output) { | ||
output->print("\n-----------Table---------\n"); | ||
for (byte reg = 0; reg <= highestUsedReg; reg++) { | ||
if (speedTable[reg].loco != 0) { | ||
output->print(speedTable[reg].loco); | ||
output->print(' '); | ||
output->print(speedTable[reg].speedCode); | ||
output->print(' '); | ||
output->print(speedTable[reg].functions); | ||
output->print(" #funcpacks:"); | ||
output->print(speedTable[reg].funccounter); | ||
output->print(" #speedpacks:"); | ||
output->print(speedTable[reg].speedcounter); | ||
speedTable[reg].funccounter = 0; | ||
speedTable[reg].speedcounter = 0; | ||
output->print('\n'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* Copyright (c) 2023 Harald Barth | ||
* | ||
* This source is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This source is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this software. If not, see | ||
* <http://www.gnu.org/licenses/>. | ||
*/ | ||
#include <Arduino.h> | ||
|
||
#define MAX_LOCOS 128 | ||
|
||
class LocoTable { | ||
public: | ||
void forgetLoco(int cab) { | ||
int reg=lookupSpeedTable(cab, false); | ||
if (reg>=0) speedTable[reg].loco=0; | ||
} | ||
static int lookupSpeedTable(int locoId, bool autoCreate); | ||
static bool updateLoco(int loco, byte speedCode); | ||
static bool updateFunc(int loco, byte func, int shift); | ||
static void dumpTable(Stream *output); | ||
|
||
private: | ||
struct LOCO | ||
{ | ||
int loco; | ||
byte speedCode; | ||
byte groupFlags; | ||
unsigned long functions; | ||
unsigned int funccounter; | ||
unsigned int speedcounter; | ||
}; | ||
static LOCO speedTable[MAX_LOCOS]; | ||
static int highestUsedReg; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters