M95128-W EEPROM. The first byte of each page that does not write or read correctly

I am working on a library to manage the M95128-W EEPROM from an STM32 device. I have a library that writes and reads data, but the first byte of each page is not as expected, and seems to be fixed in 0x04.

For example, I write 128 bytes on two pages, starting with an address 0x00with a value 0x80. When I get back, I get:

byte[0] = 0x04;
byte[1] = 0x80;
byte[2] = 0x80;
byte[3] = 0x80;
.......
byte[64] = 0x04;
byte[65] = 0x80;
byte[66] = 0x80;
byte[67] = 0x80;

I debugged SPI using a logic analyzer and confirmed sending the correct bytes. When using a logic analyzer in a read command, the cache 0x04is transferred from the EEPROM.

Here is my code:

void FLA::write(const void* data, unsigned int dataLength, uint16_t address)
{
    int pagePos = 0;
    int pageCount = (dataLength + 64 - 1) / 64;
    int bytePos = 0;
    int startAddress = address;

    while (pagePos < pageCount)
    {
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2, GPIO_PIN_SET); // WP High
        chipSelect();

        _spi->transfer(INSTRUCTION_WREN);
        chipUnselect();

        uint8_t status = readRegister(INSTRUCTION_RDSR);

        chipSelect();

        _spi->transfer(INSTRUCTION_WRITE);
        uint8_t xlow = address & 0xff;
        uint8_t xhigh = (address >> 8);
        _spi->transfer(xhigh); // part 1 address MSB
        _spi->transfer(xlow); // part 2 address LSB


        for (unsigned int i = 0; i < 64 && bytePos < dataLength; i++ )
        {
            uint8_t byte = ((uint8_t*)data)[bytePos];
            _spi->transfer(byte);

            printConsole("Wrote byte to ");
            printConsoleInt(startAddress + bytePos);
            printConsole("with value ");
            printConsoleInt(byte);
            printConsole("\n");

            bytePos ++;
        }

        _spi->transfer(INSTRUCTION_WRDI);

        chipUnselect();
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2, GPIO_PIN_RESET); //WP LOW

        bool writeComplete = false;
        while (writeComplete == false)
        {
            uint8_t status = readRegister(INSTRUCTION_RDSR);

            if(status&1<<0)
            {
                printConsole("Waiting for write to complete....\n");
            }

            else
            {
                writeComplete = true;
                printConsole("Write complete to page ");
                printConsoleInt(pagePos);
                printConsole("@ address ");
                printConsoleInt(bytePos);
                printConsole("\n");
            }
        }

        pagePos++;
        address = address + 64;
    }

    printConsole("Finished writing all pages total bytes ");
    printConsoleInt(bytePos);
    printConsole("\n");
}
void FLA::read(char* returndata, unsigned int dataLength, uint16_t address)
{
    chipSelect();
          _spi->transfer(INSTRUCTION_READ);
            uint8_t xlow = address & 0xff;
                    uint8_t xhigh = (address >> 8);
          _spi->transfer(xhigh); // part 1 address
          _spi->transfer(xlow); // part 2 address

            for (unsigned int i = 0; i < dataLength; i++)
                returndata[i] = _spi->transfer(0x00);
               chipUnselect();


}

Any suggestion or help appreciated.

UPDATE:

255 , . :

byte[0] = 4; // Incorrect Mystery Byte 
byte[1] = 1; 
byte[2] = 2;
byte[3] = 3; 
....... 
byte[63] = 63; 
byte[64] = 4; // Incorrect Mystery Byte 
byte[65] = 65; 
byte[66] = 66;
....... 
byte[127] = 127; 
byte[128] = 4; // Incorrect Mystery Byte 
byte[129} = 129;

. 8 0x00, , , .

printConsole .

SPI :

enter image description here

, :

enter image description here

gitlab : https://gitlab.com/DanielBeyzade/stm32f107vc-home-control-master/blob/master/Src/flash.cpp

SPI MX_SPI_Init()

https://gitlab.com/DanielBeyzade/stm32f107vc-home-control-master/blob/master/Src/main.cpp

SPI (RFM69HW RF Module), .

+4
2

. . , - CS - INSTRUCTION_WRDI. , ? , 4, .

:

    chipSelect();

    _spi->transfer(INSTRUCTION_WRITE);
    uint8_t xlow = address & 0xff;
    uint8_t xhigh = (address >> 8);
    _spi->transfer(xhigh); // part 1 address MSB
    _spi->transfer(xlow); // part 2 address LSB


    for (unsigned int i = 0; i < 64 && bytePos < dataLength; i++ )
    {
        uint8_t byte = ((uint8_t*)data)[bytePos];
        _spi->transfer(byte);

        // ...

        bytePos ++;
    }

    _spi->transfer(INSTRUCTION_WRDI); // <-------------- ROLLOEVER!

    chipUnselect();

CS. , CS , . - CS - . , "", CS .

, WRDI - , ( CS), WEL reset. . . 18 :

(WEL), , reset :

• WRDI

• WRSR

• WRITE.

+3

: , [ ].

6.6: , , . , , , "roll-over". , , 0 .

, : for (i = 0; i < 64; i++). , LSB (xlow) . - : for (i = xlow % 64; i < 64; i++)

, . , 0x0000, , .

, .

: (, 0x01,0x02,0x03,... , , [ ].

, , (.. , 64 ), , .

, 13 [ WRITE] , , ROM , , , (-) . , , , (.. )

, 0 64 0x04. , .

, "", 0x04 .

, SILO, -, - ( _spi->transfer )

, , - (, 10 ), (, xhigh = 0; xlow = 4) , .


UPDATE:

[].

, SCLK . . , . , , . , SCLK / (.. transfer) SCLK GPIO? transfer [ ].

SPI : https://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus, .

, ​​ :

/*
 * Simultaneously transmit and receive a byte on the SPI.
 *
 * Polarity and phase are assumed to be both 0, i.e.:
 *   - input data is captured on rising edge of SCLK.
 *   - output data is propagated on falling edge of SCLK.
 *
 * Returns the received byte.
 */
uint8_t SPI_transfer_byte(uint8_t byte_out)
{
    uint8_t byte_in = 0;
    uint8_t bit;

    for (bit = 0x80; bit; bit >>= 1) {
        /* Shift-out a bit to the MOSI line */
        write_MOSI((byte_out & bit) ? HIGH : LOW);

        /* Delay for at least the peer setup time */
        delay(SPI_SCLK_LOW_TIME);

        /* Pull the clock line high */
        write_SCLK(HIGH);

        /* Shift-in a bit from the MISO line */
        if (read_MISO() == HIGH)
            byte_in |= bit;

        /* Delay for at least the peer hold time */
        delay(SPI_SCLK_HIGH_TIME);

        /* Pull the clock line low */
        write_SCLK(LOW);
    }

    return byte_in;
}

, , , , . , .

, , -, . , , .

CPOL=0,CPHA=1. CPOL=0,CPHA=0, , .

, . , CPOL=0,CPHA=0:

SCLK
          __
         |  |
      ___|  |___

DATA
           ___
          /   \
         /     \

, (CPOL=0,CPHA=1) - ROM:

SCLK
          __
         |  |
      ___|  |___

DATA
        ___
       /   \
      /     \

CPOL=0,CPHA=0 CPOL=1,CPHA=1. , ( ). , . SDK , , , (, . 18 . ROM).

, , , , .

, . , , LSB, [ ] .

, transfer(xlow) , , [ ].

xlow (, 3) . xlow, , . , , .

+3

Source: https://habr.com/ru/post/1670453/


All Articles