EEPROM Non-Blocking

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?

Parents Reply Children
No Data
Related