31
31
#define DR_REG_I2C_EXT_BASE_FIXED 0x60013000
32
32
#define DR_REG_I2C1_EXT_BASE_FIXED 0x60027000
33
33
34
+ #define COMMAND_BUFFER_LENGTH 16
35
+
34
36
struct i2c_struct_t {
35
37
i2c_dev_t * dev ;
36
38
#if !CONFIG_DISABLE_HAL_LOCKS
@@ -127,26 +129,25 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo
127
129
i2c -> dev -> command [index ].op_code = op_code ;
128
130
}
129
131
130
- void i2cResetCmd (i2c_t * i2c ){
131
- int i ;
132
+ void i2cResetCmd (i2c_t * i2c ) {
133
+ uint8_t i ;
132
134
for (i = 0 ;i < 16 ;i ++ ){
133
135
i2c -> dev -> command [i ].val = 0 ;
134
136
}
135
137
}
136
138
137
- void i2cResetFiFo (i2c_t * i2c )
138
- {
139
+ void i2cResetFiFo (i2c_t * i2c ) {
139
140
i2c -> dev -> fifo_conf .tx_fifo_rst = 1 ;
140
141
i2c -> dev -> fifo_conf .tx_fifo_rst = 0 ;
141
142
i2c -> dev -> fifo_conf .rx_fifo_rst = 1 ;
142
143
i2c -> dev -> fifo_conf .rx_fifo_rst = 0 ;
143
144
}
144
145
145
- i2c_err_t i2cWrite (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint8_t len , bool sendStop )
146
+ i2c_err_t i2cWrite (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint16_t len , bool sendStop )
146
147
{
147
148
int i ;
148
- uint8_t index = 0 ;
149
- uint8_t dataLen = len + (addr_10bit ?2 :1 );
149
+ uint16_t index = 0 ;
150
+ uint16_t dataLen = len + (addr_10bit ?2 :1 );
150
151
address = (address << 1 );
151
152
152
153
if (i2c == NULL ){
@@ -247,12 +248,25 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
247
248
return I2C_ERROR_OK ;
248
249
}
249
250
250
- i2c_err_t i2cRead (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint8_t len , bool sendStop )
251
+ uint8_t inc ( uint8_t * index )
252
+ {
253
+ uint8_t i = index [ 0 ];
254
+ if (++ index [ 0 ] == COMMAND_BUFFER_LENGTH )
255
+ {
256
+ index [ 0 ] = 0 ;
257
+ }
258
+
259
+ return i ;
260
+ }
261
+
262
+ i2c_err_t i2cRead (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint16_t len , bool sendStop )
251
263
{
252
264
address = (address << 1 ) | 1 ;
253
265
uint8_t addrLen = (addr_10bit ?2 :1 );
254
- uint8_t index = 0 ;
255
- uint8_t cmdIdx ;
266
+ uint8_t amountRead [16 ];
267
+ uint16_t index = 0 ;
268
+ uint8_t cmdIdx = 0 , currentCmdIdx = 0 , nextCmdCount ;
269
+ bool stopped = false, isEndNear = false;
256
270
uint8_t willRead ;
257
271
258
272
if (i2c == NULL ){
@@ -272,90 +286,93 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
272
286
i2cResetCmd (i2c );
273
287
274
288
//CMD START
275
- i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
289
+ i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_RSTART , 0 , false, false, false);
276
290
277
291
//CMD WRITE ADDRESS
278
- if (addr_10bit ){ // address is leftshifted with Read/Write bit set
292
+ if (addr_10bit ) { // address is left-shifted with Read/Write bit set
279
293
i2c -> dev -> fifo_data .data = (((address >> 8 ) & 0x6 ) | 0xF1 ); // send a9:a8 plus 1111 0xxR mask
280
294
i2c -> dev -> fifo_data .data = ((address >> 1 ) & 0xFF ); // send a7:a0, remove R bit (7bit address style)
281
295
}
282
296
else { // 7bit address
283
297
i2c -> dev -> fifo_data .data = address & 0xFF ;
284
298
}
299
+ i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_WRITE , addrLen , false, false, true);
300
+ nextCmdCount = cmdIdx ;
285
301
286
- i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , addrLen , false, false, true);
287
-
288
- while (len ) {
289
- cmdIdx = (index )?0 :2 ;
290
- willRead = (len > 32 )?32 :(len - 1 );
291
- if (cmdIdx ){
292
- i2cResetFiFo (i2c );
293
- }
294
-
295
- if (willRead ){
296
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_READ , willRead , false, false, false);
297
- }
298
-
299
- if ((len - willRead ) > 1 ) {
300
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_END , 0 , false, false, false);
301
- } else {
302
- willRead ++ ;
303
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_READ , 1 , true, false, false);
304
- if (sendStop ) {
305
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_STOP , 0 , false, false, false);
306
- }
307
- }
308
-
309
- //Clear Interrupts
310
- i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
311
-
312
- //START Transmission
313
- i2c -> dev -> ctr .trans_start = 1 ;
302
+ //Clear Interrupts
303
+ i2c -> dev -> int_clr .val = 0x00001FFF ;
314
304
305
+ //START Transmission
306
+ i2c -> dev -> ctr .trans_start = 1 ;
307
+ while (!stopped ) {
315
308
//WAIT Transmission
316
309
uint32_t startAt = millis ();
317
310
while (1 ) {
318
311
//have been looping for too long
319
- if ((millis () - startAt )> 50 ){
320
- log_e ("Timeout! Addr: %x" , address >> 1 );
312
+ if ((millis () - startAt )> 50 ) {
313
+ log_e ("Timeout! Addr: %x, index %d " , ( address >> 1 ), index );
321
314
I2C_MUTEX_UNLOCK ();
322
315
return I2C_ERROR_BUS ;
323
316
}
324
317
325
318
//Bus failed (maybe check for this while waiting?
326
319
if (i2c -> dev -> int_raw .arbitration_lost ) {
327
- log_e ("Bus Fail! Addr: %x" , address >> 1 );
320
+ log_e ("Bus Fail! Addr: %x" , ( address >> 1 ) );
328
321
I2C_MUTEX_UNLOCK ();
329
322
return I2C_ERROR_BUS ;
330
323
}
331
324
332
325
//Bus timeout
333
326
if (i2c -> dev -> int_raw .time_out ) {
334
- log_e ("Bus Timeout! Addr: %x" , address >> 1 );
327
+ log_e ("Bus Timeout! Addr: %x, index %d " , ( address >> 1 ), index );
335
328
I2C_MUTEX_UNLOCK ();
336
329
return I2C_ERROR_TIMEOUT ;
337
330
}
338
331
339
332
//Transmission did not finish and ACK_ERR is set
340
333
if (i2c -> dev -> int_raw .ack_err ) {
341
334
log_w ("Ack Error! Addr: %x" , address >> 1 );
335
+ while ((i2c -> dev -> status_reg .bus_busy ) && ((millis () - startAt )< 50 ));
342
336
I2C_MUTEX_UNLOCK ();
343
337
return I2C_ERROR_ACK ;
344
338
}
345
339
346
- if (i2c -> dev -> command [cmdIdx - 1 ].done ) {
347
- break ;
340
+ // Save bytes from the buffer as they arrive instead of doing them at the end of the loop since there is no
341
+ // pause from an END operation in this approach.
342
+ if ((!isEndNear ) && (nextCmdCount < 2 )) {
343
+ if (willRead = ((len > 32 )?32 :len )) {
344
+ if (willRead > 1 ) {
345
+ i2cSetCmd (i2c , cmdIdx , I2C_CMD_READ , (amountRead [ inc ( & cmdIdx ) ] = willRead - 1 ), false, false, false);
346
+ nextCmdCount ++ ;
347
+ }
348
+ i2cSetCmd (i2c , cmdIdx , I2C_CMD_READ , (amountRead [ inc ( & cmdIdx ) ] = 1 ), (len <=32 ), false, false);
349
+ nextCmdCount ++ ;
350
+ len -= willRead ;
351
+ } else {
352
+ i2cSetCmd (i2c , inc ( & cmdIdx ), I2C_CMD_STOP , 0 , false, false, false);
353
+ isEndNear = true;
354
+ nextCmdCount ++ ;
355
+ }
348
356
}
349
- }
350
357
351
- int i = 0 ;
352
- while (i < willRead ) {
353
- i ++ ;
354
- data [index ++ ] = i2c -> dev -> fifo_data .val & 0xFF ;
358
+ if (i2c -> dev -> command [currentCmdIdx ].done ) {
359
+ nextCmdCount -- ;
360
+ if (i2c -> dev -> command [currentCmdIdx ].op_code == I2C_CMD_READ ) {
361
+ while (amountRead [currentCmdIdx ]> 0 ) {
362
+ data [index ++ ] = i2c -> dev -> fifo_data .val & 0xFF ;
363
+ amountRead [currentCmdIdx ]-- ;
364
+ }
365
+ i2cResetFiFo (i2c );
366
+ } else if (i2c -> dev -> command [currentCmdIdx ].op_code == I2C_CMD_STOP ) {
367
+ stopped = true;
368
+ }
369
+ inc ( & currentCmdIdx );
370
+ break ;
371
+ }
355
372
}
356
- len -= willRead ;
357
373
}
358
374
I2C_MUTEX_UNLOCK ();
375
+
359
376
return I2C_ERROR_OK ;
360
377
}
361
378
@@ -432,7 +449,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
432
449
DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT1_CLK_EN );
433
450
DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST );
434
451
}
435
-
452
+
436
453
I2C_MUTEX_LOCK ();
437
454
i2c -> dev -> ctr .val = 0 ;
438
455
i2c -> dev -> ctr .ms_mode = (slave_addr == 0 );
@@ -441,7 +458,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
441
458
i2c -> dev -> ctr .clk_en = 1 ;
442
459
443
460
//the max clock number of receiving a data
444
- i2c -> dev -> timeout .tout = 400000 ;//clocks max=1048575
461
+ i2c -> dev -> timeout .tout = 1048575 ;//clocks max=1048575
445
462
//disable apb nonfifo access
446
463
i2c -> dev -> fifo_conf .nonfifo_en = 0 ;
447
464
0 commit comments