chiark / gitweb /
Send HELLO as a result of all slaves being online. Do not crash if slave is slow...
[trains.git] / detpic / mascan.asm
index 7cf6a4b2630f87f91be40ec8003809236ec951c5..36c16f495fdfed36b1f8f1e6c31ce5d9a7334a06 100644 (file)
@@ -19,7 +19,12 @@ cbyte        res     1
 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
@@ -56,6 +61,22 @@ i2cm_intrl @
 ;======================================================================
 ; 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
@@ -79,6 +100,9 @@ i2cmu_read_got_byte
        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
@@ -294,6 +318,22 @@ i2c_consider_restartread @
        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
 
@@ -302,9 +342,15 @@ mascan_init @
                 ; 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
@@ -316,6 +362,8 @@ mascan_init_loop
        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
@@ -331,10 +379,13 @@ mascan_init_loop
        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