TG9541/stm8ef

STM8L: ULOCKF/NVM freeze when bootloader enabled (known errata)

yumkam opened this issue · 1 comments

According to, "STM8AL3xx6/8 STM8Lx5xx4/6 Errata sheet", section 1.2.6, "Program memory are write unprotected after reset when embedded bootloader enabled", if bootloader is enabled, it

  1. leaves flash unprotected upon reset/boot;
  2. writes incorrect sequence into FLASH_PUKR register;
    And once you write incorrect sequence into FLASH_PUKR, it is not possible to recover till reset (correct sequence will be ignored).
    As a result, LOCKF ULOCKF (or NVM RAM NVM) results in freeze (flash is unprotected upon reset --- unlock sequence is ignored, but initially FLASH_IAPSR.PUL==1, so first NVM succeeds, then LOCKF protects flash, then ULOCKF cannot unprotect it again, and waits forever for FLASH_IAPSR.PUL).
    (I verified this on STM8L151K6, rev.Y)

Possible workarounds:

  1. suggest to disable bootloader (use stlink/SWIM instead, etc) in documentation;
  2. turn LOCKF into no-op (for affected parts);
    2a) remember previous state in ULOCKF and keep it unprotected in LOCKF if saved state was unprotected: on affected parts flash is unprotected upon reset/boot, and it will remain unprotected; on unaffected parts, ULOCKF ... LOCKF will work as before.
  3. ignore: it is stm8l bootloader firmware issue, not a stm8ef bug;

@yumkam I've never worked with the serial bootloader, so thanks for analyzing and reporting this issue!

Since it extends the current use-case (initial flashing through SWIM) but works around a bug in the STM8L "Medium density" boot-ROM, I classify it as an "enhancement".

Regarding the proposed workarounds:

  1. accepted, I'll add that to the docs
  2. possibly, see below
  3. rejected, your work shall not be in vain :-)

Regarding 2: maybe there are even more solution options:

  • quick fix: tentatively write a RET to LOCKF after flashing by entering "$81 ' LOCKF C!" (this can be reversed by writing $72).
  • upon reset check if the flash is unlocked and issue a reset, e.g.:
\ ?fix#409 resets a device when Flash is hard-unlocked by STM8L boot-ROM
\res MCU: STM8L151
\res export FLASH_IAPSR
#require ]B@IF
: ?fix#409 ( -- ) [ FLASH_IAPSR 1 ]B@IF [ 0 C, ] THEN ;

It's of course possible to anchor ?fix#409 in the startup chain, e.g. (: init ?fix#409 hi ; ' init 'BOOT).

  • It would also be possible to put reset code in BOARDINIT (in boardcore.inc in the board configuration folder)
  • detecting and saving the unlocked state during cold start is possible but it would require some more considerations. Please check if one of the solutions above would be viable.

@yumkam please check if one of the options works for someone who uses the boot-ROM.