chiark / gitweb /
before reorg for state-based
authorian <ian>
Mon, 14 Nov 2005 00:12:37 +0000 (00:12 +0000)
committerian <ian>
Mon, 14 Nov 2005 00:12:37 +0000 (00:12 +0000)
detpic/i2clib.asm

index dbdc00dda0deeab979ceebc42957a64a5a93c2fb..b3ff2d371b83f4132889bb4ca17ae63c5a0015c0 100644 (file)
@@ -12,7 +12,7 @@
 
                udata_acs
 
-t              res     1
+ssp            res     1
 
 st             res     1       ; bitmask:
 st_writing     equ     0
@@ -43,39 +43,30 @@ i2cs_init
 i2cs_interrupt
                bt_f_if0 PIR1, SSPIF
                return
+               ; We have an interrupt:
 
-; We have an interrupt.  Firstly, clear the interrupt flag
-; so that if something else happens while we faff, the interrupt
-; will be regenerated:
+; Firstly, clear the interrupt flag so that if something else happens
+; while we faff, the interrupt will be regenerated:
                bc_f    PIR1, SSPIF
 
-; Check that nothing is wrong:
+; Check that nothing obvious is wrong:
                mov_fw  SSPCON1
-               mov_wf  t
+               mov_wf  ssp
                and_lw  0xc0
                bra_nz  i2cs_interrupt_wcolsspov_endif
                panic   morse_SV
 i2cs_interrupt_wcolsspov_endif
 
 ; Find out what's just happened:
-               mov_ff  SSPSTAT, t
+               mov_ff  SSPSTAT, ssp
        ; bits we want to check
        ;  80  60  20    10    08    04    02  01
        ;  SMP CKE D_A   P     S     R_W   UA  BF
        ;  set clr data? stop  start read? clr full?
 
-chkvalm macro mask, value, label
-               mov_fw  t
-               xor_lw  value
-               bra_z   label
-               endm
-
-               chkvalm 0xdf, 0x90, s_case_something_stop
-               chkvalm 0xdb, 0x88, s_case_uninteresting_start
-
-               mov_fw  t
-
+               mov_fw  ssp
 chkval_lastvalue equ 0
+
 chkval macro value, label
                xor_lw  value ^ chkval_lastvalue
  chkval_lastvalue equ value
@@ -85,44 +76,59 @@ chkval macro value, label
                chkval  0x89, s_case_addr_recv_write
                chkval  0x8d, s_case_addr_recv_read
                chkval  0xa9, s_case_write_data_recv
+
+               bt_f_if0 st, st_reading
+               bra     s_ifnot_reading
+
+               ; only check this if we're reading; otherwise
+               ;  this will be handled by s_case_uninteresting_start
                chkval  0xac, s_case_read_data_sent
                chkval  0xa8, s_case_read_data_nack
 
-               mov_ff  t, WREG2 ; fixme
+s_ifnot_reading
+
+chkvalm macro mask, value, label
+               mov_fw  ssp
+               xor_lw  value
+               bra_z   label
+               endm
+
+               chkvalm 0xdf, 0x90, s_case_something_stop
+               chkvalm 0xdb, 0x88, s_case_uninteresting_start
+
+               mov_ff  ssp, WREG2 ; fixme
                panic   morse_SS
 
 ;----------
 s_case_something_stop
-               bc_f    SSPCON1, 3 ; disable Start and Stop interrupts
+s_case_something_start
+s_ensure_idle
+               mov_fw  st ; were we doing something ?
+               bt_f_if1 STATUS,Z
+               return
+               ; we were, it seems:
 
-               ; Were we receiving ?
-               bt_f_if0 st, st_writing
-               bra     s_caseshare_something_uninteresting
+               bc_f    SSPCON, 3
+               clr_f   st
+               ; now we're not (but W still has old st)
 
-               ; Yes, we were receiving:
-               clr_f   st ; now we're idle
+               bt_f_if1 WREG, st_writing
                goto    i2csu_write_done
-               ; tail call; we couldn't do anything after that
-               ; anyway since it might well reenter us.
 
-;----------
-s_case_something_start
-               bc_f    SSPCON, 3 ; disable Start and Stop interrupts
-s_caseshare_something_uninteresting
-               tst_f_ifnz st ; were we doing something ?
-               bra     s_panic_st_unexpected
-               return
+               bt_f_if1 WREG, st_reading
+               goto    i2csu_read_done
+
+               mov_wf  st ; put it back and then ...
 
 s_panic_st_unexpected
                panic   morse_ST
 
 ;----------
 s_case_addr_recv_write
+               rcall   s_ensure_idle
                bs_f    SSPCON, 3; we'll need the Stop interrupt
                bs_f    st, st_writing
-s_case_addr_recv_read
-               ; well, this is all just fine so do carry on
-               rcall   s_write_slurpbyte
+               ; well, now this is all fine so do carry on:
 
 s_write_slurpbyte
 ;      W               any                     byte from master
@@ -136,40 +142,61 @@ s_case_write_data_recv
                bt_f_if0 st, st_writing
                bra     s_panic_st_unexpected
                ; ok, we are writing:
+
                rcall   s_write_slurpbyte
+
                bt_f_if1 st, st_subsequent
                goto    i2csu_write_another
-               ; not subsequent:
+               ; not subsequent (yet):
+
                bs_f    st, st_subsequent
                goto    i2csu_write_begin
 
+;----------
+s_case_addr_recv_read
+               rcall   s_ensure_idle
+               bs_f    st, st_reading
+               call    i2csu_read_begin
+               bra     s_cases_read_data_send
+
 ;----------
 s_case_read_data_sent
+               call    i2csu_read_another
+
+s_cases_read_data_send
+               mov_wf  SSPBUF
+               bs_f    SSPCON1, CKP
+               return
+
+;----------
+s_case_read_data_nack
+               rcall   s_ensure_idle
+               goto    i2csu_read_done
 
 
-s_caseshare_write_alliswell
+s_cases_write_alliswell
                
 
 
-               bt_f_if1 t, I2C_START
+               bt_f_if1 ssp, I2C_START
                bra     si_if_start
 
 si_if_notstart
                ; So it should be stop
-               mov_fw  t
+               mov_fw  ssp
                and_lw  0xdf ; ?D_A
                xor_lw  0x90 ; SMP, !CKE, P; !S, !R_W, !UA, !BF
                bra_nz  si_if_bad
 
 si_if_start
-               bt_f_if1 t, BF
+               bt_f_if1 ssp, BF
                bra     si_if_bufferfull
 si_if_bufferempty
-               bt_f_if1 t, R_W ;read?
+               bt_f_if1 ssp, R_W ;read?
                bra     si_if_bufferempty_reading
 si_if_bufferempty_notreading
                ; So we think this is just a START (which we want to ignore)
-               mov_fw  t
+               mov_fw  ssp
                and_lw  0xdf ; ?D_A
                xor_lw  0x88 ; SMP, !CKE, !P; S, !R_W, !UA, !BF
                bra_nz  si_if_bad
@@ -194,7 +221,7 @@ s_case_got_write_addr
                and_lw  0xfe
                bra_nz  nonzero
 
-               mov_wf  t
+               mov_wf  ssp
                
 
                mov_fw  SSPSTAT