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 ){
@@ -244,12 +245,25 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
244
245
return I2C_ERROR_OK ;
245
246
}
246
247
247
- i2c_err_t i2cRead (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint8_t len , bool sendStop )
248
+ uint8_t inc ( uint8_t * index )
249
+ {
250
+ uint8_t i = index [ 0 ];
251
+ if (++ index [ 0 ] == COMMAND_BUFFER_LENGTH )
252
+ {
253
+ index [ 0 ] = 0 ;
254
+ }
255
+
256
+ return i ;
257
+ }
258
+
259
+ i2c_err_t i2cRead (i2c_t * i2c , uint16_t address , bool addr_10bit , uint8_t * data , uint16_t len , bool sendStop )
248
260
{
249
261
address = (address << 1 ) | 1 ;
250
262
uint8_t addrLen = (addr_10bit ?2 :1 );
251
- uint8_t index = 0 ;
252
- uint8_t cmdIdx ;
263
+ uint8_t amountRead [16 ];
264
+ uint16_t index = 0 ;
265
+ uint8_t cmdIdx = 0 , currentCmdIdx = 0 , nextCmdCount ;
266
+ bool stopped = false, isEndNear = false;
253
267
uint8_t willRead ;
254
268
255
269
if (i2c == NULL ){
@@ -269,86 +283,90 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
269
283
i2cResetCmd (i2c );
270
284
271
285
//CMD START
272
- i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
286
+ i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_RSTART , 0 , false, false, false);
273
287
274
288
//CMD WRITE ADDRESS
275
289
i2c -> dev -> fifo_data .val = address & 0xFF ;
276
290
if (addr_10bit ) {
277
291
i2c -> dev -> fifo_data .val = (address >> 8 ) & 0xFF ;
278
292
}
279
- i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , addrLen , false, false, true);
293
+ i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_WRITE , addrLen , false, false, true);
294
+ nextCmdCount = cmdIdx ;
280
295
281
- while (len ) {
282
- cmdIdx = (index )?0 :2 ;
283
- willRead = (len > 32 )?32 :(len - 1 );
284
- if (cmdIdx ){
285
- i2cResetFiFo (i2c );
286
- }
287
-
288
- if (willRead ){
289
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_READ , willRead , false, false, false);
290
- }
291
-
292
- if ((len - willRead ) > 1 ) {
293
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_END , 0 , false, false, false);
294
- } else {
295
- willRead ++ ;
296
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_READ , 1 , true, false, false);
297
- if (sendStop ) {
298
- i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_STOP , 0 , false, false, false);
299
- }
300
- }
301
-
302
- //Clear Interrupts
303
- i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
304
-
305
- //START Transmission
306
- i2c -> dev -> ctr .trans_start = 1 ;
296
+ //Clear Interrupts
297
+ i2c -> dev -> int_clr .val = 0x00001FFF ;
307
298
299
+ //START Transmission
300
+ i2c -> dev -> ctr .trans_start = 1 ;
301
+ while (!stopped ) {
308
302
//WAIT Transmission
309
303
uint32_t startAt = millis ();
310
304
while (1 ) {
311
305
//have been looping for too long
312
- if ((millis () - startAt )> 50 ){
313
- log_e ("Timeout! Addr: %x" , address >> 1 );
306
+ if ((millis () - startAt )> 50 ) {
307
+ log_e ("Timeout! Addr: %x, index %d " , ( address >> 1 ), index );
314
308
I2C_MUTEX_UNLOCK ();
315
309
return I2C_ERROR_BUS ;
316
310
}
317
311
318
312
//Bus failed (maybe check for this while waiting?
319
313
if (i2c -> dev -> int_raw .arbitration_lost ) {
320
- log_e ("Bus Fail! Addr: %x" , address >> 1 );
314
+ log_e ("Bus Fail! Addr: %x" , ( address >> 1 ) );
321
315
I2C_MUTEX_UNLOCK ();
322
316
return I2C_ERROR_BUS ;
323
317
}
324
318
325
319
//Bus timeout
326
320
if (i2c -> dev -> int_raw .time_out ) {
327
- log_e ("Bus Timeout! Addr: %x" , address >> 1 );
321
+ log_e ("Bus Timeout! Addr: %x, index %d " , ( address >> 1 ), index );
328
322
I2C_MUTEX_UNLOCK ();
329
323
return I2C_ERROR_TIMEOUT ;
330
324
}
331
325
332
326
//Transmission did not finish and ACK_ERR is set
333
327
if (i2c -> dev -> int_raw .ack_err ) {
334
328
log_w ("Ack Error! Addr: %x" , address >> 1 );
329
+ while ((i2c -> dev -> status_reg .bus_busy ) && ((millis () - startAt )< 50 ));
335
330
I2C_MUTEX_UNLOCK ();
336
331
return I2C_ERROR_ACK ;
337
332
}
338
333
339
- if (i2c -> dev -> command [cmdIdx - 1 ].done ) {
340
- break ;
334
+ // Save bytes from the buffer as they arrive instead of doing them at the end of the loop since there is no
335
+ // pause from an END operation in this approach.
336
+ if ((!isEndNear ) && (nextCmdCount < 2 )) {
337
+ if (willRead = ((len > 32 )?32 :len )) {
338
+ if (willRead > 1 ) {
339
+ i2cSetCmd (i2c , cmdIdx , I2C_CMD_READ , (amountRead [ inc ( & cmdIdx ) ] = willRead - 1 ), false, false, false);
340
+ nextCmdCount ++ ;
341
+ }
342
+ i2cSetCmd (i2c , cmdIdx , I2C_CMD_READ , (amountRead [ inc ( & cmdIdx ) ] = 1 ), (len <=32 ), false, false);
343
+ nextCmdCount ++ ;
344
+ len -= willRead ;
345
+ } else {
346
+ i2cSetCmd (i2c , inc ( & cmdIdx ), I2C_CMD_STOP , 0 , false, false, false);
347
+ isEndNear = true;
348
+ nextCmdCount ++ ;
349
+ }
341
350
}
342
- }
343
351
344
- int i = 0 ;
345
- while (i < willRead ) {
346
- i ++ ;
347
- data [index ++ ] = i2c -> dev -> fifo_data .val & 0xFF ;
352
+ if (i2c -> dev -> command [currentCmdIdx ].done ) {
353
+ nextCmdCount -- ;
354
+ if (i2c -> dev -> command [currentCmdIdx ].op_code == I2C_CMD_READ ) {
355
+ while (amountRead [currentCmdIdx ]> 0 ) {
356
+ data [index ++ ] = i2c -> dev -> fifo_data .val & 0xFF ;
357
+ amountRead [currentCmdIdx ]-- ;
358
+ }
359
+ i2cResetFiFo (i2c );
360
+ } else if (i2c -> dev -> command [currentCmdIdx ].op_code == I2C_CMD_STOP ) {
361
+ stopped = true;
362
+ }
363
+ inc ( & currentCmdIdx );
364
+ break ;
365
+ }
348
366
}
349
- len -= willRead ;
350
367
}
351
368
I2C_MUTEX_UNLOCK ();
369
+
352
370
return I2C_ERROR_OK ;
353
371
}
354
372
@@ -425,7 +443,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
425
443
DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT1_CLK_EN );
426
444
DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST );
427
445
}
428
-
446
+
429
447
I2C_MUTEX_LOCK ();
430
448
i2c -> dev -> ctr .val = 0 ;
431
449
i2c -> dev -> ctr .ms_mode = (slave_addr == 0 );
@@ -434,7 +452,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
434
452
i2c -> dev -> ctr .clk_en = 1 ;
435
453
436
454
//the max clock number of receiving a data
437
- i2c -> dev -> timeout .tout = 400000 ;//clocks max=1048575
455
+ i2c -> dev -> timeout .tout = 1048575 ;//clocks max=1048575
438
456
//disable apb nonfifo access
439
457
i2c -> dev -> fifo_conf .nonfifo_en = 0 ;
440
458
0 commit comments