Page 1 of 1

EEPROM chip SPI spi_transaction addr issue when addr > 256

Posted: Wed Nov 17, 2021 10:16 am
by zazas321
Hello. I am working with the EEPROM chip and noticed an issue. Datasheet can be found here:
https://www.st.com/en/memories/m95m04-dr.html


From the esp32 SPI documentation it says that if I use length variable in spi_transaction structure, the address will auto increment.

I want to save chunks of 25 byte data in the EEPROM memory and it seems to work fine, however. For example I can write to addressess 0-25, 25-50, 50-75,75-100, 100-125, 125-150, 150-175, 175-200, 200-225, 225-250.

However, writing to 250-275 is not working. It looks like that whenever the 256 is reached, everything after that will be incorrect. I am not able to write, read, erase or do anything else if inside my fuction the address auto increments over 256.



For example:

Code: Select all

void EEPROM_write_25_byte_chunks(spi_device_handle_t spi,uint32_t chunk,s_thermostat_logging* data){
    s_thermostat_logging data_endian_swapped = convert_struct_to_big_endian(data);
    while(EEPROM_check_if_busy(spi) != true){ // return true if flash is not busy
        vTaskDelay(10/portTICK_PERIOD_MS);
    }

    if(EEPROM_check_if_write_enabled(external_eeprom)==true){ // returns true if write is already enabled
        EEPROM_write_enable(external_eeprom);
    }
    spi_transaction_ext_t trans = {
       .base = {
            .flags = SPI_TRANS_VARIABLE_ADDR,
            .cmd = 0b00000010,
            .addr = chunk_to_write*25,
            .length = 8*25,
            .tx_buffer = &data_endian_swapped,
       },
       .address_bits = 24,
    };

    spi_device_polling_transmit(spi, (spi_transaction_t*)&trans);
}
The above function will not work if I try to write to chunk number 10.

The .addr will be set to 250 and the first 6 bytes will be written correctly, everything after 256 will be read 0xFF.


In my main, I write some test values to chunks. First chunk will have all 0's, second chunk will have all 1's, third chunk will have all 3's and so on. When I try to read back bytes from the memory, the result is as following:

Code: Select all

