2023-08-22 06:59 AM
Hello,
we are trying to flash the external NOR flash at address 0x90000000 with Openocd 2-times and get an error at the second flash try:
Open On-Chip Debugger
> program /home/xyz/kr.elf
[stm32h750xbh6.cpu0] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08007904 msp: 0x20020000
** Programming Started **
Device: STM32H74x/75x
flash size probed value 128k
STM32H7 flash has a single bank
Bank (0) size is 128 kb, base address is 0x08000000
flash1 'micron mt25ql512' id = 0x20ba20 size = 65536 KiB
flash2 'micron mt25ql512' id = 0x20ba20 size = 65536 KiB
Adding extra erase range, 0x90052d7c .. 0x9005ffff
** Programming Finished **
> program /home/xyz/kr.elf
[stm32h750xbh6.cpu0] halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08007904 msp: 0x20020000
** Programming Started **
Adding extra erase range, 0x90052d7c .. 0x9005ffff
Cannot write enable flash1. Status=0x55
Flash sector_erase failed on sector 0
failed erasing sectors 0 to 2
embedded:startup.tcl:1516: Error: ** Programming Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 1581
at file "embedded:startup.tcl", line 1516
>
Openocd was start with:
openocd -c "gdb_port 50000" -c "tcl_port 50001" -c "telnet_port 50002" -f board/stm32h750b-disco.cfg
and connect via telnet.
When we flash one-times and start then our application at 0x08000000 all works fine. The app in internal flash init the qspi and jumps to 0x90000000 and starts the application. All works fine. But as you can see it's not possible to flash the external flash 2-times in a row. If we try this and starts then the internal application it's not possible to init the memory. The only thing that brings the external flash back to work is to use ST cube programmer and read from 0x90000000.
Has anyone made the same experience?
Setup:
Thanks!
2023-08-22 07:23 AM
>>If we try this and starts then the internal application it's not possible to init the memory. The only thing that brings the external flash back to work is to use ST cube programmer and read from 0x90000000.
Suggests you're walking the device into a mode that subsequent usage can't recover, or leaving a device busy mid-erase.
Say you've pushed it into 4-bit / 4-byte mode, and then expect 1-bit / 3-byte mode addressing to work.
Perhaps your code needs to refine the reset process, or determine what mode the memory is in, before proceeding?
2023-08-22 08:05 AM
Yes maybe thats the problem when the internal app starts and tries to init the memory. (by the way we using this in default config: https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H750B-DK/Templates/ExtMem_Boot)
But what is astonishing that the Openocd is unable to flash 2-times in a row. It looks like the Openocd it also not able to set up the memory well for a second flash.
We also debug a little bit more the ExtMem_Boot app and can see (after we tried to flash the second time) that the app stucks to run:
2023-08-22 09:03 AM
Yeah, I don't know what OPENOCD or related TCL scripts know about your hardware or pins. Seems to identify the two parts, but might not be able to address them individually, some devices / boards will expect them to be used consistently in DUAL mode, and that will complicate the WRITE, ERASE and wait for BUSY implementation, as the devices are not synchronous (one might complete before the other, especially ERASE/CHIP ERASE where the content might drive time to completion significantly). The TL is two die within one package.
Would suggest reviewing and understanding the scripts in the context of how the chips are attached.
2023-08-22 11:19 AM
Well, the stmqspi driver and the related scripts expect the external flash to be in "power-up" configuration. If your application reconfigures the flash (i.e. changes number of dummy cycles, switches to 4-line mode, protect some sectors, ...) your programming script (the tcl script which comes with openocd) has to revert the flash to original configuration - and/or go through power-up reset. That's unpleasant, indeed, but most SPI flash don't have a dedicated reset pin, or even is so, it's rarely connected in a known way. As there are a lot of ways to reconfigure the flash it's rather impossible to write a universal (for all types of flash) "reset script". So, check your application and see how to revert the configuration it applies. The 0x55 suggests 4-line mode vs. 1-line mode mismatch.
2023-08-25 06:04 AM
Yes, I think you are right.
It will be very interesting to see how the ST Cube Programmer reset the external flash. Because it's works fine every time and would be nice to copy the sequence. ;)
2023-08-25 10:35 AM
Well, simply collect from major manufacturer's datasheets the reset (or similar) commands and send all of them "blindly" to the flash, one after another in 2-line and 4-line mode. This will cover most cases - unfortunately not all. And there is a small chance that an "exotic" device might misbehave upon receiving an unsupported command.
It's different if you already know the type of flash and what your application does, then you can simply revert that in the programming setup.
2023-08-25 02:15 PM
2023-08-28 12:54 AM
I use the reset sequence and debuged it and it looks ok. But after the reset it's not possible to activate the 4 byte address mode:
https://github.com/STMicroelectronics/stm32-external-loader/blob/e94cf9aff79165843d46fe140524ca57749e73eb/STM32H7x_boards/MT25TL01G_STM32H747I-EVAL/Sources/Library/stm32h747i_eval_qspi.c#L169
As the datasheet of the mt25tl01g mentioned:
"To reset the device, the RESET ENABLE command must be followed by the RESET MEMORY
command. When the two commands are executed, the device enters a power-on reset condition.
It is recommended to exit XIP mode before executing these two commands."
I tried to deactivate the XIP before the reset but it's also not worked.
2023-08-28 07:42 AM
I think there must be also a problem in OpenOcd. I tried to flash hex file which is delivered with the board:
https://www.st.com/resource/en/compiled_demos/stm32h750b-dk_demo.zip
The first time works. The second time not:
Is it necessary to do something in between the both program calls?