diff options
author | px4dev <px4@purgatory.org> | 2012-09-09 11:14:54 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2012-09-09 11:14:54 -0700 |
commit | a9c4fabda6cccb15912348ac5061827a6cb38304 (patch) | |
tree | b74b6486a320907a7a333b274eb8dceeb09b5fb0 /apps | |
parent | 65ecf1b1c184e56dab4f168c89a2b4c23dfe5cb0 (diff) | |
download | px4-firmware-a9c4fabda6cccb15912348ac5061827a6cb38304.tar.gz px4-firmware-a9c4fabda6cccb15912348ac5061827a6cb38304.tar.bz2 px4-firmware-a9c4fabda6cccb15912348ac5061827a6cb38304.zip |
Change the EEPROM read/write timeout behavior so that we can get actual errors rather than just hanging forever.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/systemcmds/eeprom/24xxxx_mtd.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/apps/systemcmds/eeprom/24xxxx_mtd.c b/apps/systemcmds/eeprom/24xxxx_mtd.c index 1b8c59f77..c83362ca8 100644 --- a/apps/systemcmds/eeprom/24xxxx_mtd.c +++ b/apps/systemcmds/eeprom/24xxxx_mtd.c @@ -119,6 +119,13 @@ # define CONFIG_AT24XX_MTD_BLOCKSIZE AT24XX_PAGESIZE #endif +/* The AT24 does not respond on the bus during write cycles, so we depend on a long + * timeout to detect problems. The max program time is typically ~5ms. + */ +#ifndef CONFIG_AT24XX_WRITE_TIMEOUT_MS +# define CONFIG_AT24XX_WRITE_TIMEOUT_MS 20 +#endif + /************************************************************************************ * Private Types ************************************************************************************/ @@ -140,6 +147,8 @@ struct at24c_dev_s perf_counter_t perf_writes; perf_counter_t perf_resets; perf_counter_t perf_read_retries; + perf_counter_t perf_read_errors; + perf_counter_t perf_write_errors; }; /************************************************************************************ @@ -262,6 +271,7 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, while (blocksleft-- > 0) { uint16_t offset = startblock * priv->pagesize; + unsigned tries = CONFIG_AT24XX_WRITE_TIMEOUT_MS; addr[1] = offset & 0xff; addr[0] = (offset >> 8) & 0xff; @@ -269,7 +279,6 @@ 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); @@ -279,18 +288,19 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, fvdbg("read stall"); usleep(1000); - perf_count(priv->perf_read_retries); - /* - * Kick the bus in case it's stuck. + /* We should normally only be here on the first read after + * a write. + * + * XXX maybe do special first-read handling with optional + * bus reset as well? */ + perf_count(priv->perf_read_retries); if (--tries == 0) { - tries = 50; - up_i2creset(priv->dev); - perf_count(priv->perf_resets); + perf_count(priv->perf_read_errors); + return ERROR; } - } startblock++; @@ -350,6 +360,7 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t while (blocksleft-- > 0) { uint16_t offset = startblock * priv->pagesize; + unsigned tries = CONFIG_AT24XX_WRITE_TIMEOUT_MS; buf[1] = offset & 0xff; buf[0] = (offset >> 8) & 0xff; @@ -365,9 +376,17 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t if (ret >= 0) break; - /* XXX probably want a bus reset in here and an eventual timeout */ fvdbg("write stall"); usleep(1000); + + /* We expect to see a number of retries per write cycle as we + * poll for write completion. + */ + if (--tries == 0) + { + perf_count(priv->perf_write_errors); + return ERROR; + } } startblock++; @@ -496,6 +515,8 @@ FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev) 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"); + priv->perf_read_errors = perf_alloc(PC_COUNT, "EEPROM read errors"); + priv->perf_write_errors = perf_alloc(PC_COUNT, "EEPROM write errors"); } /* Return the implementation-specific state structure as the MTD device */ |