Showing results for 
Search instead for 
Did you mean: 

Cannot write to Micron NOR flash

Associate II

I’m trying to write data to the [MT25QL512ABB NOR flash]( using an STM32H7 chip, but the flash keeps returning a PROGRAM error and the write does not go through.


I am using the command 0x34, the 4-BYTE QUAD INPUT FAST PROGRAM command. I am then polling the flag status register after issuing the command, which returns a value of 0x91 on the flag status register. This means that the PROGRAM error bit is set, indicating the program command was not successful, and indeed this is verified by reading from the flash chip.


The specifics of the 0x34 command are as follows:

CMD: 0x34

ADDRESS: 0x00004400 (4-byte address mode)

DATA: 128 bytes, numbers 0x00 - 0x7F

Here’s a screenshot of the command as well as the first four data bytes. The command is issued in quad mode:




After the data bytes are sent, the status and flag status registers are then polled.

It takes about 4.2 milliseconds for the status register to go from 0x03 to 0x00 and for the flag status register to go from 0x01 to 0x91. Here’s a screenshot of that:



You’ll notice I read each of the registers twice, this is because the STM32 cannot go from writing to reading without 1 dummy cycle in between. So I read these registers twice and take the second reading as correct (in this case the two reads were identical, but this is not always the case). The datasheet indicates these registers can be read continuously. Though I only read them twice before re-issuing the command (so I can switch between reading the status and flag status registers).


Prior to this 0x34 command I have done the following:

Written (and verified) these values to the configuration registers:

  • volatile configuration: 0xFB (default dummy cycles, no XIP, no wrap)
  • enhanced volatile configuration: 0x2F (quad mode, STR, no RESET# on DQ3)
  • status register: 0x02 (activated by calling the WRITE ENABLE COMMAND: 0x06)
  • Cleared the flag status register of error bits (using 0x50 command)


I have also verified that all volatile lock bits are set to 0. The nonvolatile lock bits are set to 1 for every address, the global freeze bit is 1, and the sector protection register is 0xFFFF.

But the error bit for sector protection on the flag register (bit 1) is not set anyway, which I assume means this error is not caused by misconfigured sector protection.


I can’t figure out why this 0x34 command causes a PROGRAM error and refuses to write to the flash.

ST Employee

Hello @ryansrichai welcome to the community 🙂,

Could you please give more details about the mode and the device:

- Which mode are you using: indirect mode or Automatic-polling mode?

- Which STM32H7 are you using?

Could you please check the STM32H7 errata sheet and the max Quad SPI frequency mentioned in the STM32H7 datasheet and in the memory datasheet precisely for 4-BYTE QUAD INPUT FAST PROGRAM.

I advise you to take a look at QSPI_ReadWrite_IT  example an help you.

Thank you.


To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Edit/Nevermind.. Check and report content of status register, check none of the BPx protection bits are set.

What are the markings on the IC, are we sure this isn't an older dual die part? Would explain need to read falls twice as it alternates between die. Mass Erase would also fail as you need Die Erase to deal with each die individually.

Read the full JEDEC ID bytes including serial#

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I am using an STM32H735ZGT6, indirect mode with OCTOSPI (using four data lines, since it seems like the STM32H735ZGT6 has OCTOSPI but not native QUADSPI). Here is the OCTOSPI HAL setup:


So the prescaler is 128 on a 450MHz clock, which means around 3.5MHz for the OCTOSPI clock, which should be definitely slow enough that it does not cause issues on the controller or peripheral side (here is the table from the Micron flash).


And here's the STM's OCTOSPI frequency table:


And I would imagine that if it's a clock frequency issue, the flash chip would not be able to respond with a 0x91 on the flag status, it probably would just not know what I even sent or have the ability to send back that status.


Here's the function I use to read the device ID from the MT25QL512ABB. This works in both single and quad mode:


And erase functions do succeed, as in, they do not return an error. But that could be because all of the data is already erased (all bits are set to 1) on the flash memory. Curiously, the write functions DO succeed (flag status returns 0x81) but only IF the data you are writing are all 0xFF bytes (so you can write all 1s to the flash which is already what it is, but if you even have a single 0 bit that you try to write then the flag status returns 0x91).

See my response to KDJEM.1 for additional information. TLDR: Erase functions work, I have read the Device ID but only the first four bytes, which are 0x20, 0xBA, 0x20, 0x10. I will read the extended device ID (5th byte) today when I get to the lab, but the only thing useful that could come out of that is whether the HOLD# or RESET# hardware is enabled but I've already disabled those functionality in firmware via the enhanced volatile configuration register (bit 4 is set to 0, since the value is 0x2F):




Hi @ryansrichai ,

Could you please refer to AN5050 precisely section 6.2.4 OCTOSPI configuration and parameter settings table 8. and check the OCTOSPI configuration: Sample shifting, Delay hold quarter cycle and  Chip select boundary...

  • Sample shifting (SSHT) recommended to be enabled in STR mode and disabled in DTR mode
  • Delay hold quarter cycle (DHQC) enabled in DTR mode and disabled in STR mode.
  • Chip select boundary (CSBOUND) configured depending on the memory datasheet. The chip select must go high when crossing the page boundary (2^CSBOUND bytes defines the page size).

Thank you.


To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.