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

How can I enable and disable UART devices at run time on nRF9160?

I need to enable UART1 in runtime in order to be able to read some data coming on that device.

In order to be able to use the uart functionality, I need to set CONFIG_SERIAL=y, otherwise I get compilation errors. So I wonder how can I disable all uart devices and then enable them back on runtime.

I read this thread, but when I tried to implement it for both UART0 and UART1, the application hang.


This how I try to do it:

void disable_uart()
{
    NRF_UARTE1_NS->TASKS_STOPRX=1;
    while(NRF_UARTE1_NS->EVENTS_RXTO == 0);
    NRF_UARTE1_NS->EVENTS_RXTO = 0;

    NRF_UARTE1_NS->TASKS_STOPTX = 1;
    while(NRF_UARTE1_NS->EVENTS_TXSTOPPED == 0);
    NRF_UARTE1_NS->EVENTS_TXSTOPPED = 0;

    NRF_UARTE1_NS->ENABLE = 0;
    NRF_UARTE1_NS->PSEL.TXD = 0xFFFFFFFF;
    NRF_P0_NS->OUTCLR = (1 << 1);



    NRF_UARTE0_NS->TASKS_STOPRX=1;
    while(NRF_UARTE0_NS->EVENTS_RXTO == 0);
    NRF_UARTE0_NS->EVENTS_RXTO = 0;

    NRF_UARTE0_NS->TASKS_STOPTX = 1;
    while(NRF_UARTE0_NS->EVENTS_TXSTOPPED == 0);
    NRF_UARTE0_NS->EVENTS_TXSTOPPED = 0;

    NRF_UARTE0_NS->ENABLE = 0;
    NRF_UARTE0_NS->PSEL.TXD = 0xFFFFFFFF;
    NRF_P0_NS->OUTCLR = (1 << 29);
}

void enable_uart()
{

    NRF_UARTE1_NS->ENABLE = 8;
    NRF_UARTE1_NS->TASKS_STARTRX = 1;
    NRF_UARTE1_NS->TASKS_STARTTX = 1;

    NRF_UARTE0_NS->ENABLE = 8;
    NRF_UARTE0_NS->TASKS_STARTRX = 1;
    NRF_UARTE0_NS->TASKS_STARTTX = 1;
}


So what am I missing?

Thank you very much for your assistance!

Parents Reply Children
  • In the prj.conf the related configurations are the following:

    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=4
    CONFIG_SERIAL=y
    CONFIG_AT_HOST_LIBRARY=y
    CONFIG_UART_1_NRF_UARTE=y
    CONFIG_BSD_LIBRARY_TRACE_ENABLED=n


    I am assuming that switching on and off of the 2 UARTS, would result in toggling printk on and off.

    But it doesn't work out like that. After disabling UART0 once it is not possible to see anything being printed.

    UART1 seems to work though after a cycle of enabling and disabling.

    But my end goal is to achieve low power, so I also need to toggle UART0.

    The overlay I am using is this (I know that those are the defaults, but anyway):

    &uart1 {
    	status = "okay";
    	current-speed = <115200>;
    	tx-pin = <1>;
    	rx-pin = <0>;
    	rts-pin = <14>;
    	cts-pin = <15>;
    };

    This is what I am currently doing to switch them on and off:

    void disable_uart()
    {
        NRF_UARTE1_NS->TASKS_STOPRX=1;
        while(NRF_UARTE1_NS->EVENTS_RXTO == 0);
        NRF_UARTE1->EVENTS_RXTO = 0;
    
        NRF_UARTE1_NS->TASKS_STOPTX = 1;
        while(NRF_UARTE1_NS->EVENTS_TXSTOPPED == 0);
        NRF_UARTE1_NS->EVENTS_TXSTOPPED = 0;
    
        NRF_UARTE1_NS->ENABLE = 0;
        NRF_UARTE1_NS->PSEL.TXD = 0xFFFFFFFF;
        NRF_P0_NS->OUTCLR = (1 << 1);
    
        printk("One UART DOWN\n");
    
        NRF_UARTE0_NS->TASKS_STOPRX=1;
        while(NRF_UARTE0_NS->EVENTS_RXTO == 0);
        NRF_UARTE0_NS->EVENTS_RXTO = 0;
    
        NRF_UARTE0_NS->TASKS_STOPTX = 1;
        while(NRF_UARTE0_NS->EVENTS_TXSTOPPED == 0);
        NRF_UARTE0_NS->EVENTS_TXSTOPPED = 0;
    
        NRF_UARTE0_NS->ENABLE = 0;
        NRF_UARTE0_NS->PSEL.TXD = 0xFFFFFFFF;
        NRF_P0_NS->OUTCLR = (1 << 29);
    }
    
    void enable_uart()
    {
    
       NRF_UARTE1_NS->ENABLE = 8;
       NRF_UARTE1_NS->TASKS_STARTRX = 1;
       NRF_UARTE1_NS->TASKS_STARTTX = 1;
    
       NRF_UARTE0_NS->ENABLE = 8;
       NRF_UARTE0_NS->TASKS_STARTRX = 1;
       NRF_UARTE0_NS->TASKS_STARTTX = 1;
    }

Related