Skip to content

Commit e5e0649

Browse files
author
Don Goodman-Wilson
committed
Added support for new traction control MTIs. No previous functionality removed, so should be compatible with existing JMRI implementations
git-svn-id: svn+ssh://svn.code.sf.net/p/openlcb/svn/trunk/prototypes/C@2808 87536cb5-86f1-4cdc-8fc6-3f0f71bcd267
1 parent 3319929 commit e5e0649

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

RosterNode/DCC_Proxy.cpp

+63-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
#define PROXY_SLOT_FREE 01,01,00,00,00,00,03,04
1111
#define COMMAND_STATION_EVENT 01,01,00,00,00,00,04,01
1212

13+
/***
14+
Messages under a single MTI: Priority 1, index 15, addressed => MTI 0x05E8, CAN frame [195E8sss] fd dd
15+
Content (after address bytes):
16+
1st byte selects sub-instruction. High nibble selects protocol (Train Protocol; DCC; and future ones). Low nibble is a specific operation.
17+
Train Protocol:
18+
0x00 Speed instruction, followed by 2 bytes float16 speed (sign is direction)
19+
0x01 Function instruction: 3 byte address, 2 bytes content
20+
To allow read back, the results of these operations are stored in the 0xFE memory space of the node. The train can also be controlled by direct write of these via the memory protocol.
21+
***/
22+
1323
void DCC_Proxy::initialize(void)
1424
{
1525
_dcc_address = 0;
@@ -646,7 +656,59 @@ uint8_t DCC_Proxy::readCDI(uint16_t address, uint8_t length, uint8_t *data)
646656

647657
bool DCC_Proxy::handleMessage(OLCB_Buffer *buffer)
648658
{
649-
if (buffer->isIdentifyProducers())
659+
if(buffer->isTractionControl())
660+
{
661+
Serial.println("Traction!");
662+
//do stuff here.
663+
switch(buffer->data[2])
664+
{
665+
case 0x00: //speed
666+
{
667+
_float16_shape_type f_val;
668+
Serial.println("New MTI Speed change");
669+
Serial.println("raw data");
670+
f_val.words.msw = buffer->data[3];
671+
f_val.words.lsw = buffer->data[4];
672+
Serial.print(buffer->data[3], HEX);
673+
Serial.print(" ");
674+
Serial.println(buffer->data[4], HEX);
675+
float new_speed = float16_to_float32(f_val);
676+
Serial.println(new_speed);
677+
Serial.println("----");
678+
if(new_speed == 0)
679+
{
680+
if(f_val.bits & 0x8000) //-0
681+
_speed = -1;
682+
else
683+
_speed = 1;
684+
}
685+
else
686+
{
687+
_speed = map(new_speed, -100, 100, -126, 126);
688+
if(_speed < 0) --_speed; //to get it in range -2..-126
689+
else ++_speed; //to get it in range 2..126
690+
}
691+
_active = true; //assume it has been placed on layout.
692+
_dirty_speed = true; //force transmission to CS at next update.
693+
}
694+
break;
695+
case 0x01: //function
696+
{
697+
uint32_t address;
698+
address = (buffer->data[3] << 12) | (buffer->data[4] << 8) | (buffer->data[5]);
699+
if(address >= 32)
700+
break; //can't handle it, just ditch it.
701+
if(buffer->data[6] | buffer->data[7]) //treat non-zero as "on", zero as "off"
702+
_FX |= (1<<address);
703+
else
704+
_FX &= ~(1<<address);
705+
_active = true;
706+
_dirty_FX = true;
707+
}
708+
break;
709+
}
710+
}
711+
else if (buffer->isIdentifyProducers())
650712
{
651713
//get the EventID, see if it matches the preset one.
652714
OLCB_Event evt;

0 commit comments

Comments
 (0)