16.12 NVMKEY Register Unlocking Sequence
Important register settings that can compromise the Flash memory if inadvertently changed are protected by a register-unlocking sequence. The user can implement this feature using the NVMKEY register. The NVMKEY register is a write-only register that is used to implement an unlock sequence to help prevent accidental writes or erasures of the Flash memory.
In some instances, the operation is also dependent on the setting of the WREN bit (NVMCON[14]) (see the following table).
| Operation | WREN Setting | Unlock Sequence Required |
|---|---|---|
| Changing value of NVMOP[3:0] (NVMCON[3:0]) | 0 | No |
| Setting WR (NVMCON[15]) to start a write or erase operation | 1 | Yes |
| Changing any fields in the NVMPWP* register | — | Yes |
| Changing any fields in the NVMLBWP register | — | Yes |
The user must follow the following steps in the exact order as shown to enable writes to registers that require this unlock sequence:
- Write 0x00000000 to NVMKEY.
- Write 0xAA996655 to NVMKEY.
- Write 0x556699AA to NVMKEY.
- Write the value to the register NVMCON, NVMCON2, NVMPWP* or NVMLBWP requiring the unlock sequence.
When using the unlock sequence to set or clear bits in the NVMCON register (see step 4). The user must execute steps 2 through 4 without any other activity on the peripheral bus that is in use by the Flash Controller. Disable the interrupts and DMA transfers that access the same peripheral bus as the Flash Controller. In addition, the operation in step 4 must be atomic. Use the Set, Clear and Invert registers, where applicable, for the target register in step 4.
The following code shows code written in the C language to initiate an NVM Operation (NVMOP) command. In this particular example, the WR bit is being set in the NVMCON register and, therefore, must include the unlock sequence.
void NVMInitiateOperation(void)
{
// Disable Interrupts
asm volatile(“di%0” : “=r”(int_status));
uint32_t globalInterruptState= __get_PRIMASK();
// Disable Interrupts
__disable_irq();
NVMKEY = 0x0;
NVMKEY = 0xAA996655;
NVMKEY = 0x556699AA;
NVMCONSET = 1 << 15;// must be an atomic instruction
// Restore Interrupts
__set_PRIMASK(globalInterruptState);
}1 fails as this line of code compiles to a read-modify-write sequence.