53 #include <px4_platform_common/px4_config.h> 54 #include <px4_platform_common/time.h> 56 #include <sys/types.h> 65 #include <nuttx/kmalloc.h> 66 #include <nuttx/fs/ioctl.h> 67 #include <nuttx/i2c/i2c_master.h> 68 #include <nuttx/mtd/mtd.h> 83 #ifndef CONFIG_AT24XX_SIZE 88 # define CONFIG_AT24XX_SIZE 64 90 #ifndef CONFIG_AT24XX_ADDR 95 # define CONFIG_AT24XX_ADDR 0x50 100 #if CONFIG_AT24XX_SIZE == 2 101 # define AT24XX_NPAGES 16 102 # define AT24XX_PAGESIZE 16 103 # define AT24XX_ADDRSIZE 1 104 #elif CONFIG_AT24XX_SIZE == 4 105 # define AT24XX_NPAGES 32 106 # define AT24XX_PAGESIZE 16 107 # define AT24XX_ADDRSIZE 1 108 #elif CONFIG_AT24XX_SIZE == 8 109 # define AT24XX_NPAGES 64 110 # define AT24XX_PAGESIZE 16 111 # define AT24XX_ADDRSIZE 1 112 #elif CONFIG_AT24XX_SIZE == 16 113 # define AT24XX_NPAGES 128 114 # define AT24XX_PAGESIZE 16 115 # define AT24XX_ADDRSIZE 1 116 #elif CONFIG_AT24XX_SIZE == 32 117 # define AT24XX_NPAGES 128 118 # define AT24XX_PAGESIZE 32 119 #elif CONFIG_AT24XX_SIZE == 48 120 # define AT24XX_NPAGES 192 121 # define AT24XX_PAGESIZE 32 122 #elif CONFIG_AT24XX_SIZE == 64 123 # define AT24XX_NPAGES 256 124 # define AT24XX_PAGESIZE 32 125 #elif CONFIG_AT24XX_SIZE == 128 126 # define AT24XX_NPAGES 256 127 # define AT24XX_PAGESIZE 64 128 #elif CONFIG_AT24XX_SIZE == 256 129 # define AT24XX_NPAGES 512 130 # define AT24XX_PAGESIZE 64 140 #ifndef CONFIG_AT24XX_MTD_BLOCKSIZE 145 # define CONFIG_AT24XX_MTD_BLOCKSIZE AT24XX_PAGESIZE 151 #ifndef CONFIG_AT24XX_WRITE_TIMEOUT_MS 152 # define CONFIG_AT24XX_WRITE_TIMEOUT_MS 20 166 FAR
struct i2c_master_s *
dev;
183 static ssize_t
at24c_bread(FAR
struct mtd_dev_s *
dev, off_t startblock,
184 size_t nblocks, FAR uint8_t *buf);
185 static ssize_t
at24c_bwrite(FAR
struct mtd_dev_s *
dev, off_t startblock,
186 size_t nblocks, FAR
const uint8_t *buf);
187 static int at24c_ioctl(FAR
struct mtd_dev_s *
dev,
int cmd,
unsigned long arg);
211 struct i2c_msg_s msgv[1] = {
217 .length =
sizeof(buf),
221 memset(&buf[2], 0xff, priv->pagesize);
223 BOARD_EEPROM_WP_CTRL(
false);
225 for (startblock = 0; startblock < priv->npages; startblock++) {
226 uint16_t offset = startblock * priv->pagesize;
227 buf[1] = offset & 0xff;
228 buf[0] = (offset >> 8) & 0xff;
230 while (I2C_TRANSFER(priv->dev, &msgv[0], 1) < 0) {
231 fwarn(
"erase stall\n");
236 BOARD_EEPROM_WP_CTRL(
true);
262 for (count = 0; count < 10000; count++) {
265 if (result == ERROR) {
267 syslog(LOG_INFO,
"too many errors\n");
271 }
else if (result != 1) {
272 syslog(LOG_INFO,
"unexpected %u\n", result);
275 if ((count % 100) == 0) {
276 syslog(LOG_INFO,
"test %u errors %u\n", count, errors);
286 size_t nblocks, FAR uint8_t *buffer)
293 struct i2c_msg_s msgv[2] = {
299 .length =
sizeof(
addr),
310 #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE 316 finfo(
"startblock: %08lx nblocks: %d\n", (
long)startblock, (
int)nblocks);
318 if (startblock >= priv->
npages) {
322 if (startblock + nblocks > priv->
npages) {
323 nblocks = priv->
npages - startblock;
326 while (blocksleft-- > 0) {
327 uint16_t offset = startblock * priv->
pagesize;
330 addr[1] = offset & 0xff;
331 addr[0] = (offset >> 8) & 0xff;
332 msgv[1].buffer = buffer;
337 ret = I2C_TRANSFER(priv->
dev, &msgv[0], 2);
365 #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE 380 FAR
const uint8_t *buffer)
387 struct i2c_msg_s msgv[1] = {
393 .length =
sizeof(buf),
397 #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE 403 if (startblock >= priv->
npages) {
407 if (startblock + nblocks > priv->
npages) {
408 nblocks = priv->
npages - startblock;
411 finfo(
"startblock: %08lx nblocks: %d\n", (
long)startblock, (
int)nblocks);
413 BOARD_EEPROM_WP_CTRL(
false);
415 while (blocksleft-- > 0) {
416 uint16_t offset = startblock * priv->
pagesize;
419 buf[1] = offset & 0xff;
420 buf[0] = (offset >> 8) & 0xff;
421 memcpy(&buf[2], buffer, priv->
pagesize);
426 ret = I2C_TRANSFER(priv->
dev, &msgv[0], 1);
433 finfo(
"write stall");
441 BOARD_EEPROM_WP_CTRL(
true);
450 BOARD_EEPROM_WP_CTRL(
true);
452 #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE 468 finfo(
"cmd: %d \n", cmd);
471 case MTDIOC_GEOMETRY: {
472 FAR
struct mtd_geometry_s *geo = (FAR
struct mtd_geometry_s *)((uintptr_t)arg);
496 #if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE 503 geo->neraseblocks = priv->
npages;
507 finfo(
"blocksize: %d erasesize: %d neraseblocks: %d\n",
508 geo->blocksize, geo->erasesize, geo->neraseblocks);
513 case MTDIOC_BULKERASE:
544 finfo(
"dev: %p\n", dev);
574 unsigned char buf[5];
575 uint8_t addrbuf[2] = {0, 0};
577 struct i2c_msg_s msgv[2] = {
582 .buffer = &addrbuf[0],
583 .length =
sizeof(addrbuf),
590 .length =
sizeof(buf),
594 BOARD_EEPROM_WP_CTRL(
true);
597 int ret = I2C_TRANSFER(priv->
dev, &msgv[0], 2);
606 finfo(
"Return %p\n", priv);
607 return (FAR
struct mtd_dev_s *)priv;
#define CONFIG_AT24XX_ADDR
perf_counter_t perf_resets_retries
measure the time elapsed performing an event
FAR struct i2c_master_s * dev
static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, FAR uint8_t *buf)
count the number of times an event occurs
#define CONFIG_AT24XX_MTD_BLOCKSIZE
void perf_count(perf_counter_t handle)
Count a performance event.
perf_counter_t perf_errors
#define CONFIG_AT24XX_SIZE
void perf_end(perf_counter_t handle)
End a performance event.
static struct at24c_dev_s g_at24c
static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
perf_counter_t perf_transfers
static int at24c_eraseall(FAR struct at24c_dev_s *priv)
FAR struct mtd_dev_s * at24c_initialize(FAR struct i2c_master_s *dev)
void perf_begin(perf_counter_t handle)
Begin a performance event.
static int at24c_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks, FAR const uint8_t *buf)
Performance measuring tools.
#define CONFIG_AT24XX_WRITE_TIMEOUT_MS