@@ -158,6 +158,8 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
158
158
159
159
i2cResetFiFo (i2c );
160
160
i2cResetCmd (i2c );
161
+ //Clear Interrupts
162
+ i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
161
163
162
164
//CMD START
163
165
i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
@@ -174,26 +176,32 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
174
176
i = 0 ;
175
177
while (i < dataSend ) {
176
178
i ++ ;
177
- i2c -> dev -> fifo_data .data = data [index ++ ];
179
+ i2c -> dev -> fifo_data .val = data [index ++ ];
180
+ while (i2c -> dev -> status_reg .tx_fifo_cnt < i );
178
181
}
179
182
i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , willSend , false, false, true);
180
183
dataLen -= willSend ;
181
184
182
185
//CMD STOP or CMD END if there is more data
183
- if (dataLen ) {
186
+ if (dataLen || ! sendStop ) {
184
187
i2cSetCmd (i2c , 2 , I2C_CMD_END , 0 , false, false, false);
185
188
} else if (sendStop ) {
186
189
i2cSetCmd (i2c , 2 , I2C_CMD_STOP , 0 , false, false, false);
187
190
}
188
191
189
- //Clear Interrupts
190
- i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
191
-
192
192
//START Transmission
193
193
i2c -> dev -> ctr .trans_start = 1 ;
194
194
195
195
//WAIT Transmission
196
+ uint32_t startAt = millis ();
196
197
while (1 ) {
198
+ //have been looping for too long
199
+ if ((millis () - startAt )> 50 ){
200
+ //log_e("Timeout! Addr: %x", address >> 1);
201
+ I2C_MUTEX_UNLOCK ();
202
+ return I2C_ERROR_BUS ;
203
+ }
204
+
197
205
//Bus failed (maybe check for this while waiting?
198
206
if (i2c -> dev -> int_raw .arbitration_lost ) {
199
207
//log_e("Bus Fail! Addr: %x", address >> 1);
@@ -210,14 +218,12 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
210
218
211
219
//Transmission did not finish and ACK_ERR is set
212
220
if (i2c -> dev -> int_raw .ack_err ) {
213
- //log_e ("Ack Error! Addr: %x", address >> 1);
221
+ //log_w ("Ack Error! Addr: %x", address >> 1);
214
222
I2C_MUTEX_UNLOCK ();
215
223
return I2C_ERROR_ACK ;
216
224
}
217
225
218
- if (i2c -> dev -> ctr .trans_start || i2c -> dev -> status_reg .bus_busy || !(i2c -> dev -> int_raw .trans_complete ) || !(i2c -> dev -> command [2 ].done )) {
219
- continue ;
220
- } else if (i2c -> dev -> command [2 ].done ) {
226
+ if ((sendStop && i2c -> dev -> command [2 ].done ) || !i2c -> dev -> status_reg .bus_busy ){
221
227
break ;
222
228
}
223
229
}
@@ -248,9 +254,9 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
248
254
i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
249
255
250
256
//CMD WRITE ADDRESS
251
- i2c -> dev -> fifo_data .data = address & 0xFF ;
257
+ i2c -> dev -> fifo_data .val = address & 0xFF ;
252
258
if (addr_10bit ) {
253
- i2c -> dev -> fifo_data .data = (address >> 8 ) & 0xFF ;
259
+ i2c -> dev -> fifo_data .val = (address >> 8 ) & 0xFF ;
254
260
}
255
261
i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , addrLen , false, false, true);
256
262
@@ -279,7 +285,15 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
279
285
i2c -> dev -> ctr .trans_start = 1 ;
280
286
281
287
//WAIT Transmission
288
+ uint32_t startAt = millis ();
282
289
while (1 ) {
290
+ //have been looping for too long
291
+ if ((millis () - startAt )> 50 ){
292
+ //log_e("Timeout! Addr: %x", address >> 1);
293
+ I2C_MUTEX_UNLOCK ();
294
+ return I2C_ERROR_BUS ;
295
+ }
296
+
283
297
//Bus failed (maybe check for this while waiting?
284
298
if (i2c -> dev -> int_raw .arbitration_lost ) {
285
299
//log_e("Bus Fail! Addr: %x", address >> 1);
@@ -296,21 +310,20 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
296
310
297
311
//Transmission did not finish and ACK_ERR is set
298
312
if (i2c -> dev -> int_raw .ack_err ) {
299
- //log_e ("Ack Error! Addr: %x", address >> 1);
313
+ //log_w ("Ack Error! Addr: %x", address >> 1);
300
314
I2C_MUTEX_UNLOCK ();
301
315
return I2C_ERROR_ACK ;
302
316
}
303
- if (i2c -> dev -> ctr .trans_start || i2c -> dev -> status_reg .bus_busy || !(i2c -> dev -> int_raw .trans_complete ) || !(i2c -> dev -> command [cmdIdx - 1 ].done )) {
304
- continue ;
305
- } else if (i2c -> dev -> command [cmdIdx - 1 ].done ) {
317
+
318
+ if (i2c -> dev -> command [cmdIdx - 1 ].done ) {
306
319
break ;
307
320
}
308
321
}
309
322
310
323
int i = 0 ;
311
324
while (i < willRead ) {
312
325
i ++ ;
313
- data [index ++ ] = i2c -> dev -> fifo_data .data ;
326
+ data [index ++ ] = i2c -> dev -> fifo_data .val & 0xFF ;
314
327
}
315
328
len -= willRead ;
316
329
}
@@ -320,24 +333,34 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
320
333
321
334
i2c_err_t i2cSetFrequency (i2c_t * i2c , uint32_t clk_speed )
322
335
{
323
- uint32_t period = (APB_CLK_FREQ /clk_speed ) / 2 ;
324
-
325
336
if (i2c == NULL ){
326
337
return I2C_ERROR_DEV ;
327
338
}
328
339
340
+ uint32_t period = (APB_CLK_FREQ /clk_speed ) / 2 ;
341
+ uint32_t halfPeriod = period /2 ;
342
+ uint32_t quarterPeriod = period /4 ;
343
+
329
344
I2C_MUTEX_LOCK ();
345
+ //the clock num during SCL is low level
330
346
i2c -> dev -> scl_low_period .scl_low_period = period ;
347
+ //the clock num during SCL is high level
331
348
i2c -> dev -> scl_high_period .period = period ;
332
349
333
- i2c -> dev -> scl_start_hold .time = 50 ;
334
- i2c -> dev -> scl_rstart_setup .time = 50 ;
350
+ //the clock num between the negedge of SDA and negedge of SCL for start mark
351
+ i2c -> dev -> scl_start_hold .time = halfPeriod ;
352
+ //the clock num between the posedge of SCL and the negedge of SDA for restart mark
353
+ i2c -> dev -> scl_rstart_setup .time = halfPeriod ;
335
354
336
- i2c -> dev -> scl_stop_hold .time = 50 ;
337
- i2c -> dev -> scl_stop_setup .time = 50 ;
355
+ //the clock num after the STOP bit's posedge
356
+ i2c -> dev -> scl_stop_hold .time = halfPeriod ;
357
+ //the clock num between the posedge of SCL and the posedge of SDA
358
+ i2c -> dev -> scl_stop_setup .time = halfPeriod ;
338
359
339
- i2c -> dev -> sda_hold .time = 25 ;
340
- i2c -> dev -> sda_sample .time = 25 ;
360
+ //the clock num I2C used to hold the data after the negedge of SCL.
361
+ i2c -> dev -> sda_hold .time = quarterPeriod ;
362
+ //the clock num I2C used to sample data on SDA after the posedge of SCL
363
+ i2c -> dev -> sda_sample .time = quarterPeriod ;
341
364
I2C_MUTEX_UNLOCK ();
342
365
return I2C_ERROR_OK ;
343
366
}
@@ -389,7 +412,9 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
389
412
i2c -> dev -> ctr .scl_force_out = 1 ;
390
413
i2c -> dev -> ctr .clk_en = 1 ;
391
414
415
+ //the max clock number of receiving a data
392
416
i2c -> dev -> timeout .tout = 400000 ;//clocks max=1048575
417
+ //disable apb nonfifo access
393
418
i2c -> dev -> fifo_conf .nonfifo_en = 0 ;
394
419
395
420
i2c -> dev -> slave_addr .val = 0 ;
@@ -402,4 +427,19 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
402
427
return i2c ;
403
428
}
404
429
405
-
430
+ void i2cInitFix (i2c_t * i2c ){
431
+ if (i2c == NULL ){
432
+ return ;
433
+ }
434
+ I2C_MUTEX_LOCK ();
435
+ i2cResetFiFo (i2c );
436
+ i2cResetCmd (i2c );
437
+ i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
438
+ i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
439
+ i2c -> dev -> fifo_data .data = 0 ;
440
+ i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , 1 , false, false, false);
441
+ i2cSetCmd (i2c , 2 , I2C_CMD_STOP , 0 , false, false, false);
442
+ i2c -> dev -> ctr .trans_start = 1 ;
443
+ while (!i2c -> dev -> command [2 ].done );
444
+ I2C_MUTEX_UNLOCK ();
445
+ }
0 commit comments