NRF9160 Disable UART and RX pin into an interrupt pin

Hello everyone,

I'm working on a project with NRF9160 nRF Connect SDK v2.3.0.

In my project i use UART0 to exchange data and i disable the UART when is not use.

I need an interrupt to wake up my device when data come on the UART pin (TX/RX).

I have found different topic to disable and enable UART on runinng time. 

Now, when my uart is disable, i would like to convert RX pin into an interrupt pin which allow me to re-enable the UART to get data when interrupt occur.

Could you tell me if you have any advice about that ?

Best regards,

Lam

  • Hello Lam,

    I have been working in your case. I will get back to you shortly.

    Thanks.

    BR

    Kazi

  • Hello,

    Which device are you connecting the nRF9160 to over UART? if it's another nordic device, you can use our low-power UART driver.

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/samples/peripheral/lpuart/README.html

    ''The low power UART driver implements the standard asynchronous UART API that can be enabled with the CONFIG_UART_ASYNC_API configuration option. Alternatively, you can also enable the interrupt-driven UART API using the CONFIG_NRF_SW_LPUART_INT_DRIVEN configuration option.

    The protocol used by this driver implements two control lines, instead of standard hardware flow control lines, to allow for disabling the UART receiver during the idle period. This results in low power consumption, as you can shut down the high-frequency clock when UART is in idle state.''

    Thanks.

    BR

    Kazi

  • Hello,

    Thanks for your return,

    It's connected to a specific board that i have develop. 

    My objectif is to reduce power consumption to 50uA.

    So i'm thinking to stop UART completely and waiting an interrupt on my RX line that i will have convert into interrupt GPIO. And when interrupt coming, i reactivate my uart to receive data.

    This way is possible ?

    Best regards,

    Lam

  • Hello,

    ''So i'm thinking to stop UART completely and waiting an interrupt on my RX line that i will have convert into interrupt GPIO. And when interrupt coming, i reactivate my uart to receive data.

    This way is possible ?''

    The work sequence of drive (Low power uART) is :

    1. The transmitter initiates the transmission by calling uart_tx().

    2. The driver reconfigures the REQ line to input with pull-up and enables the detection of high to low transition.

    3. The line is set to high due to the pull-up register, and that triggers an interrupt on the RDY line.

    4. On that interrupt, the driver starts the UART receiver.

    5. When the receiver is ready, the driver reconfigures the RDY line to output low.

    6. Then, the driver reconfigures the RDY line to input with pull-up and enables the interrupt on detection of high to low transition.

    7. This sequence results in a short pulse on the line, as the line goes low and high.

    8. The initiator detects the pulse and starts the standard UART transfer.

    9. When the transfer is completed, the driver reconfigures the REQ line to the initial state: output set to low. This results in a line state change.

    10. As the line goes low, the receiver detects the change. This indicates that the UART receiver can be stopped.'

    So, I think this is possible.

  • Hello,

    I'm able to disable my uart with this part of code : 

    uint8_t disable_uart(void){
    
        //Disable uart0 which use to exchange message between modem and an external device
        NRF_UARTE0_NS->TASKS_STOPTX = 1;
        NRF_UARTE0_NS->TASKS_STOPRX = 1;
        NRF_UARTE0_NS->ENABLE = 0;
    
        //configure RX pin int o input gpio
        const struct device * gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0));
        gpio_pin_configure(gpio_dev,6, GPIO_INPUT);
       
    }

    And i obtain an power consumption arround 6uA.

    Now i'm trying to convert my RX gpio into an interrupt GPIO but without success.

    I have try this after checking information in the sample button in SDK

    #define SWIN3_NODE	DT_ALIAS(swin3)
    #if !DT_NODE_HAS_STATUS(SWIN3_NODE, okay)
    #error "Unsupported board: SWIN3 devicetree alias is not defined"
    #endif
    
    static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SWIN3, gpios,{0}); 
    static struct gpio_callback button_cb_data;
    
    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	printk("Button pressed\r\n");
    }
    
    //gpio for UART interrupt definition
    void configure_int_rx(void){
    	int ret;
    
    	printk("configure interrupt\r\n");
    
    	ret = gpio_pin_configure_dt(&button,GPIO_INPUT);
    	if (ret != 0) {
    		printk("Error");// %d: failed to configure %s pin %d\n",
    		      // ret, button.port->name, button.pin);
    		return;
    	}
    
    	printk("test1\r\n");
    
    	ret = gpio_pin_interrupt_configure_dt(&button,GPIO_INT_EDGE_TO_ACTIVE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error");// %d: failed to configure interrupt on %s pin %d\n",
    			//ret, button.port->name, button.pin);
    		return;
    	}
    
    	printk("test2\r\n");
    
    	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    	gpio_add_callback(button.port, &button_cb_data);
    	printk("Set up button");// at %s pin %d\n", button.port->name, button.pin);
    
    }
    
    

    The resultat that i obtain is a reboot of my board every time the code start to execute "configure_int_rx" function.

    Update below

    thanks for your help,

    Best regards,

    Lam

Related