|
10 | 10 | #define PROXY_SLOT_FREE 01,01,00,00,00,00,03,04
|
11 | 11 | #define COMMAND_STATION_EVENT 01,01,00,00,00,00,04,01
|
12 | 12 |
|
| 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 | + |
13 | 23 | void DCC_Proxy::initialize(void)
|
14 | 24 | {
|
15 | 25 | _dcc_address = 0;
|
@@ -646,7 +656,59 @@ uint8_t DCC_Proxy::readCDI(uint16_t address, uint8_t length, uint8_t *data)
|
646 | 656 |
|
647 | 657 | bool DCC_Proxy::handleMessage(OLCB_Buffer *buffer)
|
648 | 658 | {
|
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()) |
650 | 712 | {
|
651 | 713 | //get the EventID, see if it matches the preset one.
|
652 | 714 | OLCB_Event evt;
|
|
0 commit comments