chiark / gitweb /
master wip
authorian <ian>
Wed, 16 Nov 2005 01:13:30 +0000 (01:13 +0000)
committerian <ian>
Wed, 16 Nov 2005 01:13:30 +0000 (01:13 +0000)
detpic/i2clib.asm
detpic/morse-auto.messages

index 5188fe4da599f0dd0491e66879e9289dc5e6f0eb..de07695fc90082d32bd6afcf6a1555a40e727c32 100644 (file)
 
 sspstat                res     1
 sspcon1                res     1
-sspcon2                res     1
+sspcon2                res     1       ; master only
+slave          res     1       ; master only
 
 st     res     1 ; bitmask, bit set in visible states:
                  ;    master                          slave
 st_reading     equ 0 ; Reading-*                       Transmitting
 st_writing     equ 1 ; Writing-*                       [Idle-going-]Receiving
-st_subsequent  equ 2 ;                                 Receiving
-st_working     equ 3 ; Writing-*,Reading-Busy,Stopping
-st_starting    equ 4 ; Writing-Setup,Reading-Busy
+st_subsequent  equ 2 ; Writing?                        Receiving
+;st_working    equ 3 ; Writing-*,Reading-Busy,Stopping
+st_starting    equ 4 ; Writing-Setup?,Reading-Busy?
+st_addressing  equ 4 ; Writing-Setup?,Reading-Busy?
+                 ; ...? means not always set in that state
 
                code
 
@@ -35,18 +38,6 @@ slave2addr
                rlc_w
                return
 
-;----------
-check_wcolsspov
-               mov_fw  SSPCON1
-               mov_wf  ssp
-               and_lw  0xc0 ; WCOL,SSPOV
-               bra_z   intr_wcolsspov
-               return
-
-;----------
-intr_wcolsspov
-               panic   morse_SV
-
 ;======================================================================
 ; MASTER
 
@@ -61,60 +52,116 @@ i2cm_init
                bra     init_enable
 
 ;----------
-i2cm_write_start
-;                              At call         On return
-;   State                      Idle            Writing-Setup
-;   W                          slave number    any
-               tst_f_ifnz st
-               bra     m_bad_write_start
-               bs_f    st, st_writing
-m_start
-               bs_f    st, st_starting
-               bs_f    SSPCON2, SEN
+i2cm_interrupt
+               bt_f_if0 PIR1, SSPIF
                return
+               ; We have an interrupt:
 
-;----------
-m_bad_write_start
-               panic   morse_SPW
+               mov_ff  SSPSTAT, sspstat
+               mov_ff  SSPCON1, sspcon1
+               mov_ff  SSPCON2, sspcon2
 
-;----------
-i2cm_interrupt
-               ; Do we have a doomy clash ?
-               bsr     check_wcolsspov
+               bt_f_if1 sspcon1, WCOL
+               bra_z   m_event_bad
+               bt_f_if1 sspcon1, SSPOV
+               bra_z   m_event_bad
 
                ; No ?  Well, then the I2C should be idle now:
-               mov_fw  SSPCON2
-               mov_wf  ssp
+               mov_fw  sspcon2
                and_lw  ~0x60 ; ACKSTAT,ACKDT
-               bra_nz  m_bad_sspcon2
-               ; OK, what's happening;
+               bra_nz  m_event_bad
+               ; OK...
 
-               bt_f_if0 PIR1, SSPIF
-               return
-               ; We have an interrupt:
+               bt_f_if1 sspstat, R_W
+               bra_nz  m_event_bad
 
                bt_f_if1 st, st_starting
-               bra     m_event_starting
+               bra     m_event_done_starting
                ; not just done SEN
 
-               fixme
+               bt_f_if1 st, st_addressing
+               bra     m_event_done_addressing
 
-;----------
-m_bad_sspcon2
+m_event_bad
                panic   morse_SM
 
+;----------
+m_event_done_starting
+               mov_fw  slave
+               bsr     slave2addr
+
+               bt_f_if1 st_reading
+               bs_w    0       ; address bottom bit means read
+
+               mov_wf  SSPBUF
+               bc_f    st, st_starting
+               bs_f    st, st_addressing
+               return
 
 ;----------
-m_event_starting
-               mov_lw  0x88
-               bsr     m_check_sspstat
+m_event_done_addressing
+               bt_f_if1 sspcon2, ACKSTAT
+               bra     m_bad_address_ack
+               ; OK, we got ack.
 
+               bc_f    st, st_addressing
+               bt_f_if1 st, st_reading
+               bra     m_event_done_addressing_read
+               bra     m_event_done_addressing_write
+
+;----------
+m_bad_address_ack
+               panic   morse_SK
 
