mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-30 03:26:13 +01:00
DCC Turnouts: Store address/subaddress separately. Enable address 0.
The range of accessory decoder addresses for the <a> command is 0-511 in line with the DCC packet contents. The turnout command previously rejected address 0; this has been changed to the same range of addresses can be used by both commands, i.e. address 0-511 and subaddress 0-3. The linear address mapping remains so that linear address 1 is addr/subaddr 1/0; i.e. the first decoder address is not accessible by linear address.
This commit is contained in:
parent
e59e07b971
commit
e287af83ff
|
@ -736,15 +736,17 @@ bool DCCEXParser::parseT(Print *stream, int16_t params, int16_t p[])
|
||||||
if (!VpinTurnout::create(p[0], p[2])) return false;
|
if (!VpinTurnout::create(p[0], p[2])) return false;
|
||||||
} else
|
} else
|
||||||
if (params >= 3 && p[1] == HASH_KEYWORD_DCC) {
|
if (params >= 3 && p[1] == HASH_KEYWORD_DCC) {
|
||||||
if (params==4 && p[2]>0 && p[2]<=512 && p[3]>=0 && p[3]<4) { // <T id DCC n m>
|
// <T id DCC addr subadd> 0<=addr<=511, 0<=subadd<=3 (like <a> command).<T>
|
||||||
|
if (params==4 && p[2]>=0 && p[2]<512 && p[3]>=0 && p[3]<4) { // <T id DCC n m>
|
||||||
if (!DCCTurnout::create(p[0], p[2], p[3])) return false;
|
if (!DCCTurnout::create(p[0], p[2], p[3])) return false;
|
||||||
} else if (params==3 && p[2]>0 && p[2]<=512*4) { // <T id DCC nn>, 1<=nn<=2048
|
} else if (params==3 && p[2]>0 && p[2]<=512*4) { // <T id DCC nn>, 1<=nn<=2048
|
||||||
|
// Linearaddress 1 maps onto decoder address 1/0 (not 0/0!).
|
||||||
if (!DCCTurnout::create(p[0], (p[2]-1)/4+1, (p[2]-1)%4)) return false;
|
if (!DCCTurnout::create(p[0], (p[2]-1)/4+1, (p[2]-1)%4)) return false;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
} else
|
} else
|
||||||
if (params==3) { // legacy <T id n n> for DCC accessory
|
if (params==3) { // legacy <T id addr subadd> for DCC accessory
|
||||||
if (p[1]>0 && p[1]<=512 && p[2]>=0 && p[2]<4) {
|
if (p[1]>=0 && p[1]<512 && p[2]>=0 && p[2]<4) {
|
||||||
if (!DCCTurnout::create(p[0], p[1], p[2])) return false;
|
if (!DCCTurnout::create(p[0], p[1], p[2])) return false;
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
|
|
17
Turnouts.cpp
17
Turnouts.cpp
|
@ -340,7 +340,8 @@
|
||||||
DCCTurnout::DCCTurnout(uint16_t id, uint16_t address, uint8_t subAdd) :
|
DCCTurnout::DCCTurnout(uint16_t id, uint16_t address, uint8_t subAdd) :
|
||||||
Turnout(id, TURNOUT_DCC, false)
|
Turnout(id, TURNOUT_DCC, false)
|
||||||
{
|
{
|
||||||
_dccTurnoutData.address = ((address-1) << 2) + subAdd + 1;
|
_dccTurnoutData.address = address;
|
||||||
|
_dccTurnoutData.subAddress = subAdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create function
|
// Create function
|
||||||
|
@ -351,7 +352,8 @@
|
||||||
if (tt->isType(TURNOUT_DCC)) {
|
if (tt->isType(TURNOUT_DCC)) {
|
||||||
// Yes, so set parameters<T>
|
// Yes, so set parameters<T>
|
||||||
DCCTurnout *dt = (DCCTurnout *)tt;
|
DCCTurnout *dt = (DCCTurnout *)tt;
|
||||||
dt->_dccTurnoutData.address = ((add-1) << 2) + subAdd + 1;
|
dt->_dccTurnoutData.address = add;
|
||||||
|
dt->_dccTurnoutData.subAddress = subAdd;
|
||||||
// Don't touch the _closed parameter, retain the original value.
|
// Don't touch the _closed parameter, retain the original value.
|
||||||
return tt;
|
return tt;
|
||||||
} else {
|
} else {
|
||||||
|
@ -371,27 +373,24 @@
|
||||||
EEStore::advance(sizeof(dccTurnoutData));
|
EEStore::advance(sizeof(dccTurnoutData));
|
||||||
|
|
||||||
// Create new object
|
// Create new object
|
||||||
DCCTurnout *tt = new DCCTurnout(turnoutData->id, (((dccTurnoutData.address-1) >> 2)+1), ((dccTurnoutData.address-1) & 3));
|
DCCTurnout *tt = new DCCTurnout(turnoutData->id, dccTurnoutData.address, dccTurnoutData.subAddress);
|
||||||
|
|
||||||
return tt;
|
return tt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DCCTurnout::print(Print *stream) {
|
void DCCTurnout::print(Print *stream) {
|
||||||
StringFormatter::send(stream, F("<H %d DCC %d %d %d>\n"), _turnoutData.id,
|
StringFormatter::send(stream, F("<H %d DCC %d %d %d>\n"), _turnoutData.id,
|
||||||
(((_dccTurnoutData.address-1) >> 2)+1), ((_dccTurnoutData.address-1) & 3),
|
_dccTurnoutData.address, _dccTurnoutData.subAddress, !_turnoutData.closed);
|
||||||
!_turnoutData.closed);
|
|
||||||
// Also report using classic DCC++ syntax for DCC accessory turnouts, since JMRI expects this.
|
// Also report using classic DCC++ syntax for DCC accessory turnouts, since JMRI expects this.
|
||||||
StringFormatter::send(stream, F("<H %d %d %d %d>\n"), _turnoutData.id,
|
StringFormatter::send(stream, F("<H %d %d %d %d>\n"), _turnoutData.id,
|
||||||
(((_dccTurnoutData.address-1) >> 2)+1), ((_dccTurnoutData.address-1) & 3),
|
_dccTurnoutData.address, _dccTurnoutData.subAddress, !_turnoutData.closed);
|
||||||
!_turnoutData.closed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DCCTurnout::setClosedInternal(bool close) {
|
bool DCCTurnout::setClosedInternal(bool close) {
|
||||||
// DCC++ Classic behaviour is that Throw writes a 1 in the packet,
|
// DCC++ Classic behaviour is that Throw writes a 1 in the packet,
|
||||||
// and Close writes a 0.
|
// and Close writes a 0.
|
||||||
// RCN-213 specifies that Throw is 0 and Close is 1.
|
// RCN-213 specifies that Throw is 0 and Close is 1.
|
||||||
DCC::setAccessory((((_dccTurnoutData.address-1) >> 2) + 1),
|
DCC::setAccessory(_dccTurnoutData.address, _dccTurnoutData.subAddress, close ^ !rcn213Compliant);
|
||||||
((_dccTurnoutData.address-1) & 3), close ^ !rcn213Compliant);
|
|
||||||
_turnoutData.closed = close;
|
_turnoutData.closed = close;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,9 +213,11 @@ private:
|
||||||
// DCCTurnoutData contains data specific to this subclass that is
|
// DCCTurnoutData contains data specific to this subclass that is
|
||||||
// written to EEPROM when the turnout is saved.
|
// written to EEPROM when the turnout is saved.
|
||||||
struct DCCTurnoutData {
|
struct DCCTurnoutData {
|
||||||
// DCC address (Address in bits 15-2, subaddress in bits 1-0
|
// DCC address (Address in bits 15-2, subaddress in bits 1-0)
|
||||||
uint16_t address; // CS currently supports linear address 1-2048
|
struct {
|
||||||
// That's DCC accessory address 1-512 and subaddress 0-3.
|
uint16_t address : 14;
|
||||||
|
uint8_t subAddress : 2;
|
||||||
|
};
|
||||||
} _dccTurnoutData; // 2 bytes
|
} _dccTurnoutData; // 2 bytes
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
|
Loading…
Reference in New Issue
Block a user