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
133 mov_ff buf0_startval, buf0
142 goto reset_detectread
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
155 mov_lw message_buffer_end-1
162 backgroundloop_again macro backgroundloop_whatever
164 inc_f_ifnz unattendedl
165 bra backgroundloop_whatever
166 mov_lw branchposition - backgroundloop_whatever
169 bra_nc backgroundloop_whatever
170 inc_f_ifz unattendedu
172 bra backgroundloop_whatever
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
185 ; called from High ISR, see i2clib.inc
194 ;======================================================================
195 ; main detection bit-twiddling
197 ; 80 40 20 10 08 04 02 01
200 ;----------------------------------------------------------------------
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
209 ; buf0 MM zz B2 B1 zz zz zz zz
211 ; scheme for bit shuffling:
213 ; 1: ; _<A 19 09 12 15 18 xx xx xx
214 ; ; >>B xx xx xx xx xx 04 20 17
216 ; 2: ; _>E 06 xx xx xx xx xx 03 00
217 ; ; [*D xx 01 07 02 11 14 xx ?? C=08
219 ; 0: ; [_C xx 05 xx xx 10 13 16 08
221 ; ; where _ means do nothing
225 ; [ rotate left through carry (NB
226 ; that the carry bit propagates to
227 ; the subsequent [ or ] *in the
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.
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)
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)
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)
249 backgroundloop_again backgroundloop_detectors
251 ;---------- ; buf0 MM zz zz zz zz zz zz zz
252 i2csu_read_begin_detectors
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
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
263 bs_f buf0,4 ; buf0 MM zz zz B1 zz zz zz zz
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
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
275 bs_f buf0,5 ; buf0 MM zz B2 B1 zz zz zz zz
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
301 ;----------------------------------------------------------------------
302 ; both detectors and reversers
304 i2csu_read_begin_either_tail
308 mov_lfsr message_buffer, 1
310 bra msg_copy_exitnone
311 ; some extra bytes to copy
319 mov_ff FSR2L, outmsg_end
320 mov_ff buf0_startval, buf0
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
332 unattended_timeout equ 100 ; ms
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
348 mov_lw unattended_init & 255
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 ?
365 ;----------------------------------------------------------------------
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)
382 backgroundloop_reversers
383 backgroundloop_reversers_core
384 backgroundloop_again backgroundloop_reversers
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
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
397 i2csu_read_begin_reversers
398 read_begin_calc_buf0_reversers
403 bra i2csu_read_begin_either_tail
405 ;======================================================================
409 backgroundloop_master
410 backgroundloop_reversers_core
411 bra backgroundloop_master
414 read_detection_head_master
415 read_begin_calc_buf0_reversers
416 bra_n read_detection_head_master_badmore
419 mov_ff buf0_startval, buf0
423 read_detection_head_master_badmore
426 ;======================================================================