cancel
Showing results for 
Search instead for 
Did you mean: 

OTP went to invalid

Daniel S.
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
PatrickF
ST Employee

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

PatrickF_0-1721289241616.png

 

Regards.

In order 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.

View solution in original post

2 REPLIES 2
PatrickF
ST Employee

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

PatrickF_0-1721289241616.png

 

Regards.

In order 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.
Daniel S.
Associate II

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.