mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-24 21:21:24 +01:00
Fixup functionMap and remove duplicates
This commit is contained in:
parent
b0c9806f3b
commit
e5c66a2755
7
DCC.cpp
7
DCC.cpp
@ -200,6 +200,7 @@ int DCC::changeFn( int cab, int16_t functionNumber, bool pressed) {
|
|||||||
if (cab<=0 || functionNumber>28) return funcstate;
|
if (cab<=0 || functionNumber>28) return funcstate;
|
||||||
int reg = lookupSpeedTable(cab);
|
int reg = lookupSpeedTable(cab);
|
||||||
if (reg<0) return funcstate;
|
if (reg<0) return funcstate;
|
||||||
|
uint32_t oldFunctionMap=speedTable[reg].functions;
|
||||||
|
|
||||||
// Take care of functions:
|
// Take care of functions:
|
||||||
// Imitate how many command stations do it: Button press is
|
// Imitate how many command stations do it: Button press is
|
||||||
@ -222,7 +223,7 @@ int DCC::changeFn( int cab, int16_t functionNumber, bool pressed) {
|
|||||||
funcstate = (speedTable[reg].functions & funcmask)? 1 : 0;
|
funcstate = (speedTable[reg].functions & funcmask)? 1 : 0;
|
||||||
}
|
}
|
||||||
updateGroupflags(speedTable[reg].groupFlags, functionNumber);
|
updateGroupflags(speedTable[reg].groupFlags, functionNumber);
|
||||||
CommandDistributor::broadcastLoco(reg);
|
if (oldFunctionMap!=speedTable[reg].functions) CommandDistributor::broadcastLoco(reg);
|
||||||
return funcstate;
|
return funcstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ void DCC::updateGroupflags(byte & flags, int16_t functionNumber) {
|
|||||||
flags |= groupMask;
|
flags |= groupMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t DCC::getFunctionMap(int cab) {
|
uint32_t DCC::getFunctionMap(int cab) {
|
||||||
if (cab<=0) return 0; // unknown pretend all functions off
|
if (cab<=0) return 0; // unknown pretend all functions off
|
||||||
int reg = lookupSpeedTable(cab);
|
int reg = lookupSpeedTable(cab);
|
||||||
return (reg<0)?0:speedTable[reg].functions;
|
return (reg<0)?0:speedTable[reg].functions;
|
||||||
@ -696,7 +697,7 @@ void DCC::updateLocoReminder(int loco, byte speedCode) {
|
|||||||
|
|
||||||
// determine speed reg for this loco
|
// determine speed reg for this loco
|
||||||
int reg=lookupSpeedTable(loco);
|
int reg=lookupSpeedTable(loco);
|
||||||
if (reg>=0) {
|
if (reg>=0 && speedTable[reg].speedCode!=speedCode) {
|
||||||
speedTable[reg].speedCode = speedCode;
|
speedTable[reg].speedCode = speedCode;
|
||||||
CommandDistributor::broadcastLoco(reg);
|
CommandDistributor::broadcastLoco(reg);
|
||||||
}
|
}
|
||||||
|
2
DCC.h
2
DCC.h
@ -101,7 +101,7 @@ public:
|
|||||||
static void setFn(int cab, int16_t functionNumber, bool on);
|
static void setFn(int cab, int16_t functionNumber, bool on);
|
||||||
static int changeFn(int cab, int16_t functionNumber, bool pressed);
|
static int changeFn(int cab, int16_t functionNumber, bool pressed);
|
||||||
static int getFn(int cab, int16_t functionNumber);
|
static int getFn(int cab, int16_t functionNumber);
|
||||||
static uint16_t getFunctionMap(int cab);
|
static uint32_t getFunctionMap(int cab);
|
||||||
static void updateGroupflags(byte &flags, int16_t functionNumber);
|
static void updateGroupflags(byte &flags, int16_t functionNumber);
|
||||||
static void setAccessory(int aAdd, byte aNum, bool activate);
|
static void setAccessory(int aAdd, byte aNum, bool activate);
|
||||||
static bool writeTextPacket(byte *b, int nBytes);
|
static bool writeTextPacket(byte *b, int nBytes);
|
||||||
|
@ -273,15 +273,16 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
|
|||||||
if (myLocos[loco].throttle=='\0') {
|
if (myLocos[loco].throttle=='\0') {
|
||||||
myLocos[loco].throttle=throttleChar;
|
myLocos[loco].throttle=throttleChar;
|
||||||
myLocos[loco].cab=locoid;
|
myLocos[loco].cab=locoid;
|
||||||
|
myLocos[loco].functionMap=DCC::getFunctionMap(locoid);
|
||||||
|
myLocos[loco].broadcastPending=true; // means speed/dir will be sent later
|
||||||
mostRecentCab=locoid;
|
mostRecentCab=locoid;
|
||||||
StringFormatter::send(stream, F("M%c+%c%d<;>\n"), throttleChar, cmd[3] ,locoid); //tell client to add loco
|
StringFormatter::send(stream, F("M%c+%c%d<;>\n"), throttleChar, cmd[3] ,locoid); //tell client to add loco
|
||||||
//Get known Fn states from DCC
|
|
||||||
for(int fKey=0; fKey<=28; fKey++) {
|
for(int fKey=0; fKey<=28; fKey++) {
|
||||||
int fstate=DCC::getFn(locoid,fKey);
|
int fstate=DCC::getFn(locoid,fKey);
|
||||||
if (fstate>=0) StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,fstate,fKey);
|
if (fstate>=0) StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"),throttleChar,cmd[3],locoid,fstate,fKey);
|
||||||
}
|
}
|
||||||
StringFormatter::send(stream, F("M%cA%c%d<;>V%d\n"), throttleChar, cmd[3], locoid, DCCToWiTSpeed(DCC::getThrottleSpeed(locoid)));
|
//speed and direction will be published at next broadcast cycle
|
||||||
StringFormatter::send(stream, F("M%cA%c%d<;>R%d\n"), throttleChar, cmd[3], locoid, DCC::getThrottleDirection(locoid));
|
|
||||||
StringFormatter::send(stream, F("M%cA%c%d<;>s1\n"), throttleChar, cmd[3], locoid); //default speed step 128
|
StringFormatter::send(stream, F("M%cA%c%d<;>s1\n"), throttleChar, cmd[3], locoid); //default speed step 128
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -303,6 +304,7 @@ void WiThrottle::multithrottle(RingStream * stream, byte * cmd){
|
|||||||
void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar, int cab){
|
void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar, int cab){
|
||||||
// Note cab=-1 for all cabs in the consist called throttleChar.
|
// Note cab=-1 for all cabs in the consist called throttleChar.
|
||||||
// DIAG(F("Loco Action aval=%c%c throttleChar=%c, cab=%d"), aval[0],aval[1],throttleChar, cab);
|
// DIAG(F("Loco Action aval=%c%c throttleChar=%c, cab=%d"), aval[0],aval[1],throttleChar, cab);
|
||||||
|
(void) stream;
|
||||||
switch (aval[0]) {
|
switch (aval[0]) {
|
||||||
case 'V': // Vspeed
|
case 'V': // Vspeed
|
||||||
{
|
{
|
||||||
@ -310,32 +312,24 @@ void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar,
|
|||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
mostRecentCab=myLocos[loco].cab;
|
mostRecentCab=myLocos[loco].cab;
|
||||||
DCC::setThrottle(myLocos[loco].cab, WiTToDCCSpeed(witSpeed), DCC::getThrottleDirection(myLocos[loco].cab));
|
DCC::setThrottle(myLocos[loco].cab, WiTToDCCSpeed(witSpeed), DCC::getThrottleDirection(myLocos[loco].cab));
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>V%d\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab, witSpeed);
|
// SetThrottle will cause speed change broadcast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'F': //F onOff function
|
case 'F': //F onOff function
|
||||||
{
|
{
|
||||||
bool funcstate;
|
bool pressed=aval[1]=='1';
|
||||||
bool pressed=aval[1]=='1';
|
|
||||||
int fKey = getInt(aval+2);
|
int fKey = getInt(aval+2);
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
funcstate = DCC::changeFn(myLocos[loco].cab, fKey, pressed);
|
DCC::changeFn(myLocos[loco].cab, fKey, pressed);
|
||||||
if(funcstate==0 || funcstate==1)
|
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>F%d%d\n"), throttleChar, LorS(myLocos[loco].cab),
|
|
||||||
myLocos[loco].cab, funcstate, fKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'q':
|
case 'q':
|
||||||
if (aval[1]=='V') { //qV
|
if (aval[1]=='V' || aval[1]=='R' ) { //qV or qR
|
||||||
|
// just flag the loco for broadcast and it will happen.
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>V%d\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab, DCCToWiTSpeed(DCC::getThrottleSpeed(myLocos[loco].cab)));
|
myLocos[loco].broadcastPending=true;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (aval[1]=='R') { // qR
|
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>R%d\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab, DCC::getThrottleDirection(myLocos[loco].cab));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -345,15 +339,15 @@ void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar,
|
|||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
mostRecentCab=myLocos[loco].cab;
|
mostRecentCab=myLocos[loco].cab;
|
||||||
DCC::setThrottle(myLocos[loco].cab, DCC::getThrottleSpeed(myLocos[loco].cab), forward);
|
DCC::setThrottle(myLocos[loco].cab, DCC::getThrottleSpeed(myLocos[loco].cab), forward);
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>R%d\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab, forward);
|
// setThrottle will cause a broadcast so notification will be sent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
//Emergency Stop (speed code 1)
|
//Emergency Stop (speed code 1)
|
||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
DCC::setThrottle(myLocos[loco].cab, 1, DCC::getThrottleDirection(myLocos[loco].cab));
|
DCC::setThrottle(myLocos[loco].cab, 1, DCC::getThrottleDirection(myLocos[loco].cab));
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>V%d\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab, -1);
|
// setThrottle will cause a broadcast so notification will be sent
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'I': // Idle, set speed to 0
|
case 'I': // Idle, set speed to 0
|
||||||
@ -361,7 +355,7 @@ void WiThrottle::locoAction(RingStream * stream, byte* aval, char throttleChar,
|
|||||||
LOOPLOCOS(throttleChar, cab) {
|
LOOPLOCOS(throttleChar, cab) {
|
||||||
mostRecentCab=myLocos[loco].cab;
|
mostRecentCab=myLocos[loco].cab;
|
||||||
DCC::setThrottle(myLocos[loco].cab, 0, DCC::getThrottleDirection(myLocos[loco].cab));
|
DCC::setThrottle(myLocos[loco].cab, 0, DCC::getThrottleDirection(myLocos[loco].cab));
|
||||||
StringFormatter::send(stream,F("M%cA%c%d<;>V%d\n"), throttleChar, LorS(myLocos[loco].cab), myLocos[loco].cab, 0);
|
// setThrottle will cause a broadcast so notification will be sent
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -403,10 +397,15 @@ void WiThrottle::checkHeartbeat(RingStream * stream) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send any speed/direction/function changes for this loco
|
// send any outstanding speed/direction/function changes for this clients locos
|
||||||
|
// Changes may have been caused by this client, or another non-Withrottle or Exrail
|
||||||
|
bool streamHasBeenMarked=false;
|
||||||
LOOPLOCOS('*', -1) {
|
LOOPLOCOS('*', -1) {
|
||||||
if (myLocos[loco].throttle!='\0' && myLocos[loco].broadcastPending) {
|
if (myLocos[loco].throttle!='\0' && myLocos[loco].broadcastPending) {
|
||||||
stream->mark(clientid);
|
if (!streamHasBeenMarked) {
|
||||||
|
stream->mark(clientid);
|
||||||
|
streamHasBeenMarked=true;
|
||||||
|
}
|
||||||
myLocos[loco].broadcastPending=false;
|
myLocos[loco].broadcastPending=false;
|
||||||
int cab=myLocos[loco].cab;
|
int cab=myLocos[loco].cab;
|
||||||
char lors=LorS(cab);
|
char lors=LorS(cab);
|
||||||
@ -417,8 +416,8 @@ void WiThrottle::checkHeartbeat(RingStream * stream) {
|
|||||||
throttle, lors , cab, DCC::getThrottleDirection(cab));
|
throttle, lors , cab, DCC::getThrottleDirection(cab));
|
||||||
|
|
||||||
// compare the DCC functionmap with the local copy and send changes
|
// compare the DCC functionmap with the local copy and send changes
|
||||||
uint16_t dccFunctionMap=DCC::getFunctionMap(cab);
|
uint32_t dccFunctionMap=DCC::getFunctionMap(cab);
|
||||||
uint16_t myFunctionMap=myLocos[loco].functionMap;
|
uint32_t myFunctionMap=myLocos[loco].functionMap;
|
||||||
myLocos[loco].functionMap=dccFunctionMap;
|
myLocos[loco].functionMap=dccFunctionMap;
|
||||||
|
|
||||||
// loop the maps sending any bit changed
|
// loop the maps sending any bit changed
|
||||||
@ -432,9 +431,9 @@ void WiThrottle::checkHeartbeat(RingStream * stream) {
|
|||||||
dccFunctionMap>>=1;
|
dccFunctionMap>>=1;
|
||||||
myFunctionMap>>=1;
|
myFunctionMap>>=1;
|
||||||
}
|
}
|
||||||
stream->commit();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (streamHasBeenMarked) stream->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiThrottle::markForBroadcast(int cab) {
|
void WiThrottle::markForBroadcast(int cab) {
|
||||||
|
@ -25,7 +25,7 @@ struct MYLOCO {
|
|||||||
char throttle; //indicates which throttle letter on client, often '0','1' or '2'
|
char throttle; //indicates which throttle letter on client, often '0','1' or '2'
|
||||||
int cab; //address of this loco
|
int cab; //address of this loco
|
||||||
bool broadcastPending;
|
bool broadcastPending;
|
||||||
uint16_t functionMap;
|
uint32_t functionMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WiThrottle {
|
class WiThrottle {
|
||||||
|
Loading…
Reference in New Issue
Block a user