nRF52840 Plus - using pins D14 and D15 as GPIO

The pinout for the nRF52840 has the NFC pins D14 and D15 also labeled as RX1 and TX1, so presumably they can be used as general GPIO ?

I am using the SEEEED NRF52 Boards Arduino core, 1.1.10.

How do I set the D14 and D15 pins as GPIO, if I blink them nothing happens.

1 Like

D14 and D15 can be used as GPIO on the nRF52840 Plus, but you must explicitly set them to GPIO mode in your sketch instead of using their default UART/NFC function.

Do you know how exactly you set D14 and D15 to GPIO in a sketch ?

Hi there,

So, The reason nothing happens is that D14 and D15 are the NFC pins on the nRF52840, and those pins are not normal GPIO by default.

On the nRF52840, these are P0.09 and P0.10, and Nordic notes that they must be switched from NFC mode to GPIO mode before you can use them as regular pins.

So yes, they can be used as GPIO, but first you need to disable NFC pin mode.

What to do

For nRF52, the usual way is to enable:

CONFIG_NFCT_PINS_AS_GPIOS

That is the standard Nordic mechanism for making the NFC pins usable as GPIO

Important practical note

On Arduino cores, this is sometimes not exposed cleanly as a sketch-level option, because it is really a UICR / board configuration setting, not just a normal pinMode() call. That means:

  • pinMode(D14, OUTPUT);
  • digitalWrite(D14, HIGH);

by themselves may do nothing until the NFC function is disabled first.

Also worth noting

Seeed’s NFC wiki for the XIAO nRF52840 explicitly identifies the NFC pins as P0.09 and P0.10 and treats them as the NFC interface pair.

They will NOT work as GPIO until NFC is disabled.

Flash a sketch that forces NFC → GPIO using Nordic register:

#include <nrfx.h>
#include <nrf.h>

void setup() {
  // Disable NFC, enable GPIO on P0.09 / P0.10
  NRF_UICR->NFCPINS = 0xFFFFFFFE;
  NVIC_SystemReset();  // Apply change
}

void loop() {}

:backhand_index_pointing_right: Upload this ONCE
:backhand_index_pointing_right: Board will reset
:backhand_index_pointing_right: After that, pins behave as normal GPIO

Test sketch (blink both pins)


#define PIN_D14 14
#define PIN_D15 15

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("Testing D14 / D15 GPIO...");

  pinMode(PIN_D14, OUTPUT);
  pinMode(PIN_D15, OUTPUT);
}

void loop() {
  Serial.println("ON");
  digitalWrite(PIN_D14, HIGH);
  digitalWrite(PIN_D15, HIGH);
  delay(1000);

  Serial.println("OFF");
  digitalWrite(PIN_D14, LOW);
  digitalWrite(PIN_D15, LOW);
  delay(1000);
}

input test (if they wired buttons)

#define PIN_D14 14

void setup() {
  Serial.begin(115200);
  pinMode(PIN_D14, INPUT_PULLUP);
}

void loop() {
  Serial.println(digitalRead(PIN_D14));
  delay(500);
}

Bottom Line…

  • P0.09 / P0.10 default = NFC antenna pins
  • They are disconnected from GPIO hardware
  • Writing UICR flips them permanently to GPIO mode

Practical notes (from experience)

  • This setting survives reset and reflash
  • Only needs to be done once per board
  • If they ever want NFC back → they must reprogram UICR

HTH
GL :slight_smile: PJ :v:

YMMV on the BSP used..:crossed_fingers:

Thanks for that.

Tried the write to the NRF52840 register sketch and whilst it runs, and the board does reset on the ‘NVIC_SystemReset();’ command, I still cannot blink D14, D15. I can blink D13 and D16.

Tried the Seeed NRF52 Boards and Seeed NRF52 mbed-enabled Boards cores.

HI there,
Which BSP’s I would roll back to an older one.
See if that yield any better results , You are on the trails for sure with the cores..:+1:

HTH
GL :slight_smile: PJ :v:

There is a solution to this issue, at least it works on the NRF52840 Plus boards I have.

Tech support have said that ‘D14 and D15 are configured as GPIO by default’, but that appears not to have been the case on my boards.

After quite a bit of searching I found this note;

https://embeddedartistry.com/blog/2019/04/17/exploring-startup-implementations-newlib-arm/

“If NFC is not used for an nRF52 platform, the associated NFC pins are configured as normal GPIO.”

And this code is provided;

if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == 
		(UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos))
    {
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
        NVIC_SystemReset();
    }

When executed in a Arduino sketch the NFCPINS Register does change from 0xFFFFFFFF to 0XFFFFFFFE which is the change needed to make the NFC pins operate as GPIO.

However its a one way change, if you want to go back to using D14 and D15 as NFC you need to restore the UICR configuration. Probably this requires a full erase and programming of the chip using a J-Link.