- Section 1 - Introduction
- Section 2 - Hardware Implementation
- Section 3 - Software and Logical Implementation
- Section 4 - Component-Level Integration
As would be expected, individual components spewing data are not, by themselves, very
useful. Since MRBus is initially designed to replace signal systems with literally dozens
of individual logic lines connecting nodes, a sensible starting point is the ability to build "virtual logic connections" between nodes.
For example, take the following ABS signaling setup:
(insert picture here)
Nodes 0x71-0x73 clearly need logical inputs from block detectors 0x11 and 0x12 in order
to determine the correct aspects on the signals. For simple R-Y-G signaling, at least two
inputs are needed for each signal – immediate block occupancy (the block the signal is
guarding), and adjacent block occupancy (the block beyond the immediate block). We'll
call these inputs IMD and ADJ for brevity. So, for the westbound signal (right-facing) on
0x73, it needs the occupancy of Block N for its IMD input, and Block O for its ADJ input.
Block detector 0x11 is transmitting Data ('D') packets that are as follows:
[0x11][0xFF][CRC (16b)][0x07][0x44][b0000(-)(-)(P)(O)]
Block detector 0x12 is transmitting Data ('D') packets that are as follows:
[0x12][0xFF][CRC (16b)][0x07][0x44][b0000(-)(M)(N)(-)]
In both cases, the last byte is a bitmap of occupancy statuses, where (*) represents the
occupancy of block *, or (-) means unknown or not relevant.
A fundamental recommended practice with MRBus is to make all possibly needed outputs a bit. That way virtual logic connections are possible by just selecting bits out of
incoming packets. This input selection process, known as "building virtual logic
connections", should allow the user to specify by source address, packet type, and
bit/byte position the desired input. For complex logic, a combination of inputs may be
used, but as in most cases simplicity is to be valued.
Source and packet type are fairly straightforward – if you want the input from a 'D' packet sent by a detector at 0x12, your source is 0x12 and your type is 0x44 ('D' in ASCII). Bit/byte are more complex, as they can be bitpacked into a single byte to save
configuration memory space.
It's recommended they be assembled as follows:
@@Bit/byte = XXXYYYYY
XXX = Bit number, 0-7
YYYYY = Byte number, from start of packet. Source address is byte 0@@
So, signal node 0x73 has, in its configuration values (CV), positions for source address,
packet type, and byte/bit to use as the IMD and ADJ virtual logic connections. Let's say
these are CV10, CV20, and CV30 for IMD and CV11, CV21, and CV31 for ADJ.
So, to configure the Westbound IMD input to read block N:
@@CV10 (IMD Source Addr)= 0x12 (Block N's detector address)
CV20 (IMD Packet Type)= 0x44 ('D')
CV30 (IMD Byte/Bit) = 0x26 (Bit 1 (XXX=b001) and byte 6 (YYYYY=b00110)@@
Likewise, the Westbound ADJ input for Block O would be configured as:
@@CV11 (ADJ Source Addr)= 0x11 (Block O's detector address)
CV21 (ADJ Packet Type)= 0x44 ('D')
CV31 (ADJ Byte/Bit) = 0x06 (Bit 0 (XXX=b000) and byte 6 (YYYYY=b00110)@@
The virtual logic connections for the eastbound signal would have similar configurations,
except being set up to read Block M and the unnamed (and not shown) block to the right
of that.
So, the example conversation on the bus would look like:
@@[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:00 Regular update on 0x11
[0x12][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:00 Regular update on 0x12
[0x72][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:00 Two greens on 0x72
[0x71][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:00 Two greens on 0x71
[0x73][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:00 Two greens on 0x73
Next Second ----
[0x12][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:01 Regular update on 0x12
[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:01 Regular update on 0x11
[0x12][0xFF][CRC16][0x07][0x44][b00000100] -- 00:00:01 Train enters Block M
[0x73][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:01 Eastbound drops to red
[0x72][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:01 Eastbound drops to yellow
Next Second ----
[0x12][0xFF][CRC16][0x07][0x44][b00000100] -- 00:00:02 Regular update on 0x12
[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:02 Regular update on 0x11
[0x71][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:02 Two greens on 0x71
[0x73][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:02 E=Red, W=Grn on 0x73
[0x72][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:02 E=Ylw, W=Grn on 0x72
... Time elapses ...
[0x12][0xFF][CRC16][0x07][0x44][b00000110] -- 00:00:33 Train enters Block N
[0x71][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:33 E=Ylw, W=Grn on 0x71
[0x72][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:33 E=Red, W=Grn on 0x72
[0x73][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:33 E=Red, W=Grn on 0x73
[0x12][0xFF][CRC16][0x07][0x44][b00000100] -- 00:00:33 Regular update on 0x12
[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:33 Regular update on 0x11
Next Second ----
[0x12][0xFF][CRC16][0x07][0x44][b00000110] -- 00:00:34 Regular update on 0x12
[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:34 Regular update on 0x11
Next Second ----
[0x11][0xFF][CRC16][0x07][0x44][b00000000] -- 00:00:35 Regular update on 0x11
[0x12][0xFF][CRC16][0x07][0x44][b00000010] -- 00:00:35 Block M clears
[0x71][0xFF][CRC16][0x07][0x53][0x21] -- 00:00:35 E=Ylw, W=Grn on 0x71
[0x73][0xFF][CRC16][0x07][0x53][0x11] -- 00:00:35 E=Grn, W=Grn on 0x73
[0x72][0xFF][CRC16][0x07][0x53][0x41] -- 00:00:35 E=Red, W=Grn on 0x72@@
...and so it goes. This bus example should give you some idea of how devices
communicate on a simple, basic level using the example ABS system pictured above.
In addition, it should be noted that CV0-9 are reserved for standardized uses. At the
moment, only CV1 is used, however.
@@CV0 = Undefined
CV1 = Device Address (should initialize to 0x00)
CV2 = Undefined
CV3 = Undefined
CV4 = Undefined
CV5 = Undefined
CV6 = Undefined
CV7 = Undefined
CV8 = Undefined
CV9 = Undefined@@
A special set of commands, packet types 'R' and 'W', have been reserved to read and write
the CV registers. The format of these packets should be as follows, and universal across
devices:
@@[SRC][DEST][0x07][CRC16]['R'][CV_ADDR]
[SRC][DEST][0x08][CRC16]['W'][CV_ADDR][VAL]@@
SRC = Source of packet – device doing the programming, usually a computer interface
DEST = Device being programmed, 0x00 if the device has not been set to its own address yet, since all programmed devices will ignore a destination of 0x00 (*nobody*).
LEN = Length of packet – 7 for 'R' commands, 8 for 'W' commands
CRC16 = Packet checksum, computed when sent
CV_ADDR = Address of the configuration value to be manipulated (0 -???)
VAL = For writing CVs, the value to be written.