Enabling pins P0.0, P0.1, P0.2, P0.3, and P0.19 as GPIO [NRF5340]

Hey y'all,

I'm having trouble enabling these pins as GPIO for our custom nrf5340 board, and from reading around, it's not clear to me as a beginner how to properly configure these pins.

Pins  P0.0 and P0.1 are usually used to operate an oscillator, but our board doesn't need it and instead these pins should operate as GPIO pins. My understanding is that to enable these pins, I need to operate the chip with the internal oscillator which I can do with the following lines in my proj.conf.

CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n

Pins P0.2 and P0.3 are typically used for an NFC antenna, but again, our board doesn't need this functionality and these pins should be configured to be used as GPIO. My understanding is that all I need to do is add the following line to my proj.conf. 

I've read that these pins can only be used in a "secure domain", but I've tried creating different projects types (nrf5340dk_nrf5340_cpuapp_ns and nrf5340dk_nrf5340_cpuapp) and running them to no success. There is probably a misunderstanding here on my part. I get the same results as the following link (https://devzone.nordicsemi.com/f/nordic-q-a/94197/config_nfct_pins_as_gpios-y-doesn-t-work). Please direct me to resources to deepen my understanding of a secure domain so I can fix the issue.

CONFIG_NFCT_PINS_AS_GPIOS=y

Pin P.019 is the most confusing to me. On the dev kit, this pin along with pins P0.20, P0.21, P0.22 are used to make a virtual com port. Other than that though, from the manual, it seems like a normal GPIO pin with no other functionalities. It is unclear to me why this pin is not working. I've done my best to verify that the hardware and connections for this pin on the custom board are working. I'm also unable to toggle this pin on the dev board, despite making the needed physical changes to do so. Is there a setting to enable this particular pin?

If it helps, I'm using VSCode on Ubuntu.

Thanks for the help. I've included the full proj.conf and the overlay file below.

CONFIG_GPIO=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n

# I2C
CONFIG_I2C=y
CONFIG_NRFX_TWIM1=y

CONFIG_PRINTK=y


# Rebooot
CONFIG_REBOOT=n
CONFIG_RESET_ON_FATAL_ERROR=n

CONFIG_NFCT_PINS_AS_GPIOS=y

// To get started, press Ctrl+Space to bring up the completion menu and view the available nodes.

// You can also use the buttons in the sidebar to perform actions on nodes.
// Actions currently available include:

// * Enabling / disabling the node
// * Adding the bus to a bus
// * Removing the node
// * Connecting ADC channels

// For more help, browse the DeviceTree documentation at https://docs.zephyrproject.org/latest/guides/dts/index.html
// You can also visit the nRF DeviceTree extension documentation at https://nrfconnect.github.io/vscode-nrf-connect/devicetree/nrfdevicetree.html
/ {
	userpins {
		compatible = "gpio-keys";
		ex1: ex_1 {
			gpios = <&gpio0 20 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 1";
		};
		ex2: ex_2 {
			gpios = <&gpio0 21 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 2";
		};
		ex3: ex_3 {
			gpios = <&gpio0 22 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 3";
		};
		ex4: ex_4 {
			gpios = <&gpio0 23 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 4";
		};
		ex5: ex_5 {
			gpios = <&gpio0 24 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 5";
		};
		ex6: ex_6 {
			gpios = <&gpio0 25 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 6";
		};
		ex7: ex_7 {
			gpios = <&gpio0 26 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 7";
		};
		ex8: ex_8 {
			gpios = <&gpio0 27 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 8";
		};
		ex9: ex_9 {
			gpios = <&gpio0 28 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 9";
		};
		ex10: ex_10 {
			gpios = <&gpio0 29 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 10";
		};
		ex11: ex_11 {
			gpios = <&gpio0 30 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 11";
		};
		ex12: ex_12 {
			gpios = <&gpio0 31 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "External pin 12";
		};
		enl: en_l {
			gpios = <&gpio1 4 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Enable LED Mux";
		};
		mux0: mux_0 {
			gpios = <&gpio1 5 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "LED Mux select 0";
		};
		mux1: mux_1 {
			gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "LED Mux select 1";
		};
		mux2: mux_2 {
			gpios = <&gpio1 7 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "LED Mux select 2";
		};
		smux0: smux_0 {
			gpios = <&gpio1 8 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Stepper Mux select 0";
		};
		smux1: smux_1 {
			gpios = <&gpio1 9 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Stepper Mux select 1";
		};
		smux2: smux_2 {
			gpios = <&gpio1 10 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Stepper Mux select 2";
		};
		smux3: smux_3 {
			gpios = <&gpio1 11 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Stepper Mux select 3";
		};
		ens: en_s {
			gpios = <&gpio1 12 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Enable stepper motors";
		};
		clks: clk_s {
			gpios = <&gpio1 13 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Clock for stepper motors";
		};
		steps: step_s {
			gpios = <&gpio1 14 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Step pin for stepper motors";
		};
		dirs: dir_s {
			gpios = <&gpio1 15 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Dir pin for stepper motors";
		};
		mmux0: mmux_0 {
			gpios = <&gpio0 13 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Misc mux select 0";
		};
		mmux1: mmux_1 {
			gpios = <&gpio0 14 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Misc mux select 1";
		};
		mmux2: mmux_2 {
			gpios = <&gpio0 15 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Misc mux select 2";
		};
		clkm: clk_m {
			gpios = <&gpio0 5 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Clock for miscellaneous";
		};
		miscm: misc_m {
			gpios = <&gpio0 4 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Misc input";
		};
		lmux0: lmux_0 {
			gpios = <&gpio0 16 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Limit mux select 0";
		};
		lmux1: lmux_1 {
			gpios = <&gpio0 17 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Limit mux select 1";
		};
		lmux2: lmux_2 {
			gpios = <&gpio0 18 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Limit mux select 2";
		};
		lmux3: lmux_3 {
			gpios = <&gpio0 19 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Limit mux select 3";
		};
		lmt: lmt {
			gpios = <&gpio0 6 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Limit pin";
		};
		serv0: serv_0 {
			gpios = <&gpio0 0 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Servo 0 pin";
		};
		serv1: serv_1 {
			gpios = <&gpio0 1 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Servo 1 pin";
		};
		serv2: serv_2 {
			gpios = <&gpio0 2 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Servo 2 pin";
		};
		serv3: serv_3 {
			gpios = <&gpio0 3 (GPIO_ACTIVE_HIGH | GPIO_VOLTAGE_3P3)>;
			label = "Servo 3 pin";
		};
	};
};

&i2c1 {
	status = "okay";
	compatible = "nordic,nrf-twim";
	label = "I2C_1";
	pinctrl-0 = <&i2c1_default>;
	pinctrl-1 = <&i2c1_sleep>;
	pinctrl-names = "default", "sleep";
	clock-frequency = <100000>; 

	bh1749: bh1749@38 {
		compatible = "rohm,bh1749";
		label = "BH1749";
		reg = <0x38>;
		int-gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
	};

	tca9548: tca9548a@70 {
		compatible = "ti,tca9548a";
		label = "TCA9548";
		reg = <0x70>;
	};
};

&pinctrl {
	i2c1_default: i2c1_default{
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 35)>,
				<NRF_PSEL(TWIM_SCL, 0, 34)>;
		};
	};

	i2c1_sleep: i2c1_sleep{
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 35)>,
				<NRF_PSEL(TWIM_SCL, 0, 34)>;
			low-power-enable;
		};
	};
};

  • Hi James

    Thanks for sharing the files, unfortunately there isn't anything that immediately jumps out at me...

    Regarding the crystal pins there is a remaining issue that might be relevant, causing the TF-M firmware to ignore the LF clock configuration and set these pins regardless of the setting.  
    In order to see if this is the problem, could you try to comment out lines 787 and 788 in modules/tee/tf-m/trusted-firmware-m/platform/ext/target/nordic_nrf/common/nrf5340/target_cfg.c?

    nrf_gpio_pin_control_select(PIN_XL1, NRF_GPIO_PIN_SEL_PERIPHERAL);
    nrf_gpio_pin_control_select(PIN_XL2, NRF_GPIO_PIN_SEL_PERIPHERAL);

    A similar issue was found for the NFC pins, but this issue has been fixed in v2.4.0 of the SDK so it is odd that it would still show up. 

    This older case discuses the issue in more detail. 

    Could you try to read out the register as mentioned in that case to see if the NFCPINS register in the UICR gets configured correctly?

    nrfjprog --memrd 0xff8028

    Best regards
    Torbjørn

  • Hi Torbjorn,

    Thanks again for your help and patience. I was able to get P0.2, P0.3 (NFC pins) and P0.19 working. I think I was inconsistent earlier in opening VSCode through the provided Nordic tool which caused me to sometimes use SDK 2.1.0. This would make P0.2, P0.3 and oddly P0.19 to not work. I don't know why pin 19 did not work on SDK 2.1.0 as it should be a normal pin. Regardless, these pins now work.

    Unfortunately, pins P0.0 and P0.1 (crystal pins) still do not work and they don't work even after commenting out those lines of code. Hopefully there's something else I can try. Just to confirm, you're able to blink these pins on your side, correct?

  • Hi James

    Great to hear that you got some of the pins working, now we have less pins to worry about Slight smile

    DubiousDooby said:
    Just to confirm, you're able to blink these pins on your side, correct?

    I was, eventually...

    I tried to enable these pins in a standard Bluetooth example, and at first it failed to work. I realized that despite the external 32kHz crystal being disabled and the pins being set as outputs the MCUSEL field in the PIN_CNF registers was still set to 0x3 (peripheral), not 0 as expected. 

    The reason for this was that CONFIG_SOC_ENABLE_LFXO was still set in my example, since it is set implicitly by the DK board files. Setting CONFIG_SOC_ENABLED_LFXO=n in my config files (prj.conf and child_image/hci_rpmsg.conf) solved the issue. 

    Could you try this as well, and see if it works? 

    Please note that I tested a secure build only, without TF-M or mcuboot enabled, so things might work differently in your case. 

    Best regards
    Torbjørn

  • Good to hear. Unfortunately that setting didn't end up changing much. I was unable to find the child_image/hci_rpmsg.conf file in my project so I just set it in the proj.conf file. I also don't know how to check the registers on my end. Maybe there's a way I check that to give more information?

    Here's the error message I received, which makes it look like the setting is not being used.

    /home/james/org/work/nrf/ncs_projects/blinkysupreme/prj.conf:16: warning: attempt to assign the value 'n' to the undefined symbol SOC_ENABLED_LFXO

  • Hi James

    You should be able to read out the value of the NRF_P0->PIN_CNF[0] and NRF_P0->PIN_CNF[1] registers (or check them in the debugger) after the application is booted up, which will show you how those pins are configured. 
    Maybe you could give this a go and see if the MCUSEL field is the problem?

    I will do some more testing on my side and add TF-M support, in order to see if I can get that working. Unfortunately I won't be able to continue this work until I am back in office on Monday. 

    Best regards
    Torbjørn

Related