chiark / gitweb /
realtime: print all movpos positions on entering Run
[trains.git] / cebpic / README.protocol
1 PROTOCOL BETWEEN HOST AND MASTER PIC
2 ====================================
3
4 9600 8N1 over the serial port.  The PIC must obey the host's flow
5 control line, so that if the host gets backed up none of the PICs
6 messages can get lost.  (If this is too hard, then the PIC should
7 attempt to buffer some data while the host is busy but if the PIC's
8 buffer gets too full it should panic.)
9
10 Each message consists of a number of 8-bit bytes.  The top bit of each
11 byte is 1 iff there is another byte in the message.
12
13  First       Second      ASCII  Message   Brief
14   Byte        byte etc.  or hex  name      description
15
16 From host to PIC:
17
18  > 1 0100 TTT  0 TTTTTTT  (a0)  POINT     Point T fire
19  > 1 1111 111  ....       (ff)  NMRADATA  NMRA data
20  > 1 0001 XXX  0 XXXXXXX  (88+) PING      Ping `X' (please Pong `X(+)0x5a')
21  > 1 0010 RRR  E RRR...   (90+) POLARITY  Set polarity
22  > 1 0011 000  0 MMMMMMM  (98+) WATCHDOG  W'dog reset, t/o <M*16>ms from now
23  > 0 0010 001             (11)  ON        Power on
24  > 0 0010 000             (10)  OFF       Power off
25
26  > 1 0101 WWW  0 WWWWWWV  (a1)  WAGGLE    Set pin WWWWWWWWW to level V
27
28 ;> 00000000                     CRASHED   Acknowledge panic, go to readout mode
29 ;> 00001010               (0a)  TELLMODE  Confirm mode - say HELLO or CRASHED
30 ;                                          if crashed, undoes the effect of ack
31
32 ; In crash readout mode:
33 ;
34 ;       00000000  MS    Select crash readout mode if not already
35 ;                       Reset crash readout pointer to 0
36 ;
37 ;       00001000        Acknowledge RS232 framing error or overrun
38 ;       00001001        Reboot
39 ;
40 ;       1vvvvvvv  M     Prepare byte 0vvvvvvv for transmission to the slave
41 ;
42 ;       00000nnn  M     (n>0) prepare to receive nnnn bytes from slave
43 ;       0001nnnn  M     (n>0) transmit nnnn bytes of our own from the
44 ;                         readout pointer
45 ;
46 ;       001sssss  M     Select slave S^0x10.  Then:
47 ;                        After 1vvvvvvv
48 ;                         Transmit just 0vvvvvvv to slave
49 ;                         and then send some some unspecified byte to host
50 ;                        After 0000nnnn
51 ;                         Receive nnnn bytes, forwarding each one
52 ;                         to the host.
53 ;                        After the transaction is complete, 1vvvvvvv
54 ;                         or 0000nnnn must be specified again before
55 ;                         001sssss is repeated.
56 ;
57 ;       01bbbbbb  MS    Supply 6 bits for crash readout pointer
58 ;                        (crash readout mode only)
59 ;                        Effect is   FSR << 6; FSR |= bbbbbb
60
61 From PIC to host:
62
63  < 1 001Y SSS  0 SSSSSSS  (9?)  DETECT    Train is (Y=1) or is not (Y=0) at S
64  < 1 0001 XXX  0 XXXXXXX  (88+) PONG      Pong `X' (reply to Ping `X(+)0x5a')
65  < 1 100 0001  0 NNNNNNN  (ENQ) SPURIOUS  Number of spurious fault interrupts
66  < 0 000 1001             (HT)  HELLO     I am booted
67  < 0 000 1011             (VT)  AAARGH    Followed by debug chars (only)
68  < 0 000 1101             (CR)  WTIMEOUT  Watchdog timeout happened
69  < 0 000 0111             (BEL) FAULT     Fault exists
70  < 0 000 0110             (ACK) RETRIABLE Fault may be tested once more
71  < 0 000 0100             (ENQ) WAGGLED   Pin changed according to WAGGLE
72  < 0 0100 PPP             (20+) POINTED   Point change done using capacitor P
73  < 0 0101 PPP             (28+) CHARGED   Point capacitor P is now charged
74  < 0 00000 00                   NUL       Junk, prob because layout turned off
75  < 0 00000 FF                   NMRADONE  Have processed F NMRADATA message(s)
76
77  < 0000 1010              (LF)  } debugging output        0x0a (newline) and
78  < 001C CCCC                    } (works with terminal      0x20-0x7e
79  < 01CC CCCC except 0111 1111   }  emulator, or host logs)  (printing ASCII)
80
81 (These are all shown big-endian, and all of the numerical
82 representations are big-endian too.  Where a number is split across
83 two or more bytes, the relevant bits are to be concatenated, in the
84 order shown, ie bits from the MS byte first, into a larger number.)
85
86
87 HELLO, AAARGH and debugging output
88 ----------------------------------
89
90 When the master PIC starts up and has confirmed that all is well (all
91 of the other PICs are there, etc), it should send HELLO once.
92
93 If the host makes a mistake (eg, sends an unknown command, or does
94 something else wrong) or something goes horribly wrong, the master PIC
95 should send AAARGH.
96
97 The PIC may always send printing ASCII characters and spaces and
98 newlines (ie, bytes 0x0a, 0x20-0x7e).  These will print out nicely in
99 a terminal emulator, if that's what's running on the host.  If the
100 host is running the real software, that software will put the
101 characters sent in its log or somewhere else nicely accessible.
102
103 Apart from debugging output, the PIC should send nothing before HELLO
104 and nothing after AAARGH.
105
106
107 POWER AND FAULT
108 ---------------
109
110 The host can send ON and OFF to turn the track (and various other
111 stuff) on and off.  After ON, the track power should be enabled and
112 transmitting NMRA idle, and the CDU should be enabled.
113
114 If the power is ON, and a track power short circuit is detected, the
115 PIC should send FAULT.  When the short circuit is removed, the PIC
116 should send FIXED but not fully reenable track power; track power
117 should be reenabled when the host transmits ON.
118
119
120        Track and CDU                     Track and CDU  ----->-----.
121         disabled      -------ON------->   enabled                   \
122           .     __                    __                             |
123          /|\   |`-._             ON  ,-'|    |,--------<-------.     |
124           |         `-._          ,-'        |                  |    |
125        OFF|         OFF `-._   ,-'           |Short             |    |
126           |                 ,-' _       FAULT| circuit          |    |
127      ,->-'|              ,+'     `-._        | detected         |    |
128     /     |           ,-' |         `-._     V                  |    |
129    |                 '    |             `                       |    |
130    |   Track disabled     |               Wait for post-fault   |    |
131    |   CDU enabled     <-----500ms------   minimum off time     |    |
132    |   User Fault         |  RETRIABLE    User fault            |    |
133    |    flashes slowly    |                flashes rapidly      |    |
134    |                     /                                      |    |
135     \                   '                                       |    |
136      `----- Track disabled  ---------------->-------------------'   /
137             CDU enabled     ----------------<----------------------'
138             User Fault lit      WTIMEOUT        watchdog timer runs out
139
140
141
142
143
144 If ON or OFF are issued in the first 500ms following a short circuit,
145 they are ignored.
146
147
148 POINTS and CDU
149 --------------
150
151 The ON command should cause the CDU to be enabled (and of course all
152 point motor outputs should be disabled first - see README.circuitry).
153
154 Following ON the host must wait until it receives CHARGED before
155 attempting to change a point.  After CHARGED it may send POINT, to
156 activate the point and direction specified by T.  The PICs will report
157 POINTED when the point has stopped moving, and CHARGED when the CDU is
158 ready to change another point (the host may not send POINT for a point
159 on the same CDU until then).
160
161 Currently there is only one CDU so P is always 0 (but the PICs need
162 not check that the received P value is 0; they may simply assume it).
163
164
165     ----ON-----> CDU is  ------CHARGED---> CDU is charged
166                  charging              _.  and ready
167                                        /|
168                         ,----CHARGED--'       |
169                        /                      |POINT
170                       /                       |
171            Point has '                        V
172          changed; CDU
173         is recharging  <----POINTED----  Point is changing
174
175
176 Note that OFF will turn the CDU off, and a short circuit (FAULT) will
177 turn it off 500ms later (this delay avoids losing races where the host
178 sends a point change instruction just before a short happens).
179
180
181 PING and PONG
182 -------------
183
184 The host may send PING at any time; the PIC should reply with PONG
185 with the same X as was in the PING message, but with the bottom byte
186 xor'd with 0x5a..  The host may not send another PING until the first
187 one's PONG has come back.
188
189
190 POLARITY
191 --------
192
193 The POLARITY command may be sent whether the track power is enabled or
194 disabled.  The polarity of each segment is `unreversed' after ON; it
195 remains constant until from then on except as modified by POLARITY.
196
197 The command is of variable length (but at least two bytes):
198
199  > 1 0010 RRR  E RRR...         POLARITY  Set polarity
200
201 Each byte after the first contains 7 more R bits.  The first R bit
202 (most significant R bit in the first byte) corresponds to track
203 reversal segment 1; The next bit (2nd most significant bit in the
204 first byte) corresponds to track reversal segment 2; and so on.
205
206 Bits which do not correspond to defined reversal segments will be
207 ignored by the PICs.  The host must send exactly as many bytes as are
208 necessary to include all of the reversal segments for each reversers
209 board (for every potential reversal segment, regardless of whether
210 that segment is a defined segment corresponding to some actual track;
211 however a board with _no_ reversers segments used does not count).
212
213 For example, if there are 14 reversible segments (numbered 1 to 14)
214 then the following message
215    1 0010 000    1 000 1000    0 111 1010     Actual message
216   (E      RRR)  (E RRR RRRR)  (E RRR R---)    } helpful annotations
217                           1      111 1111     }  and commentary
218           123      456 7890      123 4567     }
219 specifies to reverse segments 7 and 11 to 14.  The trailing bits are
220 for segments 15 to 17 and are ignored.  (Note that the assignment of
221 physical segments to segment numbers is complex due to bit-twiddling.
222 see detpic/reverse.asm and layout/data2safety.)
223
224
225 NMRADATA and NMRAFULL
226 ---------------------
227
228 The data bits in all of the bytes of the NMRADATA command (including
229 the first) are simply transmitted as NMRA data to the track (most
230 significant bit first).  The top `end of packet' bit is not
231 transmitted, though.
232
233 The first 14 data bits in the NMRA packet should be 1s.  (i.e. the
234 first two complete bytes should be 11111111 11111111).  Packets
235 beginning with a different first byte are reserved for other commands
236 to the PIC and the 14 idle bits are a requirement of the NMRA
237 specification.
238
239 The maximum NMRA message length is 15 bytes each carrying 7 bits of
240 actual NMRA data (i.e. 105 bits).
241
242 Up to three NMRADATA commands may be supplied by the host to the
243 master PIC, and their will be transmitted in sequence.  After each
244 NMRADATA is completed, the PIC will send an NMRAFULL message to the
245 host.  In the NMRAFULL message, F is the number of completely-received
246 NMRADATA commands awaiting transmission to the track.
247
248 If the PIC runs out of NMRA data, it will transmit an NMRA idle
249 stream.  It is an error for the host to try to have more than three
250 outstanding NMRADATA commands.
251
252
253 DETECT
254 ------
255
256 The DETECT command indicates to the host whether there is currently a
257 train being detected at a specific location.  The PIC must send a
258 DETECT with Y=1 when a train is detected in a location where there was
259 previously none, and with Y=0 when a train ceases to be detectable for
260 more than a small amount of time.
261
262 At HELLO, the host will assume that no trains are being detected.
263
264
265 RAM (data) memory map
266 =====================
267
268 The data memory map (for PIC18F458) looks like this:
269
270  0x000-0x05f    Access bank RAM - RAM locations accessible via
271                  access bank instructions; also form part of
272                  RAM page 0
273  0x060-0x0ff    Remainder of RAM page 0, accessible only via correct
274                  BSR setting (ie, BSR==0), INDF, etc.
275
276  0x100-0x1ff    RAM page 1, accessible only via bank switching etc.
277  0x200-0x2ff    RAM page 2, accessible only via bank switching etc.
278  0x300-0x3ff    RAM page 3, accessible only via bank switching etc.
279  0x400-0x4ff    RAM page 4, accessible only via bank switching etc.
280  0x500-0x5ff    RAM page 5, accessible only via bank switching etc.
281
282  0x600-0xeff    Nothing here, don't try to access.
283
284  0xf00-0xf5f    SFR's (memory-mapped peripherals etc.) accessible
285                  only via correct BSR, INDF, etc - but these are only
286                  the CAN SFR's and we do not use the CAN controller.
287  0xf60-0xfff    SFR's accessible via access bank (also form part
288                  of RAM page 15).
289
290
291 See common.inc for actual uses of the RAM areas.
292
293
294 Program (flash etc.) memory map
295 ===============================
296
297 Program memory map (for PIC18F458) looks like this:
298
299   0x00 0000-    Program memory
300   0x00 7fff      Contains actual program instructions and can also
301                  contain preprogrammed data provided via special .asm
302                  files.  Notable contents and addresses:
303                    0x00 0000  reset vector
304                    0x00 0008  high-priority interrupt vector
305                    0x00 0018  low-priority interrupt vector
306                  See common.inc for some special tables in here, for
307                  morse messages, pin/hardware-object definitions, etc.
308
309   0x20 0000-    ID locations
310   0x20 0007      Programming which varies per PIC.  Programmed by
311                  idlocs*.asm which are made by make-idlocs and
312                  included in perpic*.hex.  Contents:
313
314                 0x20 0000
315                   bits 7-5 = 000
316                   bits 4-0 = PIC number (guaranteed to be
317                              in the range 0..31 inclusive)
318                 0x20 0001
319                   bit 7     = 1 for the main PIC (#0)
320                               0 otherwise
321                   bit 6     = 1 for Reversers board, 0 for Detectors
322                   bits 0-5  = currently unused, set to 0
323
324                 0x20 0002-  } not currently used,
325                 0x20 0007   }  may contain anything
326
327   0x30 0000-    Hardware configuration
328   0x30 000f      Defines (clock source, WDT operation, etc.)
329                  Probably best not to touch.  `config.asm' provides
330                  correct contents, which is included in *-withcfg.hex
331                  and perpic*.hex.
332
333   0x3f fffe-    Hardware device ID
334   0x3f ffff      Fixed at manufacturing time; can be read to discover
335                  hardware type and version (probably not very useful)
336
337   0xf0 0000-    EEPROM data area
338   0xf0 00ff      Not currently used by us
339
340   0x01 0000-    } These locations, not listed above,
341   0x1f ffff     }   do not correspond to anything - there
342   0x20 0008-    }   is no hardware or memory in the chip
343   0x2f ffff     }   at these locations.
344   0x30 0010-    }
345   0x3f fffd     } Accessing them isn't useful
346   0x40 0000-    }   and should probably be avoided.
347   0xef ffff     }
348
349
350 (Buffer page 50 0000h reserved for NMRA)    XXXX these look wrong
351 (Buffer page 40 0000h reserved for i2c)     XXXX   -iwj
352
353
354
355 I2C
356 ===
357 (slave addresses will be 10xxxxx where xxxxx=PIC number above)