1 ;######################################################################
2 ; i2clib.inc - I2C LIBRARY - IMPLEMENTATION
4 ; See i2clib.asm for documentation of the interface to this file.
6 include /usr/share/gputils/header/p18f458.inc
8 include ../iwjpictest/insn-aliases.inc
10 ;============================================================
11 ; COMMON ADMINISTRATIVE ROUTINES and VARIABLES
25 ; computes slave address in form suitable for use in i2c controller
26 ; actual i2c slave address is (slave number) + 0b0001000
27 ; W slave number i2c address * 2
33 ;======================================================================
38 ; W slave number undefined
42 mov_lw 0x16 ; !SSPEN, CKP(release), I2C 7-bit slave no-SP-int
44 mov_lw 0x01 ; !GCEN, SEN
46 mov_lw 0x8 ; SMP(noslew), !CKE, !BF(empty)
55 ;========================================
56 ; SLAVE - INTERRUPT HANDLING
58 ; In general, we figure out our state and then see what kind of events
59 ; we were expecting. Bits we want to check:
60 ; 80 60 20 10 08 04 02 01
61 ; SMP CKE D_A P S R_W UA BF
62 ; set clr data? stop start read? clr full?
63 ; (we don't usually mention SMP, CKE and UA below)
69 chkval_lastvalue equ 0
72 chkval macro value, label
73 xor_lw value ^ chkval_lastvalue
74 chkval_lastvalue equ value
78 chkvals_addrrecv macro
79 chkval 0x8c, s_event_idle_addrrecvread ; A,!P, S,R,!BF
80 chkval 0x89, s_event_idle_addrrecvwrite ; A,!P, S,W,BF
87 ; We have an interrupt:
89 ; Firstly, clear the interrupt flag so that if something else happens
90 ; while we faff, the interrupt will be regenerated:
93 ; Check that nothing obvious is wrong:
96 and_lw 0xc0 ; WCOL, SSPOV
97 bra_nz i2cs_interrupt_wcolsspov_endif
99 i2cs_interrupt_wcolsspov_endif
101 bt_f_if0 st, st_reading
104 bt_f_if0 st, st_writing
113 ;========================================
117 s_event_idle_addrrecvread
119 call i2csu_read_begin
120 bra s_events_read_datasend
125 chkval 0xac, s_event_reading_datasent ; D,!P, S,R,!BF
127 ; Whatever is happening, we're done reading now !
131 chkval 0xa8, s_event_reading_datanack ; D,!P, S,!R,!BF
132 ; Or, maybe it was nack and then we were reselected:
138 s_event_reading_datasent
139 call i2csu_read_another
140 s_events_reading_datasend
143 s_event_reading_datanack
146 ;========================================
150 s_event_idle_addrrecvwrite
151 bs_f SSPCON, 3 ; we'll need the Stop interrupt
153 ; well, this is all fine so far, so do carry on:
156 ; W any byte from master
157 ; i2c controller waiting due to SEN etc continuing with next byte
165 chkval 0xa9, s_event_writing_datarecv ; D,!P, S,W,BF
167 ; Well, we're done writing now in any case
169 bc_f SSPCON1, 3 ; no Start and Stop interrupts any more
170 call i2csu_write_done
172 ; Who knows what might have happened. We may have
173 ; missed a number of S and P due to delay between
174 ; clearing SSPIF and SSPM3(s&p-intrs) so we can't be
177 ; First, the nice cases:
183 and_lw 0xc7 ; ?D_A, ?P; ?S
184 xor_lw 0x80 ; SMP, !CKE, !R_W, !UA, !BF
191 s_event_writing_datarecv
192 rcall s_write_slurpbyte
194 bt_f_if1 st, st_subsequent
195 goto i2csu_write_another
196 ; not subsequent (yet):
198 bs_f st, st_subsequent
199 goto i2csu_write_begin
201 ;======================================================================