1 ;======================================================================
2 ; MASTER - SCANNING ETC.
6 ;----------------------------------------------------------------------
9 ; for reading and detection:
10 b res 1 ; byte just read
11 cslot res 1 ; current slave in slave table, points to flags byte
13 ; one of the following:
14 ; 0000 0000 we're expecting the first byte
15 ; M0B1 0000 we're expecting more detection byte 1
16 ; M010 0000 we're expecting more detection byte 2
17 ; 1000 0000 we're expecting an extra byte
18 ; ???? ???1 reading halted for any reason:
19 cbyte_halted equ 0 ; also set briefly while we decide what to do next
21 wslave res 1 ; slave we need to write to
22 outmsg_targetlen res 1 ;
24 slaves_awaiting res 1 ; no. of slaves without stf_responding
25 slavenoack_counter res 2 ; +0=L, +=H
26 slavenoack_counter_init equ (i2c_kbitpersec * 100)
27 ; slaves/sec, @ 10clocks/slave
29 ;======================================================================
30 ; HANDLING OF I2C EVENTS
32 near_getwritebyteyes code
33 ;----------------------------------------
34 i2c_getwritebyte_yes @
35 pop ; we don't care where we were in i2cmu_write_next_byte
36 bc_f STATUS, Z ; yes, we want to write this byte
37 return ; from i2cmu_write_next_byte
40 ;----------------------------------------
43 ; add calls to getwritebyte_<foo> here:
44 call polarity_getwritebyte
45 call waggle_getwritebyte
46 call points_getwritebyte
47 ; end of list of calls to getwritebyte_<foo>
48 ; so, no-one wants this slave:
52 ;----------------------------------------
54 ; handles i2c interrupt using i2cm_interrupt[_definite],
55 ; according to the rules for <something>_intrl.
59 call i2cm_interrupt_definite
62 ;======================================================================
63 ; PROCESSING OF INCOMING BYTES - CORE AND DETECTION
68 ; W received byte preserved
69 ; b received byte preserved
72 bs_f INDF1, stf_responding
73 dec_f_ifnz slaves_awaiting
75 ; that's the last slave, excellent
76 mov_lw b'00001001' ; W trashed
78 mov_fw b ; W = received byte (again)
81 ;----------------------------------------
84 ; State Reading Reading-Wait
87 ; See detect.asm head comment for protocol info, in particular
88 ; the meaning of these bytes.
90 mov_wf b ; W = b = received byte
95 Df b ; also restores b to W
97 mov_lfsr slavetable, 1
98 mov_ff cslot, FSR1L ; FSR1 -> slave's flags
101 bra read_got_notfirst
102 ; this is a first (head) byte:
104 bt_f_if0 INDF1, stf_responding ; seen this PIC ack already ?
105 rcall read_first_response ; no, we might have to send HELLO
107 bt_f_if0 POSTINC1, stf_detect ; FSR1 -> detbasel
108 bra read_got_first_reversers
109 read_got_first_detectors ; b = MdBBdddd
110 and_lw 0xb0 ; W = M0BB0000
111 mov_wf cbyte ; cbyte = M0BB0000
112 mov_lw 0x4f ; W = 01001111
113 and_wff b ; b = 0d00dddd
114 mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0
115 rcall read_got_detectbyte_prep ; b = 0d00dddd
117 bt_f_if1 b, 6 ; b bit .d......
118 bs_f b, 4 ; b = 0d0ddddd
119 ; ^ ^ copies of same bit
120 ; u = (still) 0C00CCCC
121 ; or, using detection segment bit numbers:
127 read_got_first_reversers
129 bra read_got_bad_first_reversers
130 and_lw 0x80 ; W = M0000000
131 mov_wf cbyte ; cbyte = M0000000
132 bc_f b, 7 ; b = 00dddddd
133 mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0
134 rcall read_got_detectbyte_prep
138 read_got_bad_first_reversers panic morse_MR
141 read_got_detectors_b1 ; b = dddddddd
142 ; ; W = detbasel; FSR1 -> detbasel
143 add_lw 5 ; W = adjdetbasel
144 bs_f FSR1L, 2 ; FSR1L -> lastd1
145 bc_f cbyte, 4 ; cbyte = M0B00000
146 rcall read_got_detectbyte_prep
150 read_got_detectors_b2 ; b = dddddddd
151 ; ; W = detbasel; FSR1 -> detbasel
152 add_lw 13 ; W = adjdetbasel
153 inc_f FSR1L ; FSR1 -> lastd0
154 inc_f FSR1L ; FSR1 -> lastd2
155 bc_f cbyte,5 ; cbyte = M0000000
156 rcall read_got_detectbyte_prep
160 read_got_detectbyte_prep_ifsomething
162 ; This is a branch of read_got_detectbyte_prep, called if we're doing
163 ; `return' rather than `pop+return'. For conditions on return, see
164 ; read_got_detectbyte_prep; these are supposed to be (basically) the
165 ; same as the entry conditions for addmsgs_<kind>.
179 Df u ; also restores u to W
181 xor_wff INDF1 ; lastd<n> = [d0]*
182 ; to force test of repeated detection notification,
183 ; comment out previous line
185 ior_wff FSR1L ; FSR1L -> detmsgh
186 return ; to addmsgs_<something>, very shortly
188 ;----------------------------------------
191 mov_fw PREINC1 ; W = detbasel; FSR1 -> detbasel
193 bra read_got_detectors_b1
195 bra read_got_detectors_b2
196 ; it must be an extra byte
198 bt_f_if0 b, 7 ; any more ?
201 call process_got_extra
202 bra i2c_arrange_next_byte
205 read_got_detectbyte_prep
207 ; Sees if anything has changed. If no changes pops one return address
208 ; and branches to i2c_arrange_next_byte; if some changes, returns to
211 ; So, caller should be i2cmu_read_got_byte, and next stuff
212 ; should basically be a call to addmsg_<something> (perhaps preceded
213 ; by a bit of fiddling of b). addmsg_<something> will finish
214 ; by branching to i2c_arrange_next_byte.
216 ; call return pop+return
217 ; W adjdetbasel preserved undefined
218 ; b [d0]* preserved preserved
219 ; FSR1 -> lastd<n> detmsgh preserved
220 ; cbyte set for next read etc. preserved preserved
221 ; u undefined [C0]* preserved
222 ; lastd<n> [o0]* [d0]* preserved = [d0]*
224 ; TOS -> (optionally, fiddle b, and then:) goto addmsgs_<something>
225 ; NOS return address for i2cmu_read_got_byte
227 mov_wf t ; t = adjdetbasel
232 xor_wfw INDF1 ; W = [C0]*, Z iff same
233 ; where C set iff change to that detection segment
234 bra_nz read_got_detectbyte_prep_ifsomething
235 ; there's nothing to do
238 ;----------------------------------------
239 i2c_arrange_next_byte
241 goto i2cm_read_another
243 ;======================================================================
244 ; DECIDING WHICH SLAVE TO ADDRESS
246 i2c_arrange_something
248 ; figure out what to do next - which pic to address, etc.
249 bs_f cbyte, cbyte_halted
251 tst_f_ifnz wslave ; anyone asked to write ?
254 ; Anyone else to write to ?
255 ; add calls to needwrite_<foo> here:
256 call polarity_needwrite
257 call waggle_needwrite
258 call points_needwrite
259 ; end of list of calls to needwrite_<foo>
261 ; no, if we're here, no-one wants to write:
264 ; no writing needed, we consider reading:
265 bt_f_if1 flags, flags_polarising
266 return ; do not scan while booster PWM is off while polarising
267 ; to avoid all trains disappearing and reappearing
271 and_lw outbuf_size - 1
272 cmp_fw_ifle outmsg_targetlen
273 return ; target len < actual len, do not add anything
274 ; ok, there's space, go ahead:
275 bc_f cbyte, cbyte_halted
278 add_wff cslot ; cslot -> next ste_flags
279 mov_lfsr slavetable, 1 ; FSR1H -> slavetable
280 mov_ff cslot, FSR1L ; FSR1 -> new ste_flags
282 bt_f_if1 POSTDEC1, stf_sentinel ; FSR1 -> ste_slave
283 bra nextslave_looparound
284 ; Ok, we have a slave:
287 mov_fw INDF1 ; W = new slave number
291 ; now we do our own detection
292 mov_lw (slavetable + ste_flags) & 0xff ; select our own slot
295 call read_detection_head_master
296 goto i2cmu_read_got_byte
298 ;----------------------------------------
300 ; Informs mascan that we need to write to some slave.
301 ; Some time after this, mascan will call getwritebyte_<everything>
302 ; and this must yield at least one byte to write.
303 ; W slave that we must write to
305 bt_f_if0 cbyte, cbyte_halted
306 return ; we're currently doing something
310 ; wslave slave to write to
311 bc_f cbyte, cbyte_halted
315 goto i2cm_write_start
317 ;----------------------------------------
318 i2c_consider_restartread @
319 bt_f_if0 cbyte, cbyte_halted
321 bra nextslave_nowrite
323 ;----------------------------------------
325 mov_lfsr slavetable, 1
326 mov_ff cslot, FSR1L ; FSR1 -> slave's flags
327 bt_f_if1 INDF1, stf_responding
328 bra slavenoack_crashed
330 dec_f_ifnz slavenoack_counter
332 dec_f_ifnz slavenoack_counter+1
339 ;======================================================================
343 mov_lw (slavetable + ste_flags) & 0xff
344 ; pretend we've just done us, to start with 1st actual slave
347 bs_f cbyte, cbyte_halted
350 mov_lw slavenoack_counter_init & 0xff
351 mov_wf slavenoack_counter
352 mov_lw slavenoack_counter_init >> 8
353 mov_wf slavenoack_counter+1
354 clr_f slaves_awaiting
357 mov_lfsr slavetable, 0 ; FSR0 -> slavetable
358 load_tblptr pic2detinfo ; TBLPTR* -> pic2detinfo
359 clr_f t ; t = loop counter
361 tblrd_postinc_fixup ; TABLAT = EOOOOSSS
362 mov_fw TABLAT ; W = EOOOOSSS, N = E
364 tblrd_postinc_fixup ; TABLAT = DSSSSSSS, N (still) = E
365 bra_nn mascan_init_ifabsent ; E.......
367 inc_f slaves_awaiting
369 mov_ff t, POSTINC0 ; ste_slave = slave
370 mov_wf u ; u = 1OOOOSSS
372 bra_nz mascan_bad_detinfo0
375 mov_fw TABLAT ; W = DSSSSSSS
376 and_lw 0x80 ; W = D0000000
377 mov_wf POSTINC0 ; ste_flags = D0000000
379 mov_fw TABLAT ; W = DSSSSSSS
380 bc_w 7 ; W = 0SSSSSSS = first
381 add_lw -0xf8 ; W = first - 0xf8 = detbasel
382 mov_wf POSTINC0 ; detbasel
384 mov_lw 0x4f ; W = 01001111 for det., MM 05 B2 B1...
385 bt_f_if0 TABLAT, 7 ; D ? otherwise, rev. board:
386 mov_lw 0x3f ; W = 01111111 for rev., MM zz 01...
387 mov_wf POSTINC0 ; lastd0
388 set_f POSTINC0 ; lastd2
389 set_f POSTINC0 ; unused
390 set_f POSTINC0 ; lastd1
392 mov_fw u ; W = 10000SSS
393 xor_lw b'10011000' ^ 0x80 ; W = detmsgh
394 mov_wf POSTINC0 ; detmsgh
398 bt_f_if0 t, maxpics_ln2
400 ; we've read the whole flash table
402 if slavetable == 0x400
404 bra mascan_bad_toomany
407 clr_f POSTINC0 ; ste_slave
408 mov_lw (1<<stf_detect)|(1<<stf_sentinel)
409 mov_wf POSTINC0 ; ste_flags
410 ; rest of final entry, and rest of table, is undefined
412 ; at 9600, it's about 1ms per char.
413 ; we allow 1ms to scan 2 pics via i2c.
414 ; so our target len is (no of pics)/2
415 ; plus 2 bytes of slop
418 mov_wf outmsg_targetlen
422 mascan_bad_detinfo0 panic morse_DF
423 mascan_bad_toomany panic morse_DG
425 ;======================================================================
426 ; PROCESSING OF INCOMING BYTES - EXTRA (NON-DETECTION)
429 ;----------------------------------------
441 ;======================================================================
442 ; GENERATION OF DETECTION MESSAGES FOR HOST - MAD BT_F_IF1 TABLES
444 addmsg_testbit macro addmsg_macro_bit
445 bt_f_if1 u, addmsg_macro_bit
449 addmsg_return macro dummy_addmsg_macro_bit
450 goto i2c_arrange_next_byte
453 addmsg_ignore macro dummy_addmsg_macro_bit
458 addmsg_padding macro dummy_addmsg_macro_bit
460 mov_lw dummy_addmsg_macro_bit
463 ;----------------------------------------
466 ; on entry after first addmsg_one, or when done
467 ; W, STATUS, v, FSR0 undefined trashed
468 ; t adjdetbasel not modified by addmsgs_<kind> or _one
469 ; u [C0]* not modified by addmsgs_<kind> or _one
470 ; b [d0]* not modified by addmsgs_<kind> or _one
471 ; lastd<n> [d0]* (new) not modified by addmsgs_<kind> or _one
472 ; FSR1 -> detmsgh not modified by addmsgs_<kind> or _one
473 ; outbuf, outmsg_* not full, updated appropriately
474 ; all others any not interfered with
476 ; (this is all set up by read_prep_detectbyte and
477 ; read_got_detectbyte_prep_ifsomething)
478 ; when done, branches to i2c_arrange_next_byte, rather than returning
480 addmsgs_section code ( 7 )*4 + 0x2100
483 ; |- PCL bbb value after macro - number in this
484 ; V column should increment 1 each line
486 addmsgs_revhead addmsg_testbit 0
494 addmsgs_all addmsg_testbit 7
504 addmsgs_dethead addmsg_testbit 0
508 addmsg_testbit 6 ; bit 6 was copied to 4 but only in b, not u
513 ; TOS - 4 -> bt_f_if1 u, b'bbb'
515 ; other conditions on entry and exit as for entry to addmsgs_<kind>, above
518 rr_fw TOSL ; W = 0???bbb0
520 ior_lw 0xf8 ; W = 11111bbb
521 mov_wf FSR0L ; FSR0L = 11111bbb
522 clr_f FSR0H ; FSR0 -> bitnum2bit[bbb]
523 add_wfw t ; W = adjdetbasel + 11111bbb
524 ; ie = 0 SSSSSSS (det msg low byte)
525 mov_wf v ; v = 0 SSSSSSS (det msg low byte)
529 and_wfw INDF0 ; train: W = 0x00, Z=1; none: W = 0*d0*, Z=0
531 mov_lw 0x08 ; train: W = 0 000 0 000; none: W = 0 000 1 000
532 xor_wfw INDF1 ; W = 1 001 Y SSS (det msg high byte)
536 mov_fw v ; W = 0 SSSSSSS (det msg low byte)
538 goto serial_addbyte_another
540 addmsg_bad panic morse_DJ
542 ;======================================================================