Search code examples
stm32f4jtagopenocd

Openocd how to write option bytes to STM32F4


I have two boards with a STM32F437 (IGH6 7BA4S VQ PHL 7B 542) processor. We program these with openocd and a jtag, however lately one card stopped working. It is no longer possible to program the card and one of the differences we have found is that the user option bytes differ between the cards.

  • 0x0EC On the working card
  • 0xCFC On the broken

What I tried to do is using the options_write command. Note that the STM32F4 apparently goes under the "stm32f2x" command.

openocd -f openocd.cfg -c "reset halt; stm32f2x unlock 0; reset halt; stm32f2x options_write 0 0x0EC"

This resulted in the error message: "Error: stm32x device protected"

In the STM32F437 Reference manual RM0090 under "3.7.2 Programming user option bytes" it says:

To run any operation on this sector, the option lock bit (OPTLOCK) in the Flash option control register (FLASH_OPTCR) must be cleared. To be allowed to clear this bit, you have to perform the following sequence: \n

  • Write OPTKEY1 = 0x0819 2A3B in the Flash option key register (FLASH_OPTKEYR)
  • Write OPTKEY2 = 0x4C5D 6E7F in the Flash option key register (FLASH_OPTKEYR)

The user option bytes can be protected against unwanted erase/program operations by setting the OPTLOCK bit by software.

To do that I tried the following in a telnet session:

  1. mww 0x08 0x08192A3B
  2. mww 0x08 0x04C5D6E7F
  3. mdw 0x0C
  4. mww 0x18 0x0EC
  5. mww 0x14 0x0EC

The 0x08 on line 1 is FLASH_OPTKEYR, 0x0C on line 3 is FLASH_SR to check if BSY bit is not set, 0x14 on line 4 is FLASH_OPTCR1, and 0x14 on line 5 is FLASH_OPTCR.

Then a reboot and trying to program the application openocd -f openocd.cfg -c "program HCF-220_07_010_PA2.hex reset exit"

This results in the error:

Error: stm32x device protected.

I also tried to do the following command to unlock before programming: openocd -f openocd.cfg -c "openocd -f openocd.cfg -c "reset halt; stm32f2x unlock 0; program HCF-220_07_010_PA2.hex reset exit"

Same result:

Error: stm32x device protected.

Update

I tried the following in telnet without luck, the user option is still 0xCFC:

  1. mww 0x40023C08 0x08192A3B
  2. mww 0x40023C08 0x04C5D6E7F
  3. mdw 0x40023c0c
  4. mww 0x40023C18 0x0EC
  5. mww 0x40023C14 0x0EC
  6. mww 0x40023C08 0x02
  7. Power Cycle

In RM0090 chapter 3.7.2 it also says: 4. Set the option start bit (OPTSTRT) in the FLASH_OPTCR register Hence the nr 6. above.


Solution

  • The working solution for me was as follows:

    1. stm32f2x lock 0 Yes lock not unlock.
    2. Do a power cycle
    3. reset init
    4. mww 0x40023C08 0x08192A3B
    5. mww 0x40023C08 0x04C5D6E7F
    6. mdw 0x40023c0c Wait for flash write to finish, make sure we receive 00000000
    7. mww 0x40023C18 0x0FFF0000
    8. mww 0x40023C14 0x0FFFAAEC Write user_options to same as a working
    9. mww 0x40023C14 0x0FFFAAEE Set option start bit, step "4." in rm0090.
    10. mdw 0x40023c0c Wait for flash erase to finish, make sure we receive 00000. This takes about 10 seconds.
    11. Do a power cycle

    The reason why it did not work with OpenOCD command "options_write", can be found in the manual for OpenOCD. The "user_options" argument takes the bits 31-28 and 7-0 from FLASH_OPTCR.