Skip to main content
Graduate II
January 13, 2022
Solved

[STM32H750BX][QSPI] Issue with W25N01GVZEIG NAND Flash Driver

  • January 13, 2022
  • 7 replies
  • 8298 views

Hello,

Please, I am working on a Custom Project with STM32H7 platform and I am using a NAND Flash for Data Storage (W25N01GVZEIG). I can execute correctly all commands except :

  • (32h) Quad Program Data Load .

I can write using (02h) Program Data Load with SPI mode with no issues, but once I switch to Quad mode (32h) the data written is not correct, seems there is some bits corruption.

{0x11,0x22,0x44,0x88} is written {0x91,0x22,0x04,0x48}. I suspected the pinout first but the Quad read is working fine.

I saw a similar question QSPI of STM32L496A but didn't fix my issue.

Could you support on this?

Thanks,

Ayoub

    This topic has been closed for replies.
    Best answer by Ayoub Cheggari

    I was suspecting it to be a read issue, but when I write with SPI using cmd (02h), I can read data correctly.

    Speaking about the erase, when I execute the Block Erase cmd (D8h), the bits are set to 0 not 1 which is very strange. I will do as you proposed thanks @Community member​  for supporting as always !

    7 replies

    Explorer
    January 13, 2022

    Can you send your code? How do you do read, write, erase, execute operations?

    I can write using Quad mode (32h) but some pages (2048 byte) are not correct. For example; in block 0, page from 0 to 10 is sucsess but in block 0, page from 10 to 15 wrong.

    David Garcia (Community Member)'s answers are very helpful. In this question QSPI of STM32L496A, the codes found here are all working, I followed the instructions.

    You problem is like dummyCycles.

    Graduate II
    January 14, 2022

    Here is the code I am using:

    Write: here as we discussed in Linkedin, SPI write works fine but Quad is not as the written data is corrupted somehow. Also, don't need to execute the Program execute cmd to store the data into Physical mem.

    uint8_t W25qxx_PageProgram(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)

    {

    uint8_t result;

    W25qxx_WriteEnable();

    result = QSPI_Send_CMD(&hqspi,W25X_PageProgram,WriteAddr,QSPI_ADDRESS_16_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_1_LINE,QSPI_DATA_1_LINE,Size);

    //result = QSPI_Send_CMD(&hqspi,W25X_QUAD_INPUT_PAGE_PROG_CMD,WriteAddr,QSPI_ADDRESS_16_BITS,0,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_1_LINE,QSPI_DATA_4_LINES,Size);

    if(result == w25qxx_OK)

    result = HAL_QSPI_Transmit(&hqspi,pData,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);

    if(result == w25qxx_OK)

    W25QXX_Wait_Busy();

    //W25qxx_ProgramExecute(WriteAddr);

    return result;

    }

    Erase: the bits are set to 0 instead of 1

    uint8_t W25qxx_EraseBlock(uint16_t BlockAddress)

    {

    uint8_t result;

    uint8_t page = 0;

    uint8_t block = 0;

    uint32_t addr = (block << 6) | page;

    block_add[0] = (uint8_t) (addr >> 8);

    block_add[1] = (uint8_t) addr ;

    W25qxx_WriteEnable();

    W25QXX_Wait_Busy();

    result = QSPI_Send_CMD(&hqspi,W25X_BlockErase,BlockAddress,QSPI_ADDRESS_8_BITS,8,QSPI_INSTRUCTION_1_LINE,QSPI_ADDRESS_NONE,QSPI_DATA_1_LINE,2);

    result = HAL_QSPI_Transmit(&hqspi,(uint8_t *)block_add,HAL_QPSI_TIMEOUT_DEFAULT_VALUE);

    if(result == w25qxx_OK)

    W25QXX_Wait_Busy();

    return result;

    }

    I tried to follow instructions written by David Garcia, but didn't work.

    Explorer
    January 14, 2022

    What is your "QSPI_Send_CMD" function? Please send, function and hqspi init instructions.

    Graduate II
    January 13, 2022

    Issues tend to be on the READ side, not the WRITE, READs can be tested/validated by either having existing patterns in memory, or using the READ 1, 2 and 4-bit modes and checking they all read the same data.

    If on the WRITE side you're going to have to look at signal integrity issues, and meeting expectations of the memory device in terms of how quickly it can ingest data into internal buffers, and how quickly it can write complete blocks to its internal array.

    Check that the correct dummy and alternate cycles are programmed.

    Check that you are properly/completely initializing the command structures.

    Check that the addressing/paging is correct for each command.

    Check that data is erased properly.

    Ayoub CheggariAuthorAnswer
    Graduate II
    January 14, 2022

    I was suspecting it to be a read issue, but when I write with SPI using cmd (02h), I can read data correctly.

    Speaking about the erase, when I execute the Block Erase cmd (D8h), the bits are set to 0 not 1 which is very strange. I will do as you proposed thanks @Community member​  for supporting as always !

    Visitor II
    December 1, 2023

    Dear Ayoub,

    I'm working on functions to read from W25N01GVZEIG and write to it but I have some issues with the them. Now, I'm trying to write a function which gets page address and column address, and data, to write that data in the certain address. Next, I want to read data. I use the following functions:

    By w25qxx_peripheral I mean W25N01GVZEIG peripheral.

     

    void my_write_page_function(w25qxx_peripheral* per, uint8_t * pBuffer,
    uint16_t data_size,
    uint16_t page_address)
    {
     
    W25qxx_WriteEnable(per);
    HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_RESET);
     
    W25qxx_Spi(per, 0x02); //load data program
     
    W25qxx_Spi(per, (page_address >> 8) & 0xFF);
    W25qxx_Spi(per, page_address & 0xFF);
     
    for (int i = 0; i < data_size; i++)
    {
    W25qxx_Spi(per, pBuffer[i]);
    }
     
    // HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_SET);
    //
    // HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_RESET);
     
    W25qxx_Spi(per, 0x10); //program execute
    W25qxx_Spi(per, W25QXX_DUMMY_BYTE);
     
    W25qxx_Spi(per, (page_address >> 8) & 0xFF);
    W25qxx_Spi(per, page_address & 0xFF);
     
    HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_RESET);
     
    }
     
    //###################################################################################################################
     
    void my_read_page_function(w25qxx_peripheral* per, uint8_t * pBuffer,
    uint16_t data_size,
    uint16_t page_address)
    {
    HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_RESET);
     
    W25qxx_Spi(per, 0x13); //page data read
    W25qxx_Spi(per, W25QXX_DUMMY_BYTE);
     
    W25qxx_Spi(per, (page_address >> 8) & 0xFF);
    W25qxx_Spi(per, page_address & 0xFF);
     
    // HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_SET);
    //
    // HAL_Delay(25000);
    //
    // HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_RESET);
     
    W25qxx_Spi(per, 0x03); //read data
     
    W25qxx_Spi(per, (page_address >> 8) & 0xFF);
    W25qxx_Spi(per, page_address & 0xFF);
     
    W25qxx_Spi(per, W25QXX_DUMMY_BYTE);
     
    HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_SET);
     
     
    }

     

     

    Would you please send the functions? Thank you in advance.

    Graduate II
    December 1, 2023

    How's it going to determine what's data, and what's the next command if the chip select doesn't transition?

    https://datasheet.lcsc.com/lcsc/1809200036_Winbond-Elec-W25N01GVZEIG_C88868.pdf

    Visitor II
    December 1, 2023

    thank you for your consideration. so you mean I have to uncomment following lines?

    // HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_SET);
    //
    // HAL_GPIO_WritePin(per->cs_gpio, per->cs_pin, GPIO_PIN_RESET);
     
    I did it but it does not work :(
    Graduate II
    December 1, 2023

    >>I did it but it does not work :(

    Ok, but that's not very enlightening. But what DOES happen? You have a scope or logic analyzer on this? The signals at the pins functioning?

    Do you have code to read the JEDEC ID off the part, going to be command 0x9F? Does that function? Does it return 0xFF patterns

    There's like some minimal delay between rising and falling again on the CS, but you definitely can't go ploughing onward. The CS falling designates the start of a new command transaction.

    BTW the thread is using the QSPI Peripheral

    Graduate
    December 30, 2023

    hello. could you solve your problem? If so would you please help me or send me a link to a working qspi driver for W25N01? I asked a Question W25N01xxxIG Driver for STM32H7 - STMicroelectronics Community

    Visitor II
    January 2, 2024

    Hello Zakba.1
    Actually I am working on standard SPI for W25N NAND memory. I don't know how the QSPU supposed to work. I have some problems with writing on this memory (Load program Data & Program Execute). Did you solve it?
    Thank you.

    Graduate
    January 3, 2024

    hello hedinik

    No, because I wanted to use it in memory-mapped mode But Tesla said that It couldn't be used in this mode so I gave it up. I decided to use W25q512 instead.