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 detectors and B1 was set
39 ; 06 01 07 02 11 14 03 00 iff detectors 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
53 ; 101WWWWX Set waggler WWWW to X
55 ; 00000000 Acknowlege that slave has crashed, and
56 ; switch into crash readout mode
58 ;======================================================================
59 ; variables and memory organisation
65 unattendedl res 1 ; counts up; each det loop it is
66 unattendedh res 1 ; incremented by no. of bytes of pc in
67 unattendedu res 1 ; det loop; if it overflows, led is set to red
69 scana res 1 ; see bit-twiddling below
78 buf0_startval res 1 ; reversers start with some det bits
80 message_buffer res max_messages
81 message_buffer_end res 0
83 ;----------------------------------------------------------------------
84 ; buf0, message_buffer, and FSR1 are used mainly for recording
85 ; non-detection messages. They look like this:
87 ; +--------+--------+--------+--------+--------+
88 ; | buf0 | message_buffer... |
89 ; +--------+--------+--------+--------+--------+
91 ; |0d0d0000|???????? ???????? ???????? ????????| no extra messages
93 ; |1d0d0000|0aaaaaaa ???????? ???????? ????????| one extra byte
95 ; |1d0d0000|1aaaaaaa 0bbbbbbb ???????? ????????| two extra bytes
97 ; etc. Bits labelled `d' are detection data on reversers boards
98 ; 0 on detectors boards; `a' and `b' are extra message data;
99 ; `^' indicates the byte pointed to by FSR1
101 ;----------------------------------------------------------------------
103 ; outbuf and FSR2 are used (on slaves) for the message we are
104 ; transmitting. FSR2 points to the next byte to transmit (ie, which
105 ; will be read). outmsg_end points to the first byte after the
106 ; message, and is used for read overrun detection.
108 ; During i2csu_read_begin (High ISR), the actual first byte of the
109 ; message to be sent is calculated from buf0, and transmitted; the
110 ; extra detection bytes (if any) are stored in outbuf, and any extra
111 ; messages (from message_buffer) are also appended to outbuf.
113 ;======================================================================
118 mov_lw b'111' ; turn off comparator, or we can't use pins
119 mov_wf CMCON ; RD0-RD4 as digital inputs
120 mov_lw b'0110' ; turn off A/D except perhaps for pin
121 ior_wff ADCON1 ; AN0 ie SPARE ie RA0 (same reason as above)
123 ; compute buf0_startval
125 bt_f_if0 idloc1,idloc1_boarddet
126 mov_lw 0x14 ; see under reversers, below
136 mov_ff buf0_startval, buf0
145 goto reset_detectread
147 ;----------------------------------------
148 slave_add_short_message @
149 ; Queues a message byte for transmission to the master.
150 ; It will be transmitted as an extra message byte, when we are polled.
151 ; W message unchanged
158 mov_lw message_buffer_end-1
165 backgroundloop_again macro backgroundloop_whatever
167 inc_f_ifnz unattendedl
168 bra backgroundloop_whatever
169 mov_lw branchposition - backgroundloop_whatever
172 bra_nc backgroundloop_whatever
173 inc_f_ifz unattendedu
175 bra backgroundloop_whatever
181 ; called from High ISR, see i2clib.inc
182 bt_f_if1 idloc1,idloc1_boarddet
183 bra i2csu_read_begin_detectors
184 bra i2csu_read_begin_reversers
188 ; called from High ISR, see i2clib.inc
197 ;======================================================================
198 ; main detection bit-twiddling
200 ; 80 40 20 10 08 04 02 01
203 ;----------------------------------------------------------------------
206 ; A xx 19 09 12 15 18 xx xx
207 ; B xx xx xx 04 20 17 xx xx
208 ; C xx xx 05 xx xx 10 13 16
209 ; D 02 11 14 xx 08 xx 01 07
210 ; E xx xx xx xx xx 03 00 06
212 ; buf0 MM zz B2 B1 zz zz zz zz
214 ; scheme for bit shuffling:
216 ; 1: ; _<A 19 09 12 15 18 xx xx xx
217 ; ; >>B xx xx xx xx xx 04 20 17
219 ; 2: ; _>E 06 xx xx xx xx xx 03 00
220 ; ; [*D xx 01 07 02 11 14 xx ?? C=08
222 ; 0: ; [_C xx 05 xx xx 10 13 16 08
224 ; ; where _ means do nothing
228 ; [ rotate left through carry (NB
229 ; that the carry bit propagates to
230 ; the subsequent [ or ] *in the
232 ; and the operation done first (in backgroundloop)
233 ; is on the right next to the port letter and the one
234 ; done second (in i2csu_read_begin_...) is shown
235 ; on the left, above.
238 backgroundloop_detectors @
239 rr_fw PORTB ; W xx xx xx xx 04 20 17 xx (now)
240 and_wff scanb ; b xx xx xx xx 04 20 17 xx (cumulative)
241 rl_fw PORTA ; W 19 09 12 15 18 xx xx xx (now)
242 and_wff scana ; a 19 09 12 15 18 xx xx xx (cumulative)
244 rr_fw PORTE ; W 06 xx xx xx xx xx 03 00 (now)
245 and_wff scane ; e 06 xx xx xx xx xx 03 00 (cumulative)
246 swap_fw PORTD ; W 08 xx 01 07 02 11 14 xx (now)
247 and_wff scand ; d 08 xx 01 07 02 11 14 xx (cumulative)
249 mov_fw PORTC ; W xx xx 05 xx xx 10 13 16 (now)
250 and_wff scanc ; c xx xx 05 xx xx 10 13 16 (cumulative)
252 backgroundloop_again backgroundloop_detectors
254 ;---------- ; buf0 MM zz zz zz zz zz zz zz
255 i2csu_read_begin_detectors
257 mov_lw 0xf8 ; W yy yy yy yy yy zz zz zz
258 and_wff scana ; scana 19 09 12 15 18 zz zz zz
260 rr_fw scanb ; W xx xx xx xx xx 04 20 17
261 and_lw 0x07 ; W zz zz zz zz zz 04 20 17
262 ior_wff scana ; scana 19 09 12 15 18 04 20 17
266 bs_f buf0,4 ; buf0 MM zz zz B1 zz zz zz zz
269 mov_lw 0x83 ; W yy zz zz zz zz zz yy yy
270 and_wff scane ; scane 06 zz zz zz zz zz 03 00
272 rlc_fw scand ; W xx 01 07 02 11 14 xx xx C=08
273 and_lw 0x7c ; W zz 01 07 02 11 14 zz zz C=08
274 ior_wff scane ; scane 06 01 07 02 11 14 03 00 C=08
278 bs_f buf0,5 ; buf0 MM zz B2 B1 zz zz zz zz
280 ; detection and lead byte, 0
281 rlc_fw scanc ; W xx 05 xx xx 10 13 16 08
282 and_lw 0x4f ; W zz 05 zz zz 10 13 16 08
283 ior_wfw buf0 ; W MM 05 B2 B1 10 13 16 08
304 ;----------------------------------------------------------------------
305 ; both detectors and reversers
307 i2csu_read_begin_either_tail
311 mov_lfsr message_buffer, 1
313 bra msg_copy_exitnone
314 ; some extra bytes to copy
322 mov_ff FSR2L, outmsg_end
323 mov_ff buf0_startval, buf0
327 ; FSR1/buf0/message_buffer any set to empty
328 ; unattended* any reset
329 ; Per-PIC LED any black
330 ; may be called from High ISR or during init
335 unattended_timeout equ 100 ; ms
337 ; Fosc = sclock [kHz]
338 ; Fcy = sclock / 4 [kHz]
339 ; program counter advance rate = 2 * sclock / 4 [bytes/ms]
340 ; unattendedh increment rate = pc advance rate / 256
341 ; = 2 * sclock / (4 * 256) [counts/ms]
342 ; count needed before show unattended = uah rate * ua timeout
343 ; = (2 * sclock / (4 * 256) [counts/ms])
344 ; * (unattended_timeout [ms])
345 ; = (2 * sclock / (4 * 256)) * unattended_timeout [counts]
346 ; = sclock * unattended_timeout / 512 [counts]
347 ; we count up until overflow, so
348 unattended_init equ 65535 - (sclock * unattended_timeout / 512)
349 mov_lw unattended_init / 256
351 mov_lw unattended_init & 255
358 ; Called from i2csu_read_begin ISR to check that the whole of
359 ; the previous message was read, and to reset the FSR2 pointer
360 ; to point to the start of outbuf so that we can fill the outbuf.
361 mov_fw FSR2L ; W -> byte after the one we last sent
362 mov_lfsr outbuf, 2 ; FSR2 -> outbuf
363 cmp_fw_ifle outmsg_end ; transmitted the last byte ?
368 ;----------------------------------------------------------------------
370 ; A xx 01 xx 03 xx xx xx xx
371 ; B xx xx xx xx xx xx xx xx
372 ; C xx xx xx xx xx 00 xx xx
373 ; D xx xx xx xx xx xx 04 05
374 ;---------- ; E xx xx xx xx xx 02 xx xx
375 backgroundloop_reversers_core macro
376 rr_fw PORTA ; W xx xx 01 xx 03 xx xx xx (now)
377 and_wff scana ; a xx xx 01 xx 03 xx xx xx (cumulative)
378 mov_fw PORTD ; D xx xx xx xx xx xx 04 05 (now)
379 and_wff scand ; d xx xx xx xx xx xx 04 05 (cumulative)
380 bt_f_if0 PORTC,2 ; 00 (now)
381 bc_f buf0,2 ; buf0 MM zz zz ss zz 00 zz zz (cumulative)
382 bt_f_if0 PORTE,2 ; 02 (now)
383 bc_f buf0,4 ; buf0 MM zz zz 02 zz ss zz zz (cumulative)
385 backgroundloop_reversers @
386 backgroundloop_reversers_core
387 backgroundloop_again backgroundloop_reversers
389 ;---------- ; buf0 MM zz zz 02 zz 00 zz zz
390 read_begin_calc_buf0_reversers macro
391 mov_fw scana ; W xx xx 01 xx 03 xx xx xx
392 and_lw 0x28 ; W zz zz 01 zz 03 zz zz zz
393 ior_wff buf0 ; buf0 MM zz 01 02 03 00 zz zz
395 mov_fw scand ; W xx xx xx xx xx xx 04 05
396 and_lw 0x03 ; W zz zz zz zz zz zz 04 05
397 ior_wfw buf0 ; W MM zz 01 02 03 00 04 05
400 i2csu_read_begin_reversers
401 read_begin_calc_buf0_reversers
406 bra i2csu_read_begin_either_tail
408 ;======================================================================
412 backgroundloop_master @
413 backgroundloop_reversers_core
414 bra backgroundloop_master
417 read_detection_head_master @
418 read_begin_calc_buf0_reversers
419 bra_n read_detection_head_master_badmore
422 mov_ff buf0_startval, buf0
426 read_detection_head_master_badmore
429 ;======================================================================