chiark / gitweb /
slave done?
[trains.git] / detpic / i2clib.asm
1 ;######################################################################
2 ; i2clib.inc - I2C LIBRARY - IMPLEMENTATION
3 ;
4 ; See i2clib.asm for documentation of the interface to this file.
5
6  include /usr/share/gputils/header/p18f458.inc
7  radix dec
8  include ../iwjpictest/insn-aliases.inc
9
10 ;============================================================
11 ; COMMON ADMINISTRATIVE ROUTINES and VARIABLES
12
13                 udata_acs
14
15 ssp             res     1
16
17 st              res     1       ; bitmask:
18 st_writing      equ     0
19 st_subsequent   equ     0
20
21                 code
22
23 ;----------
24 slave2addr
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
28                 add_lw  0b0001000
29                 rlc_w
30                 return
31
32
33 ;======================================================================
34 ; SLAVE
35
36 ;----------
37 i2cs_init
38 ;       W               slave number            undefined
39                 rcall   slave2addr2
40                 mov_wf  SSPADD
41                 clr_f   st
42                 mov_lw  0x16 ; !SSPEN, CKP(release), I2C 7-bit slave no-SP-int
43                 mov_wf  SSPCON1
44                 mov_lw  0x01 ; !GCEN, SEN
45                 mov_wf  SSPCON2
46                 mov_lw  0x8 ; SMP(noslew), !CKE, !BF(empty)
47                 mov_wf  SSPSTAT
48                 bs_f    TRISB, 0
49                 bs_f    TRISB, 1
50                 bc_f    IPR1, SSPIP
51                 bs_f    SSPCON1, SSPEN
52                 bs_f    PIE1, SSPIE
53                 return
54
55 ;========================================
56 ; SLAVE - INTERRUPT HANDLING
57
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)
64
65 ; Some macros:
66
67 chkvals_start macro
68                 mov_fw  ssp
69 chkval_lastvalue equ 0
70                 endm
71
72 chkval macro value, label
73                 xor_lw  value ^ chkval_lastvalue
74  chkval_lastvalue equ value
75                 bra_z   label
76                 endm
77
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
81                 endm
82
83 ;----------
84 i2cs_interrupt
85                 bt_f_if0 PIR1, SSPIF
86                 return
87                 ; We have an interrupt:
88
89 ; Firstly, clear the interrupt flag so that if something else happens
90 ; while we faff, the interrupt will be regenerated:
91                 bc_f    PIR1, SSPIF
92
93 ; Check that nothing obvious is wrong:
94                 mov_fw  SSPCON1
95                 mov_wf  ssp
96                 and_lw  0xc0 ; WCOL, SSPOV
97                 bra_nz  i2cs_interrupt_wcolsspov_endif
98                 panic   morse_SV
99 i2cs_interrupt_wcolsspov_endif
100
101                 bt_f_if0 st, st_reading
102                 bra     s_event_reading
103
104                 bt_f_if0 st, st_writing
105                 bra     s_event_writing
106
107 s_event_idle
108                 chkvals_start
109                 chkvals_addrrecv
110
111                 panic   morse_SI
112
113 ;========================================
114 ; SLAVE - READING
115
116 ;----------
117 s_event_idle_addrrecvread
118                 bs_f    st, st_reading
119                 call    i2csu_read_begin
120                 bra     s_events_read_datasend
121
122 ;----------
123 s_event_reading
124                 chkvals_start
125                 chkval  0xac, s_event_reading_datasent ; D,!P, S,R,!BF
126
127                 ; Whatever is happening, we're done reading now !
128                 clr_f   st
129                 call    i2csu_read_done
130
131                 chkval  0xa8, s_event_reading_datanack ; D,!P, S,!R,!BF
132                 ; Or, maybe it was nack and then we were reselected:
133                 chkvals_addrrecv
134
135                 panic   morse_SR
136
137 ;----------
138 s_event_reading_datasent
139                 call    i2csu_read_another
140 s_events_reading_datasend
141                 mov_wf  SSPBUF
142                 bs_f    SSPCON1, CKP
143 s_event_reading_datanack
144                 return
145
146 ;========================================
147 ; SLAVE - WRITING
148
149 ;----------
150 s_event_idle_addrrecvwrite
151                 bs_f    SSPCON, 3 ; we'll need the Stop interrupt
152                 bs_f    st, st_writing
153                 ; well, this is all fine so far, so do carry on:
154
155 s_write_slurpbyte
156 ;       W               any                     byte from master
157 ;       i2c controller  waiting due to SEN etc  continuing with next byte
158                 mov_fw  SSPBUF
159                 bs_f    SSPCON1, CKP
160                 return
161
162 ;----------
163 s_event_writing
164                 chkvals_start
165                 chkval  0xa9, s_event_writing_datarecv ; D,!P, S,W,BF
166
167                 ; Well, we're done writing now in any case
168                 clr_f   st
169                 bc_f    SSPCON1, 3 ; no Start and Stop interrupts any more
170                 call    i2csu_write_done
171
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
175                 ; too picky.
176
177                 ; First, the nice cases:
178                 chkvals_start
179                 chkvals_addrrecv
180
181                 ; Then random junk:
182                 mov_fw  ssp
183                 and_lw  0xc7 ; ?D_A, ?P; ?S
184                 xor_lw  0x80 ; SMP, !CKE, !R_W, !UA, !BF
185                 bt_f_if1 STATUS, Z
186                 return
187
188                 panic   morse_SW
189
190 ;----------
191 s_event_writing_datarecv
192                 rcall   s_write_slurpbyte
193
194                 bt_f_if1 st, st_subsequent
195                 goto    i2csu_write_another
196                 ; not subsequent (yet):
197
198                 bs_f    st, st_subsequent
199                 goto    i2csu_write_begin
200
201 ;======================================================================
202
203  include i2clib.inc
204  end