Skip to main content
Vsv.1
Associate II
September 17, 2020
Solved

QSPI of STM32L496A

  • September 17, 2020
  • 7 replies
  • 6611 views

Hi I have interfaced STM32L4 qspi with Winbond(W25N01GV). I am using HAL api's. The problem is erase/write to a page(2KB) address(say 0x0) repeats to the page after 512 KB(Say 0x80000) and so on.

This is a 128 MiB NAND flash and erase command(D8h) only available for erasing 128KiB block. But what I experienced like it is erasing 2KiB.

I will put my initialization below. I dig so much time on it to find where I goes wrong,

 hqspi.Instance = QUADSPI;

 hqspi.Init.ClockPrescaler = 2;

 hqspi.Init.FifoThreshold = 4;

 hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;

 hqspi.Init.FlashSize = 26;

 hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;

 hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;

 hqspi.Init.FlashID = QSPI_FLASH_ID_1;

 hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;

 if (HAL_QSPI_Init(&hqspi) != HAL_OK)

 {

  Error_Handler();

 }

This topic has been closed for replies.
Best answer by David Garcia

Hi!

I have had to face the same problem and I have found the solution.

The problem is that the microcontroller sends the QSPI command fields in the following order:

  1. Instruction
  2. Address
  3. Alternate bytes
  4. Dummy
  5. Data

But, according to the memory datasheet, some commands (those in which the page address is used) need the address after the dummy bytes, not before. So, in these commands you have to leave the address field empty and send the address at the end as if it were the data.

Hope that helps.

7 replies

Tesla DeLorean
Guru
September 17, 2020

As I recall this memory is not byte addressable, and cannot be used in memory mapped or execute in place, like a NOR Flash would.

This would be usable for data storage only. Would need to review the datasheet and commands to implement suitable driver and manager.​

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Vsv.1
Vsv.1Author
Associate II
September 17, 2020

hi @Community member​ . Thanks for the reply. I am using it for bulk storage only. I have written driver for it and it is working for reading/writing registers in command+address mode. When erasing Block 0, it erases 2 KiB only, as per data sheet given it should erase entire 128 KiB. I don't know whthr my Erase/write or read goes wrong in this case. If I assume erase command is for erasing 2 KiB( against the data sheet), the other problem is there, every page after every 512KB is looks like a clone of the other.

Tesla DeLorean
Guru
September 17, 2020

>>When erasing Block 0, it erases 2 KiB only, as per data sheet given it should erase entire 128 KiB

The commands take different units, and neither are byte addresses.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Vsv.1
Vsv.1Author
Associate II
September 17, 2020

This command take 16 bit page address, nothing else. So it should work. I suspect the use of QSPI for read in this case.

Vsv.1
Vsv.1Author
Associate II
September 17, 2020

I will pin-point the issues below,

1. A data written to Page 0(column 0) appears in all the 512 KiB sections next .(i.e. data written to 0x0 appears, in 0x80000, 0x100000 and so on).

2. Erase command (D8h) is for erasing entire 128KiB block from the page address, but in my case, if I erase 0x0 and read back only 2 KiB is erased.

I have not done BBM (bad block management), will it be significant for causing the above errors.

Tesla DeLorean
Guru
September 17, 2020

I believe I have some of these Winbond 1Gbit NAND devices on hand, an L4 demo would take billable hours.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
David Garcia
David GarciaBest answer
Associate II
October 9, 2020

Hi!

I have had to face the same problem and I have found the solution.

The problem is that the microcontroller sends the QSPI command fields in the following order:

  1. Instruction
  2. Address
  3. Alternate bytes
  4. Dummy
  5. Data

But, according to the memory datasheet, some commands (those in which the page address is used) need the address after the dummy bytes, not before. So, in these commands you have to leave the address field empty and send the address at the end as if it were the data.

Hope that helps.

Vsv.1
Vsv.1Author
Associate II
October 13, 2020

@David Garcia​ 

Hi,

Thanks David for the finding and sharing this.

Is that solved your problem. Are you fixed it in a NAND flash?.

What you told is correct the WINBOND chip 'Page Address' should come after the Dummy Bytes, that I have never thought of.

I have send the Address in the data field in one line and address field NONE. What I have seen is like ERASE in this case is works. But there are incorrect write/read happens(i.e. Bytes indented to write in Page1 (2048th byte) is written to byte somewhere in 300+(I assumes writing a single page may work well)), Also observed that the data written is not retained after the power cycle and the 512KB repetition issue mentioned in post1 also persist still.

Regards,

VSV

David Garcia
Associate II
October 13, 2020

Yes, I fixed the problem and now it works correctly (my microcontroller is a STM32H7).

I've done the following test (I use 4 lines for some instructions):

  1. Read the ID of the flash to check the communication with the memory.
  2. Read the status registers and check the values of every bit.
  3. Set the write enable to write the status register 1.
  4. Write the status register 1 to put bits BP to 0 to quit the write protection (I write the value 0x04).
  5. Read the status registers again to check the last step worked.
  6. Set the write enable again to erase the flash.
  7. Erase one block (the address is block x, page 0 and it goes in the data field).
  8. Read the status register 3 and wait until the bit BUSY of the status register 3 is 0.
  9. Set the write enable to write a page.
  10. Check the BUSY bit in the status register 3.
  11. Program the data buffer in the address 0 (I use the instruction 0x32 with 4 lines).
  12. Check the BUSY bit in the status register 3.
  13. Program execute (0x10) with the address of the block you've just erased and the page 0 (this address goes in the data field).
  14. Check the BUSY bit in the status register 3 and wait until the bit BUSY of the status register 3 is 0.
  15. Page datat read (0x13) to move the data from the page to the data buffer. The page address goes in the field data.
  16. Check the BUSY bit in the status register 3.
  17. Fast Read Quad I/O (0xEB) to read the data from the data buffer. The address is 0.

At the end, you have to read the same data that you writed.

Vsv.1
Vsv.1Author
Associate II
October 13, 2020

@David Garcia​ . Woww, Thanks for the much elaborated reply.

I too checking in the similar fashion.

The difference is in the below areas,

  1. I enables the Buff read mode and ECC enable to status register 2(0x18).
  2. To unprotect everything writing (0x00) to status register 1.
  3. checking with a data buffer of 2.5K to block 0, page 0(2048 bytes) page1(remaining),using 0xD8 for erase, 0x34 for program and 0x6B for read.

I will check with the other commands and come up with the result/findings.

Regards,

SV

David Garcia
Associate II
October 13, 2020

I skip your first step because my memory, by default, already has the value 0x18.

In the status register 1, I only leave the TB bit at 1 (0x04), but according to the table 7.4 of the datasheet, if the BP bits are 0, the value of TB does not matter.

Note that the 0x34 instruction does not reset the data buffer, that is, if you write only 500 bytes, the rest remain with the data that you programmed on the last page. However, the instruction 0x32 does reset the rest of the buffer.

Regards

Ahmet Yasin CİVAN
Associate III
January 5, 2022

is this problem solved?

Ayoub Cheggari
Senior
January 13, 2022