Fix AVR I2C master 1ms timeout (#17174)
* avr i2c_master: Fix 1ms timeout i2c_start() produces a minimum time_slice of 1ms for use as timeout value. The timer granularity is 1ms, it is entirely possible for timer_count to tick up immediately after the last timer read and falsely trigger timeout with a '>= 1' comparison. * avr/drivers/i2c_master: Use timer_elapsed()
This commit is contained in:
		
							parent
							
								
									be42c5fb98
								
							
						
					
					
						commit
						608404f874
					
				
					 1 changed files with 6 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -64,7 +64,7 @@ static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) {
 | 
			
		|||
 | 
			
		||||
    uint16_t timeout_timer = timer_read();
 | 
			
		||||
    while (!(TWCR & (1 << TWINT))) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
 | 
			
		||||
            return I2C_STATUS_TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ static i2c_status_t i2c_start_impl(uint8_t address, uint16_t timeout) {
 | 
			
		|||
 | 
			
		||||
    timeout_timer = timer_read();
 | 
			
		||||
    while (!(TWCR & (1 << TWINT))) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
 | 
			
		||||
            return I2C_STATUS_TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ i2c_status_t i2c_start(uint8_t address, uint16_t timeout) {
 | 
			
		|||
    i2c_status_t status;
 | 
			
		||||
    do {
 | 
			
		||||
        status = i2c_start_impl(address, time_slice);
 | 
			
		||||
    } while ((status < 0) && ((timeout == I2C_TIMEOUT_INFINITE) || (timer_elapsed(timeout_timer) < timeout)));
 | 
			
		||||
    } while ((status < 0) && ((timeout == I2C_TIMEOUT_INFINITE) || (timer_elapsed(timeout_timer) <= timeout)));
 | 
			
		||||
    return status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +114,7 @@ i2c_status_t i2c_write(uint8_t data, uint16_t timeout) {
 | 
			
		|||
 | 
			
		||||
    uint16_t timeout_timer = timer_read();
 | 
			
		||||
    while (!(TWCR & (1 << TWINT))) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
 | 
			
		||||
            return I2C_STATUS_TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ int16_t i2c_read_ack(uint16_t timeout) {
 | 
			
		|||
 | 
			
		||||
    uint16_t timeout_timer = timer_read();
 | 
			
		||||
    while (!(TWCR & (1 << TWINT))) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
 | 
			
		||||
            return I2C_STATUS_TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ int16_t i2c_read_nack(uint16_t timeout) {
 | 
			
		|||
 | 
			
		||||
    uint16_t timeout_timer = timer_read();
 | 
			
		||||
    while (!(TWCR & (1 << TWINT))) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
 | 
			
		||||
        if ((timeout != I2C_TIMEOUT_INFINITE) && (timer_elapsed(timeout_timer) > timeout)) {
 | 
			
		||||
            return I2C_STATUS_TIMEOUT;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue