summaryrefslogtreecommitdiff
path: root/rpi2/design.txt
blob: 6957ad5058cfcb26806ff3b8085e965f79736790 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
Arduino

RPi modules:
 - Serial communication
 - Wireless map distribution
 - Routing module

Considerations:
 - Disable XON/XOFF or bytes 0x11 and 0x13 get eaten by the RPi.
 - RPi off, Uno turns on. Uno does not need to wait for RPi.
 - RPi already on, Uno just turns on. RPi needs to wait for Uno and then perform
   a reset.
 - RPi is basically the client (controlling the server)
 - Uno is basically the server

[RPi]->Uno serial handshake:
 1. Send RESET1 command.
 2. Read a byte.
    - If it is ACK1, goto 3.
    - Else repeat 1.
 3. Send RESET2 command.
 4. Read a byte.
    - If it is ACK1, repeat 4.
    - If it is ACK2, finish.
    - Else goto 1.

RPi->[Uno] serial handshake (state = UNKNOWN):
 1. Read a byte.
    - If equal to RESET1, goto 2.
    - Else write OUTOFSYNC and finish.
 2. Discard buffers and send ACK1.
 3. Wait for byte.
    - If it is RESET1, goto 2.
    - If it is RESET2, write ACK2, set state = READY and finish.
    - Else ignore and finish.

Protocol (byte-oriented):
Higher-level header (1-2 bytes):
10.. ....
  00 00..               (Handshake, chosen to reduce need to escape signed bytes)
       01               RESET1 ([RPi]->Uno) / ACK1 ([Uno]->RPi)
       10               RESET2 ([RPi]->Uno) / ACK1 ([Uno]->RPi)
       11               OUTOFSYNC, please reset ([Uno]->RPi)
  00 0000               PING ([Uno]->RPi) / PONG ([RPi]->Uno)
  00 0100  00.. ....    DATA_ESCAPE ([Uno]->RPi) Read as 10.. ....
  00 1...  101. ....    DATA_LEN2 ([Uno]->RPi) max len 256, len=...+1)
  .. ....               DATA_LEN1 ([Uno]->RPi) max len 56, len=...-7)

Rationale for no PING from RPi to Uno is because the Pi is helpless if the
Arduino died.
Rationale for DATA_ESCAPE is to avoid interpretation as handshake.
Rationale for DATA_LEN2 encoding is to avoid interpreting as handshake, but
still pass the length definition to the control handler.

Note: data length describes the length of decoded bytes following the header.
Example for sending the byte sequence for debug print:

    1111 0000  0111 1111  1011 1111
    aaaa bbbb  cccc dddd  eeee ffff

becomes:

    1000 0110  1111 0000  0111 1111  1000 0000  0011 1111
     (len=3)   aaaa bbbb  cccc dddd  eeee eeee  eeee ffff


Data is interpreted as follows:

0... ....  .... ....    Bits that need to be updated (max 15). The length of the
                        following data depends on this.
1000 0000               Debug packet, max len is determined by higher-level hdr.

Serial state machine:

init -->-- Device unavailable
         /                   \
        |                     \
        v device connected     ^ IO error
        |                      |
         \                     /
           Device available  -

RPi architecture

       main
         |
   +-----+------+---------------+
  |             |               |
serial        route           map sync
 I/O         finder       with others (optional)

route finder:
 - updates map based on data updates
 - suggests alternative directions

serial I/O
 - queues map updates from Uno and fwds to route finder
 - takes route suggestions and fwds to Uno

Linear flow:
 - I/O (in) has data update
 - data update dispatch to route finder
 - route finder calculates optimal route to target
 - route finder gives next directions
 - I/O (out) to Uno