This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nrf9160 uart Pull-Up and power consumption

hi all,

i'm trying to disable uart for lower power consumption, i've disables it with:

NRF_UARTE1->TASKS_STOPTX = 1;
NRF_UARTE1->TASKS_STOPRX = 1;


but when i measure the voltage on the rx pin i see 1.8V  (this seems to consume current on the device on the other side of the uart interface - which is turned off )
i assume its in pulled up state, so i'm trying to change it's state to no-pull:
nrf_uarte_txrx_pins_disconnect(NRF_UARTE0);
gpio_pin_configure(uart_wifi, 18, GPIO_PUD_PULL_DOWN);
gpio_pin_configure(uart_wifi, 19, GPIO_PUD_PULL_DOWN);
gpio_pin_write(uart_wifi, 18,0);
gpio_pin_write(uart_wifi, 19,0);

 but it doesnt seem to have any effect.

how can i set this pin to 0, and back to 1 when I need it , on runtime?

Thanks

Moshe

Parents
  • Hi Moshe, 

    Is the external IC power gated? It should drive the RX line to 'high' when it's inactive and powered. So that may explain why you see the current draw when you set the output to 0. 

    Also, from your code snippets, it appears that you are stopping UART instance 1 while nrf_uarte_txrx_pins_disconnect() call takes instance 0 as an argument. Not sure if this is intended or not.

    Best regards,

    Vidar

  • Hi Vidar,

    Thanks for your answer, 

    1. I called `nrf_uarte_txrx_pins_disconnect()` on both UARTs (didnt copy it into the snippet).

    2. I test this while the external IC is powered off  (it is gated ) . 

    3. Just to be clear, even when I  disable UART from the SW, I still measure 1.8v on the TX pin . I guess it is still pulled up . 

    Thanks and BR

  • Hi Moshe,

     

    Are you 100 % certain that its the nRF that is keeping this line high?

    If you power off only the nrf91, does the voltage drop to gnd?

    Is this measured on a nRF91-DK or a custom board? 

    If it still is set high, can you please post any changed overlay/dts files?

     

    PS: your stop/disable routines will not work as you intend them to, because when you issue TASKS_STOPRX=1, you have to wait for the EVENTS_RXTO to occur before you disable the UART instance (same goes for the TX, although its less of a change for that the occurring while you disable the peripheral), as stated here in the PS:

    https://infocenter.nordicsemi.com/topic/ps_nrf9160/uarte.html?cp=2_0_0_5_18_6#concept_twi_low_power

     

    Kind regards,

    Håkon

  • Hi Hakon,

    1. I'm pretty sure it is the NRF since the device on the other size is powered off.

    2. if I disable UART completely, I see the line on LOW.

    3. it is measured on a costum board.

    4. attached. 

    Thanks !!!

  • Hi Moshe,

     

    MosheSmartAmr said:
    2. if I disable UART completely, I see the line on LOW.

     Never initialize it? ie: CONFIG_SERIAL=n? 

    MosheSmartAmr said:
    4. attached. 

     Looks like they weren't attached. Could you try .zip'ing it and then attach it? 

    Did you try disabling per the recommendation in the datasheet, ie: wait for the events on RX and TX before completely disabling the peripheral to see if this has a difference on the behavior?

     

    Kind regards,

    Håkon

  • Hi,

    Sorry for the delay ,

    1.about CONFIG_SERIAL=n, this is exactly wht i did .

    2. attaching again . 

    3. just tried what you suggested (waiting for the event before disabling) , thath did not work too ...

    overlay file:

    /* SPDX-License-Identifier: Apache-2.0 */
    
    &uart1 {
            current-speed = <115200>;
            compatible = "nordic,nrf-uarte";
            status = "okay";
            tx-pin = <19>;
            rx-pin = <18>;
    };
    

    dts file :

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    / {
    	model = "Nordic PCA10090 Dev Kit";
    	compatible = "nordic,pca10090-dk", "nordic,nrf9160-sica",
    		     "nordic,nrf9160";
    
    	chosen {
    		zephyr,console = &uart0;
    		zephyr,shell-uart = &uart0;
    		zephyr,uart-mcumgr = &uart0;
    	};
    
    	leds {
    		compatible = "gpio-leds";
    		led0: led_0 {
    			gpios = <&gpio0 2 GPIO_INT_ACTIVE_HIGH>;
    			label = "Green LED 0";
    		};
    		led1: led_1 {
    			gpios = <&gpio0 3 GPIO_INT_ACTIVE_HIGH>;
    			label = "Green LED 1";
    		};
    		led2: led_2 {
    			gpios = <&gpio0 4 GPIO_INT_ACTIVE_HIGH>;
    			label = "Green LED 2";
    		};
    		led3: led_3 {
    			gpios = <&gpio0 5 GPIO_INT_ACTIVE_HIGH>;
    			label = "Green LED 3";
    		};
    	};
    
    	buttons {
    		compatible = "gpio-keys";
    		button0: button_0 {
    			gpios = <&gpio0 8 GPIO_PUD_PULL_UP>;
    			label = "Switch 1";
    		};
    		button1: button_1 {
    			gpios = <&gpio0 9 GPIO_PUD_PULL_UP>;
    			label = "Switch 2";
    		};
    		button2: button_2 {
    			gpios = <&gpio0 6 GPIO_PUD_PULL_UP>;
    			label = "Push button 1";
    		};
    		button3: button_3 {
    			gpios = <&gpio0 7 GPIO_PUD_PULL_UP>;
    			label = "Push button 2";
    		};
    	};
    
    	/* These aliases are provided for compatibility with samples */
    	aliases {
    		led0 = &led0;
    		led1 = &led1;
    		led2 = &led2;
    		led3 = &led3;
    		sw0 = &button2;
    		sw1 = &button3;
    		sw2 = &button0;
    		sw3 = &button1;
    	};
    };
    
    &adc {
    	status ="ok";
    };
    
    &gpiote {
    	status = "ok";
    };
    
    &gpio0 {
    	status = "ok";
    };
    
    
    &uart0 {
    	status = "ok";
    	current-speed = <115200>;
    	tx-pin = <26>;
    	rx-pin = <30>;
    };
    
    /*
    &uart0 {
    	status = "okay";
    	current-speed = <115200>;
    	tx-pin = <29>;
    	rx-pin = <28>;
    	rts-pin = <27>;
    	cts-pin = <26>;
    };
    */
    &uart1 {
    	status = "ok";
    	current-speed = <115200>;
    	tx-pin = <1>;
    	rx-pin = <0>;
    	rts-pin = <14>;
    	cts-pin = <15>;
    };
    
    &i2c2 {
    	status = "ok";
    	sda-pin = <12>;
    	scl-pin = <31>;
    };
    
    &pwm0 {
    	status = "ok";
    	ch0-pin = <2>;
    };
    
    &spi3 {
    	status = "ok";
    };
    
    &timer0 {
    	status = "ok";
    };
    
    &timer1 {
    	status = "ok";
    };
    
    &timer2 {
    	status = "ok";
    };
    
    &flash0 {
    	/*
    	 * For more information, see:
    	 * http://docs.zephyrproject.org/latest/guides/dts/index.html#flash-partitions
    	 */
    	partitions {
    		compatible = "fixed-partitions";
    		#address-cells = <1>;
    		#size-cells = <1>;
    
    		boot_partition: partition@0 {
    			label = "mcuboot";
    			reg = <0x00000000 0x10000>;
    		};
    		slot0_partition: partition@10000 {
    			label = "image-0";
    		};
    		slot0_ns_partition: partition@40000 {
    			label = "image-0-nonsecure";
    		};
    		slot1_partition: partition@80000 {
    			label = "image-1";
    		};
    		slot1_ns_partition: partition@b0000 {
    			label = "image-1-nonsecure";
    		};
    		scratch_partition: partition@f0000 {
    			label = "image-scratch";
    			reg = <0x000f0000 0xa000>;
    		};
    		storage_partition: partition@fa000 {
    			label = "storage";
    			reg = <0x000fa000 0x00006000>;
    		};
    	};
    };
    
    / {
    	/* SRAM allocated and used by the BSD library */
    	sram0_bsd: memory@20010000 {
    		device_type = "memory";
    		compatible = "mmio-sram";
    	};
    
    	/* SRAM allocated to the Non-Secure image */
    	sram0_ns: memory@20020000 {
    		device_type = "memory";
    		compatible = "mmio-sram";
    	};
    };
    
    /* Include partition configuration file */
    #include "nrf9160_pca10090_partition_conf.dts"

  • Hi,

     

    When the UART is disabled, the RXD is left as an input, and TXD is left as an output (with high level).

    This is the routine that I have tested your scenario with:

    #include <zephyr.h>
    #include <misc/printk.h>
    #include <uart.h>
    
    #define TXD_PIN 19
    
    static u8_t uart_buf[1024];
    
    void uart_cb(struct device *x)
    {
    	uart_irq_update(x);
    	int data_length = 0;
    
    	if (uart_irq_rx_ready(x)) {
    		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    		uart_buf[data_length] = 0;
    	}
    	printk("%s", uart_buf);
    }
    
    void main(void)
    {
    	struct device *uart = device_get_binding("UART_1");
    
    	uart_irq_callback_set(uart, uart_cb);
    	uart_irq_rx_enable(uart);
    	printk("UART loopback start!\n");
    	while (1) {
    		static u32_t wakeup_cnt;		
    		k_cpu_idle();
    		wakeup_cnt++;
    		if (wakeup_cnt > 40) {
    			wakeup_cnt = 0;
    			NRF_UARTE1->TASKS_STOPRX=1;
    			while(NRF_UARTE1->EVENTS_RXTO == 0);
    			NRF_UARTE1->EVENTS_RXTO = 0;
    
    			NRF_UARTE1->TASKS_STOPTX = 1;
    			while(NRF_UARTE1->EVENTS_TXSTOPPED == 0);
    			NRF_UARTE1->EVENTS_TXSTOPPED = 0;
    			
    			NRF_UARTE1->ENABLE = 0;
    			NRF_UARTE1->PSEL.TXD = 0xFFFFFFFF;
    			NRF_P0_NS->OUTCLR = (1 << TXD_PIN);
    		}
    	}
    }
    

     

    This code assumes that I loopback UART0:TXD to UART1:RXD, and when it has gotten 40 chars, it disconnects the UART1 interface completely.

    If I do not clear the GPIO, it is held high. When I run NRF_P0_NS->OUTCLR = 1<<19;, the pin goes low again after disconnecting it from the UARTE1 peripheral.

    Could you try this and see if that works at your end?

     

    Kind regards,

    Håkon

