1 ;======================================================================
2 ; DETECTION AND SLAVE I2C
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
8 ; FSR2 is used as readout pointer
12 ; I2C protocol is as follows:
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
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)
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)
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
36 ; Following that are the zero, one or two more bytes of
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
41 ; Finally, zero or more bytes of extra messages:
42 ; MM XX XX XX XX XX XX XX
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).
49 ; Master may also write to slave. Every written byte is independent:
51 ; 11RRRRRR Set reverse to RRRRRR, see reverse.asm
52 ; 100PPPPP Fire point PPPPP
54 ; 00000000 Acknowlege that slave has crashed, and
55 ; switch into crash readout mode
57 ;======================================================================
58 ; variables and memory organisation
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
68 scana res 1 ; see bit-twiddling below
77 buf0_startval res 1 ; reversers start with some det bits
79 message_buffer res max_messages
80 message_buffer_end res 0
82 ;----------------------------------------------------------------------
83 ; buf0, message_buffer, and FSR1 are used mainly for recording
84 ; non-detection messages. They look like this:
86 ; +--------+--------+--------+--------+--------+
87 ; | buf0 | message_buffer... |
88 ; +--------+--------+--------+--------+--------+
90 ; |0d0d0000|???????? ???????? ???????? ????????| no extra messages
92 ; |1d0d0000|0aaaaaaa ???????? ???????? ????????| one extra byte
94 ; |1d0d0000|1aaaaaaa 0bbbbbbb ???????? ????????| two extra bytes
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
100 ;----------------------------------------------------------------------
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.
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.
112 ;======================================================================
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)
122 ; compute buf0_startval
124 bt_f_if0 idloc1,idloc1_boarddet
125 mov_lw 0x14 ; see under reversers, below
135 mov_ff buf0_startval, buf0
144 goto reset_detectread
146 ;----------------------------------------
147 slave_add_short_message @
148 ; Queues a message byte for transmission to the master.
149 ; It will be transmitted as an extra message byte, when we are polled.
150 ; W message unchanged
157 mov_lw message_buffer_end-1
164 backgroundloop_again macro backgroundloop_whatever
166 inc_f_ifnz unattendedl
167 bra backgroundloop_whatever
168 mov_lw branchposition - backgroundloop_whatever
171 bra_nc backgroundloop_whatever
172 inc_f_ifz unattendedu
174 bra backgroundloop_whatever
180 ; called from High ISR, see i2clib.inc
181 bt_f_if1 idloc1,idloc1_boarddet
182 bra i2csu_read_begin_detectors
183 bra i2csu_read_begin_reversers
187 ; called from High ISR, see i2clib.inc
196 ;======================================================================
197 ; main detection bit-twiddling
199 ; 80 40 20 10 08 04 02 01
202 ;----------------------------------------------------------------------
205 ; A xx 19 09 12 15 18 xx xx
206 ; B xx xx xx 04 20 17 xx xx
207 ; C xx xx 05 xx xx 10 13 16
208 ; D 02 11 14 xx 08 xx 01 07
209 ; E xx xx xx xx xx 03 00 06
211 ; buf0 MM zz B2 B1 zz zz zz zz
213 ; scheme for bit shuffling:
215 ; 1: ; _<A 19 09 12 15 18 xx xx xx
216 ; ; >>B xx xx xx xx xx 04 20 17
218 ; 2: ; _>E 06 xx xx xx xx xx 03 00
219 ; ; [*D xx 01 07 02 11 14 xx ?? C=08
221 ; 0: ; [_C xx 05 xx xx 10 13 16 08
223 ; ; where _ means do nothing
227 ; [ rotate left through carry (NB
228 ; that the carry bit propagates to
229 ; the subsequent [ or ] *in the
231 ; and the operation done first (in backgroundloop)
232 ; is on the right next to the port letter and the one
233 ; done second (in i2csu_read_begin_...) is shown
234 ; on the left, above.
237 backgroundloop_detectors @
238 rr_fw PORTB ; W xx xx xx xx 04 20 17 xx (now)
239 and_wff scanb ; b xx xx xx xx 04 20 17 xx (cumulative)
240 rl_fw PORTA ; W 19 09 12 15 18 xx xx xx (now)
241 and_wff scana ; a 19 09 12 15 18 xx xx xx (cumulative)
243 rr_fw PORTE ; W 06 xx xx xx xx xx 03 00 (now)
244 and_wff scane ; e 06 xx xx xx xx xx 03 00 (cumulative)
245 swap_fw PORTD ; W 08 xx 01 07 02 11 14 xx (now)
246 and_wff scand ; d 08 xx 01 07 02 11 14 xx (cumulative)
248 mov_fw PORTC ; W xx xx 05 xx xx 10 13 16 (now)
249 and_wff scanc ; c xx xx 05 xx xx 10 13 16 (cumulative)
251 backgroundloop_again backgroundloop_detectors
253 ;---------- ; buf0 MM zz zz zz zz zz zz zz
254 i2csu_read_begin_detectors
256 mov_lw 0xf8 ; W yy yy yy yy yy zz zz zz
257 and_wff scana ; scana 19 09 12 15 18 zz zz zz
259 rr_fw scanb ; W xx xx xx xx xx 04 20 17
260 and_lw 0x07 ; W zz zz zz zz zz 04 20 17
261 ior_wff scana ; scana 19 09 12 15 18 04 20 17
265 bs_f buf0,4 ; buf0 MM zz zz B1 zz zz zz zz
268 mov_lw 0x83 ; W yy zz zz zz zz zz yy yy
269 and_wff scane ; scane 06 zz zz zz zz zz 03 00
271 rlc_fw scand ; W xx 01 07 02 11 14 xx xx C=08
272 and_lw 0x7c ; W zz 01 07 02 11 14 zz zz C=08
273 ior_wff scane ; scane 06 01 07 02 11 14 03 00 C=08
277 bs_f buf0,5 ; buf0 MM zz B2 B1 zz zz zz zz
279 ; detection and lead byte, 0
280 rlc_fw scanc ; W xx 05 xx xx 10 13 16 08
281 and_lw 0x4f ; W zz 05 zz zz 10 13 16 08
282 ior_wfw buf0 ; W MM 05 B2 B1 10 13 16 08
303 ;----------------------------------------------------------------------
304 ; both detectors and reversers
306 i2csu_read_begin_either_tail
310 mov_lfsr message_buffer, 1
312 bra msg_copy_exitnone
313 ; some extra bytes to copy
321 mov_ff FSR2L, outmsg_end
322 mov_ff buf0_startval, buf0
326 ; FSR1/buf0/message_buffer any set to empty
327 ; unattended* any reset
328 ; Per-PIC LED any black
329 ; may be called from High ISR or during init
334 unattended_timeout equ 100 ; ms
336 ; Fosc = sclock [kHz]
337 ; Fcy = sclock / 4 [kHz]
338 ; program counter advance rate = 2 * sclock / 4 [bytes/ms]
339 ; unattendedh increment rate = pc advance rate / 256
340 ; = 2 * sclock / (4 * 256) [counts/ms]
341 ; count needed before show unattended = uah rate * ua timeout
342 ; = (2 * sclock / (4 * 256) [counts/ms])
343 ; * (unattended_timeout [ms])
344 ; = (2 * sclock / (4 * 256)) * unattended_timeout [counts]
345 ; = sclock * unattended_timeout / 512 [counts]
346 ; we count up until overflow, so
347 unattended_init equ 65535 - (sclock * unattended_timeout / 512)
348 mov_lw unattended_init / 256
350 mov_lw unattended_init & 255
357 ; Called from i2csu_read_begin ISR to check that the whole of
358 ; the previous message was read, and to reset the FSR2 pointer
359 ; to point to the start of outbuf so that we can fill the outbuf.
360 mov_fw FSR2L ; W -> byte after the one we last sent
361 mov_lfsr outbuf, 2 ; FSR2 -> outbuf
362 cmp_fw_ifle outmsg_end ; transmitted the last byte ?
367 ;----------------------------------------------------------------------
369 ; A xx 01 xx 03 xx xx xx xx
370 ; B xx xx xx xx xx xx xx xx
371 ; C xx xx xx xx xx 00 xx xx
372 ; D xx xx xx xx xx xx 04 05
373 ;---------- ; E xx xx xx xx xx 02 xx xx
374 backgroundloop_reversers_core macro
375 rr_fw PORTA ; W xx xx 01 xx 03 xx xx xx (now)
376 and_wff scana ; a xx xx 01 xx 03 xx xx xx (cumulative)
377 mov_fw PORTD ; D xx xx xx xx xx xx 04 05 (now)
378 and_wff scand ; d xx xx xx xx xx xx 04 05 (cumulative)
379 bt_f_if0 PORTC,2 ; 00 (now)
380 bc_f buf0,2 ; buf0 MM zz zz ss zz 00 zz zz (cumulative)
381 bt_f_if0 PORTE,2 ; 02 (now)
382 bc_f buf0,4 ; buf0 MM zz zz 02 zz ss zz zz (cumulative)
384 backgroundloop_reversers @
385 backgroundloop_reversers_core
386 backgroundloop_again backgroundloop_reversers
388 ;---------- ; buf0 MM zz zz 02 zz 00 zz zz
389 read_begin_calc_buf0_reversers macro
390 mov_fw scana ; W xx xx 01 xx 03 xx xx xx
391 and_lw 0x28 ; W zz zz 01 zz 03 zz zz zz
392 ior_wff buf0 ; buf0 MM zz 01 02 03 00 zz zz
394 mov_fw scand ; W xx xx xx xx xx xx 04 05
395 and_lw 0x03 ; W zz zz zz zz zz zz 04 05
396 ior_wfw buf0 ; W MM zz 01 02 03 00 04 05
399 i2csu_read_begin_reversers
400 read_begin_calc_buf0_reversers
405 bra i2csu_read_begin_either_tail
407 ;======================================================================
411 backgroundloop_master @
412 backgroundloop_reversers_core
413 bra backgroundloop_master
416 read_detection_head_master @
417 read_begin_calc_buf0_reversers
418 bra_n read_detection_head_master_badmore
421 mov_ff buf0_startval, buf0
425 read_detection_head_master_badmore
428 ;======================================================================