I have an nRF5340 with an AT24CM01 EEPROM on an I2C bus (SDA = P0.16, SDL = P0.17). My devicetree looks like so:
&i2c3 {
compatible = "nordic,nrf-twim";
status = "okay";
clock-frequency = <I2C_BITRATE_FAST>;
pinctrl-0 = <&i2c3_default>;
pinctrl-1 = <&i2c3_sleep>;
pinctrl-names = "default", "sleep";
// EEPROM
at24cm01: at24cm01@50 {
compatible = "atmel,at24";
reg = <0x50>;
size = <131072>;
pagesize = <256>;
address-width = <16>;
timeout = <5>;
status = "okay";
};
};
I'm having troubles when writing and reading in rapid succession. If I do this, it throws a bunch of errors:
#include <zephyr/drivers/eeprom.h>
int test() {
uint8_t readdata;
for(uint32_t addr = 0; addr < 131072; addr++) {
uint8_t data = addr % 255;
LOG_INF("Writing...");
err = eeprom_write(dev, addr, &data, sizeof(data));
if(err) {
LOG_ERR("EEPROM write failed at address %d, err: %d", addr, err);
return false;
}
LOG_INF("Written! Reading...");
err = eeprom_read(dev, addr, &readdata, sizeof(readdata));
if(err) {
LOG_ERR("EEPROM read failed at address %d, err: %d", addr, err);
return false;
}
LOG_INF("Read!");
if(readdata != data) {
LOG_ERR("EEPROM failed at address %d (expected %d, got %d)", addr,
data, readdata);
return false;
}
k_msleep(500);
}
return 0;
}
[00:00:05.435,577] <inf> myapp: Writing... [00:00:05.435,791] <inf> myapp: Written! Reading... [00:00:05.435,882] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0 [00:00:05.437,042] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0 [00:00:05.438,201] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0 [00:00:05.439,514] <inf> myapp: Read! [00:00:05.939,575] <inf> myapp: Writing... [00:00:05.939,758] <inf> myapp: Written! Reading... [00:00:05.939,849] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0 [00:00:05.940,979] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0 [00:00:05.942,169] <err> i2c_nrfx_twim: Error 0x0BAE0001 occurred for message 0 [00:00:05.943,450] <inf> myapp: Read!
From other forum posts, this error appears to be a NACK. If I put a delay in between the write and read though:
#include <zephyr/drivers/eeprom.h>
int test() {
uint8_t readdata;
for(uint32_t addr = 0; addr < 131072; addr++) {
uint8_t data = addr % 255;
LOG_INF("Writing...");
err = eeprom_write(dev, addr, &data, sizeof(data));
if(err) {
LOG_ERR("EEPROM write failed at address %d, err: %d", addr, err);
return false;
}
k_msleep(5);
LOG_INF("Written! Reading...");
err = eeprom_read(dev, addr, &readdata, sizeof(readdata));
if(err) {
LOG_ERR("EEPROM read failed at address %d, err: %d", addr, err);
return false;
}
LOG_INF("Read!");
if(readdata != data) {
LOG_ERR("EEPROM failed at address %d (expected %d, got %d)", addr,
data, readdata);
return false;
}
k_msleep(500);
}
return 0;
}
Then it works fine:
[00:00:05.739,227] <inf> myapp: Writing... [00:00:05.749,511] <inf> myapp: Written! Reading... [00:00:05.749,755] <inf> myapp: Read! [00:00:06.249,816] <inf> myapp: Writing... [00:00:06.260,070] <inf> myapp: Written! Reading... [00:00:06.260,284] <inf> myapp: Read!
Is this expected behaviour? I'm surprised that the Zephyr library doesn't wait for the operation to be complete before returning. Is there a recommended approach to dealing with this, other than putting a (likely unnecessary) sleep after each operation?


