1
+ use super :: i2c:: { SclPin , SdaPin } ;
2
+ use super :: pac:: I2C1 ;
3
+
4
+ #[ derive( PartialEq ) ]
5
+ pub enum TransferState {
6
+ Idle ,
7
+ Addressed ,
8
+ RegisterSet ,
9
+ Receiving ,
10
+ Transmitting ,
11
+ }
12
+
13
+ #[ derive( Copy , Clone ) ]
14
+ pub enum State {
15
+ DataRequested ( u8 ) ,
16
+ DataReceived ( u8 ) ,
17
+ }
18
+
19
+ const BUFFER_SIZE : usize = 32 ;
20
+
21
+ pub struct I2CSlave < SDA , SCL > {
22
+ i2c : I2C1 ,
23
+ transfer_buffer : [ u8 ; BUFFER_SIZE ] ,
24
+ transfer_len : usize ,
25
+ buffer_index : usize ,
26
+ register : u8 ,
27
+ transfer_state : TransferState ,
28
+ state : Option < State > ,
29
+ _sda : SDA ,
30
+ _scl : SCL ,
31
+ }
32
+
33
+ // direction as specified in the datasheet
34
+ #[ derive( PartialEq ) ]
35
+ pub enum Direction {
36
+ Write , // slave is receiver
37
+ Read , // slave is transmitter
38
+ }
39
+
40
+ impl From < Direction > for bool {
41
+ fn from ( dir : Direction ) -> Self {
42
+ match dir {
43
+ Direction :: Write => false ,
44
+ Direction :: Read => true ,
45
+ }
46
+ }
47
+ }
48
+
49
+ impl From < bool > for Direction {
50
+ fn from ( raw : bool ) -> Self {
51
+ if raw {
52
+ Direction :: Read
53
+ } else {
54
+ Direction :: Write
55
+ }
56
+ }
57
+ }
58
+
59
+ pub enum Status {
60
+ AddressMatch ( Direction ) ,
61
+ Busy ,
62
+ Timeout ,
63
+ Overrun ,
64
+ ArbitrationLost ,
65
+ BusError ,
66
+ TransferCompleteReload ,
67
+ Stop ,
68
+ NACKReceived ,
69
+ RxNotEmpty ,
70
+ TxDataMustBeWritten ,
71
+ TxEmpty ,
72
+ }
73
+
74
+ impl < SDA , SCL > I2CSlave < SDA , SCL >
75
+ where
76
+ SDA : SdaPin < I2C1 > ,
77
+ SCL : SclPin < I2C1 > ,
78
+ {
79
+ pub fn new ( i2c : I2C1 , address : u8 , sda : SDA , scl : SCL ) -> Self {
80
+ let rcc = unsafe { & ( * stm32f0xx_hal:: pac:: RCC :: ptr ( ) ) } ;
81
+ rcc. apb1enr . modify ( |_, w| w. i2c1en ( ) . enabled ( ) ) ;
82
+ rcc. apb1rstr . modify ( |_, w| w. i2c1rst ( ) . set_bit ( ) ) ;
83
+ rcc. apb1rstr . modify ( |_, w| w. i2c1rst ( ) . clear_bit ( ) ) ;
84
+
85
+ i2c. cr1 . write ( |w| {
86
+ w. nostretch ( )
87
+ . enabled ( ) // enable clock stretching
88
+ . anfoff ( )
89
+ . enabled ( ) // enable analog filter
90
+ . dnf ( )
91
+ . no_filter ( ) // disable digital filter
92
+ . errie ( )
93
+ . enabled ( ) // error interrupt enabled
94
+ . stopie ( )
95
+ . enabled ( ) // stop interrupt enabled
96
+ . nackie ( )
97
+ . enabled ( ) // nack interrupt enabled
98
+ . addrie ( )
99
+ . enabled ( ) // address match interrupt enabled
100
+ . rxie ( ) // rx interrupt enabled
101
+ . enabled ( )
102
+ . wupen ( )
103
+ . enabled ( ) // wake up when address match
104
+ } ) ;
105
+
106
+ // TODO set up timing for nostretch mode
107
+ // let scll = cmp::max((((48_000_000 >> 1) >> 1) / KiloHertz(100).0) - 1, 255) as u8;
108
+ // i2c.timingr.write(|w| {
109
+ // w.presc()
110
+ // .bits(1)
111
+ // .scldel()
112
+ // .bits(4)
113
+ // .sdadel()
114
+ // .bits(2)
115
+ // .sclh()
116
+ // .bits(scll - 4)
117
+ // .scll()
118
+ // .bits(scll)
119
+ // });
120
+
121
+ i2c. oar1 . write ( |w| {
122
+ w. oa1en ( )
123
+ . enabled ( )
124
+ . oa1 ( )
125
+ . bits ( ( address as u16 ) << 1 )
126
+ . oa1mode ( )
127
+ . bit7 ( )
128
+ } ) ;
129
+
130
+ i2c. cr1 . modify (
131
+ |_, w| w. pe ( ) . enabled ( ) , // enable peripheral
132
+ ) ;
133
+
134
+ I2CSlave {
135
+ i2c,
136
+ transfer_buffer : [ 0u8 ; BUFFER_SIZE ] ,
137
+ transfer_len : 0 ,
138
+ buffer_index : 0 ,
139
+ register : 0 ,
140
+ transfer_state : TransferState :: Idle ,
141
+ state : None ,
142
+ _sda : sda,
143
+ _scl : scl,
144
+ }
145
+ }
146
+
147
+ pub fn is_status ( & self , status : Status , clear : bool ) -> bool {
148
+ let isr = self . i2c . isr . read ( ) ;
149
+
150
+ match status {
151
+ Status :: AddressMatch ( dir) => {
152
+ if isr. addr ( ) . bit_is_set ( ) {
153
+ if dir != isr. dir ( ) . bit ( ) . into ( ) {
154
+ return false ;
155
+ }
156
+ if clear {
157
+ self . i2c . icr . write ( |w| w. addrcf ( ) . clear ( ) ) ;
158
+ }
159
+ return true ;
160
+ } else {
161
+ false
162
+ }
163
+ }
164
+ Status :: Busy => {
165
+ return isr. busy ( ) . bit_is_set ( ) ;
166
+ }
167
+ Status :: Timeout => {
168
+ if isr. timeout ( ) . bit_is_set ( ) {
169
+ if clear {
170
+ self . i2c . icr . write ( |w| w. timoutcf ( ) . clear ( ) ) ;
171
+ }
172
+ return true ;
173
+ }
174
+ return false ;
175
+ }
176
+ Status :: Overrun => {
177
+ if isr. ovr ( ) . bit_is_set ( ) {
178
+ if clear {
179
+ self . i2c . icr . write ( |w| w. ovrcf ( ) . clear ( ) ) ;
180
+ }
181
+ return true ;
182
+ }
183
+ return false ;
184
+ }
185
+ Status :: ArbitrationLost => {
186
+ if isr. arlo ( ) . bit_is_set ( ) {
187
+ if clear {
188
+ self . i2c . icr . write ( |w| w. arlocf ( ) . clear ( ) ) ;
189
+ }
190
+ return true ;
191
+ }
192
+ return false ;
193
+ }
194
+ Status :: BusError => {
195
+ if isr. berr ( ) . bit_is_set ( ) {
196
+ if clear {
197
+ self . i2c . icr . write ( |w| w. berrcf ( ) . clear ( ) ) ;
198
+ }
199
+ return true ;
200
+ }
201
+ return false ;
202
+ }
203
+ Status :: TransferCompleteReload => {
204
+ if isr. tcr ( ) . bit_is_set ( ) {
205
+ if clear {
206
+ // defmt::error!("Cannot be cleared.");
207
+ }
208
+ return true ;
209
+ }
210
+ return false ;
211
+ }
212
+ Status :: Stop => {
213
+ if isr. stopf ( ) . bit_is_set ( ) {
214
+ if clear {
215
+ self . i2c . icr . write ( |w| w. stopcf ( ) . clear ( ) ) ;
216
+ }
217
+ return true ;
218
+ }
219
+ return false ;
220
+ }
221
+ Status :: NACKReceived => {
222
+ if isr. nackf ( ) . bit_is_set ( ) {
223
+ if clear {
224
+ self . i2c . icr . write ( |w| w. nackcf ( ) . clear ( ) ) ;
225
+ }
226
+ return true ;
227
+ }
228
+ return false ;
229
+ }
230
+ Status :: RxNotEmpty => {
231
+ if isr. rxne ( ) . bit_is_set ( ) {
232
+ if clear {
233
+ // defmt::error!("Cannot be cleared.");
234
+ }
235
+ return true ;
236
+ }
237
+ return false ;
238
+ }
239
+ Status :: TxDataMustBeWritten => {
240
+ if isr. txis ( ) . bit_is_set ( ) {
241
+ if clear {
242
+ // defmt::error!("Cannot be cleared.");
243
+ }
244
+ return true ;
245
+ }
246
+ return false ;
247
+ }
248
+ Status :: TxEmpty => {
249
+ if isr. txe ( ) . bit_is_set ( ) {
250
+ if clear {
251
+ // defmt::error!("Cannot be cleared.");
252
+ }
253
+ return true ;
254
+ }
255
+ return false ;
256
+ }
257
+ }
258
+ }
259
+
260
+ pub fn read ( & self ) -> u8 {
261
+ self . i2c . rxdr . read ( ) . bits ( ) as u8
262
+ }
263
+
264
+ pub fn write ( & self , value : u8 ) {
265
+ self . i2c . txdr . write ( |w| w. txdata ( ) . bits ( value) ) ;
266
+ }
267
+
268
+ pub fn set_txe ( & self ) {
269
+ self . i2c . isr . modify ( |_, w| w. txe ( ) . set_bit ( ) ) ;
270
+ }
271
+
272
+ pub fn enable_txie ( & self , enable : bool ) {
273
+ self . i2c
274
+ . cr1
275
+ . modify ( |_, w| w. txie ( ) . bit ( enable) . tcie ( ) . bit ( enable) ) ;
276
+ }
277
+
278
+ pub fn interrupt ( & mut self ) {
279
+ if self . transfer_state == TransferState :: Idle {
280
+ self . state = None ;
281
+ self . enable_txie ( false ) ;
282
+ }
283
+
284
+ if self . is_status ( Status :: BusError , true ) {
285
+ self . handle_error ( ) ;
286
+ return ;
287
+ }
288
+ if self . is_status ( Status :: Overrun , true ) {
289
+ self . handle_error ( ) ;
290
+ return ;
291
+ }
292
+ if self . is_status ( Status :: ArbitrationLost , true ) {
293
+ self . handle_error ( ) ;
294
+ return ;
295
+ }
296
+ if self . is_status ( Status :: NACKReceived , true ) {
297
+ self . handle_error ( ) ;
298
+ return ;
299
+ }
300
+ if self . is_status ( Status :: Timeout , true ) {
301
+ self . handle_error ( ) ;
302
+ return ;
303
+ }
304
+
305
+ if self . is_status ( Status :: RxNotEmpty , false ) {
306
+ if self . transfer_state == TransferState :: Addressed {
307
+ self . transfer_state = TransferState :: RegisterSet ;
308
+ self . register = self . read ( ) ;
309
+ } else if self . transfer_state == TransferState :: RegisterSet {
310
+ self . transfer_state = TransferState :: Receiving ;
311
+ } else if self . transfer_state == TransferState :: Receiving {
312
+ // do not change state, just read
313
+ self . transfer_buffer [ self . buffer_index ] = self . read ( ) ;
314
+ self . buffer_index += 1 ;
315
+ }
316
+ }
317
+
318
+ if self . is_status ( Status :: Stop , true ) {
319
+ // handle reception
320
+ if self . transfer_state == TransferState :: Receiving {
321
+ self . state = Some ( State :: DataReceived ( self . register ) ) ;
322
+ } else if self . transfer_state == TransferState :: Transmitting {
323
+ // data was transmitted, nothing else to do
324
+ self . state = None ;
325
+ }
326
+ self . i2c . isr . modify ( |_, w| w. txe ( ) . set_bit ( ) ) ; // flush txdr
327
+ self . transfer_state = TransferState :: Idle ;
328
+ }
329
+
330
+ if self . is_status ( Status :: AddressMatch ( Direction :: Write ) , true ) {
331
+ self . transfer_state = TransferState :: Addressed ;
332
+ }
333
+ if self . is_status ( Status :: TxDataMustBeWritten , false ) {
334
+ // this may be true more times than actual data length, ignore then
335
+ if self . transfer_state == TransferState :: Transmitting {
336
+ // state is not changed
337
+ if self . buffer_index < self . transfer_len {
338
+ self . write ( self . transfer_buffer [ self . buffer_index ] ) ;
339
+ self . buffer_index += 1 ;
340
+ } else {
341
+ self . enable_txie ( false ) ;
342
+ self . state = None ;
343
+ }
344
+ }
345
+ }
346
+ if self . is_status ( Status :: AddressMatch ( Direction :: Read ) , true ) {
347
+ if self . transfer_state == TransferState :: RegisterSet {
348
+ self . enable_txie ( true ) ;
349
+ self . transfer_state = TransferState :: Transmitting ;
350
+ self . state = Some ( State :: DataRequested ( self . register ) ) ;
351
+ }
352
+ }
353
+ }
354
+
355
+ fn handle_error ( & mut self ) {
356
+ self . transfer_state = TransferState :: Idle ;
357
+ self . state = None ;
358
+ self . transfer_len = 0 ;
359
+ self . buffer_index = 0 ;
360
+ self . i2c . isr . modify ( |_, w| w. txe ( ) . set_bit ( ) ) ; // flush txdr
361
+ }
362
+
363
+ pub fn set_transmit_buffer ( & mut self , buffer : & [ u8 ] ) {
364
+ for ( index, item) in buffer. iter ( ) . enumerate ( ) {
365
+ self . transfer_buffer [ index] = * item;
366
+ }
367
+ self . transfer_len = buffer. len ( ) ;
368
+ self . buffer_index = 0 ;
369
+ self . state = None
370
+ }
371
+
372
+ pub fn get_received_data ( & mut self ) -> & [ u8 ] {
373
+ let data = & self . transfer_buffer [ ..self . buffer_index ] ;
374
+ self . state = None ;
375
+ self . buffer_index = 0 ;
376
+ self . transfer_len = 0 ;
377
+ data
378
+ }
379
+
380
+ pub fn get_state ( & self ) -> Option < State > {
381
+ self . state
382
+ }
383
+ }
0 commit comments