data_holder[25]=0 
data_holder[26]=0 
data_holder[27]=0
data_holder[28]=0
data_holder[29]=0
data_holder[30]=0
data_holder[31]=0
data_holder[32]=0
data_holder[33]=0
data_holder[34]=0
data_holder[35]=0
data_holder[36]=0
data_holder[37]=0
data_holder[38]=0
data_holder[39]=0
data_holder[40]=0
data_holder[41]=0
data_holder[42]=0
data_holder[43]=0
data_holder[44]=0
data_holder[45]=0
data_holder[46]=0
data_holder[47]=0 
data_holder[48]=0
data_holder[49]=0
data_holder[50]=1 
data_holder[51]=1 
data_holder[52]=1
data_holder[53]=1
data_holder[54]=1
data_holder[55]=1
data_holder[56]=1
data_holder[57]=1
data_holder[58]=1
data_holder[59]=1
data_holder[60]=1
data_holder[61]=1
data_holder[62]=1
data_holder[63]=1
data_holder[64]=1
data_holder[65]=1
data_holder[66]=1
data_holder[67]=1
data_holder[68]=1
data_holder[69]=1
data_holder[70]=1
data_holder[71]=1
data_holder[72]=1
data_holder[73]=1
data_holder[74]=1
data_holder[75]=2
data_holder[76]=2 
data_holder[77]=2 
data_holder[78]=2
data_holder[79]=2
data_holder[80]=2
data_holder[81]=2
data_holder[82]=2
data_holder[83]=2
data_holder[84]=2
data_holder[85]=2
data_holder[86]=2
data_holder[87]=2
data_holder[88]=2
data_holder[89]=2
data_holder[90]=2
data_holder[91]=2
data_holder[92]=2
data_holder[93]=2
data_holder[94]=2
data_holder[95]=2
data_holder[96]=2
data_holder[97]=2
data_holder[98]=2
data_holder[99]=2
data_holder[100]=3
data_holder[101]=3 
data_holder[102]=3 
data_holder[103]=3
data_holder[104]=3
data_holder[105]=3
data_holder[106]=3
data_holder[107]=3
data_holder[108]=3
data_holder[109]=3
data_holder[110]=3
data_holder[111]=3
data_holder[112]=3
data_holder[113]=3
data_holder[114]=3
data_holder[115]=3
data_holder[116]=3
data_holder[117]=3
data_holder[118]=3
data_holder[119]=3
data_holder[120]=3
data_holder[121]=3
data_holder[122]=3
data_holder[123]=3
data_holder[124]=3
data_holder[125]=4
data_holder[126]=4 
data_holder[127]=4 
data_holder[128]=4
data_holder[129]=4
data_holder[130]=4
data_holder[131]=4
data_holder[132]=4
data_holder[133]=4
data_holder[134]=4
data_holder[135]=4
data_holder[136]=4
data_holder[137]=4
data_holder[138]=4
data_holder[139]=4
data_holder[140]=4
data_holder[141]=4
data_holder[142]=4
data_holder[143]=4
data_holder[144]=4
data_holder[145]=4
data_holder[146]=4
data_holder[147]=4
data_holder[148]=4
data_holder[149]=4
data_holder[150]=5 
data_holder[151]=5 
data_holder[152]=5
data_holder[153]=5
data_holder[154]=5
data_holder[155]=5
data_holder[156]=5
data_holder[157]=5
data_holder[158]=5
data_holder[159]=5
data_holder[160]=5
data_holder[161]=5
data_holder[162]=5
data_holder[163]=5
data_holder[164]=5
data_holder[165]=5
data_holder[166]=5
data_holder[167]=5
data_holder[168]=5
data_holder[169]=5
data_holder[170]=5
data_holder[171]=5
data_holder[172]=5
data_holder[173]=5
data_holder[174]=5 
data_holder[175]=6 
data_holder[176]=6
data_holder[177]=6
data_holder[178]=6
data_holder[179]=6
data_holder[180]=6
data_holder[181]=6
data_holder[182]=6
data_holder[183]=6
data_holder[184]=6
data_holder[185]=6
data_holder[186]=6
data_holder[187]=6
data_holder[188]=6
data_holder[189]=6
data_holder[190]=6
data_holder[191]=6
data_holder[192]=6
data_holder[193]=6
data_holder[194]=6
data_holder[195]=6
data_holder[196]=6
data_holder[197]=6
data_holder[198]=6
data_holder[199]=6 
data_holder[200]=7 
data_holder[201]=7
data_holder[202]=7
data_holder[203]=7
data_holder[204]=7
data_holder[205]=7
data_holder[206]=7
data_holder[207]=7
data_holder[208]=7
data_holder[209]=7
data_holder[210]=7
data_holder[211]=7
data_holder[212]=7
data_holder[213]=7
data_holder[214]=7
data_holder[215]=7
data_holder[216]=7
data_holder[217]=7
data_holder[218]=7
data_holder[219]=7
data_holder[220]=7
data_holder[221]=7
data_holder[222]=7
data_holder[223]=7 
data_holder[224]=7 
data_holder[225]=8
data_holder[226]=8
data_holder[227]=8
data_holder[228]=8
data_holder[229]=8
data_holder[230]=8
data_holder[231]=8
data_holder[232]=8
data_holder[233]=8
data_holder[234]=8
data_holder[235]=8
data_holder[236]=8
data_holder[237]=8
data_holder[238]=8
data_holder[239]=8
data_holder[240]=8
data_holder[241]=8
data_holder[242]=8
data_holder[243]=8
data_holder[244]=8
data_holder[245]=8
data_holder[246]=8
data_holder[247]=8
data_holder[248]=8 
data_holder[249]=8 
data_holder[250]=9
data_holder[251]=9
data_holder[252]=9
data_holder[253]=9
data_holder[254]=9
data_holder[255]=9
data_holder[256]=255
data_holder[257]=255
data_holder[258]=255
data_holder[259]=255
data_holder[260]=255
data_holder[261]=255
data_holder[262]=255
data_holder[263]=255
data_holder[264]=255
data_holder[265]=255
data_holder[266]=255
data_holder[267]=255
data_holder[268]=255
data_holder[269]=255
data_holder[270]=255
data_holder[271]=255
data_holder[272]=255
data_holder[273]=255
data_holder[274]=255
[\code]

