Prevent I2C Bus locks and wrong data being sent on retry
This commit is contained in:
parent
45f5449fbf
commit
3ecb32c4ba
@ -89,6 +89,8 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
|
|||||||
uint8_t willSend = (dataLen > 32)?32:dataLen;
|
uint8_t willSend = (dataLen > 32)?32:dataLen;
|
||||||
uint8_t dataSend = willSend;
|
uint8_t dataSend = willSend;
|
||||||
|
|
||||||
|
i2cResetFiFo(i2c);
|
||||||
|
|
||||||
//CMD START
|
//CMD START
|
||||||
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
|
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
|
||||||
|
|
||||||
@ -124,33 +126,31 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
|
|||||||
|
|
||||||
//WAIT Transmission
|
//WAIT Transmission
|
||||||
while(1) {
|
while(1) {
|
||||||
|
//Bus failed (maybe check for this while waiting?
|
||||||
|
if(i2c->dev->int_raw.arbitration_lost) {
|
||||||
|
//log_e("Bus Fail! Addr: %x", address >> 1);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bus timeout
|
||||||
|
if(i2c->dev->int_raw.time_out) {
|
||||||
|
//log_e("Bus Timeout! Addr: %x", address >> 1);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Transmission did not finish and ACK_ERR is set
|
||||||
|
if(i2c->dev->int_raw.ack_err) {
|
||||||
|
//log_e("Ack Error! Addr: %x", address >> 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) {
|
if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) {
|
||||||
continue;
|
continue;
|
||||||
} else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) {
|
|
||||||
break;
|
|
||||||
} else if(i2c->dev->command[2].done) {
|
} else if(i2c->dev->command[2].done) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Bus failed (maybe check for this while waiting?
|
|
||||||
if(i2c->dev->int_raw.arbitration_lost) {
|
|
||||||
//log_e("Bus Fail! Addr: %x", address >> 1);
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Bus timeout
|
|
||||||
if(i2c->dev->int_raw.time_out) {
|
|
||||||
//log_e("Bus Timeout! Addr: %x", address >> 1);
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Transmission did not finish and ACK_ERR is set
|
|
||||||
if(i2c->dev->int_raw.ack_err) {
|
|
||||||
//log_e("Ack Error! Addr: %x", address >> 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -163,6 +163,8 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
|
|||||||
uint8_t cmdIdx;
|
uint8_t cmdIdx;
|
||||||
uint8_t willRead;
|
uint8_t willRead;
|
||||||
|
|
||||||
|
i2cResetFiFo(i2c);
|
||||||
|
|
||||||
//CMD START
|
//CMD START
|
||||||
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
|
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
|
||||||
|
|
||||||
@ -176,6 +178,10 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
|
|||||||
while(len) {
|
while(len) {
|
||||||
cmdIdx = (index)?0:2;
|
cmdIdx = (index)?0:2;
|
||||||
willRead = (len > 32)?32:(len-1);
|
willRead = (len > 32)?32:(len-1);
|
||||||
|
if(cmdIdx){
|
||||||
|
i2cResetFiFo(i2c);
|
||||||
|
}
|
||||||
|
|
||||||
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_READ, willRead, false, false, false);
|
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_READ, willRead, false, false, false);
|
||||||
if((len - willRead) > 1) {
|
if((len - willRead) > 1) {
|
||||||
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_END, 0, false, false, false);
|
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_END, 0, false, false, false);
|
||||||
@ -195,32 +201,30 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
|
|||||||
|
|
||||||
//WAIT Transmission
|
//WAIT Transmission
|
||||||
while(1) {
|
while(1) {
|
||||||
|
//Bus failed (maybe check for this while waiting?
|
||||||
|
if(i2c->dev->int_raw.arbitration_lost) {
|
||||||
|
//log_e("Bus Fail! Addr: %x", address >> 1);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bus timeout
|
||||||
|
if(i2c->dev->int_raw.time_out) {
|
||||||
|
//log_e("Bus Timeout! Addr: %x", address >> 1);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Transmission did not finish and ACK_ERR is set
|
||||||
|
if(i2c->dev->int_raw.ack_err) {
|
||||||
|
//log_e("Ack Error! Addr: %x", address >> 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) {
|
if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[cmdIdx-1].done)) {
|
||||||
continue;
|
continue;
|
||||||
} else if(i2c->dev->int_raw.ack_err || i2c->dev->int_raw.time_out || i2c->dev->int_raw.arbitration_lost) {
|
|
||||||
break;
|
|
||||||
} else if(i2c->dev->command[cmdIdx-1].done) {
|
} else if(i2c->dev->command[cmdIdx-1].done) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Bus failed (maybe check for this while waiting?
|
|
||||||
if(i2c->dev->int_raw.arbitration_lost) {
|
|
||||||
//log_e("Bus Fail! Addr: %x", address >> 1);
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Bus timeout
|
|
||||||
if(i2c->dev->int_raw.time_out) {
|
|
||||||
//log_e("Bus Timeout! Addr: %x", address >> 1);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Transmission did not finish and ACK_ERR is set
|
|
||||||
if(i2c->dev->int_raw.ack_err) {
|
|
||||||
//log_e("Ack Error! Addr: %x", address >> 1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(i<willRead) {
|
while(i<willRead) {
|
||||||
i++;
|
i++;
|
||||||
|
Loading…
Reference in New Issue
Block a user