diff options
author | px4dev <px4@purgatory.org> | 2013-01-26 17:07:58 -0800 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2013-01-26 17:07:58 -0800 |
commit | 33c12d13ad42582745989794bf1d966d2a9e070f (patch) | |
tree | 592c25a3a88f8064e34cf0591fa7dec085a21f92 /apps/drivers | |
parent | 7864176b5a1f2ac9cde4ac29ef19c5a72f87b3d3 (diff) | |
download | px4-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.
Diffstat (limited to 'apps/drivers')
-rw-r--r-- | apps/drivers/device/i2c.cpp | 19 |
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; } |