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

Parents
  • Hello,

    We think the problem lies where it is starting and stopping the UART. Can you check this (+) How can I enable and disable UART devices at run time on nRF9160? - Nordic Q&A - Nordic DevZone - Nordic DevZone (nordicsemi.com) case? You may need to check the RXTO event. 

    Thanks.

    BR

    Kazi

  • Hello,

    Thanks for your help,

    I found a solution that was the following, if this can help someone.

    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	int ret;
    
    	printk("Button pressed\r\n");
    
    	ret = gpio_pin_interrupt_configure(button.port,button.pin,GPIO_INT_DISABLE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error disable INT\r\n");
    		return;
    	}
    	
    	//restart_uart();
    	k_work_submit(&button_action_work);
    	//flag_interrupt = 1;
    }

    //gpio for UART interrupt definition
    void configure_int_rx(void){
    	int ret;
    
    	printk("configure interrupt\r\n");
    
    	if (!device_is_ready(button.port)) {
    		printk("Error config INT 1\r\n");
    		return;
    	}
    	
    	ret = gpio_pin_configure(button.port,button.pin,GPIO_INPUT);
    	if (ret != 0) {
    		printk("Error config INT 2\r\n");
    		return;
    	}
    
    	ret = gpio_pin_interrupt_configure(button.port,button.pin,GPIO_INT_EDGE_TO_ACTIVE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error config INT 3\r\n");
    		return;
    	}
    
    	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    
    	ret = gpio_add_callback(button.port, &button_cb_data);
    	if (ret != 0) {
    		printk("Error config INT 4\r\n");
    		return;
    	}
    
    	printk("Config INT OK\r\n");
    }

    void timer_disable_uart_work_fn(struct k_work *work)
    {
    	disable_uart();
        configure_int_rx();
    }

    void process_work_timer_uart_disable(void){
    	//scehdule a time to disable uart
        //cancel last schedule
        if(k_work_delayable_busy_get(&timer_disable_uart_work) != 0 ){
            k_work_cancel_delayable(&timer_disable_uart_work);
    		while(k_work_delayable_busy_get(&timer_disable_uart_work) != 0 );	//wait until cancelation finnish
        }
        //enable new schedule
        k_work_schedule(&timer_disable_uart_work, K_SECONDS(WAIT_UART_DISABLE));
    }

    /* other code line to use to work */
    #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_NODE, gpios,0); 
    static struct gpio_callback button_cb_data;
    
    K_WORK_DEFINE(button_action_work, button_action_work_handler);
    void button_action_work_handler(struct k_work *work) {
        //do_something_because_a_button_was_pressed();
    	restart_uart();
    }
    
    static struct k_work_delayable timer_disable_uart_work;
    
    k_work_init_delayable(&timer_disable_uart_work,timer_disable_uart_work_fn);
    
    
    
    

Reply
  • Hello,

    Thanks for your help,

    I found a solution that was the following, if this can help someone.

    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	int ret;
    
    	printk("Button pressed\r\n");
    
    	ret = gpio_pin_interrupt_configure(button.port,button.pin,GPIO_INT_DISABLE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error disable INT\r\n");
    		return;
    	}
    	
    	//restart_uart();
    	k_work_submit(&button_action_work);
    	//flag_interrupt = 1;
    }

    //gpio for UART interrupt definition
    void configure_int_rx(void){
    	int ret;
    
    	printk("configure interrupt\r\n");
    
    	if (!device_is_ready(button.port)) {
    		printk("Error config INT 1\r\n");
    		return;
    	}
    	
    	ret = gpio_pin_configure(button.port,button.pin,GPIO_INPUT);
    	if (ret != 0) {
    		printk("Error config INT 2\r\n");
    		return;
    	}
    
    	ret = gpio_pin_interrupt_configure(button.port,button.pin,GPIO_INT_EDGE_TO_ACTIVE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error config INT 3\r\n");
    		return;
    	}
    
    	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    
    	ret = gpio_add_callback(button.port, &button_cb_data);
    	if (ret != 0) {
    		printk("Error config INT 4\r\n");
    		return;
    	}
    
    	printk("Config INT OK\r\n");
    }

    void timer_disable_uart_work_fn(struct k_work *work)
    {
    	disable_uart();
        configure_int_rx();
    }

    void process_work_timer_uart_disable(void){
    	//scehdule a time to disable uart
        //cancel last schedule
        if(k_work_delayable_busy_get(&timer_disable_uart_work) != 0 ){
            k_work_cancel_delayable(&timer_disable_uart_work);
    		while(k_work_delayable_busy_get(&timer_disable_uart_work) != 0 );	//wait until cancelation finnish
        }
        //enable new schedule
        k_work_schedule(&timer_disable_uart_work, K_SECONDS(WAIT_UART_DISABLE));
    }

    /* other code line to use to work */
    #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_NODE, gpios,0); 
    static struct gpio_callback button_cb_data;
    
    K_WORK_DEFINE(button_action_work, button_action_work_handler);
    void button_action_work_handler(struct k_work *work) {
        //do_something_because_a_button_was_pressed();
    	restart_uart();
    }
    
    static struct k_work_delayable timer_disable_uart_work;
    
    k_work_init_delayable(&timer_disable_uart_work,timer_disable_uart_work_fn);
    
    
    
    

Children
Related