**Note that I start writing /reading from the address 25 becuase first 25 EEPROM bytes are reserved for something else in my program.**

I am very stuck and cant understand what could be the problem. Please suggest how can this be solved?

Re: EEPROM chip SPI spi_transaction addr issue when addr > 256

Posted: Wed Nov 17, 2021 10:32 am
by zazas321
EDIT:
If I am trying to write to 10 chunk ( 250 - 275 addresses) , if I write one byte by one with the following function:

Code: Select all

void EEPROM_write_25_byte_chunks(spi_device_handle_t spi,uint32_t chunk,s_thermostat_logging* data){
    s_thermostat_logging data_endian_swapped = convert_struct_to_big_endian(data);
    for(int i = 0; i <25; i ++){
        while(EEPROM_check_if_busy(spi) != true){ // return true if flash is not busy
            vTaskDelay(10/portTICK_PERIOD_MS);
        }

        if(EEPROM_check_if_write_enabled(external_eeprom)==true){ // returns true if write is already enabled
            EEPROM_write_enable(external_eeprom);
        }
        spi_transaction_ext_t trans = {
        .base = {
                .flags = SPI_TRANS_VARIABLE_ADDR,
                .cmd = 0b00000010,
                .addr = (chunk*CHUNK_SIZE2)+i,
                .length = 8,
                .tx_buffer = &i,
        },
        .address_bits = 24,
        };
        spi_device_polling_transmit(spi, (spi_transaction_t*)&trans);

    }
}
It will work perfectly, however, If I try to write all 25 byte at once with the following function, it will not work. ( bytes 250,251,252,253,254,255 will be we written secesfullly and all bytes above 256 address will be read as 0xFF

Code: Select all

void EEPROM_write_25_byte_at_once(spi_device_handle_t spi,uint32_t chunk,s_thermostat_logging* data){
    s_thermostat_logging data_endian_swapped = convert_struct_to_big_endian(data);
        while(EEPROM_check_if_busy(spi) != true){ // return true if flash is not busy
            vTaskDelay(10/portTICK_PERIOD_MS);
        }

        if(EEPROM_check_if_write_enabled(external_eeprom)==true){ // returns true if write is already enabled
            EEPROM_write_enable(external_eeprom);
        }
        spi_transaction_ext_t trans = {
        .base = {
                .flags = SPI_TRANS_VARIABLE_ADDR,
                .cmd = 0b00000010,
                .addr = chunk*25,
                .length = 8*25,
                .tx_buffer = &data_endian_swapped ,
        },
        .address_bits = 24,
        };
        spi_device_polling_transmit(spi, (spi_transaction_t*)&trans);

    
}

Re: EEPROM chip SPI spi_transaction addr issue when addr > 256

Posted: Thu Nov 18, 2021 3:11 am
by ESP_Sprite
Strange... that is 100% sure the datasheet for the chip that you're using? I'd expect the issue is that you hit a page size limit, but that doesn't seem to be the case here; your chips pages are 512 bytes, not 256.

Re: EEPROM chip SPI spi_transaction addr issue when addr > 256

Posted: Thu Nov 18, 2021 5:39 am
by zazas321
Yes you are totaly right. I have double checked the part number and it turned out that they have given me the simmilar EEPROM but a different version of it. Im surprised everything else works. Thank you very much for pointing that out!

Either way, Is there any way to handle this? At the moment, I am writing data byte by byte and that seems to work fine, however, I would still like to know if there is any way to handle this? How can I write to adresses 250-275 in one command?

Re: EEPROM chip SPI spi_transaction addr issue when addr > 256

Posted: Fri Nov 19, 2021 1:45 am
by ESP_Sprite
You can't. Easiest way would be to detect that you're crossing a border, and in that case split the transfer into two: one to write 250-255, the other to write 256-270.

Re: EEPROM chip SPI spi_transaction addr issue when addr > 256

Posted: Fri Nov 19, 2021 9:27 am
by zazas321
Okay thank you. I will probably implement that