-NMRA
-====
+PROTOCOL BETWEEN HOST AND MASTER PIC
+====================================
-NMRA packets from the computer to the PIC should consist of 8-bit bytes.
+9600 8N1 over the serial port. The PIC must obey the host's flow
+control line, so that if the host gets backed up none of the PICs
+messages can get lost. (If this is too hard, then the PIC should
+attempt to buffer some data while the host is busy but if the PIC's
+buffer gets too full it should panic.)
-bits 6-0 contain the data to be sent to the track
-bit 7 is 1 if the byte is the last in the packet and 0 otherwise
-
-The first 14 data bits in the NMRA packet should be 1s.
-(i.e. the first two complete bytes should be 01111111 01111111)
-(packets beginning with some other sequence are reserved for non-NMRA messages)
+Each message consists of a number of 8-bit bytes. The top bit of each
+byte is 1 iff there is another byte in the message.
-Maximum NMRA message length = 15 bytes (i.e. 105 bits).
-Messages longer than this will cause things to get confused at the moment.
+ First Second ASCII Message Brief
+ Byte byte etc. name description
-baud rate 9600
-most significant bit first
-8n1
+From host to PIC:
+ > 1 0100 TTT 0 TTTTTTT POINT Point T fire
+ > 1 1111 111 .... NMRADATA NMRA data
+ > 1 0001 XXX 0 XXXXXXX PING Ping `X' (please Pong `X')
+ > 1 0010 RRR E RRR... POLARITY Set polarity
+ > 0 0100 001 ON Power on
+ > 0 0100 000 OFF Power off
+
+From PIC to host:
+
+ < 1 001Y SSS 0 SSSSSSS DETECT Train is (Y=1) or is not (Y=0) at S
+ < 1 0001 XXX 0 XXXXXXX PONG Pong `X' (reply to Ping `X')
+ < 0 000 1001 (HT) HELLO I am booted
+ < 0 000 1011 (VT) AAARGH Followed by debug chars (only)
+ < 0 000 0111 (BEL) FAULT Fault exists
+ < 0 000 0110 (ACK) FIXED Fault now fixed
+ < 0 000 0100 POLARISED Set polarity done
+ < 0 0100 PPP POINTED Point change done using capacitor P
+ < 0 0101 PPP CHARGED Point capacitor P is now charged
+ < 0 00000 FF NMRAFULL F pending NMRA messages
+
+ < 0000 1010 (LF) } debugging output 0x0a (newline) and
+ < 001C CCCC } (works with terminal 0x20-0x7e
+ < 01CC CCCC except 0111 1111 } emulator, or host logs) (printing ASCII)
+
+(These are all shown big-endian, and all of the numerical
+representations are big-endian too. Where a number is split across
+two or more bytes, the relevant bits are to be concatenated, in the
+order shown, ie bits from the MS byte first, into a larger number.)
+
+
+HELLO, AAARGH and debugging output
+----------------------------------
+
+When the master PIC starts up and has confirmed that all is well (all
+of the other PICs are there, etc), it should send HELLO once.
+
+If the host makes a mistake (eg, sends an unknown command, or does
+something else wrong) or something goes horribly wrong, the master PIC
+should send AAARGH.
+
+The PIC may always send printing ASCII characters and spaces and
+newlines (ie, bytes 0x0a, 0x20-0x7e). These will print out nicely in
+a terminal emulator, if that's what's running on the host. If the
+host is running the real software, that software will put the
+characters sent in its log or somewhere else nicely accessible.
+
+Apart from debugging output, the PIC should send nothing before HELLO
+and nothing after AAARGH.
+
+
+POWER AND FAULT
+---------------
+
+The host can send ON and OFF to turn the track (and various other
+stuff) on and off. After ON, the track power should be enabled and
+transmitting NMRA idle, and the CDU should be enabled. (ON - or the
+things that might precede ON such as FAULT etc. - should clear the
+data from any previous NMRADATA commands.)
+
+If the power is ON, and a track power short circuit is detected, the
+PIC should send FAULT. When the short circuit is removed, the PIC
+should send FIXED but not fully reenable track power; track power
+should be reenabled when the host transmits ON.
+
+
+ Track and CDU Track and CDU
+ disabled -------ON-------> enabled
+ . (clears NMRA
+ /|\ buffers) |
+ | |Short circuit detected
+ \ |
+ \FIXED FAULT
+ \ |
+ \__________________ V
+ operator `
+ fixes the short Short circuit
+ (User Fault indicator lit)
+
+
+
+POINTS and CDU
+--------------
+
+The ON command should cause the CDU to be enabled (and of course all
+point motor outputs should be disabled first - see README.circuitry).
+
+Following ON the host must wait until it receives CHARGED before
+attempting to change a point. After CHARGED it may send POINT, to
+activate the point and direction specified by T. The PICs will report
+POINTED when the point has stopped moving, and CHARGED when the CDU is
+ready to change another point (the host may not send POINT for a point
+on the same CDU until then).
+
+Currently there is only one CDU so P is always 0 (but the PICs need
+not check that the received P value is 0; they may simply assume it).
+
+
+ ----ON-----> CDU is ------CHARGED---> CDU is charged
+ charging _. and ready
+ /|
+ ,----CHARGED--' |
+ / |POINT
+ / |
+ Point has ' V
+ changed; CDU
+ is recharging <----POINTED---- Point is changing
+
+
+
+PING and PONG
+-------------
+
+The host may send PING at any time; the PIC should reply with PONG
+with the same X as was in the PING message. The host may not send
+another PING until the first one's PONG has come back.
+
+
+POLARITY and POLARISED
+----------------------
+
+The POLARITY command may be sent whether the track power is enabled or
+disabled. The polarity of each segment is `unreversed' after ON; it
+remains constant until from then on except as modified by POLARITY.
+
+The command is of variable length (but at least two bytes):
+
+ > 1 0010 RRR E RRR... POLARITY Set polarity
+
+Each byte after the first contains 7 more R bits. The first R bit
+(most significant R bit in the first byte) corresponds to track
+detection segment 1; The next bit (2nd most significant bit in the
+first byte) corresponds to track detection segment 2; and so on.
+
+Bits which do not correspond to defined track detection segments will
+be sent as 0 by the host but may be ignored by the PICs. The host
+must send exactly as many bytes as are necessary to include all of the
+defined segments.
+
+For example, if there are 14 detection segments (numbered 1 to 14)
+then the following message
+ 1 0010 000 1 000 1000 0 111 1010 Actual message
+ (E RRR) (E RRR RRRR) (E RRR R---) } helpful annotations
+ 1 111 1111 } and commentary
+ 123 456 7890 123 4567 }
+specifies to reverse segments 7 and 11 to 14. The trailing bits are
+for segments 15 to 17 and are ignored.
+
+The PIC will reply to POLARITY with POLARISED when the polarity change
+is complete. The host must not send another POLARITY until then.
+
+
+NMRADATA and NMRAFULL
+---------------------
+
+The data bits in all of the bytes of the NMRADATA command (including
+the first) are simply transmitted as NMRA data to the track (most
+significant bit first). The top `end of packet' bit is not
+transmitted, though.
+
+The first 14 data bits in the NMRA packet should be 1s. (i.e. the
+first two complete bytes should be 11111111 11111111). Packets
+beginning with a different first byte are reserved for other commands
+to the PIC and the 14 idle bits are a requirement of the NMRA
+specification.
+
+The maximum NMRA message length is 15 bytes each carrying 7 bits of
+actual NMRA data (i.e. 105 bits).
+
+Up to three NMRADATA commands may be supplied by the host to the
+master PIC, and their will be transmitted in sequence. After each
+NMRADATA is completed, the PIC will send an NMRAFULL message to the
+host. In the NMRAFULL message, F is the number of completely-received
+NMRADATA commands awaiting transmission to the track.
+
+If the PIC runs out of NMRA data, it will transmit an NMRA idle
+stream. It is an error for the host to try to have more than three
+outstanding NMRADATA commands.
+
+
+DETECT
+------
+
+The DETECT command indicates to the host whether there is currently a
+train being detected at a specific location. The PIC must send a
+DETECT with Y=1 when a train is detected in a location where there was
+previously none, and with Y=0 when a train ceases to be detectable for
+more than a small amount of time.
+
+At HELLO, the host will assume that no trains are being detected.
RAM (data) memory map
0x00 0018 low-priority interrupt vector
See common.inc for some special tables in here, for
morse messages, pin/hardware-object definitions, etc.
-
+
0x20 0000- ID locations
0x20 0007 Programming which varies per PIC. Programmed by
idlocs*.asm which are made by make-idlocs and
0x20 0002- } not currently used,
0x20 0007 } may contain anything
-
+
0x30 0000- Hardware configuration
0x30 000f Defines (clock source, WDT operation, etc.)
Probably best not to touch. `config.asm' provides
correct contents, which is included in *-withcfg.hex
and perpic*.hex.
-
+
0x3f fffe- Hardware device ID
0x3f ffff Fixed at manufacturing time; can be read to discover
hardware type and version (probably not very useful)
0xf0 0000- EEPROM data area
0xf0 00ff Not currently used by us
- 0x01 0000- } These locations, not listed above,
- 0x1f ffff } do not correspond to anything - there
- 0x20 0008- } is no hardware or memory in the chip
- 0x2f ffff } at these locations.
+ 0x01 0000- } These locations, not listed above,
+ 0x1f ffff } do not correspond to anything - there
+ 0x20 0008- } is no hardware or memory in the chip
+ 0x2f ffff } at these locations.
0x30 0010- }
0x3f fffd } Accessing them isn't useful
0x40 0000- } and should probably be avoided.