How to use UART pins as GPIO instead

I'm relatively new to both nRF and Zephyr platforms and I'm wondering how to disable UART on the UART pins (such as p0.19-p0.22 on the nRF5340 that I'm using) so that they can be used for simple digital output. I've been looking around and nothing that I've found has worked so far.

Parents
  • Hello,

    My first question is: are you really sure that you want to do this? If you are using the development kit, those pins are connected to the onboard J-Link debugger (also called interface MCU in the documentation). You will possibly have to prototype without a debugger connected most of the time (there is a switch for that on the DK). It is also important to state your NCS version, since there were some big changes in 2.0.0 with the introduction of the pinctrl API.

    The second question is: do you want to completely turn off the UART0, or just change the pins that it uses? Because you can (almost) freely change the pins for this peripheral. I will assume the former for this reply, but please tell me if that is not the case.

    Otherwise, it's a case of adding a devicetree overlay file. Since you are relatively new to the whole platform you may want to go through at least some part of our DevAcademy course.

    Lesson 2 is about devicetree and setting up and controlling GPIO pins, while lesson 3 has information about the devicetree overlay and configuration files.

    We also have a whole chapter/guide about devicetree in the Zephyr documentation.

    I understand that it is a lot, so I am also going to show you a pretty simple example.

    The overlay file beneath is based on the following file: zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dts

    The rest of the answer is in the comments in the code.

    // Turn off UART0 completely to free the pins
    &uart0 {
        status = "disabled";
    };
    
    // "/" slash means the root node
    / {
        my_gpios {
            compatible = "gpio-leds";
            my_gpio0: my_gpio_0 {
                gpios = < &gpio0 19 GPIO_PUSH_PULL>;
                label = "My GPIO 0";
            };
            my_gpio1: my_gpio_1 {
                gpios = < &gpio0 20 GPIO_PUSH_PULL>;
                label = "My GPIO 1";
            };
        };
    
        aliases {
            my-gpio0 = &my_gpio0;
            my-gpio1 = &my_gpio1;
        };
    
        // only add this if you want to use another UART instance for all the zephyr messages etc.
        // if you want to not use UART at all, remember to add CONFIG_SERIAL=N to the prj.conf
        chosen {
    		zephyr,console = &uart1;
    		zephyr,shell-uart = &uart1;
    		zephyr,uart-mcumgr = &uart1;
    		zephyr,bt-mon-uart = &uart1;
    		zephyr,bt-c2h-uart = &uart1;
    	};
    };

    Best regards,

    Michal

Reply
  • Hello,

    My first question is: are you really sure that you want to do this? If you are using the development kit, those pins are connected to the onboard J-Link debugger (also called interface MCU in the documentation). You will possibly have to prototype without a debugger connected most of the time (there is a switch for that on the DK). It is also important to state your NCS version, since there were some big changes in 2.0.0 with the introduction of the pinctrl API.

    The second question is: do you want to completely turn off the UART0, or just change the pins that it uses? Because you can (almost) freely change the pins for this peripheral. I will assume the former for this reply, but please tell me if that is not the case.

    Otherwise, it's a case of adding a devicetree overlay file. Since you are relatively new to the whole platform you may want to go through at least some part of our DevAcademy course.

    Lesson 2 is about devicetree and setting up and controlling GPIO pins, while lesson 3 has information about the devicetree overlay and configuration files.

    We also have a whole chapter/guide about devicetree in the Zephyr documentation.

    I understand that it is a lot, so I am also going to show you a pretty simple example.

    The overlay file beneath is based on the following file: zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340_cpuapp_common.dts

    The rest of the answer is in the comments in the code.

    // Turn off UART0 completely to free the pins
    &uart0 {
        status = "disabled";
    };
    
    // "/" slash means the root node
    / {
        my_gpios {
            compatible = "gpio-leds";
            my_gpio0: my_gpio_0 {
                gpios = < &gpio0 19 GPIO_PUSH_PULL>;
                label = "My GPIO 0";
            };
            my_gpio1: my_gpio_1 {
                gpios = < &gpio0 20 GPIO_PUSH_PULL>;
                label = "My GPIO 1";
            };
        };
    
        aliases {
            my-gpio0 = &my_gpio0;
            my-gpio1 = &my_gpio1;
        };
    
        // only add this if you want to use another UART instance for all the zephyr messages etc.
        // if you want to not use UART at all, remember to add CONFIG_SERIAL=N to the prj.conf
        chosen {
    		zephyr,console = &uart1;
    		zephyr,shell-uart = &uart1;
    		zephyr,uart-mcumgr = &uart1;
    		zephyr,bt-mon-uart = &uart1;
    		zephyr,bt-c2h-uart = &uart1;
    	};
    };

    Best regards,

    Michal

Children
  • Thanks for the reply. I am using NCS v2.0.2. Would I still be able to prototype using the debug SWD interface while UART pins are disabled? Alternatively, can the J-Link use UART1? I would also be interested in how to change the UART0 pins, which might be useful on the design I'm working on. Would it be something like this (based on nrf5340_cpuapp_common-pinctrl.dtsi)?

    &pinctrl {
    	uart0_default: uart0_default {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, new_tx)>,
    				<NRF_PSEL(UART_RTS, 0, new_rts)>;
    		};
    		group2 {
    			psels = <NRF_PSEL(UART_RX, 0, new_rx)>,
    				<NRF_PSEL(UART_CTS, 0, new_cts)>;
    			bias-pull-up;
    		};
    	};
    
    	uart0_sleep: uart0_sleep {
    		group1 {
    			psels = <NRF_PSEL(UART_TX, 0, new_tx)>,
    				<NRF_PSEL(UART_RX, 0, new_rts)>,
    				<NRF_PSEL(UART_RTS, 0, new_rts)>,
    				<NRF_PSEL(UART_CTS, 0, new_cts)>;
    			low-power-enable;
    		};
    	};
    };

  • Hello,

    The debug SWD interface is connected to other pins, so that's fine. There are dedicated pins for that on the chip.

    It's just that UART0 on the default pins is being redirected via the debugger chip, so that you can access it via a VCOM port on your PC.
    I think that you can still use Segger RTT for that instead.

    Your pinctrl overlay looks correct to me.

    Best regards,

    Michal

Related