@@ -76,6 +76,7 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
76
76
// Enable I2C clock
77
77
if (obj -> i2c == I2C_1 ) {
78
78
RCC_APB1PeriphClockCmd (RCC_APB1Periph_I2C1 , ENABLE );
79
+ RCC_I2CCLKConfig (RCC_I2C1CLK_SYSCLK );
79
80
}
80
81
if (obj -> i2c == I2C_2 ) {
81
82
RCC_APB1PeriphClockCmd (RCC_APB1Periph_I2C2 , ENABLE );
@@ -113,35 +114,66 @@ void i2c_frequency(i2c_t *obj, int hz) {
113
114
* Fast Mode (up to 400 kHz)
114
115
* Fast Mode Plus (up to 1 MHz)
115
116
Below values obtained with:
116
- - I2C clock source = 8 MHz (HSI clock per default )
117
+ - I2C clock source = 64 MHz (System Clock w/ HSI) or 72 (System Clock w/ HSE )
117
118
- Analog filter delay = ON
118
119
- Digital filter coefficient = 0
119
120
- Rise time = 100 ns
120
121
- Fall time = 10ns
121
122
*/
122
- switch (hz ) {
123
- case 100000 :
124
- tim = 0x00201D2B ; // Standard mode
123
+ if (SystemCoreClock == 64000000 ) {
124
+ switch (hz ) {
125
+ case 100000 :
126
+ tim = 0x60302730 ; // Standard mode
125
127
break ;
126
- case 200000 :
127
- tim = 0x0010021E ; // Fast Mode
128
+ case 200000 :
129
+ tim = 0x00C07AB3 ; // Fast Mode
128
130
break ;
129
- case 400000 :
130
- tim = 0x0010020A ; // Fast Mode
131
+ case 400000 :
132
+ tim = 0x00C0216C ; // Fast Mode
131
133
break ;
132
- case 1000000 :
133
- tim = 0x00100001 ; // Fast Mode Plus
134
- // Enable the Fast Mode Plus capability
135
- if (obj -> i2c == I2C_1 ) {
136
- SYSCFG_I2CFastModePlusConfig (SYSCFG_I2CFastModePlus_I2C1 , ENABLE );
137
- }
138
- if (obj -> i2c == I2C_2 ) {
139
- SYSCFG_I2CFastModePlusConfig (SYSCFG_I2CFastModePlus_I2C2 , ENABLE );
140
- }
134
+ case 1000000 :
135
+ tim = 0x00900B22 ; // Fast Mode Plus
136
+ // Enable the Fast Mode Plus capability
137
+ if (obj -> i2c == I2C_1 ) {
138
+ SYSCFG_I2CFastModePlusConfig (SYSCFG_I2CFastModePlus_I2C1 , ENABLE );
139
+ }
140
+ if (obj -> i2c == I2C_2 ) {
141
+ SYSCFG_I2CFastModePlusConfig (SYSCFG_I2CFastModePlus_I2C2 , ENABLE );
142
+ }
141
143
break ;
142
- default :
143
- error ("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported." );
144
+ default :
145
+ error ("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported." );
144
146
break ;
147
+ }
148
+ }
149
+ else if (SystemCoreClock == 72000000 ) {
150
+ switch (hz ) {
151
+ case 100000 :
152
+ tim = 0x10C08DCF ; // Standard mode
153
+ break ;
154
+ case 200000 :
155
+ tim = 0xA010031A ; // Fast Mode
156
+ break ;
157
+ case 400000 :
158
+ tim = 0x00E0257A ; // Fast Mode
159
+ break ;
160
+ case 1000000 :
161
+ tim = 0x00A00D26 ; // Fast Mode Plus
162
+ // Enable the Fast Mode Plus capability
163
+ if (obj -> i2c == I2C_1 ) {
164
+ SYSCFG_I2CFastModePlusConfig (SYSCFG_I2CFastModePlus_I2C1 , ENABLE );
165
+ }
166
+ if (obj -> i2c == I2C_2 ) {
167
+ SYSCFG_I2CFastModePlusConfig (SYSCFG_I2CFastModePlus_I2C2 , ENABLE );
168
+ }
169
+ break ;
170
+ default :
171
+ error ("Only 100kHz, 200kHz, 400kHz and 1MHz I2C frequencies are supported." );
172
+ break ;
173
+ }
174
+ }
175
+ else {
176
+ error ("System clock setting is not supported." );
145
177
}
146
178
147
179
// I2C configuration
@@ -184,64 +216,58 @@ inline int i2c_stop(i2c_t *obj) {
184
216
return 0 ;
185
217
}
186
218
219
+
187
220
int i2c_read (i2c_t * obj , int address , char * data , int length , int stop ) {
188
221
I2C_TypeDef * i2c = (I2C_TypeDef * )(obj -> i2c );
189
222
int count ;
223
+ int timeout ;
190
224
int value ;
191
225
192
226
if (length == 0 ) return 0 ;
193
227
194
228
// Configure slave address, nbytes, reload, end mode and start or stop generation
195
- I2C_TransferHandling (i2c , address , length , I2C_AutoEnd_Mode , I2C_Generate_Start_Read );
229
+ I2C_TransferHandling (i2c , address , length , I2C_SoftEnd_Mode , I2C_Generate_Start_Read );
196
230
197
231
// Read all bytes
198
232
for (count = 0 ; count < length ; count ++ ) {
199
233
value = i2c_byte_read (obj , 0 );
200
234
data [count ] = (char )value ;
201
235
}
202
236
237
+ timeout = FLAG_TIMEOUT ;
238
+ while (!I2C_GetFlagStatus (i2c , I2C_FLAG_TC )) {
239
+ timeout -- ;
240
+ if (timeout == 0 ) return 0 ;
241
+ }
242
+
243
+ if (stop ) i2c_stop (obj );
244
+
203
245
return length ;
204
246
}
205
247
248
+
206
249
int i2c_write (i2c_t * obj , int address , const char * data , int length , int stop ) {
207
250
I2C_TypeDef * i2c = (I2C_TypeDef * )(obj -> i2c );
208
- // int timeout;
251
+ int timeout ;
209
252
int count ;
210
253
211
254
if (length == 0 ) return 0 ;
212
255
213
- // [TODO] The stop is always sent even with I2C_SoftEnd_Mode. To be corrected.
214
-
215
- // Configure slave address, nbytes, reload, end mode and start or stop generation
216
- //if (stop) {
217
- I2C_TransferHandling (i2c , address , length , I2C_AutoEnd_Mode , I2C_Generate_Start_Write );
218
- //}
219
- //else {
220
- // I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
221
- //}
256
+ // Configure slave address, nbytes, reload, end mode and start generation
257
+ I2C_TransferHandling (i2c , address , length , I2C_SoftEnd_Mode , I2C_Generate_Start_Write );
222
258
223
259
// Write all bytes
224
260
for (count = 0 ; count < length ; count ++ ) {
225
- if (i2c_byte_write (obj , data [count ]) != 1 ) {
226
- i2c_stop (obj );
227
- return 0 ;
228
- }
261
+ i2c_byte_write (obj , data [count ]);
229
262
}
230
263
231
- /*
232
- if (stop) {
233
- // Wait until STOPF flag is set
234
- timeout = LONG_TIMEOUT;
235
- while (I2C_GetFlagStatus(i2c, I2C_ISR_STOPF) == RESET) {
236
- timeout--;
237
- if (timeout == 0) {
238
- return 0;
239
- }
240
- }
241
- // Clear STOPF flag
242
- I2C_ClearFlag(i2c, I2C_ICR_STOPCF);
264
+ timeout = FLAG_TIMEOUT ;
265
+ while (!I2C_GetFlagStatus (i2c , I2C_FLAG_TC )) {
266
+ timeout -- ;
267
+ if (timeout == 0 ) return 0 ;
243
268
}
244
- */
269
+
270
+ if (stop ) i2c_stop (obj );
245
271
246
272
return count ;
247
273
}
@@ -304,14 +330,17 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
304
330
I2C_TypeDef * i2c = (I2C_TypeDef * )(obj -> i2c );
305
331
uint16_t tmpreg ;
306
332
333
+ // reset own address enable
334
+ i2c -> OAR1 &=~ I2C_OAR1_OA1EN ;
335
+
307
336
// Get the old register value
308
337
tmpreg = i2c -> OAR1 ;
309
338
// Reset address bits
310
339
tmpreg &= 0xFC00 ;
311
340
// Set new address
312
341
tmpreg |= (uint16_t )((uint16_t )address & (uint16_t )0x00FE ); // 7-bits
313
342
// Store the new register value
314
- i2c -> OAR1 = tmpreg ;
343
+ i2c -> OAR1 = tmpreg | I2C_OAR1_OA1EN ;
315
344
}
316
345
317
346
void i2c_slave_mode (i2c_t * obj , int enable_slave ) {
@@ -325,8 +354,21 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) {
325
354
#define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
326
355
327
356
int i2c_slave_receive (i2c_t * obj ) {
328
- // TO BE DONE
329
- return (0 );
357
+ I2C_TypeDef * i2c = (I2C_TypeDef * )(obj -> i2c );
358
+ int event = NoData ;
359
+
360
+ if (I2C_GetFlagStatus (i2c , I2C_ISR_BUSY ) == SET ) {
361
+ if (I2C_GetFlagStatus (i2c , I2C_ISR_ADDR ) == SET ) {
362
+ // Check direction
363
+ if (I2C_GetFlagStatus (i2c , I2C_ISR_DIR ) == SET ) {
364
+ event = ReadAddressed ;
365
+ }
366
+ else event = WriteAddressed ;
367
+ // Clear adress match flag to generate an acknowledge
368
+ i2c -> ICR |= I2C_ICR_ADDRCF ;
369
+ }
370
+ }
371
+ return event ;
330
372
}
331
373
332
374
int i2c_slave_read (i2c_t * obj , char * data , int length ) {
0 commit comments