st res 1 ; bitmask:
st_writing equ 0
+st_subsequent equ 0
code
; Find out what's just happened:
mov_ff SSPSTAT, t
- ; 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?
+ ; 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?
- bt_f_if1 t, I2C_START
- bra si_if_start
+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
-si_if_notstart
- ; So it should be stop
mov_fw t
- and_lw 0xdf ; ?D_A
- xor_lw 0x90 ; SMP, !CKE, P; !S, !R_W, !UA, !BF
- bra_nz si_if_bad
+
+chkval_lastvalue equ 0
+chkval macro value, label
+ xor_lw value ^ chkval_lastvalue
+ chkval_lastvalue equ value
+ bra_z label
+ endm
+
+ chkval 0x89, s_case_addr_recv_write
+ chkval 0x8d, s_case_addr_recv_read
+ chkval 0xa9, s_case_write_data_recv
+ chkval 0xac, s_case_read_data_sent
+ chkval 0xa8, s_case_read_data_nack
+
+ mov_ff t, WREG2 ; fixme
+ panic morse_SS
+
+;----------
+s_case_something_stop
+ bc_f SSPCON1, 3 ; disable Start and Stop interrupts
; Were we receiving ?
bt_f_if0 st, st_writing
- return
+ bra s_caseshare_something_uninteresting
; Yes, we were receiving:
- bc_f st, st_writing
+ clr_f st ; now we're idle
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
+
+s_panic_st_unexpected
+ panic morse_ST
+
+;----------
+s_case_addr_recv_write
+ 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
+
+s_write_slurpbyte
+; W any byte from master
+; i2c controller waiting due to SEN etc continuing with next byte
+ mov_fw SSPBUF
+ bs_f SSPCON1, CKP
+ return
+
+;----------
+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:
+ bs_f st, st_subsequent
+ goto i2csu_write_begin
+
+;----------
+s_case_read_data_sent
+
+
+s_caseshare_write_alliswell
+
+
+
+ bt_f_if1 t, I2C_START
+ bra si_if_start
+
+si_if_notstart
+ ; So it should be stop
+ mov_fw t
+ 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
bra si_if_bufferfull
-chkval macro mask, value, label
- mov_fw t
- if mask ^ 0xff
- and_lw mask
- endif
- xor_lw value
- bra_z label
- endm
- ; 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?
-
- chkval 0xff, 0x90, s_case_writing_stop
- chkval 0xff, 0x89, s_case_addr_recv_write
- chkval 0xff, 0x8d, s_case_addr_recv_read
- chkval 0xff, 0xa9, s_case_write_data_recv
- chkval 0xff, 0xac, s_case_read_data_sent
- chkval 0xff, 0xa8, s_case_read_data_nack
- chkval 0xdb, 0x90, s_case_unknown_stop
- chkval 0xdb, 0x88, s_case_unknown_start
-
- mov_ff t, WREG2 ; fixme
- panic morse_SI
;----------
s_case_unknown_stop
IH INTCON,INTCON3,PIR1,PIR2,PIR3 ; Interrupt source not found (high pri.)
IL INTCON,INTCON3,PIR1,PIR2,PIR3 ; Interrupt source not found (low pri.)
IP INTCON ; Interrupt of priority supposedly disabled
-SA SSPCON2 ; Slave didn't I2C ack address
-SD SSPCON2 ; Slave didn't I2C ack data
# Messages starting with T are temporary entries for testing and development
TM PIE1,SSPSTAT,SSPCON1,SSPCON2 ; Master got I2C interrupt
TI3 ; for iwj
TI4 ; for iwj
TI5 ; for iwj
+
+# Messages for i2clib, S*
+SV SSPSTAT, t ; WCOL or SSPOV
+SS t, SSPCON1 ; slave got i2c interrupt but bad SSPSTAT
+ST t, st ; slave got i2c interrupt but bad st
+
+SA SSPCON2 ; Slave didn't I2C ack address
+SD SSPCON2 ; Slave didn't I2C ack data