3131#define DR_REG_I2C_EXT_BASE_FIXED 0x60013000
3232#define DR_REG_I2C1_EXT_BASE_FIXED 0x60027000
3333
34+ #define COMMAND_BUFFER_LENGTH 16
35+
3436struct i2c_struct_t {
3537 i2c_dev_t * dev ;
3638#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
127129 i2c -> dev -> command [index ].op_code = op_code ;
128130}
129131
130- void i2cResetCmd (i2c_t * i2c ){
131- int i ;
132+ void i2cResetCmd (i2c_t * i2c ) {
133+ uint8_t i ;
132134 for (i = 0 ;i < 16 ;i ++ ){
133135 i2c -> dev -> command [i ].val = 0 ;
134136 }
135137}
136138
137- void i2cResetFiFo (i2c_t * i2c )
138- {
139+ void i2cResetFiFo (i2c_t * i2c ) {
139140 i2c -> dev -> fifo_conf .tx_fifo_rst = 1 ;
140141 i2c -> dev -> fifo_conf .tx_fifo_rst = 0 ;
141142 i2c -> dev -> fifo_conf .rx_fifo_rst = 1 ;
142143 i2c -> dev -> fifo_conf .rx_fifo_rst = 0 ;
143144}
144145
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 )
146147{
147148 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 );
150151 address = (address << 1 );
151152
152153 if (i2c == NULL ){
@@ -244,12 +245,25 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
244245 return I2C_ERROR_OK ;
245246}
246247
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 )
248260{
249261 address = (address << 1 ) | 1 ;
250262 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;
253267 uint8_t willRead ;
254268
255269 if (i2c == NULL ){
@@ -269,86 +283,90 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
269283 i2cResetCmd (i2c );
270284
271285 //CMD START
272- i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
286+ i2cSetCmd (i2c , cmdIdx ++ , I2C_CMD_RSTART , 0 , false, false, false);
273287
274288 //CMD WRITE ADDRESS
275289 i2c -> dev -> fifo_data .val = address & 0xFF ;
276290 if (addr_10bit ) {
277291 i2c -> dev -> fifo_data .val = (address >> 8 ) & 0xFF ;
278292 }
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 ;
280295
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 ;
307298
299+ //START Transmission
300+ i2c -> dev -> ctr .trans_start = 1 ;
301+ while (!stopped ) {
308302 //WAIT Transmission
309303 uint32_t startAt = millis ();
310304 while (1 ) {
311305 //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 );
314308 I2C_MUTEX_UNLOCK ();
315309 return I2C_ERROR_BUS ;
316310 }
317311
318312 //Bus failed (maybe check for this while waiting?
319313 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 ) );
321315 I2C_MUTEX_UNLOCK ();
322316 return I2C_ERROR_BUS ;
323317 }
324318
325319 //Bus timeout
326320 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 );
328322 I2C_MUTEX_UNLOCK ();
329323 return I2C_ERROR_TIMEOUT ;
330324 }
331325
332326 //Transmission did not finish and ACK_ERR is set
333327 if (i2c -> dev -> int_raw .ack_err ) {
334328 log_w ("Ack Error! Addr: %x" , address >> 1 );
329+ while ((i2c -> dev -> status_reg .bus_busy ) && ((millis () - startAt )< 50 ));
335330 I2C_MUTEX_UNLOCK ();
336331 return I2C_ERROR_ACK ;
337332 }
338333
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+ }
341350 }
342- }
343351
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+ }
348366 }
349- len -= willRead ;
350367 }
351368 I2C_MUTEX_UNLOCK ();
369+
352370 return I2C_ERROR_OK ;
353371}
354372
@@ -425,7 +443,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
425443 DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT1_CLK_EN );
426444 DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST );
427445 }
428-
446+
429447 I2C_MUTEX_LOCK ();
430448 i2c -> dev -> ctr .val = 0 ;
431449 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)
434452 i2c -> dev -> ctr .clk_en = 1 ;
435453
436454 //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
438456 //disable apb nonfifo access
439457 i2c -> dev -> fifo_conf .nonfifo_en = 0 ;
440458
0 commit comments