-m_check_sspstat
-;      W       expected bit values             any
-; Panics if  (SSPSTAT ^ W) & mask  != 0
-               mov_ff  SSPSTAT, ssp
-               
+
+               mov_fw  slave
+               bsr     slave2addr
+
+               bt_f_if1 st_reading
+               bs_w    0       ; address bottom bit means read
+
+               mov_wf  SSPBUF
+               bc_f    st, st_starting
+               bs_f    st, st_addressing
+               return
+
+;----------
+i2cm_write_start
+;                              At call         On return
+;   State                      Idle            Writing-Setup
+;   W                          slave number    any
+               tst_f_ifnz st
+               bra     m_improper_write_start
+               bs_f    st, st_writing
+m_start
+               mov_wf  slave
+               and_lw  31
+               bra_nz  m_improper_slave
+               bs_f    st, st_starting
+               bs_f    st, st_working
+               bs_f    SSPCON2, SEN
+               return
+
+;----------
+m_event_done_writing
+               check for ack ?  check this when we bra here
+               bs_f    st, st_subsequent
+m_event_done_addressing_write
+               call    i2cmu_write_next_byte
+               bra_z   m_event_write_mustfinish
+
+               now what ?  fixme
+
+;----------
+m_event_write_mustfinish
+               bt_f_if0 st, st_subsequent
+               bra     m_improper_write_finish
+
+               fixme
+
+;----------
+m_improper_write_finish
+               panic   morse_SF
 
 ;======================================================================
 ; SLAVE
@@ -141,6 +188,10 @@ ms_init_enable
 ;      TRISB<1,0>              any                     configured for I2C
 ;      SSPIP                   any                     configured correctly
 ;      GIEL                    0 (disabled)            0 (disabled)
+;      ssp* shadows            any                     all bits set
+               set_f   sspstat
+               set_f   sspcon1
+               set_f   sspcon2
                bs_f    TRISB, 0
                bs_f    TRISB, 1
                bc_f    IPR1, SSPIP
@@ -160,8 +211,8 @@ ms_init_enable
 
 ; Some macros:
 
-chkvals_start macro
-               mov_fw  ssp
+chkvals_start_sspstat macro
+               mov_fw  sspstat
 chkval_lastvalue equ 0
                endm
 
@@ -182,10 +233,17 @@ i2cs_interrupt
                return
                ; We have an interrupt:
 
+               bt_f_if1 sspcon1, WCOL
+               bra_z   s_event_bad
+               bt_f_if1 sspcon1, SSPOV
+               bra_z   s_event_bad
+
 ; Firstly, clear the interrupt flag so that if something else happens
 ; while we faff, the interrupt will be regenerated:
                bc_f    PIR1, SSPIF
 
+               mov_ff  SSPSTAT, sspstat
+               mov_ff  SSPCON1, sspcon1
 ; Check that nothing obvious is wrong:
                bsr     check_wcolsspov
 
@@ -198,8 +256,8 @@ i2cs_interrupt
 s_event_idle
                chkvals_start
                chkvals_addrrecv
-
-               panic   morse_SI
+s_event_bad
+               panic   morse_SS
 
 ;========================================
 ; SLAVE - READING
@@ -212,7 +270,7 @@ s_event_idle_addrrecvread
 
 ;----------
 s_event_reading
-               chkvals_start
+               chkvals_start_sspstat
                chkval  0xac, s_event_reading_datasent ; D,!P, S,R,!BF
 
                ; Whatever is happening, we're done reading now !
@@ -223,7 +281,7 @@ s_event_reading
                ; Or, maybe it was nack and then we were reselected:
                chkvals_addrrecv
 
-               panic   morse_SR
+               bra     s_event_bad
 
 ;----------
 s_event_reading_datasent
@@ -252,7 +310,7 @@ s_write_slurpbyte
 
 ;----------
 s_event_writing
-               chkvals_start
+               chkvals_start_sspstat
                chkval  0xa9, s_event_writing_datarecv ; D,!P, S,W,BF
 
                ; Well, we're done writing now in any case
@@ -266,17 +324,18 @@ s_event_writing
                ; too picky.
 
                ; First, the nice cases:
-               chkvals_start
+               chkvals_start_sspstat
                chkvals_addrrecv
 
                ; Then random junk:
-               mov_fw  ssp
+               mov_fw  sspstat
                and_lw  0xc7 ; ?D_A, ?P; ?S
                xor_lw  0x80 ; SMP, !CKE, !R_W, !UA, !BF
                bt_f_if1 STATUS, Z
                return
+               ; no good
 
-               panic   morse_SW
+               bra     s_event_bad
 
 ;----------
 s_event_writing_datarecv
index 32235fdea6b117a47ef128dad6ce896c537ebec4..19faa72b1b5cdcab74806f85e6634801413118ad 100644 (file)
@@ -32,15 +32,30 @@ TI4                         ; for iwj
 TI5                            ; for iwj
 
 # Messages for i2clib, S*
+SM     st, sspstat, sspcon1, sspcon2   ; master interrupt bad state
+SS     st, sspstat, sspcon1            ; slave interrupt bad state
+SK     slave                           ; m. couldn't address slave (no ack)
+SA     slave                           ; improper slave address
+SW     st                              ; improper master write start
+SF     st                              ; improper master write finish
+
 #  in both
+
+SS     sspstat, sspcon1, 
+
 SV     SSPSTAT, ssp, st        ; WCOL or SSPOV (ssp = SSPCON1, unusually)
 
 #  in master
+
+
 SM     SSPSTAT, SSPCON1, ssp, st ; interrupt with unexpected bits in SSPCON2
                                        ; (ssp = SSPCON2, unusually)
 
 
 #  in slave
+SS     st, sspstat, sspcon1
+
+
 SI     ssp, SSPCON1            ; bad SSPSTAT when idle
 SR     ssp, SSPCON1            ; bad SSPSTAT when reading
 SW     ssp, SSPCON1            ; bad SSPSTAT when writing