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).

Table 16-4. NVMKEY Register Unlocking and WREN
OperationWREN SettingUnlock Sequence Required
Changing value of NVMOP[3:0] (NVMCON[3:0])0No
Setting WR (NVMCON[15]) to start a write or erase operation1Yes
Changing any fields in the NVMPWP* registerYes
Changing any fields in the NVMLBWP registerYes

The user must follow the following steps in the exact order as shown to enable writes to registers that require this unlock sequence:

  1. Write 0x00000000 to NVMKEY.
  2. Write 0xAA996655 to NVMKEY.
  3. Write 0x556699AA to NVMKEY.
  4. 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.

Initiate NVM Operation (System Unlock Sequence Example):
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);
}
Note: After writing the unlock codes to the NVMKEY register, the next activity on the same peripheral bus as the Flash Controller resets the lock. As a result, the user can only use the atomic operations. Use of the NVMCONSET register sets the WR bit in a single instruction without changing other bits in the register. Using NVMCONbits.WR = 1 fails as this line of code compiles to a read-modify-write sequence.