diff --git a/platform/drivers/NVM/AT24Cx.h b/platform/drivers/NVM/AT24Cx.h index 5a477144..cb81df12 100644 --- a/platform/drivers/NVM/AT24Cx.h +++ b/platform/drivers/NVM/AT24Cx.h @@ -45,7 +45,18 @@ void AT24Cx_terminate(); * @param addr: start address for read operation. * @param buf: pointer to a buffer where data is written to. * @param len: number of bytes to read. + * @return zero on success, negative errno code on fail. */ -void AT24Cx_readData(uint32_t addr, void *buf, size_t len); +int AT24Cx_readData(uint32_t addr, void *buf, size_t len); + +/** + * Write data to EEPROM memory. + * + * @param addr: start address for write operation. + * @param buf: pointer to the data to be written. + * @param len: number of bytes to write. + * @return zero on success, negative errno code on fail. + */ +int AT24Cx_writeData(uint32_t addr, const void *buf, size_t len); #endif /* AT24Cx_H */ diff --git a/platform/drivers/NVM/AT24Cx_GDx.c b/platform/drivers/NVM/AT24Cx_GDx.c index 21220975..70228b5d 100644 --- a/platform/drivers/NVM/AT24Cx_GDx.c +++ b/platform/drivers/NVM/AT24Cx_GDx.c @@ -18,14 +18,15 @@ * along with this program; if not, see * ***************************************************************************/ -#include "AT24Cx.h" #include #include -#include #include +#include #include +#include "AT24Cx.h" -static const uint8_t devAddr = 0xA0; /* EEPROM I2C address */ +static const uint8_t DEV_ADDR = 0xA0; /* EEPROM I2C address */ +static const size_t PAGE_SIZE = 128; void AT24Cx_init() { @@ -40,7 +41,7 @@ void AT24Cx_terminate() } -void AT24Cx_readData(uint32_t addr, void* buf, size_t len) +int AT24Cx_readData(uint32_t addr, void* buf, size_t len) { uint16_t a = __builtin_bswap16((uint16_t) addr); @@ -50,9 +51,48 @@ void AT24Cx_readData(uint32_t addr, void* buf, size_t len) */ i2c0_lockDeviceBlocking(); - i2c0_write(devAddr, &a, 2, false); + i2c0_write(DEV_ADDR, &a, 2, false); delayUs(10); - i2c0_read(devAddr, buf, len); + i2c0_read(DEV_ADDR, buf, len); i2c0_releaseDevice(); + + return 0; } + +int AT24Cx_writeData(uint32_t addr, const void *buf, size_t len) +{ + size_t toWrite; + uint8_t writeBuf[PAGE_SIZE + 2]; + + /* + * On GDx devices the I2C bus is shared between the EEPROM and the AT1846S, + * so we have to acquire exclusive ownership before exchanging data + */ + i2c0_lockDeviceBlocking(); + + while(len > 0) + { + toWrite = len; + if(toWrite >= PAGE_SIZE) + toWrite = PAGE_SIZE; + + writeBuf[0] = (addr >> 8) & 0xFF; /* High address byte */ + writeBuf[1] = (addr & 0xFF); /* Low address byte */ + memcpy(&writeBuf[2], buf, toWrite); /* Data */ + + i2c0_write(DEV_ADDR, writeBuf, toWrite + 2, true); + + len -= toWrite; + buf = ((const uint8_t *) buf) + toWrite; + addr += toWrite; + + /* Wait for the write cycle to end (max 5ms as per datasheet) */ + sleepFor(0, 5); + } + + i2c0_releaseDevice(); + + return 0; +} +