; 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
- D 0x70
- mov_fw cslot
- call debugbyte
- mov_fw cbyte
- call debugbyte
- mov_fw b
- call debugbyte
+ 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
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
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
; FSR1 -> lastd<n>
;
mov_wf u ; u = [C0]*
- D 0x74
- mov_fw FSR1L
- call debugbyte
- mov_fw u
- call debugbyte
- xor_wff 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
; NOS return address for i2cmu_read_got_byte
;
mov_wf t ; t = adjdetbasel
- D 0x73
- mov_fw INDF1
- call debugbyte
+ Dl 0x93
+ Df INDF1
mov_fw b ; W = [d0]*
- call debugbyte
+ 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
bra nextslave_looparound
; Ok, we have a slave:
- D 0x71
+ Dl 0x91
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
+ Dl 0x92
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.
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
; 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
tblrd_postinc_fixup ; TABLAT = DSSSSSSS, N (still) = E
bra_nn mascan_init_ifabsent ; E.......
+ inc_f slaves_awaiting
+
mov_ff t, POSTINC0 ; ste_slave = slave
mov_wf u ; u = 1OOOOSSS
and_lw 0x78
add_lw -0xf8 ; W = first - 0xf8 = detbasel
mov_wf POSTINC0 ; detbasel
- clr_f POSTINC0 ; lastd0
- 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
- clr_f POSTINC0 ; lastd1
+ set_f POSTINC0 ; lastd1
mov_fw u ; W = 10000SSS
xor_lw b'10011000' ^ 0x80 ; W = detmsgh
; TOS - 4 -> bt_f_if1 u, b'bbb'
; TOSL ???bbb00
; other conditions on entry and exit as for entry to addmsgs_<kind>, above
- ;dec_f_ifz xdebug+7
- ;bra boom
- D 0x75
- mov_fw TOSL
- call debugbyte
+ Dl 0x95
+ Df TOSL
rr_fw TOSL ; W = 0???bbb0
rr_w ; W = 00???bbb
ior_lw 0xf8 ; W = 11111bbb
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
+ Dv
call serial_addbyte
- ;bt_f_if1 xdebug+6, 0
- ;bra boom
-
mov_fw v ; W = 0 SSSSSSS (det msg low byte)
- call debugbyte
+ Dv
goto serial_addbyte_another
addmsg_bad panic morse_DJ
-boom
- panic morse_TI5
;======================================================================
include final.inc