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
  • I have a better answer now,

    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	int ret;
    	ret = gpio_pin_interrupt_configure_dt(&button,GPIO_INT_DISABLE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error disable INT\r\n");
    		return;
    	}
    	printk("Button pressed\r\n");
    	restart_uart();
    
    }
    
    uint8_t restart_uart(void){
    
        NRF_UARTE0_NS->PSEL.RXD = 6;
        NRF_UARTE0_NS->PSEL.TXD = 7;
        NRF_UARTE0_NS->ENABLE = 8;
        NRF_UARTE0_NS->TASKS_STARTRX = 1;
        NRF_UARTE0_NS->TASKS_STARTTX = 1;
    
        send_uart_data_char("UART RESTARTED\r\n");
    
        //initControlUart();
    
        printk("restart uart\r\n");
    }

    I correctly have an answer from my UART, i correctly receive "UART RESTARTED".

    But 2 errors messages stay : 

    - ERROR : uart_rx_buf_rsp Failed

    - UART_TX_ABORTED

    The first one come from uart libray and the other one come from my uart callback function

    static void uart_callback(const struct device *dev, struct uart_event *evt, struct uart_info_struct *user_data){
        uint8_t *buffer, error;
    	switch(evt->type){
    		case UART_RX_RDY:
    		    //printk("RCV %d bytes\n", evt->data.rx.len);
                if(user_data->cmd_buffer_len < CMD_BUFF_LEN){
                    if((user_data->cmd_buffer_len + evt->data.rx.len) <= CMD_BUFF_LEN){
                        //case of new data less than remaining space in cmd_buffer
                        memcpy(user_data->cmd_buffer + user_data->cmd_buffer_len, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len);
                        user_data->cmd_buffer_len += evt->data.rx.len;
                    }else{
                        //case of new data more than remaining space
                        memcpy(user_data->cmd_buffer + user_data->cmd_buffer_len, evt->data.rx.buf + evt->data.rx.offset, CMD_BUFF_LEN - user_data->cmd_buffer_len);
                        user_data->cmd_buffer_len += CMD_BUFF_LEN - user_data->cmd_buffer_len;
                    }
                }
                process_buffer(user_data);
    		break;
    		case UART_TX_ABORTED:
    		    printk("UART_TX_ABORTED\n");
    		break;
    		case UART_TX_DONE:
    		    //printk("UART_TX_DONE\n");
                //printk("+SEM=%d\n",k_sem_count_get(user_data->tx_semaphore));
                k_sem_give(user_data->tx_semaphore);
                //printk("+SEM=%d\n",k_sem_count_get(user_data->tx_semaphore));
    		break;
    		case UART_RX_BUF_REQUEST:
                //printk("UART_RX_BUF_REQUEST\n");
                buffer = k_malloc(RX_BUFF_LEN);
                if(buffer == NULL){
                    printk("ERROR : RX_BUF_REQUEST Failed to allocate buffer\n");
                    return;
                }
                error = uart_rx_buf_rsp(uart_info.dev, buffer, RX_BUFF_LEN);
                if(error != 0){
                    printk("ERROR : uart_rx_buf_rsp Failed\n");
                    return;
                }
    		break;
                case UART_RX_BUF_RELEASED:
                k_free(evt->data.rx_buf.buf);
                //printk("UART_RX_BUF_RELEASED\n");
    		break;
    		case UART_RX_DISABLED:
    		    printk("UART_RX_DISABLED\n");
    		break;
    		case UART_RX_STOPPED:
    		    printk("UART_RX_STOPPED\n");
    		break;
    	}
    }

    I think i'm on the right way,

    do you have advice about that ?

    Best regards,

    Lam

Reply
  • I have a better answer now,

    void button_pressed(const struct device *dev, struct gpio_callback *cb,
    		    uint32_t pins)
    {
    	int ret;
    	ret = gpio_pin_interrupt_configure_dt(&button,GPIO_INT_DISABLE);		//GPIO_INT_EDGE_BOTH
    	if (ret != 0) {
    		printk("Error disable INT\r\n");
    		return;
    	}
    	printk("Button pressed\r\n");
    	restart_uart();
    
    }
    
    uint8_t restart_uart(void){
    
        NRF_UARTE0_NS->PSEL.RXD = 6;
        NRF_UARTE0_NS->PSEL.TXD = 7;
        NRF_UARTE0_NS->ENABLE = 8;
        NRF_UARTE0_NS->TASKS_STARTRX = 1;
        NRF_UARTE0_NS->TASKS_STARTTX = 1;
    
        send_uart_data_char("UART RESTARTED\r\n");
    
        //initControlUart();
    
        printk("restart uart\r\n");
    }

    I correctly have an answer from my UART, i correctly receive "UART RESTARTED".

    But 2 errors messages stay : 

    - ERROR : uart_rx_buf_rsp Failed

    - UART_TX_ABORTED

    The first one come from uart libray and the other one come from my uart callback function

    static void uart_callback(const struct device *dev, struct uart_event *evt, struct uart_info_struct *user_data){
        uint8_t *buffer, error;
    	switch(evt->type){
    		case UART_RX_RDY:
    		    //printk("RCV %d bytes\n", evt->data.rx.len);
                if(user_data->cmd_buffer_len < CMD_BUFF_LEN){
                    if((user_data->cmd_buffer_len + evt->data.rx.len) <= CMD_BUFF_LEN){
                        //case of new data less than remaining space in cmd_buffer
                        memcpy(user_data->cmd_buffer + user_data->cmd_buffer_len, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len);
                        user_data->cmd_buffer_len += evt->data.rx.len;
                    }else{
                        //case of new data more than remaining space
                        memcpy(user_data->cmd_buffer + user_data->cmd_buffer_len, evt->data.rx.buf + evt->data.rx.offset, CMD_BUFF_LEN - user_data->cmd_buffer_len);
                        user_data->cmd_buffer_len += CMD_BUFF_LEN - user_data->cmd_buffer_len;
                    }
                }
                process_buffer(user_data);
    		break;
    		case UART_TX_ABORTED:
    		    printk("UART_TX_ABORTED\n");
    		break;
    		case UART_TX_DONE:
    		    //printk("UART_TX_DONE\n");
                //printk("+SEM=%d\n",k_sem_count_get(user_data->tx_semaphore));
                k_sem_give(user_data->tx_semaphore);
                //printk("+SEM=%d\n",k_sem_count_get(user_data->tx_semaphore));
    		break;
    		case UART_RX_BUF_REQUEST:
                //printk("UART_RX_BUF_REQUEST\n");
                buffer = k_malloc(RX_BUFF_LEN);
                if(buffer == NULL){
                    printk("ERROR : RX_BUF_REQUEST Failed to allocate buffer\n");
                    return;
                }
                error = uart_rx_buf_rsp(uart_info.dev, buffer, RX_BUFF_LEN);
                if(error != 0){
                    printk("ERROR : uart_rx_buf_rsp Failed\n");
                    return;
                }
    		break;
                case UART_RX_BUF_RELEASED:
                k_free(evt->data.rx_buf.buf);
                //printk("UART_RX_BUF_RELEASED\n");
    		break;
    		case UART_RX_DISABLED:
    		    printk("UART_RX_DISABLED\n");
    		break;
    		case UART_RX_STOPPED:
    		    printk("UART_RX_STOPPED\n");
    		break;
    	}
    }

    I think i'm on the right way,

    do you have advice about that ?

    Best regards,

    Lam

Children
No Data
Related