; 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:
+ ; ???? ???1 reading halted for any reason:
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 ;
+outmsg_targetlen res 1 ;
+
+slaves_awaiting res 1 ; no. of slaves without stf_responding
+slavenoack_counter res 2 ; +0=L, +=H
+slavenoack_counter_init equ (i2c_kbitpersec * 100)
+ ; slaves/sec, @ 10clocks/slave
;======================================================================
; HANDLING OF I2C EVENTS
code
;----------------------------------------
i2cmu_write_next_byte
+ Dl 0x91
; add calls to getwritebyte_<foo> here:
call polarity_getwritebyte
call points_getwritebyte
i2cm_intrl @
; handles i2c interrupt using i2cm_interrupt[_definite],
; according to the rules for <something>_intrl.
+ Dl 0x90
bt_f_if0 PIR1, SSPIF
return
call i2cm_interrupt_definite
;======================================================================
; PROCESSING OF INCOMING BYTES - CORE AND DETECTION
+;--------------------
+read_first_response
+; on entry on return
+; W received byte preserved
+; b received byte preserved
+; FSR0 any trashed
+; STATUS any trashed
+ bs_f INDF1, stf_responding
+ dec_f_ifnz slaves_awaiting
+ return
+; that's the last slave, excellent
+ mov_lw b'00001001' ; W trashed
+ call serial_addbyte
+ mov_fw b ; W = received byte (again)
+ return
+
;----------------------------------------
i2cmu_read_got_byte
; Beforehand At call
; W = received byte
mov_wf b ; W = b = received byte
+ Dl 0x90
+ Df cslot
+ Df cbyte
+ Df b ; also restores b to W
+
mov_lfsr slavetable, 1
mov_ff cslot, FSR1L ; FSR1 -> slave's flags
bra read_got_notfirst
; this is a first (head) byte:
+ bt_f_if0 INDF1, stf_responding ; seen this PIC ack already ?
+ rcall read_first_response ; no, we might have to send HELLO
+
bt_f_if0 POSTINC1, stf_detect ; FSR1 -> detbasel
bra read_got_first_reversers
read_got_first_detectors ; b = MdBBdddd
;----------
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_fw POSTINC1 ; W = detbasel; FSR1 -> lastd0
- inc_f FSR1L ; FSR1 -> lastd1
- add_lw 5 ; W = detbasel+8
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
- mov_fw POSTDEC1 ; W = detbasel; FSR1 -> flags
- bs_f FSR1L, 2 ; FSR1L -> lastd2
- add_lw 13 ; W = detbasel+16
rcall read_got_detectbyte_prep
goto addmsgs_all
; FSR1 -> lastd<n>
;
mov_wf u ; u = [C0]*
- xor_wfw INDF1 ; lastd<n> = [d0]*
+
+ Dl 0x94
+ Df FSR1L
+ Df u ; also restores u to W
+
+ xor_wff INDF1 ; lastd<n> = [d0]*
+ ; to force test of repeated detection notification,
+ ; comment out previous line
mov_lw 0x07
ior_wff FSR1L ; FSR1L -> detmsgh
return ; to addmsgs_<something>, 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
; NOS return address for i2cmu_read_got_byte
;
mov_wf t ; t = adjdetbasel
+ Dl 0x93
+ Df INDF1
mov_fw b ; W = [d0]*
+ Dv
xor_wfw INDF1 ; W = [C0]*, Z iff same
; where C set iff change to that detection segment
bra_nz read_got_detectbyte_prep_ifsomething
; 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_<foo> here:
+ call polarity_needwrite
+ call points_needwrite
+ ; end of list of calls to needwrite_<foo>
+
+ ; 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
- return ; do not scan yet
-
- neg_fw outmsg_begin
- add_wfw outmsg_end
+ 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
bra nextslave_looparound
; Ok, we have a slave:
+ Dl 0x91
mov_fw INDF1 ; W = new slave number
goto i2cm_read_start
; now we do our own detection
mov_lw (slavetable + ste_flags) & 0xff ; select our own slot
mov_wf cslot
+ Dl 0x92
call read_detection_head_master
goto i2cmu_read_got_byte
-;----------------------------------------
-i2cmu_done
- ; So we've done one write.
- bs_f cbyte, cbyte_halted
-
- tst_f_ifnz wslave ; anyone asked in the meantime ?
- bra arrange_write
-
- ; Anyone else to write to ?
- ; add calls to needwrite_<foo> here:
- call polarity_needwrite
- call points_needwrite
- ; end of list of calls to needwrite_<foo>
-
- ; no, if we're here, no-one wants to write
- bra nextslave_nowrite
-
;----------------------------------------
i2c_needwrite @
; Informs mascan that we need to write to some slave.
return
bra nextslave_nowrite
+;----------------------------------------
+i2cmu_slave_no_ack
+ mov_lfsr slavetable, 1
+ mov_ff cslot, FSR1L ; FSR1 -> slave's flags
+ bt_f_if1 INDF1, stf_responding
+ bra slavenoack_crashed
+
+ dec_f_ifnz slavenoack_counter
+ return
+ dec_f_ifnz slavenoack_counter+1
+ return
+ panic morse_ST
+
+slavenoack_crashed
+ panic morse_SC
+
;======================================================================
; INITIALISATION
mascan_init @
- mov_lw (slavetable + ste_flags + ste_size) & 0xff
- ; start with 1st actual slave
+ 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
+ bs_f cbyte, cbyte_halted
clr_f wslave
+ mov_lw slavenoack_counter_init & 0xff
+ mov_wf slavenoack_counter
+ mov_lw slavenoack_counter_init >> 8
+ mov_wf slavenoack_counter+1
+ clr_f slaves_awaiting
+
mov_lw 2
mov_lfsr slavetable, 0 ; FSR0 -> slavetable
load_tblptr pic2detinfo ; TBLPTR* -> pic2detinfo
mov_fw TABLAT ; W = EOOOOSSS, N = E
tblrd_postinc_fixup ; TABLAT = DSSSSSSS, N (still) = E
- bra_nn mascan_init_ifabsent
+ bra_nn mascan_init_ifabsent ; E.......
+
+ inc_f slaves_awaiting
mov_ff t, POSTINC0 ; ste_slave = slave
mov_wf u ; u = 1OOOOSSS
add_lw -0xf8 ; W = first - 0xf8 = detbasel
mov_wf POSTINC0 ; detbasel
- clr_f POSTINC0 ; lastd0
- clr_f POSTINC0 ; lastd1
- clr_f POSTINC0 ; lastd2
+ mov_lw 0x4f ; W = 01001111 for det., MM 05 B2 B1...
+ bt_f_if0 TABLAT, 7 ; D ? otherwise, rev. board:
+ mov_lw 0x3f ; W = 01111111 for rev., MM zz 01...
+ mov_wf POSTINC0 ; lastd0
+ set_f POSTINC0 ; lastd2
set_f POSTINC0 ; unused
+ set_f POSTINC0 ; lastd1
mov_fw u ; W = 10000SSS
xor_lw b'10011000' ^ 0x80 ; W = detmsgh
;======================================================================
; GENERATION OF DETECTION MESSAGES FOR HOST - MAD BT_F_IF1 TABLES
-addmsg_testbit macro bit
- bt_f_if1 u, bit
+addmsg_testbit macro addmsg_macro_bit
+ bt_f_if1 u, addmsg_macro_bit
rcall addmsg_one
endm
-addmsg_return macro dummy_bit
+addmsg_return macro dummy_addmsg_macro_bit
goto i2c_arrange_next_byte
endm
-addmsg_ignore macro dummy_bit
+addmsg_ignore macro dummy_addmsg_macro_bit
nop
nop
endm
-addmsg_padding macro dummy_bit
+addmsg_padding macro dummy_addmsg_macro_bit
nop
- mov_lw dummy_bit
+ mov_lw dummy_addmsg_macro_bit
endm
;----------------------------------------
;----------
addmsg_one
-; TOS - 4 -> bt_f_if1 w, b'bbb'
+; TOS - 4 -> bt_f_if1 u, b'bbb'
; TOSL ???bbb00
; other conditions on entry and exit as for entry to addmsgs_<kind>, above
+ Dl 0x95
+ Df TOSL
rr_fw TOSL ; W = 0???bbb0
rr_w ; W = 00???bbb
- ior_wfw 0xf8 ; W = 11111bbb
+ 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)
+ Dv
call serial_addbyte
mov_fw v ; W = 0 SSSSSSS (det msg low byte)
+ Dv
goto serial_addbyte_another
+addmsg_bad panic morse_DJ
+
;======================================================================
include final.inc