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,15 +126,6 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        //WAIT Transmission
 | 
					        //WAIT Transmission
 | 
				
			||||||
        while(1) {
 | 
					        while(1) {
 | 
				
			||||||
            if(i2c->dev->ctr.trans_start || i2c->dev->status_reg.bus_busy || !(i2c->dev->int_raw.trans_complete) || !(i2c->dev->command[2].done)) {
 | 
					 | 
				
			||||||
                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) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            //Bus failed (maybe check for this while waiting?
 | 
					            //Bus failed (maybe check for this while waiting?
 | 
				
			||||||
            if(i2c->dev->int_raw.arbitration_lost) {
 | 
					            if(i2c->dev->int_raw.arbitration_lost) {
 | 
				
			||||||
                //log_e("Bus Fail! Addr: %x", address >> 1);
 | 
					                //log_e("Bus Fail! Addr: %x", address >> 1);
 | 
				
			||||||
@ -151,6 +144,13 @@ int i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uin
 | 
				
			|||||||
                return 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)) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            } else if(i2c->dev->command[2].done) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    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,15 +201,6 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        //WAIT Transmission
 | 
					        //WAIT Transmission
 | 
				
			||||||
        while(1) {
 | 
					        while(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)) {
 | 
					 | 
				
			||||||
                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) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            //Bus failed (maybe check for this while waiting?
 | 
					            //Bus failed (maybe check for this while waiting?
 | 
				
			||||||
            if(i2c->dev->int_raw.arbitration_lost) {
 | 
					            if(i2c->dev->int_raw.arbitration_lost) {
 | 
				
			||||||
                //log_e("Bus Fail! Addr: %x", address >> 1);
 | 
					                //log_e("Bus Fail! Addr: %x", address >> 1);
 | 
				
			||||||
@ -221,6 +218,13 @@ int i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint
 | 
				
			|||||||
                //log_e("Ack Error! Addr: %x", address >> 1);
 | 
					                //log_e("Ack Error! Addr: %x", address >> 1);
 | 
				
			||||||
                return -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)) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            } else if(i2c->dev->command[cmdIdx-1].done) {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int i = 0;
 | 
					        int i = 0;
 | 
				
			||||||
        while(i<willRead) {
 | 
					        while(i<willRead) {
 | 
				
			||||||
            i++;
 | 
					            i++;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user