@@ -158,6 +158,8 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
158158
159159i2cResetFiFo (i2c );
160160i2cResetCmd (i2c );
161+ //Clear Interrupts
162+ i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
161163
162164//CMD START
163165i2cSetCmd (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
174176i = 0 ;
175177while (i < dataSend ){
176178i ++ ;
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 );
178181 }
179182i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , willSend , false, false, true);
180183dataLen -= willSend ;
181184
182185//CMD STOP or CMD END if there is more data
183- if (dataLen ){
186+ if (dataLen || ! sendStop ){
184187i2cSetCmd (i2c , 2 , I2C_CMD_END , 0 , false, false, false);
185188 } else if (sendStop ){
186189i2cSetCmd (i2c , 2 , I2C_CMD_STOP , 0 , false, false, false);
187190 }
188191
189- //Clear Interrupts
190- i2c -> dev -> int_clr .val = 0xFFFFFFFF ;
191-
192192//START Transmission
193193i2c -> dev -> ctr .trans_start = 1 ;
194194
195195//WAIT Transmission
196+ uint32_t startAt = millis ();
196197while (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+
197205//Bus failed (maybe check for this while waiting?
198206if (i2c -> dev -> int_raw .arbitration_lost ){
199207//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
210218
211219//Transmission did not finish and ACK_ERR is set
212220if (i2c -> dev -> int_raw .ack_err ){
213- //log_e ("Ack Error! Addr: %x", address >> 1);
221+ //log_w ("Ack Error! Addr: %x", address >> 1);
214222I2C_MUTEX_UNLOCK ();
215223return I2C_ERROR_ACK ;
216224 }
217225
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 ){
221227break ;
222228 }
223229 }
@@ -248,9 +254,9 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
248254i2cSetCmd (i2c , 0 , I2C_CMD_RSTART , 0 , false, false, false);
249255
250256//CMD WRITE ADDRESS
251- i2c -> dev -> fifo_data .data = address & 0xFF ;
257+ i2c -> dev -> fifo_data .val = address & 0xFF ;
252258if (addr_10bit ){
253- i2c -> dev -> fifo_data .data = (address >> 8 ) & 0xFF ;
259+ i2c -> dev -> fifo_data .val = (address >> 8 ) & 0xFF ;
254260 }
255261i2cSetCmd (i2c , 1 , I2C_CMD_WRITE , addrLen , false, false, true);
256262
@@ -279,7 +285,15 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
279285i2c -> dev -> ctr .trans_start = 1 ;
280286
281287//WAIT Transmission
288+ uint32_t startAt = millis ();
282289while (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+
283297//Bus failed (maybe check for this while waiting?
284298if (i2c -> dev -> int_raw .arbitration_lost ){
285299//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
296310
297311//Transmission did not finish and ACK_ERR is set
298312if (i2c -> dev -> int_raw .ack_err ){
299- //log_e ("Ack Error! Addr: %x", address >> 1);
313+ //log_w ("Ack Error! Addr: %x", address >> 1);
300314I2C_MUTEX_UNLOCK ();
301315return I2C_ERROR_ACK ;
302316 }
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 ){
306319break ;
307320 }
308321 }
309322
310323int i = 0 ;
311324while (i < willRead ){
312325i ++ ;
313- data [index ++ ] = i2c -> dev -> fifo_data .data ;
326+ data [index ++ ] = i2c -> dev -> fifo_data .val & 0xFF ;
314327 }
315328len -= willRead ;
316329 }
@@ -320,24 +333,34 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
320333
321334i2c_err_t i2cSetFrequency (i2c_t * i2c , uint32_t clk_speed )
322335{
323- uint32_t period = (APB_CLK_FREQ /clk_speed ) / 2 ;
324-
325336if (i2c == NULL ){
326337return I2C_ERROR_DEV ;
327338 }
328339
340+ uint32_t period = (APB_CLK_FREQ /clk_speed ) / 2 ;
341+ uint32_t halfPeriod = period /2 ;
342+ uint32_t quarterPeriod = period /4 ;
343+
329344I2C_MUTEX_LOCK ();
345+ //the clock num during SCL is low level
330346i2c -> dev -> scl_low_period .scl_low_period = period ;
347+ //the clock num during SCL is high level
331348i2c -> dev -> scl_high_period .period = period ;
332349
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 ;
335354
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 ;
338359
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 ;
341364I2C_MUTEX_UNLOCK ();
342365return I2C_ERROR_OK ;
343366}
@@ -389,7 +412,9 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
389412i2c -> dev -> ctr .scl_force_out = 1 ;
390413i2c -> dev -> ctr .clk_en = 1 ;
391414
415+ //the max clock number of receiving a data
392416i2c -> dev -> timeout .tout = 400000 ;//clocks max=1048575
417+ //disable apb nonfifo access
393418i2c -> dev -> fifo_conf .nonfifo_en = 0 ;
394419
395420i2c -> dev -> slave_addr .val = 0 ;
@@ -402,4 +427,19 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
402427return i2c ;
403428}
404429
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