From 33c12d13ad42582745989794bf1d966d2a9e070f Mon Sep 17 00:00:00 2001 From: px4dev Date: Sat, 26 Jan 2013 17:07:58 -0800 Subject: Defer I2C bus resets for the first couple of retries to avoid transient slave errors causing massive retry spam. --- apps/drivers/device/i2c.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/drivers/device/i2c.cpp b/apps/drivers/device/i2c.cpp index d2cd5f19b..a416801eb 100644 --- a/apps/drivers/device/i2c.cpp +++ b/apps/drivers/device/i2c.cpp @@ -120,7 +120,7 @@ I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned re struct i2c_msg_s msgv[2]; unsigned msgs; int ret; - unsigned tries = 0; + unsigned retry_count = 0; do { // debug("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len); @@ -154,13 +154,15 @@ I2C::transfer(const uint8_t *send, unsigned send_len, uint8_t *recv, unsigned re I2C_SETFREQUENCY(_dev, _frequency); ret = I2C_TRANSFER(_dev, &msgv[0], msgs); + /* success */ if (ret == OK) break; - // reset the I2C bus to unwedge on error - up_i2creset(_dev); + /* if we have already retried once, or we are going to give up, then reset the bus */ + if ((retry_count >= 1) || (retry_count >= _retries)) + up_i2creset(_dev); - } while (tries++ < _retries); + } while (retry_count++ < _retries); return ret; @@ -170,15 +172,14 @@ int I2C::transfer(i2c_msg_s *msgv, unsigned msgs) { int ret; + unsigned retry_count = 0; /* force the device address into the message vector */ for (unsigned i = 0; i < msgs; i++) msgv[i].addr = _address; - unsigned tries = 0; do { - /* * I2C architecture means there is an unavoidable race here * if there are any devices on the bus with a different frequency @@ -187,13 +188,15 @@ I2C::transfer(i2c_msg_s *msgv, unsigned msgs) I2C_SETFREQUENCY(_dev, _frequency); ret = I2C_TRANSFER(_dev, msgv, msgs); + /* success */ if (ret == OK) break; - if (ret != OK) + /* if we have already retried once, or we are going to give up, then reset the bus */ + if ((retry_count >= 1) || (retry_count >= _retries)) up_i2creset(_dev); - } while (tries++ < _retries); + } while (retry_count++ < _retries); return ret; } -- cgit v1.2.3