forked from Archive/PX4-Autopilot
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.
This commit is contained in:
parent
6caa3038ba
commit
65ecf1b1c1
|
@ -138,6 +138,8 @@ struct at24c_dev_s
|
||||||
|
|
||||||
perf_counter_t perf_reads;
|
perf_counter_t perf_reads;
|
||||||
perf_counter_t perf_writes;
|
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 (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
unsigned tries = 50;
|
||||||
|
|
||||||
perf_begin(priv->perf_reads);
|
perf_begin(priv->perf_reads);
|
||||||
ret = I2C_TRANSFER(priv->dev, &msgv[0], 2);
|
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)
|
if (ret >= 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* XXX probably want a bus reset in here and an eventual timeout */
|
|
||||||
fvdbg("read stall");
|
fvdbg("read stall");
|
||||||
usleep(1000);
|
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++;
|
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_reads = perf_alloc(PC_ELAPSED, "EEPROM read");
|
||||||
priv->perf_writes = perf_alloc(PC_ELAPSED, "EEPROM write");
|
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 */
|
/* Return the implementation-specific state structure as the MTD device */
|
||||||
|
|
|
@ -67,13 +67,16 @@
|
||||||
|
|
||||||
__EXPORT int eeprom_main(int argc, char *argv[]);
|
__EXPORT int eeprom_main(int argc, char *argv[]);
|
||||||
|
|
||||||
|
static void eeprom_attach(void);
|
||||||
static void eeprom_start(void);
|
static void eeprom_start(void);
|
||||||
static void eeprom_erase(void);
|
static void eeprom_erase(void);
|
||||||
static void eeprom_ioctl(unsigned operation);
|
static void eeprom_ioctl(unsigned operation);
|
||||||
static void eeprom_save(const char *name);
|
static void eeprom_save(const char *name);
|
||||||
static void eeprom_load(const char *name);
|
static void eeprom_load(const char *name);
|
||||||
|
|
||||||
|
static bool attached = false;
|
||||||
static bool started = false;
|
static bool started = false;
|
||||||
|
static struct mtd_dev_s *eeprom_mtd;
|
||||||
|
|
||||||
int eeprom_main(int argc, char *argv[])
|
int eeprom_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -105,13 +108,8 @@ int eeprom_main(int argc, char *argv[])
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eeprom_start(void)
|
eeprom_attach(void)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (started)
|
|
||||||
errx(1, "EEPROM service already started");
|
|
||||||
|
|
||||||
/* find the right I2C */
|
/* find the right I2C */
|
||||||
struct i2c_dev_s *i2c = up_i2cinitialize(PX4_I2C_BUS_ONBOARD);
|
struct i2c_dev_s *i2c = up_i2cinitialize(PX4_I2C_BUS_ONBOARD);
|
||||||
/* this resets the I2C bus, set correct bus speed again */
|
/* this resets the I2C bus, set correct bus speed again */
|
||||||
|
@ -121,16 +119,27 @@ eeprom_start(void)
|
||||||
errx(1, "failed to locate I2C bus");
|
errx(1, "failed to locate I2C bus");
|
||||||
|
|
||||||
/* start the MTD driver */
|
/* start the MTD driver */
|
||||||
struct mtd_dev_s *mtd = at24c_initialize(i2c);
|
eeprom_mtd = at24c_initialize(i2c);
|
||||||
|
|
||||||
if (mtd == NULL)
|
if (eeprom_mtd == NULL)
|
||||||
errx(1, "failed to initialize EEPROM driver");
|
errx(1, "failed to initialize EEPROM driver");
|
||||||
|
|
||||||
/* driver is started, even if NXFFS fails to mount */
|
attached = true;
|
||||||
started = true;
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eeprom_start(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (started)
|
||||||
|
errx(1, "EEPROM already mounted");
|
||||||
|
|
||||||
|
if (!attached)
|
||||||
|
eeprom_attach();
|
||||||
|
|
||||||
/* start NXFFS */
|
/* start NXFFS */
|
||||||
ret = nxffs_initialize(mtd);
|
ret = nxffs_initialize(eeprom_mtd);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
errx(1, "failed to initialize NXFFS - erase EEPROM to reformat");
|
errx(1, "failed to initialize NXFFS - erase EEPROM to reformat");
|
||||||
|
@ -141,7 +150,9 @@ eeprom_start(void)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
errx(1, "failed to mount /eeprom - erase EEPROM to reformat");
|
errx(1, "failed to mount /eeprom - erase EEPROM to reformat");
|
||||||
|
|
||||||
errx(0, "mounted EEPROM at /eeprom");
|
started = true;
|
||||||
|
warnx("mounted EEPROM at /eeprom");
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int at24c_nuke(void);
|
extern int at24c_nuke(void);
|
||||||
|
@ -149,8 +160,8 @@ extern int at24c_nuke(void);
|
||||||
static void
|
static void
|
||||||
eeprom_erase(void)
|
eeprom_erase(void)
|
||||||
{
|
{
|
||||||
if (!started)
|
if (!attached)
|
||||||
errx(1, "must be started first");
|
eeprom_attach();
|
||||||
|
|
||||||
if (at24c_nuke())
|
if (at24c_nuke())
|
||||||
errx(1, "erase failed");
|
errx(1, "erase failed");
|
||||||
|
|
Loading…
Reference in New Issue