In adding some security features to my project, I was reading the Code Security page, and read that SW_GP1 and GP3 fuses are recommended to store identity data. I also noticed that the FuseWrite code generated when putting a Lockable Teensy in Secure Mode writes the GP3 fuses with the flash memory chip's unique ID.
However, when I went to write to the fuses myself, they consistently read back 0s afterwards, despite being unlocked. Even reading the fuses from a Teensy 4.1-like board in secure mode would return 0s, showing that the attempt by FuseWrite to set them to the flash ID failed (note this is a custom PCB, and a chip from NXP, not PJRC).
My code is able to write and lock the SW_GP1 fuses fine, however when it comes to GP3, they seemingly cannot be written to. I assume I must be misinterpreting something, and that this is by design, but I'm not entirely sure what I've missed. I've skimmed through the datasheet's pages on the GP3, GP3_LOCK, SW_GP1, and SW_GP1_LOCK fuses, as well as looked through the NXP and PJRC forums, but can't seem to find an answer.
The reason I'm posting this here (and not on NXP's own forums) is that on a stock Teensy 4.1 and 4.0 (both non lockable), I was able to write and lock SW_GP1's fuses, but once again couldn't write GP3's.
Here is the code used for GP3 writing:
And the output from running this code on a Teensy 4.1/4.0 (non-lockable), or the custom board (rt1062 from NXP) in secure mode:
However, when I went to write to the fuses myself, they consistently read back 0s afterwards, despite being unlocked. Even reading the fuses from a Teensy 4.1-like board in secure mode would return 0s, showing that the attempt by FuseWrite to set them to the flash ID failed (note this is a custom PCB, and a chip from NXP, not PJRC).
My code is able to write and lock the SW_GP1 fuses fine, however when it comes to GP3, they seemingly cannot be written to. I assume I must be misinterpreting something, and that this is by design, but I'm not entirely sure what I've missed. I've skimmed through the datasheet's pages on the GP3, GP3_LOCK, SW_GP1, and SW_GP1_LOCK fuses, as well as looked through the NXP and PJRC forums, but can't seem to find an answer.
The reason I'm posting this here (and not on NXP's own forums) is that on a stock Teensy 4.1 and 4.0 (both non lockable), I was able to write and lock SW_GP1's fuses, but once again couldn't write GP3's.
Here is the code used for GP3 writing:
C++:
#include <Arduino.h>
const uint32_t to_write[4] = {
0x12345678,
0x87654321,
0xABCDEF12,
0x12ABCDEF
};
void setup() {
Serial.begin(1000000);
while (!Serial && micros() < 2000) {}
if (HW_OCOTP_LOCK & 0x0C000000) {
Serial.println("GP3 is locked");
} else {
if (HW_OCOTP_GP30 == 0 &&
HW_OCOTP_GP31 == 0 &&
HW_OCOTP_GP32 == 0 &&
HW_OCOTP_GP33 == 0) {
Serial.printf("Setting GP3 to: 0x%lX, 0x%lX, 0x%lX, 0x%lX\n", to_write[0], to_write[1], to_write[2], to_write[3]);
IMXRTfuseWrite(&HW_OCOTP_GP30, to_write[0]);
IMXRTfuseWrite(&HW_OCOTP_GP31, to_write[1]);
IMXRTfuseWrite(&HW_OCOTP_GP32, to_write[2]);
IMXRTfuseWrite(&HW_OCOTP_GP33, to_write[3]);
Serial.println("Wrote GP3");
} else {
Serial.printf("GP3 already had value: 0x%lX, 0x%lX, 0x%lX, 0x%lX\n", HW_OCOTP_GP30, HW_OCOTP_GP31, HW_OCOTP_GP32, HW_OCOTP_GP33);
}
}
IMXRTfuseReload();
if (HW_OCOTP_GP30 == to_write[0] &&
HW_OCOTP_GP31 == to_write[1] &&
HW_OCOTP_GP32 == to_write[2] &&
HW_OCOTP_GP33 == to_write[3]) {
Serial.println("GP3 is correctly set");
} else {
Serial.printf("GP3 is incorrectly set to: 0x%lX, 0x%lX, 0x%lX, 0x%lX\n", HW_OCOTP_GP30, HW_OCOTP_GP31, HW_OCOTP_GP32, HW_OCOTP_GP33);
}
}
void loop () {}
Code:
Setting GP3 to: 0x12345678, 0x87654321, 0xABCDEF12, 0x12ABCDEF
Wrote GP3
GP3 is incorrectly set to: 0x0, 0x0, 0x0, 0x0