aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2013-01-26 17:07:58 -0800
committerpx4dev <px4@purgatory.org>2013-01-26 17:07:58 -0800
commit33c12d13ad42582745989794bf1d966d2a9e070f (patch)
tree592c25a3a88f8064e34cf0591fa7dec085a21f92
parent7864176b5a1f2ac9cde4ac29ef19c5a72f87b3d3 (diff)
downloadpx4-firmware-33c12d13ad42582745989794bf1d966d2a9e070f.tar.gz
px4-firmware-33c12d13ad42582745989794bf1d966d2a9e070f.tar.bz2
px4-firmware-33c12d13ad42582745989794bf1d966d2a9e070f.zip
Defer I2C bus resets for the first couple of retries to avoid transient slave errors causing massive retry spam.
-rw-r--r--apps/drivers/device/i2c.cpp19
1 files 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;
}