|
18 | 18 | #include "freertos/task.h"
|
19 | 19 | #include "freertos/semphr.h"
|
20 | 20 | #include "rom/ets_sys.h"
|
| 21 | +#include "driver/periph_ctrl.h" |
21 | 22 | #include "soc/i2c_reg.h"
|
22 | 23 | #include "soc/i2c_struct.h"
|
23 | 24 | #include "soc/dport_reg.h"
|
@@ -154,6 +155,13 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
|
154 | 155 |
|
155 | 156 | I2C_MUTEX_LOCK();
|
156 | 157 |
|
| 158 | + if (i2c->dev->status_reg.bus_busy == 1) |
| 159 | + { |
| 160 | + //log_w( "Busy Timeout! Addr: %x", address >> 1 ); |
| 161 | + I2C_MUTEX_UNLOCK(); |
| 162 | + return I2C_ERROR_BUSY; |
| 163 | + } |
| 164 | + |
157 | 165 | while(dataLen) {
|
158 | 166 | uint8_t willSend = (dataLen > 32)?32:dataLen;
|
159 | 167 | uint8_t dataSend = willSend;
|
@@ -221,7 +229,7 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
|
221 | 229 | //Transmission did not finish and ACK_ERR is set
|
222 | 230 | if(i2c->dev->int_raw.ack_err) {
|
223 | 231 | //log_w("Ack Error! Addr: %x", address >> 1);
|
224 |
| - while(i2c->dev->status_reg.bus_busy); |
| 232 | + while((i2c->dev->status_reg.bus_busy) && ((millis() - startAt)>50)); |
225 | 233 | I2C_MUTEX_UNLOCK();
|
226 | 234 | return I2C_ERROR_ACK;
|
227 | 235 | }
|
@@ -250,6 +258,13 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
|
250 | 258 |
|
251 | 259 | I2C_MUTEX_LOCK();
|
252 | 260 |
|
| 261 | + if (i2c->dev->status_reg.bus_busy == 1) |
| 262 | + { |
| 263 | + //log_w( "Busy Timeout! Addr: %x", address >> 1 ); |
| 264 | + I2C_MUTEX_UNLOCK(); |
| 265 | + return I2C_ERROR_BUSY; |
| 266 | + } |
| 267 | + |
253 | 268 | i2cResetFiFo(i2c);
|
254 | 269 | i2cResetCmd(i2c);
|
255 | 270 |
|
@@ -445,7 +460,25 @@ void i2cInitFix(i2c_t * i2c){
|
445 | 460 | i2c->dev->fifo_data.data = 0;
|
446 | 461 | i2cSetCmd(i2c, 1, I2C_CMD_WRITE, 1, false, false, false);
|
447 | 462 | i2cSetCmd(i2c, 2, I2C_CMD_STOP, 0, false, false, false);
|
| 463 | + if (i2c->dev->status_reg.bus_busy) // If this condition is true, the while loop will timeout as done will not be set |
| 464 | + { |
| 465 | + //log_e("Busy at initialization!"); |
| 466 | + } |
448 | 467 | i2c->dev->ctr.trans_start = 1;
|
449 |
| - while(!i2c->dev->command[2].done); |
| 468 | + uint16_t count = 50000; |
| 469 | + while ((!i2c->dev->command[2].done) && (--count > 0)); |
450 | 470 | I2C_MUTEX_UNLOCK();
|
451 | 471 | }
|
| 472 | + |
| 473 | +void i2cReset(i2c_t* i2c){ |
| 474 | + if(i2c == NULL){ |
| 475 | + return; |
| 476 | + } |
| 477 | + I2C_MUTEX_LOCK(); |
| 478 | + periph_module_t moduleId = (i2c == &_i2c_bus_array[0])?PERIPH_I2C0_MODULE:PERIPH_I2C1_MODULE; |
| 479 | + periph_module_disable( moduleId ); |
| 480 | + delay( 20 ); // Seems long but delay was chosen to ensure system teardown and setup without core generation |
| 481 | + periph_module_enable( moduleId ); |
| 482 | + I2C_MUTEX_UNLOCK(); |
| 483 | +} |
| 484 | + |
0 commit comments