|
|
@ -119,6 +119,13 @@ |
|
|
|
# define CONFIG_AT24XX_MTD_BLOCKSIZE AT24XX_PAGESIZE |
|
|
|
# define CONFIG_AT24XX_MTD_BLOCKSIZE AT24XX_PAGESIZE |
|
|
|
#endif |
|
|
|
#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 |
|
|
|
* Private Types |
|
|
|
************************************************************************************/ |
|
|
|
************************************************************************************/ |
|
|
@ -138,6 +145,10 @@ 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; |
|
|
|
|
|
|
|
perf_counter_t perf_read_errors; |
|
|
|
|
|
|
|
perf_counter_t perf_write_errors; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************************
|
|
|
|
/************************************************************************************
|
|
|
@ -260,6 +271,7 @@ static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, |
|
|
|
while (blocksleft-- > 0) |
|
|
|
while (blocksleft-- > 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint16_t offset = startblock * priv->pagesize; |
|
|
|
uint16_t offset = startblock * priv->pagesize; |
|
|
|
|
|
|
|
unsigned tries = CONFIG_AT24XX_WRITE_TIMEOUT_MS; |
|
|
|
|
|
|
|
|
|
|
|
addr[1] = offset & 0xff; |
|
|
|
addr[1] = offset & 0xff; |
|
|
|
addr[0] = (offset >> 8) & 0xff; |
|
|
|
addr[0] = (offset >> 8) & 0xff; |
|
|
@ -274,9 +286,21 @@ 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); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 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) |
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
perf_count(priv->perf_read_errors); |
|
|
|
|
|
|
|
return ERROR; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
startblock++; |
|
|
|
startblock++; |
|
|
@ -336,6 +360,7 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t |
|
|
|
while (blocksleft-- > 0) |
|
|
|
while (blocksleft-- > 0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint16_t offset = startblock * priv->pagesize; |
|
|
|
uint16_t offset = startblock * priv->pagesize; |
|
|
|
|
|
|
|
unsigned tries = CONFIG_AT24XX_WRITE_TIMEOUT_MS; |
|
|
|
|
|
|
|
|
|
|
|
buf[1] = offset & 0xff; |
|
|
|
buf[1] = offset & 0xff; |
|
|
|
buf[0] = (offset >> 8) & 0xff; |
|
|
|
buf[0] = (offset >> 8) & 0xff; |
|
|
@ -351,9 +376,17 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t |
|
|
|
if (ret >= 0) |
|
|
|
if (ret >= 0) |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
/* XXX probably want a bus reset in here and an eventual timeout */ |
|
|
|
|
|
|
|
fvdbg("write stall"); |
|
|
|
fvdbg("write stall"); |
|
|
|
usleep(1000); |
|
|
|
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++; |
|
|
|
startblock++; |
|
|
@ -480,6 +513,10 @@ 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"); |
|
|
|
|
|
|
|
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 */ |
|
|
|
/* Return the implementation-specific state structure as the MTD device */ |
|
|
|