2024-07-17 04:44 AM
We got the STM32MP157F-EV1 and struggle a bit with the understanding of OTPs.
We cloned the STM32PRGFW-UTIL repository [1], put the dip switches into "forced USB boot for flashing" mode (all off) and uploaded the provided image:
STM32PRGFW-UTIL\Projects\STM32MP15xx\Binary> stm32_programmer_cli -c port=usb1 -w .\FlashLayout_STM32PRGFW_UTIL.tsv
That works great and we can query a register like this:
stm32_programmer_cli -c port=usb1 -otp displ word=93
We then tried writing to it:
> stm32_programmer_cli -c port=usb1 -otp write word=93 value=0xF0
and querying again shows the correct value:
| Data93 : 0x000000F0
| Status93 : 0x00000000
We tried writing a second time with a similar value
> stm32_programmer_cli -c port=usb1 -otp write word=93 value=0xF1
and the value changed as expected:
| Data93 : 0x000000F1
| Status93 : 0x00000000
Then we wrote 0xF0, 0xF1 and 0x01 again just to see what happens. The Register still reads 0xF1, so nothing changed.
Adding just one bit and writing 0x02 did nothing and the value still read 0xF1 (we did expect 0xF3).
Writing 0x100 did nothing (instead of the expected 0x1F1)
At last we tried 0x1F1 (so setting all the current bits plus one new)
> stm32_programmer_cli -c port=usb1 -otp write word=93 value=0x1F1
Output of that command tells us, everything went fine:
OTP Partition read successfully
OTP words programming done successfully
But reading the value now shows an error
| Data93 : 0x00000000
| Status93 : 0x00000001
|_[00] Invalid
In the end we need to set one bit in register 18 to enable the watchdog but this experiment lets us think that we are doing something wrong. So we really want to make sure we are not getting register 18 to an invalid state.
Is it just the fact that we wrote multiple times to one register? Did we miss or misunderstand anything?
------------
[1] https://github.com/STMicroelectronics/STM32PRGFW-UTIL
Solved! Go to Solution.
2024-07-18 12:59 AM
Hi @Daniel S.
what you see sound logical,
upper OTPs (>31) cannot be reprogrammed (there is ECC behind those one, which if becoming bad make the OTP invalid on next reload from fuse array).
Lower OTPs (<32) does not have ECC, but redundancy which make them using more HW ressources, but allows bit per bit programming.
I agree that tool might have been more clever to avoid this.
on upper OTPs (31 to 95), trying to re-program them with a different value is not possible (usually you should permanently write lock once programmed).
On lower OTPs (0 to 31), you could only sets new bits to '1', but once set, a bit cannot be cleared (this is intrinsic to the fuses, which cannot be cleared).
Refer to reference manual
Regards.
2024-07-18 12:59 AM
Hi @Daniel S.
what you see sound logical,
upper OTPs (>31) cannot be reprogrammed (there is ECC behind those one, which if becoming bad make the OTP invalid on next reload from fuse array).
Lower OTPs (<32) does not have ECC, but redundancy which make them using more HW ressources, but allows bit per bit programming.
I agree that tool might have been more clever to avoid this.
on upper OTPs (31 to 95), trying to re-program them with a different value is not possible (usually you should permanently write lock once programmed).
On lower OTPs (0 to 31), you could only sets new bits to '1', but once set, a bit cannot be cleared (this is intrinsic to the fuses, which cannot be cleared).
Refer to reference manual
Regards.
2024-07-18 01:23 AM
Thanks for the explanation. We understood that bits can not be reset to 0 but thought that setting single bits might also possible in the upper registers.
So it was basically just luck that the first reprogramming (going from 0xF0 to 0xF1) worked. It should already have invalidated the register.