chiark / gitweb /
delete old design comment from ceb for detect
[trains.git] / detpic / detect.asm
1 ;======================================================================
2 ; DETECTION AND SLAVE I2C
3
4 ; FSR1 is used as pointer to where to add bytes of message; it
5 ;  points to previous byte whose top bit must be set before
6 ;  adding another bit
7
8 ; FSR2 is used as readout pointer
9
10  include common.inc
11
12 ; I2C protocol is as follows:
13 ;
14 ;  Master periodically polls each slave, addressing it for reading.
15 ;  The slave replies with the first byte of a self-delimiting message.
16 ;  The master must then read the whole message before doing anything
17 ;  else on the bus.
18 ;
19 ;  First byte is like this:
20 ;       MM 05 B2 B1  10 13 16 08        (detectors)
21 ;       MM zz 01 02  03 00 04 05        (reversers)
22 ;  where
23 ;       B1 and B2 indicates that the is more detection data;
24 ;               each bit corresponding to a subsequent byte:
25 ;               if the bit is set the byte is present; otherwise
26 ;               it is skipped and the contents can be presumed
27 ;               to be the same as last time (initially: 0)
28 ;       zz      is a zero bit
29 ;       MM      indicates that there are extra message byte(s)
30 ;       two digits indicates that the bit is the corresponding
31 ;               detection information.  The bit is clear iff current
32 ;               was detected since the last poll by the master.
33 ;               The bit value is not defined for unused sense
34 ;               segments.
35 ;
36 ;  Following that are the zero, one or two more bytes of
37 ;  detection data:
38 ;       19 09 12 15  18 04 20 17        iff reversers and B1 was set
39 ;       06 01 07 02  11 14 03 00        iff reversers and B2 was set
40 ;
41 ;  Finally, zero or more bytes of extra messages:
42 ;       MM XX XX XX  XX XX XX XX
43 ;  where
44 ;       MM      indicates that further extra message bytes follow;
45 ;               it is clear iff this is the last extra message byte.
46 ;       XX      are the lower 7 bits of a POINTED
47 ;               or AAARGH message (see README.protocol).
48
49 ; Master may also write to slave.  Every written byte is independent:
50 ;
51 ;       11RRRRRR        Set reverse to RRRRRR, see reverse.asm
52 ;       100PPPPP        Fire point PPPPP
53 ;
54 ;       00000000        Acknowlege that slave has crashed, and
55 ;                        switch into crash readout mode
56
57 ;======================================================================
58 ; variables and memory organisation
59
60 max_messages equ 4
61
62  udata_acs
63
64 unattendedl     res     1       ; counts up; each det loop it is
65 unattendedh     res     1       ; incremented by no. of bytes of pc in
66 unattendedu     res     1       ; det loop; if it overflows, led is set to red
67
68 scana           res     1 ; see bit-twiddling below
69 scanb           res     1
70 scanc           res     1
71 scand           res     1
72 scane           res     1
73
74 last1           res     1
75 last2           res     1
76
77 buf0_startval           res     1 ; reversers start with some det bits
78 buf0                    res     1
79 message_buffer          res     max_messages
80 message_buffer_end      res     0
81
82 ;----------------------------------------------------------------------
83 ; buf0, message_buffer, and FSR1 are used mainly for recording
84 ; non-detection messages.  They look like this:
85 ;
86 ;  +--------+--------+--------+--------+--------+
87 ;  |  buf0  | message_buffer...                 |
88 ;  +--------+--------+--------+--------+--------+
89 ;
90 ;  |0d0d0000|???????? ???????? ???????? ????????|   no extra messages
91 ;   ^
92 ;  |1d0d0000|0aaaaaaa ???????? ???????? ????????|   one extra byte
93 ;            ^
94 ;  |1d0d0000|1aaaaaaa 0bbbbbbb ???????? ????????|   two extra bytes
95 ;
96 ; etc.    Bits labelled `d' are detection data on reversers boards
97 ;          0 on detectors boards; `a' and `b' are extra message data;
98 ;          `^' indicates the byte pointed to by FSR1
99 ;
100 ;----------------------------------------------------------------------
101 ;
102 ; outbuf and FSR2 are used (on slaves) for the message we are
103 ; transmitting.  FSR2 points to the next byte to transmit (ie, which
104 ; will be read).  outmsg_end points to the first byte after the
105 ; message, and is used for read overrun detection.
106 ;
107 ; During i2csu_read_begin (High ISR), the actual first byte of the
108 ; message to be sent is calculated from buf0, and transmitted; the
109 ; extra detection bytes (if any) are stored in outbuf, and any extra
110 ; messages (from message_buffer) are also appended to outbuf.
111 ;
112 ;======================================================================
113         code
114
115 ;----------
116 detect_local_init
117         mov_lw  b'111'  ; turn off comparator, or we can't use pins
118         mov_wf  CMCON   ;   RD0-RD4 as digital inputs
119         mov_lw  b'0110' ; turn off A/D except perhaps for pin
120         ior_wff ADCON1  ;   AN0 ie SPARE ie RA0 (same reason as above)
121
122         ; compute buf0_startval
123         clr_w
124         bt_f_if0 idloc1,idloc1_boarddet
125         mov_lw  0x14 ; see under reversers, below
126         mov_wf  buf0_startval
127
128         set_f   scana
129         set_f   scanb
130         set_f   scanc
131         set_f   scand
132         set_f   scane
133         mov_ff  buf0_startval, buf0
134
135         return
136
137 ;----------
138 detect_slave_init
139         mov_lfsr outbuf, 2
140         clr_f   outmsg_end
141
142         goto    reset_detectread
143
144 ;----------------------------------------
145 slave_add_short_message
146 ; Queues a message byte for transmission to the master.
147 ; It will be transmitted as an extra message byte, when we are polled.
148 ;  W            message         unchanged
149 ;  GIEH         set             set
150         intrh_mask
151         bs_f    INDF1,7
152         mov_wf  PREINC1
153         intrh_unmask
154
155         mov_lw  message_buffer_end-1
156         cmp_fw_ifle FSR1L
157         return
158
159         panic   morse_DB
160
161 ;----------
162 backgroundloop_again macro backgroundloop_whatever
163  local branchposition
164         inc_f_ifnz unattendedl
165         bra     backgroundloop_whatever
166         mov_lw  branchposition - backgroundloop_whatever
167 branchposition
168         add_wff unattendedh
169         bra_nc  backgroundloop_whatever
170         inc_f_ifz unattendedu
171         call    led_red
172         bra     backgroundloop_whatever
173         endm
174
175 near_i2csu code
176 ;----------
177 i2csu_read_begin
178 ; called from High ISR, see i2clib.inc
179         bt_f_if1 idloc1,idloc1_boarddet
180         bra     i2csu_read_begin_detectors
181         bra     i2csu_read_begin_reversers
182
183 ;----------
184 i2csu_read_another
185 ; called from High ISR, see i2clib.inc
186         mov_fw  POSTINC2
187         i2cs_read_data_macro
188         mov_fw  outmsg_end
189         cmp_fw_ifle FSR2L
190         return
191         ; oops
192         panic   morse_DR
193
194 ;======================================================================
195 ; main detection bit-twiddling
196
197                         ;       80 40 20 10  08 04 02 01
198                         ;        7  6  5  4   3  2  1  0
199
200 ;----------------------------------------------------------------------
201 ; detectors
202
203                         ; A     xx 19 09 12  15 18 xx xx
204                         ; B     xx xx xx 04  20 17 xx xx
205                         ; C     xx xx 05 xx  xx 10 13 16
206                         ; D     02 11 14 xx  08 xx 01 07
207                         ; E     xx xx xx xx  xx 03 00 06
208
209                         ; buf0  MM zz B2 B1  zz zz zz zz
210
211                 ; scheme for bit shuffling:
212                 ;
213                 ; 1:    ; _<A   19 09 12 15  18 xx xx xx
214                 ;       ; >>B   xx xx xx xx  xx 04 20 17
215                 ;
216                 ; 2:    ; _>E   06 xx xx xx xx  xx 03 00
217                 ;       ; [*D   xx 01 07 02  11 14 xx ??        C=08
218                 ;
219                 ; 0:    ; [_C   xx 05 xx xx  10 13 16 08
220                 ;
221 ;               ; where _ means do nothing
222                 ;       *       swap nybbles
223                 ;       <       rotate left
224                 ;       >       rotate right
225                 ;       [       rotate left through carry (NB
226                 ;                that the carry bit propagates to
227                 ;                the subsequent [ or ] *in the
228                 ;                same column*).
229                 ; and the operation done first (in backgroundloop)
230                 ; is on the right next to the port letter and the one
231                 ; done second (in i2csu_read_begin_...) is shown
232                 ; on the left, above.
233
234 ;----------
235 backgroundloop_detectors
236         rr_fw   PORTB   ; W     xx xx xx xx  04 20 17 xx (now)
237         and_wff scanb   ; b     xx xx xx xx  04 20 17 xx (cumulative)
238         rl_fw   PORTA   ; W     19 09 12 15  18 xx xx xx (now)
239         and_wff scana   ; a     19 09 12 15  18 xx xx xx (cumulative)
240
241         rr_fw   PORTE   ; W     06 xx xx xx  xx xx 03 00 (now)
242         and_wff scane   ; e     06 xx xx xx  xx xx 03 00 (cumulative)
243         swap_fw PORTD   ; W     08 xx 01 07  02 11 14 xx (now)
244         and_wff scand   ; d     08 xx 01 07  02 11 14 xx (cumulative)
245
246         mov_fw  PORTC   ; W     xx xx 05 xx  xx 10 13 16 (now)
247         and_wff scanc   ; c     xx xx 05 xx  xx 10 13 16 (cumulative)
248
249         backgroundloop_again backgroundloop_detectors
250
251 ;----------             ; buf0  MM zz zz zz  zz zz zz zz
252 i2csu_read_begin_detectors
253  ; detection byte 1
254         mov_lw  0xf8    ; W     yy yy yy yy  yy zz zz zz
255         and_wff scana   ; scana 19 09 12 15  18 zz zz zz
256
257         rr_fw   scanb   ; W     xx xx xx xx  xx 04 20 17
258         and_lw  0x07    ; W     zz zz zz zz  zz 04 20 17
259         ior_wff scana   ; scana 19 09 12 15  18 04 20 17
260
261         mov_fw  scana
262         cmp_fw_ifne last1
263         bs_f    buf0,4  ; buf0  MM zz zz B1  zz zz zz zz
264
265  ; detection byte 2
266         mov_lw  0x83    ; W     yy zz zz zz  zz zz yy yy
267         and_wff scane   ; scane 06 zz zz zz  zz zz 03 00
268
269         rlc_fw  scand   ; W     xx 01 07 02  11 14 xx xx  C=08
270         and_lw  0x7c    ; W     zz 01 07 02  11 14 zz zz  C=08
271         ior_wff scane   ; scane 06 01 07 02  11 14 03 00  C=08
272
273         mov_fw  scane
274         cmp_fw_ifne last2
275         bs_f    buf0,5  ; buf0  MM zz B2 B1  zz zz zz zz
276
277 ; detection and lead byte, 0
278         rlc_fw  scanc   ; W     xx 05 xx xx  10 13 16 08
279         and_lw  0x4f    ; W     zz 05 zz zz  10 13 16 08
280         ior_wfw buf0    ; W     MM 05 B2 B1  10 13 16 08
281
282         i2cs_read_data_macro
283
284         rcall   new_i2c_outmsg
285
286         mov_fw  scana
287         bt_f_if1 buf0,5
288         mov_wf  POSTINC2
289         mov_wf  last1
290
291         mov_fw  scane
292         bt_f_if1 buf0,4
293         mov_wf  POSTINC2
294         mov_wf  last2
295
296         set_f   scanb
297         set_f   scanc
298         set_f   scane
299
300 ;...
301 ;----------------------------------------------------------------------
302 ; both detectors and reversers
303 ;
304 i2csu_read_begin_either_tail
305         set_f   scana
306         set_f   scand
307
308         mov_lfsr message_buffer, 1
309         bt_f_if0 buf0, 7
310         bra     msg_copy_exitnone
311         ; some extra bytes to copy
312 ;...
313 msg_copy_loop
314         mov_fw  POSTINC1
315         mov_wf  POSTINC2
316         bra_n   msg_copy_loop
317 ;...
318 msg_copy_exitnone
319         mov_ff  FSR2L, outmsg_end
320         mov_ff  buf0_startval, buf0
321         mov_lfsr outbuf, 2
322
323 reset_detectread
324 ;  FSR1/buf0/message_buffer     any             set to empty
325 ;  unattended*                  any             reset
326 ;  Per-PIC LED                  any             black
327 ;  may be called from High ISR or during init
328         mov_lfsr buf0, 1
329
330         call    led_black
331
332 unattended_timeout equ 100 ; ms
333         set_f   unattendedl
334         ; Fosc = sclock [kHz]
335         ; Fcy = sclock / 4  [kHz]
336         ; program counter advance rate = 2 * sclock / 4  [bytes/ms]
337         ; unattendedh increment rate = pc advance rate / 256
338         ;       = 2 * sclock / (4 * 256)  [counts/ms]
339         ; count needed before show unattended = uah rate * ua timeout
340         ;       = (2 * sclock / (4 * 256)  [counts/ms])
341         ;               * (unattended_timeout [ms])
342         ;       = (2 * sclock / (4 * 256)) * unattended_timeout  [counts]
343         ;       = sclock * unattended_timeout / 512  [counts]
344         ; we count up until overflow, so
345 unattended_init equ 65535 - (sclock * unattended_timeout / 512)
346         mov_lw  unattended_init / 256
347         mov_wf  unattendedu
348         mov_lw  unattended_init & 255
349         mov_wf  unattendedh
350
351         return
352
353 ;----------
354 new_i2c_outmsg
355 ; Called from i2csu_read_begin ISR to check that the whole of
356 ; the previous message was read, and to reset the FSR2 pointer
357 ; to point to the start of outbuf so that we can fill the outbuf.
358         mov_fw  FSR2L           ; W -> byte after the one we last sent
359         mov_lfsr outbuf, 2      ; FSR2 -> outbuf
360         cmp_fw_ifle outmsg_end  ; transmitted the last byte ?
361         return
362         ; no, oops:
363         panic   morse_DQ
364
365 ;----------------------------------------------------------------------
366 ; reversers
367                         ; A     xx 01 xx 03  xx xx xx xx
368                         ; B     xx xx xx xx  xx xx xx xx
369                         ; C     xx xx xx xx  xx 00 xx xx
370                         ; D     xx xx xx xx  xx xx 04 05
371 ;----------             ; E     xx xx xx xx  xx 02 xx xx
372 backgroundloop_reversers_core macro
373         rr_fw   PORTA   ; W     xx xx 01 xx  03 xx xx xx (now)
374         and_wff scana   ; a     xx xx 01 xx  03 xx xx xx (cumulative)
375         mov_fw  PORTD   ; D     xx xx xx xx  xx xx 04 05 (now)
376         and_wff scand   ; d     xx xx xx xx  xx xx 04 05 (cumulative)
377         bt_f_if0 PORTC,2 ;                      00       (now)
378         bc_f    buf0,2  ; buf0  MM zz zz ss  zz 00 zz zz (cumulative)
379         bt_f_if0 PORTE,2 ;                      02       (now)
380         bc_f    buf0,4  ; buf0  MM zz zz 02  zz ss zz zz (cumulative)
381         endm
382 backgroundloop_reversers
383         backgroundloop_reversers_core
384         backgroundloop_again backgroundloop_reversers
385
386 ;----------             ; buf0  MM zz zz 02  zz 00 zz zz
387 read_begin_calc_buf0_reversers macro
388         mov_fw  scana   ; W     xx xx 01 xx  03 xx xx xx
389         and_lw  0x28    ; W     zz zz 01 zz  03 zz zz zz
390         ior_wff buf0    ; buf0  MM zz 01 02  03 00 zz zz
391
392         mov_fw  scand   ; W     xx xx xx xx  xx xx 04 05
393         and_lw  0x03    ; W     zz zz zz zz  zz zz 04 05
394         ior_wfw buf0    ; W     MM zz 01 02  03 00 04 05
395         endm
396
397 i2csu_read_begin_reversers
398         read_begin_calc_buf0_reversers
399         call    i2cs_read_data
400
401         rcall   new_i2c_outmsg
402
403         bra     i2csu_read_begin_either_tail
404
405 ;======================================================================
406 ; FOR MASTER
407
408 ;----------
409 backgroundloop_master
410         backgroundloop_reversers_core
411         bra     backgroundloop_master
412
413 ;----------
414 read_detection_head_master
415         read_begin_calc_buf0_reversers
416         bra_n   read_detection_head_master_badmore
417         set_f   scana
418         set_f   scand
419         mov_ff  buf0_startval, buf0
420         return
421
422 ;-----
423 read_detection_head_master_badmore
424         panic   morse_DM
425
426 ;======================================================================
427  include final.inc