uC: STR912
I am having trouble programmatically setting the OTP lock bit (ie not using JTAG/CAPS to set the lock, but by using firmware running on the STR912 itself). I can read and write the OTP fine, but I cannot set the OTP lock bit.
The ST-supplied library does not provide this function, but the FLASH programming manual downloaded from ST shows the following steps:
1. write 0xC0 to any word address in bank 1 (eg FMI_BANK_1) 2. write 0x01 to any word address in bank 1 whose LSB is 0x08 (eg FMI_BANK_1 | 0x08) 3. poll PECS until operation complete 4. read status 5. write 0x50 to any word address in bank 1 to clear status 6. write 0xff to any word address in bank 1 to return to READ mode
This procedure does not seem to set the LOCK in that I can still further program OTP after doing this. The really odd thing is that the sequence above is exactly the same sequence of operations as to program the value 0x0001 into OTP locations 0x08 and 0x09 (and I do indeed seem to have 0x0001 in locations 0x08 and 0x09) so this documented procedure must be wrong (or I have misinterpreted it).
Can anyone tell me the correct procedure?
Christopher Hicks ==
For programming the OTP features you need to use ICP algorithms. The configuration is then done with the STR91xCFG.s file. See here: http://www.keil.com/support/docs/3286.htm
Thanks Reinhard. I know I *can* set the OTP lock bit using uVision/uLink (or with CAPS/RLink) like that but on our production line, the unit we are building will be fully assembled when we need to program OTP, so there will be no access for the uLink cable!
To solve this, I want to program the OTP using a program running on the ARM itself (ie IAP). My code for writing & reading the OTP itself works, but the code for programming the OTP LOCK does not. The FLASH programming manual says I can do this, but I think the description it gives of how to do it is wrong, because the sequence it gives actually programs an OTP half-word, not the lock bit.
I know this is not a Keil/Realview/uVision problem, but there is a lot of STR912 expertise here, so I was hoping someone here would know how to do this!
Christopher Hicks
#define M16(adr) (*((volatile unsigned short *) ((adr)&~1))) // do a half-word access to a half-word address #define M32(adr) (*((volatile unsigned short *) ((adr)&~3))) // do a half-word access to a word address unsigned char WriteOTPHalfWord(u32 adr, u16 data) { unsigned char status = 0; adr += FMI_BANK_1; M32(adr) = 0xc0; // program OTP half-word command M16(adr) = data; // write the data delay(); while (!(M32(adr) & 0x80)) { // wait for operation finish } status = M32(adr); // read status delay(); M32(adr) = 0x50; // clear Status Register delay(); M32(adr) = 0xff; // return to read array mode delay(); return status; } u32 ReadOTPWord(u32 adr) { u32 OTP_Data; adr += FMI_BANK_1; M32(adr) = 0x98; // switch to read OTP mode OTP_Data = *(vu32*)(adr & ~3); // read the data M32(adr) = 0xff; // return to read array mode delay(); return OTP_Data; } unsigned char LockOTP(void) { unsigned char status = 0; M32(FMI_BANK_1) = 0xc0; // write OTP delay(); M32(FMI_BANK_1 | 0x0008) = 0x01; // lock OTP delay(); while (!(M32(FMI_BANK_1) & 0x80)) { } // wait for operation finish status = M32(FMI_BANK_1); // read status delay(); M32(FMI_BANK_1) = 0x50; // clear Status Register delay(); M32(FMI_BANK_1) = 0xff; // return to read array mode delay(); return status; }
My understanding to the issue is that for the extended features you need the ICP mode (direct access to the Flash ROM). Maybe you post this question to an ST forum.
Yes, I have done already. If I get an answer I'll copy it here in case it is useful for anyone else.
This sounds like a question to send to an ST support engineer.