diff options
author | px4dev <px4@purgatory.org> | 2012-09-09 00:04:43 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2012-09-09 00:04:43 -0700 |
commit | 65ecf1b1c184e56dab4f168c89a2b4c23dfe5cb0 (patch) | |
tree | 8a5250efcf10aa171778dd8d04e57ac19002061e /apps/systemcmds/eeprom/24xxxx_mtd.c | |
parent | 6caa3038bac3039dff1d486f14f5032524f5b0e0 (diff) | |
download | px4-firmware-65ecf1b1c184e56dab4f168c89a2b4c23dfe5cb0.tar.gz px4-firmware-65ecf1b1c184e56dab4f168c89a2b4c23dfe5cb0.tar.bz2 px4-firmware-65ecf1b1c184e56dab4f168c89a2b4c23dfe5cb0.zip |
Rework the 'eeprom erase' path so it's possible to erase an EEPROM that can't be mounted.
Add some bus reset code to the EEPROM read path to maybe help with bus lockup.
Diffstat (limited to 'apps/systemcmds/eeprom/24xxxx_mtd.c')
-rw-r--r-- | apps/systemcmds/eeprom/24xxxx_mtd.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/apps/systemcmds/eeprom/24xxxx_mtd.c b/apps/systemcmds/eeprom/24xxxx_mtd.c index b5144512b..1b8c59f77 100644 --- a/apps/systemcmds/eeprom/24xxxx_mtd.c +++ b/apps/systemcmds/eeprom/24xxxx_mtd.c @@ -138,6 +138,8 @@ struct at24c_dev_s perf_counter_t perf_reads; perf_counter_t perf_writes; + perf_counter_t perf_resets; + perf_counter_t perf_read_retries; }; /************************************************************************************ @@ -267,6 +269,7 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, for (;;) { + unsigned tries = 50; perf_begin(priv->perf_reads); ret = I2C_TRANSFER(priv->dev, &msgv[0], 2); @@ -274,9 +277,20 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, if (ret >= 0) break; - /* XXX probably want a bus reset in here and an eventual timeout */ fvdbg("read stall"); usleep(1000); + perf_count(priv->perf_read_retries); + + /* + * Kick the bus in case it's stuck. + */ + if (--tries == 0) + { + tries = 50; + up_i2creset(priv->dev); + perf_count(priv->perf_resets); + } + } startblock++; @@ -480,6 +494,8 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev) priv->perf_reads = perf_alloc(PC_ELAPSED, "EEPROM read"); priv->perf_writes = perf_alloc(PC_ELAPSED, "EEPROM write"); + priv->perf_resets = perf_alloc(PC_COUNT, "EEPROM reset"); + priv->perf_read_retries = perf_alloc(PC_COUNT, "EEPROM read retries"); } /* Return the implementation-specific state structure as the MTD device */ |