Disabling the NFC pins on nRF52

Copyright © 2024 J. M. Spivey
Jump to navigation Jump to search

The nRF52-family microcontrollers have two pins assigned by default to Near-Field Communication (NFC). On the V2 micro:bit, these are connected to pads 8 and 9 on the edge connector. To use them as GPIO, the NFC connection must be disabled, and this can be done only by changing the setting of a non-volatile register in the User Information/Configuration space (UICR) and then resetting the microcontroller.

The steps are as follows:

  • If the register UICR_NFCPINS does not contain 0, then the fix is needed.
  • Enable writing to the UICR resgisters by setting NVMC_CONFIG.
  • Overwrite the UICR_NFCPINS register with zero. (Only the LSB is significant, but all bits are writable.)
  • Wait until the NVMC is no longer busy.
  • Disable writes again (this is safe but maybe not necessary).
  • Request a reset.
  • Wait for the reset to happen.

After the reset, the UICR_NFCPINS register will be seen to contain zero, and the application will start. This fix needs to be activated just once each time the flash is erased and reprogrammed. This code does the trick (see __reset in startup.c):

    /* If NFCT pins are reserved, fix it and reset */
    if (UICR_NFCPINS != 0) {
        NVMC_CONFIG = NVMC_CONFIG_Wen;
        UICR_NFCPINS = 0;
        while (! NVMC_READY) { }
        NVMC_CONFIG = NVMC_CONFIG_Ronly;
        sysreset();
        while (1) { }           // Wait for the reset to take effect
    }        

The sysreset() macro is defined by

#define sysreset()  SCB_AIRCR = FIELD(SCB_AIRCR_VECTKEY, 0x05fa) \
        	            | BIT(SCB_AIRCR_SYSRESETREQ)

It works by setting the SYSRESETREQ bit in the Application Interrupt and Reset Control Register, part of the System Control Block. To enable this setting, the magic number 0x05fa must simultaneously be written to the VECTKEY field of the same register.