From af9590eef7cc7f9a13f8471e5820591991f3ced6 Mon Sep 17 00:00:00 2001 From: Marten Svanfeldt Date: Wed, 21 Oct 2015 11:32:57 +0800 Subject: [PATCH 1/2] Extend the AT24Cxx MTD driver with support for -04,-08 and -16 parts. These parts utilize the same one-byte-address in the I2C protocol as the -02, but requires different I2C addresses for different banks of the EEPROM. Signed-off-by: Marten Svanfeldt --- drivers/mtd/at24xx.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/at24xx.c b/drivers/mtd/at24xx.c index 32ea3c618e..b4f982b9ef 100644 --- a/drivers/mtd/at24xx.c +++ b/drivers/mtd/at24xx.c @@ -81,10 +81,22 @@ /* Get the part configuration based on the size configuration */ -#if CONFIG_AT24XX_SIZE == 2 /* AT24C32: 2Kbits = 256; 16 * 16 = 256 */ +#if CONFIG_AT24XX_SIZE == 2 /* AT24C02: 2Kbits = 256; 16 * 16 = 256 */ # define AT24XX_NPAGES 16 # define AT24XX_PAGESIZE 16 # define AT24XX_ADDRSIZE 1 +#elif CONFIG_AT24XX_SIZE == 4 /* AT24C04: 4Kbits = 512B; 32 * 16 = 512 */ +# define AT24XX_NPAGES 32 +# define AT24XX_PAGESIZE 16 +# define AT24XX_ADDRSIZE 1 +#elif CONFIG_AT24XX_SIZE == 8 /* AT24C08: 8Kbits = 1KiB; 64 * 16 = 1024 */ +# define AT24XX_NPAGES 64 +# define AT24XX_PAGESIZE 16 +# define AT24XX_ADDRSIZE 1 +#elif CONFIG_AT24XX_SIZE == 16 /* AT24C16: 16Kbits = 2KiB; 128 * 16 = 2048 */ +# define AT24XX_NPAGES 128 +# define AT24XX_PAGESIZE 16 +# define AT24XX_ADDRSIZE 1 #elif CONFIG_AT24XX_SIZE == 32 /* AT24C32: 32Kbits = 4KiB; 128 * 32 = 4096 */ # define AT24XX_NPAGES 128 # define AT24XX_PAGESIZE 32 @@ -185,12 +197,13 @@ static int at24c_eraseall(FAR struct at24c_dev_s *priv) for (startblock = 0; startblock < priv->npages; startblock++) { -#if AT24XX_ADDRSIZE == 2 uint16_t offset = startblock * priv->pagesize; +#if AT24XX_ADDRSIZE == 2 buf[1] = offset & 0xff; buf[0] = (offset >> 8) & 0xff; #else - buf[0] = startblock * priv->pagesize; + buf[0] = offset & 0xff; + I2C_SETADDRESS(priv->dev, priv->addr | ((offset >> 8) & 0x07), 7); #endif while (I2C_WRITE(priv->dev, buf, AT24XX_ADDRSIZE) < 0) @@ -228,7 +241,6 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, fvdbg("offset: %lu nbytes: %lu address: %02x\n", (unsigned long)offset, (unsigned long)nbytes, address); - I2C_SETADDRESS(priv->dev, address, 7); I2C_SETFREQUENCY(priv->dev, 100000); /* "Random Read: A Random Read requires a dummy byte write sequence to load in the @@ -247,8 +259,12 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, #if AT24XX_ADDRSIZE == 2 buf[1] = offset & 0xff; buf[0] = (offset >> 8) & 0xff; + + I2C_SETADDRESS(priv->dev, address, 7); #else - buf[0] = (uint8_t)offset; + buf[0] = offset & 0xff; + + I2C_SETADDRESS(priv->dev, address | ((offset >> 8) & 0x07), 7); #endif while (I2C_WRITE(priv->dev, buf, AT24XX_ADDRSIZE) < 0) @@ -356,12 +372,14 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t while (blocksleft-- > 0) { -#if AT24XX_ADDRSIZE == 2 uint16_t offset = startblock * priv->pagesize; +#if AT24XX_ADDRSIZE == 2 buf[1] = offset & 0xff; buf[0] = (offset >> 8) & 0xff; #else - buf[0] = startblock * priv->pagesize; + buf[0] = offset & 0xff; + + I2C_SETADDRESS(priv->dev, address | ((offset >> 8) & 0x07), 7); #endif while (I2C_WRITE(priv->dev, buf, AT24XX_ADDRSIZE) < 0) From a31d1fd378381089d430cdd1972e16f8102416a5 Mon Sep 17 00:00:00 2001 From: Marten Svanfeldt Date: Wed, 21 Oct 2015 11:34:34 +0800 Subject: [PATCH 2/2] Make I2C frequency configurable for the AT24Cxx EEPROM driver Signed-off-by: Marten Svanfeldt --- drivers/mtd/Kconfig | 8 ++++++++ drivers/mtd/at24xx.c | 9 ++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 97ce9effca..c35d28a34b 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -309,6 +309,14 @@ config AT24XX_EXTSIZE Other, block-oriented access are not effected by this setting +config AT24XX_FREQUENCY + int "AT24xx I2C bus frequency" + default 100000 + ---help--- + Set the I2C frequency to use when accessing the AT24CXX EEPROM. This value + must represent a valid I2C speed (normally less than 400.000) or the driver + might fail. + endif config MTD_AT25 diff --git a/drivers/mtd/at24xx.c b/drivers/mtd/at24xx.c index b4f982b9ef..e8842f8bdd 100644 --- a/drivers/mtd/at24xx.c +++ b/drivers/mtd/at24xx.c @@ -78,6 +78,9 @@ # warning "Assuming AT24 address of 0x50" # define CONFIG_AT24XX_ADDR 0x50 #endif +#ifndef CONFIG_AT24XX_FREQUENCY +# define CONFIG_AT24XX_FREQUENCY 100000 +#endif /* Get the part configuration based on the size configuration */ @@ -193,7 +196,7 @@ static int at24c_eraseall(FAR struct at24c_dev_s *priv) memset(&buf[AT24XX_ADDRSIZE], 0xff, priv->pagesize); I2C_SETADDRESS(priv->dev, priv->addr, 7); - I2C_SETFREQUENCY(priv->dev, 100000); + I2C_SETFREQUENCY(priv->dev, CONFIG_AT24XX_FREQUENCY); for (startblock = 0; startblock < priv->npages; startblock++) { @@ -241,7 +244,7 @@ static ssize_t at24c_read_internal(FAR struct at24c_dev_s *priv, off_t offset, fvdbg("offset: %lu nbytes: %lu address: %02x\n", (unsigned long)offset, (unsigned long)nbytes, address); - I2C_SETFREQUENCY(priv->dev, 100000); + I2C_SETFREQUENCY(priv->dev, CONFIG_AT24XX_FREQUENCY); /* "Random Read: A Random Read requires a dummy byte write sequence to load in the * data word address. Once the device address word and data word address are clocked @@ -368,7 +371,7 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks); I2C_SETADDRESS(priv->dev, priv->addr, 7); - I2C_SETFREQUENCY(priv->dev, 100000); + I2C_SETFREQUENCY(priv->dev, CONFIG_AT24XX_FREQUENCY); while (blocksleft-- > 0) {