Skip to content

Commit

Permalink
Fix AVR I2C master 1ms timeout (#17174)
Browse files Browse the repository at this point in the history
* 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()
  • Loading branch information
dkao authored Jun 21, 2022
1 parent be42c5f commit 608404f
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions platforms/avr/drivers/i2c_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand All @@ -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;
}
}
Expand All @@ -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;
}

Expand All @@ -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;
}
}
Expand All @@ -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;
}
}
Expand All @@ -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;
}
}
Expand Down

0 comments on commit 608404f

Please sign in to comment.