Reply
  • Hi,

     

    When the UART is disabled, the RXD is left as an input, and TXD is left as an output (with high level).

    This is the routine that I have tested your scenario with:

    #include <zephyr.h>
    #include <misc/printk.h>
    #include <uart.h>
    
    #define TXD_PIN 19
    
    static u8_t uart_buf[1024];
    
    void uart_cb(struct device *x)
    {
    	uart_irq_update(x);
    	int data_length = 0;
    
    	if (uart_irq_rx_ready(x)) {
    		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    		uart_buf[data_length] = 0;
    	}
    	printk("%s", uart_buf);
    }
    
    void main(void)
    {
    	struct device *uart = device_get_binding("UART_1");
    
    	uart_irq_callback_set(uart, uart_cb);
    	uart_irq_rx_enable(uart);
    	printk("UART loopback start!\n");
    	while (1) {
    		static u32_t wakeup_cnt;		
    		k_cpu_idle();
    		wakeup_cnt++;
    		if (wakeup_cnt > 40) {
    			wakeup_cnt = 0;
    			NRF_UARTE1->TASKS_STOPRX=1;
    			while(NRF_UARTE1->EVENTS_RXTO == 0);
    			NRF_UARTE1->EVENTS_RXTO = 0;
    
    			NRF_UARTE1->TASKS_STOPTX = 1;
    			while(NRF_UARTE1->EVENTS_TXSTOPPED == 0);
    			NRF_UARTE1->EVENTS_TXSTOPPED = 0;
    			
    			NRF_UARTE1->ENABLE = 0;
    			NRF_UARTE1->PSEL.TXD = 0xFFFFFFFF;
    			NRF_P0_NS->OUTCLR = (1 << TXD_PIN);
    		}
    	}
    }
    

     

    This code assumes that I loopback UART0:TXD to UART1:RXD, and when it has gotten 40 chars, it disconnects the UART1 interface completely.

    If I do not clear the GPIO, it is held high. When I run NRF_P0_NS->OUTCLR = 1<<19;, the pin goes low again after disconnecting it from the UARTE1 peripheral.

    Could you try this and see if that works at your end?

     

    Kind regards,

    Håkon

Children
Related