summary refs log tree commit diff
path: root/platforms/avr
diff options
context:
space:
mode:
authorDaniel Kao <daniel.m.kao@gmail.com>2022-06-21 15:00:04 -0700
committerGitHub <noreply@github.com>2022-06-22 00:00:04 +0200
commit608404f8742f01d1821a74c5a107e0c62b046423 (patch)
treefa68b047ca13c4becb47f0cd8678c88ade60e8ad /platforms/avr
parentbe42c5fb9885d3bcbf47f99ad6cef343ba2b0b97 (diff)
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()
Diffstat (limited to 'platforms/avr')
-rw-r--r--platforms/avr/drivers/i2c_master.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/platforms/avr/drivers/i2c_master.c b/platforms/avr/drivers/i2c_master.c
index c1a7b5f72d..524494c99d 100644
--- a/platforms/avr/drivers/i2c_master.c
+++ b/platforms/avr/drivers/i2c_master.c
@@ -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;
         }
     }