;====================================================================== ; MASTER - SCANNING ETC. include common.inc ;---------------------------------------------------------------------- udata_acs ; for reading and detection: b res 1 ; byte just read cslot res 1 ; current slave in slave table, points to flags byte cbyte res 1 ; one of the following: ; 0000 0000 we're expecting the first byte ; M0B1 0000 we're expecting more detection byte 1 ; M010 0000 we're expecting more detection byte 2 ; 1000 0000 we're expecting an extra byte ; ???? ???1 reading halted due to lack of buffer space: cbyte_halted equ 0 ; also set briefly while we decide what to do next wslave res 1 ; slave we need to write to outmsg_targetlen res 1 ; ;====================================================================== ; HANDLING OF I2C EVENTS near_getwritebyteyes code ;---------------------------------------- i2c_getwritebyte_yes @ pop ; we don't care where we were in i2cmu_write_next_byte bc_f STATUS, Z ; yes, we want to write this byte return ; from i2cmu_write_next_byte code ;---------------------------------------- i2cmu_write_next_byte ; add calls to getwritebyte_ here: call polarity_getwritebyte call points_getwritebyte ; end of list of calls to getwritebyte_ ; so, no-one wants this slave: bs_f STATUS, Z return ;---------------------------------------- i2cm_intrl @ ; handles i2c interrupt using i2cm_interrupt[_definite], ; according to the rules for _intrl. bt_f_if0 PIR1, SSPIF return call i2cm_interrupt_definite intrl_handled_nostack ;====================================================================== ; PROCESSING OF INCOMING BYTES - CORE AND DETECTION ;---------------------------------------- i2cmu_read_got_byte ; Beforehand At call ; State Reading Reading-Wait ; W data from slave ; ; See detect.asm head comment for protocol info, in particular ; the meaning of these bytes. ; W = received byte mov_wf b ; W = b = received byte D 0x70 mov_fw cslot call debugbyte mov_fw cbyte call debugbyte mov_fw b call debugbyte mov_lfsr slavetable, 1 mov_ff cslot, FSR1L ; FSR1 -> slave's flags tst_f_ifnz cbyte bra read_got_notfirst ; this is a first (head) byte: bt_f_if0 POSTINC1, stf_detect ; FSR1 -> detbasel bra read_got_first_reversers read_got_first_detectors ; b = MdBBdddd and_lw 0xb0 ; W = M0BB0000 mov_wf cbyte ; cbyte = M0BB0000 mov_lw 0x4f ; W = 01001111 and_wff b ; b = 0d00dddd mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0 rcall read_got_detectbyte_prep ; b = 0d00dddd ; u = 0C00CCCC ;mov_ff b, xdebug+5 bt_f_if1 b, 6 ; b bit .d...... bs_f b, 4 ; b = 0d0ddddd ; ^ ^ copies of same bit ; u = (still) 0C00CCCC ; or, using detection segment bit numbers: ; b = z4z43210 ; u = z4zz3210 goto addmsgs_dethead ;---------- read_got_first_reversers bt_f_if1 b, 6 bra read_got_bad_first_reversers and_lw 0x80 ; W = M0000000 mov_wf cbyte ; cbyte = M0000000 bc_f b, 7 ; b = 00dddddd mov_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0 rcall read_got_detectbyte_prep goto addmsgs_revhead ;----- read_got_bad_first_reversers panic morse_MR ;---------- read_got_detectors_b1 ; b = dddddddd ; ; W = detbasel; FSR1 -> detbasel add_lw 5 ; W = adjdetbasel bs_f FSR1L, 2 ; FSR1L -> lastd1 bc_f cbyte, 4 ; cbyte = M0B00000 mov_ff xdebug+4, xdebug+5 mov_ff xdebug+3, xdebug+4 mov_ff b, xdebug+3 rcall read_got_detectbyte_prep goto addmsgs_all ;---------- read_got_detectors_b2 ; b = dddddddd ; ; W = detbasel; FSR1 -> detbasel add_lw 13 ; W = adjdetbasel inc_f FSR1L ; FSR1 -> lastd0 inc_f FSR1L ; FSR1 -> lastd2 bc_f cbyte,5 ; cbyte = M0000000 rcall read_got_detectbyte_prep goto addmsgs_all ;---------- read_got_detectbyte_prep_ifsomething ; ; This is a branch of read_got_detectbyte_prep, called if we're doing ; `return' rather than `pop+return'. For conditions on return, see ; read_got_detectbyte_prep; these are supposed to be (basically) the ; same as the entry conditions for addmsgs_. ; ; on entry ; W [C0]* ; t adjdetbasel ; u undefined ; b [d0]* ; lastd [o0]* ; FSR1 -> lastd ; mov_wf u ; u = [C0]* D 0x74 mov_fw FSR1L call debugbyte mov_fw u call debugbyte xor_wff INDF1 ; lastd = [d0]* ; to force test of repeated detection notification, ; comment out previous line mov_lw 0x07 ior_wff FSR1L ; FSR1L -> detmsgh return ; to addmsgs_, very shortly ;---------------------------------------- read_got_notfirst ; ; FSR1 -> flags mov_fw PREINC1 ; W = detbasel; FSR1 -> detbasel bt_f_if1 cbyte, 4 bra read_got_detectors_b1 bt_f_if1 cbyte, 5 bra read_got_detectors_b2 ; it must be an extra byte bt_f_if0 b, 7 ; any more ? bc_f cbyte, 7 bc_f b, 7 call process_got_extra bra i2c_arrange_next_byte ;---------- read_got_detectbyte_prep ; ; Sees if anything has changed. If no changes pops one return address ; and branches to i2c_arrange_next_byte; if some changes, returns to ; calling point. ; ; So, caller should be i2cmu_read_got_byte, and next stuff ; should basically be a call to addmsg_ (perhaps preceded ; by a bit of fiddling of b). addmsg_ will finish ; by branching to i2c_arrange_next_byte. ; ; call return pop+return ; W adjdetbasel preserved undefined ; b [d0]* preserved preserved ; FSR1 -> lastd detmsgh preserved ; cbyte set for next read etc. preserved preserved ; u undefined [C0]* preserved ; lastd [o0]* [d0]* preserved = [d0]* ; ; TOS -> (optionally, fiddle b, and then:) goto addmsgs_ ; NOS return address for i2cmu_read_got_byte ; mov_wf t ; t = adjdetbasel D 0x73 mov_fw INDF1 call debugbyte mov_fw b ; W = [d0]* call debugbyte xor_wfw INDF1 ; W = [C0]*, Z iff same ; where C set iff change to that detection segment bra_nz read_got_detectbyte_prep_ifsomething ; there's nothing to do pop ;... ;---------------------------------------- i2c_arrange_next_byte tst_f_ifnz cbyte goto i2cm_read_another ;... ;====================================================================== ; DECIDING WHICH SLAVE TO ADDRESS ;... i2c_arrange_something i2cmu_done ; figure out what to do next - which pic to address, etc. bs_f cbyte, cbyte_halted tst_f_ifnz wslave ; anyone asked to write ? bra arrange_write ; Anyone else to write to ? ; add calls to needwrite_ here: call polarity_needwrite call points_needwrite ; end of list of calls to needwrite_ ; no, if we're here, no-one wants to write: nextslave_nowrite ; no writing needed, we consider reading: bt_f_if1 flags, flags_polarising return ; do not scan while booster PWM is off while polarising ; to avoid all trains disappearing and reappearing mov_fw outmsg_begin sub_wfw outmsg_end and_lw outbuf_size - 1 cmp_fw_ifle outmsg_targetlen return ; target len < actual len, do not add anything ; ok, there's space, go ahead: bc_f cbyte, cbyte_halted mov_lw ste_size add_wff cslot ; cslot -> next ste_flags mov_lfsr slavetable, 1 ; FSR1H -> slavetable mov_ff cslot, FSR1L ; FSR1 -> new ste_flags bt_f_if1 POSTDEC1, stf_sentinel ; FSR1 -> ste_slave bra nextslave_looparound ; Ok, we have a slave: D 0x71 mov_fw INDF1 ; W = new slave number goto i2cm_read_start nextslave_looparound bt_f_if1 xdebug+6,2 goto boom2 bt_f_if1 xdebug+6,1 bs_f xdebug+6,2 ; now we do our own detection mov_lw (slavetable + ste_flags) & 0xff ; select our own slot mov_wf cslot D 0x72 call read_detection_head_master goto i2cmu_read_got_byte boom2 panic morse_TI1 ;---------------------------------------- i2c_needwrite @ ; Informs mascan that we need to write to some slave. ; Some time after this, mascan will call getwritebyte_ ; and this must yield at least one byte to write. ; W slave that we must write to mov_wf wslave bt_f_if0 cbyte, cbyte_halted return ; we're currently doing something ;... ;---------- arrange_write ; wslave slave to write to bc_f cbyte, cbyte_halted mov_fw wslave mov_wf cwslave clr_f wslave goto i2cm_write_start ;---------------------------------------- i2c_consider_restartread @ bt_f_if0 cbyte, cbyte_halted return bra nextslave_nowrite ;====================================================================== ; INITIALISATION mascan_init @ mov_lw (slavetable + ste_flags) & 0xff ; pretend we've just done us, to start with 1st actual slave mov_wf cslot clr_f cbyte bs_f cbyte, cbyte_halted ; serial output of `hello' will start us up clr_f wslave mov_lw 2 mov_lfsr slavetable, 0 ; FSR0 -> slavetable load_tblptr pic2detinfo ; TBLPTR* -> pic2detinfo clr_f t ; t = loop counter mascan_init_loop tblrd_postinc_fixup ; TABLAT = EOOOOSSS mov_fw TABLAT ; W = EOOOOSSS, N = E tblrd_postinc_fixup ; TABLAT = DSSSSSSS, N (still) = E bra_nn mascan_init_ifabsent ; E....... mov_ff t, POSTINC0 ; ste_slave = slave mov_wf u ; u = 1OOOOSSS and_lw 0x78 bra_nz mascan_bad_detinfo0 ; ok ; u = 10000SSS mov_fw TABLAT ; W = DSSSSSSS and_lw 0x80 ; W = D0000000 mov_wf POSTINC0 ; ste_flags = D0000000 mov_fw TABLAT ; W = DSSSSSSS bc_w 7 ; W = 0SSSSSSS = first add_lw -0xf8 ; W = first - 0xf8 = detbasel mov_wf POSTINC0 ; detbasel clr_f POSTINC0 ; lastd0 clr_f POSTINC0 ; lastd2 set_f POSTINC0 ; unused clr_f POSTINC0 ; lastd1 mov_fw u ; W = 10000SSS xor_lw b'10011000' ^ 0x80 ; W = detmsgh mov_wf POSTINC0 ; detmsgh mascan_init_ifabsent inc_f t ; next slave bt_f_if0 t, maxpics_ln2 bra mascan_init_loop ; we've read the whole flash table if slavetable == 0x400 bt_f_if1 FSR0H, 0 bra mascan_bad_toomany endif clr_f POSTINC0 ; ste_slave mov_lw (1< ; ; on entry after first addmsg_one, or when done ; W, STATUS, v, FSR0 undefined trashed ; t adjdetbasel not modified by addmsgs_ or _one ; u [C0]* not modified by addmsgs_ or _one ; b [d0]* not modified by addmsgs_ or _one ; lastd [d0]* (new) not modified by addmsgs_ or _one ; FSR1 -> detmsgh not modified by addmsgs_ or _one ; outbuf, outmsg_* not full, updated appropriately ; all others any not interfered with ; ; (this is all set up by read_prep_detectbyte and ; read_got_detectbyte_prep_ifsomething) ; when done, branches to i2c_arrange_next_byte, rather than returning addmsgs_section code ( 7 )*4 + 0x2100 ; ; A ; |- PCL bbb value after macro - number in this ; V column should increment 1 each line ; addmsgs_revhead addmsg_testbit 0 addmsg_testbit 1 addmsg_testbit 2 addmsg_testbit 3 addmsg_testbit 4 addmsg_testbit 5 addmsg_return 6 addmsgs_all addmsg_testbit 7 addmsg_testbit 0 addmsg_testbit 1 addmsg_testbit 2 addmsg_testbit 3 addmsg_testbit 4 addmsg_testbit 5 addmsg_testbit 6 addmsg_return 7 addmsgs_dethead addmsg_testbit 0 addmsg_testbit 1 addmsg_testbit 2 addmsg_testbit 3 addmsg_testbit 6 ; bit 6 was copied to 4 but only in b, not u addmsg_return 5 ;---------- addmsg_one ; TOS - 4 -> bt_f_if1 u, b'bbb' ; TOSL ???bbb00 ; other conditions on entry and exit as for entry to addmsgs_, above ;dec_f_ifz xdebug+7 ;bra boom D 0x75 mov_fw TOSL call debugbyte rr_fw TOSL ; W = 0???bbb0 rr_w ; W = 00???bbb ior_lw 0xf8 ; W = 11111bbb mov_wf FSR0L ; FSR0L = 11111bbb clr_f FSR0H ; FSR0 -> bitnum2bit[bbb] add_wfw t ; W = adjdetbasel + 11111bbb ; ie = 0 SSSSSSS (det msg low byte) mov_wf v ; v = 0 SSSSSSS (det msg low byte) bra_n addmsg_bad mov_fw b ; W = [d0]* and_wfw INDF0 ; train: W = 0x00, Z=1; none: W = 0*d0*, Z=0 bt_f_if0 STATUS, Z mov_lw 0x08 ; train: W = 0 000 0 000; none: W = 0 000 1 000 xor_wfw INDF1 ; W = 1 001 Y SSS (det msg high byte) call debugbyte call serial_addbyte ;bt_f_if1 xdebug+6, 0 ;bra boom mov_fw v ; W = 0 SSSSSSS (det msg low byte) call debugbyte goto serial_addbyte_another addmsg_bad panic morse_DJ boom panic morse_TI5 ;====================================================================== include final.inc