diff options
author | px4dev <px4@purgatory.org> | 2012-08-22 22:25:10 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2012-08-22 22:25:10 -0700 |
commit | a0b9c056d78604397a407c86e3ad13d19fed372a (patch) | |
tree | ff66a4211a5e236286880c22bbb523bf9936aaff /apps | |
parent | a3b78163c3bbcc64a7aa5ada6a0f62670b7fd1cc (diff) | |
download | px4-firmware-a0b9c056d78604397a407c86e3ad13d19fed372a.tar.gz px4-firmware-a0b9c056d78604397a407c86e3ad13d19fed372a.tar.bz2 px4-firmware-a0b9c056d78604397a407c86e3ad13d19fed372a.zip |
Add a bus reset on I2C error. Also add a mechanism for automated retries of operations.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/drivers/device/i2c.cpp | 50 | ||||
-rw-r--r-- | apps/drivers/device/i2c.h | 6 |
2 files changed, 37 insertions, 19 deletions
diff --git a/apps/drivers/device/i2c.cpp b/apps/drivers/device/i2c.cpp index 8489db4bb..e403ce42b 100644 --- a/apps/drivers/device/i2c.cpp +++ b/apps/drivers/device/i2c.cpp @@ -53,6 +53,7 @@ I2C::I2C(const char *name, CDev(name, devname, irq), // public // protected + _retries(0), // private _bus(bus), _address(address), @@ -117,33 +118,44 @@ I2C::transfer(uint8_t *send, unsigned send_len, uint8_t *recv, unsigned recv_len struct i2c_msg_s msgv[2]; unsigned msgs; int ret; + unsigned tries; -// debug("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len); + do { + // debug("transfer out %p/%u in %p/%u", send, send_len, recv, recv_len); - msgs = 0; + msgs = 0; - if (send_len > 0) { - msgv[msgs].addr = _address; - msgv[msgs].flags = 0; - msgv[msgs].buffer = send; - msgv[msgs].length = send_len; - msgs++; - } + if (send_len > 0) { + msgv[msgs].addr = _address; + msgv[msgs].flags = 0; + msgv[msgs].buffer = send; + msgv[msgs].length = send_len; + msgs++; + } - if (recv_len > 0) { - msgv[msgs].addr = _address; - msgv[msgs].flags = I2C_M_READ; - msgv[msgs].buffer = recv; - msgv[msgs].length = recv_len; - msgs++; - } + if (recv_len > 0) { + msgv[msgs].addr = _address; + msgv[msgs].flags = I2C_M_READ; + msgv[msgs].buffer = recv; + msgv[msgs].length = recv_len; + msgs++; + } + + if (msgs == 0) + return -EINVAL; - if (msgs == 0) - return -EINVAL; + ret = I2C_TRANSFER(_dev, &msgv[0], msgs); - ret = I2C_TRANSFER(_dev, &msgv[0], msgs); + if (ret == OK) + break; + + // reset the I2C bus to unwedge on error + up_i2creset(_dev); + + } while (tries++ < _retries); return ret; + } } // namespace device
\ No newline at end of file diff --git a/apps/drivers/device/i2c.h b/apps/drivers/device/i2c.h index d84f7bd09..7c5a14d6b 100644 --- a/apps/drivers/device/i2c.h +++ b/apps/drivers/device/i2c.h @@ -53,6 +53,12 @@ class __EXPORT I2C : public CDev protected: /** + * The number of times a read or write operation will be retried on + * error. + */ + unsigned _retries; + + /** * @ Constructor * * @param name Driver name |