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

Handling the UART when sleeping

I'm using simple_uart_init to enable UART I/O from my target. This all works fine but I'm not sure what to do with the UART before I sleep (by calling sd_app_event_wait) so that it does not consume power.

I'm especially concerned that the GPIO line associated with TX not leak current into the serial terminator.

I'm also slightly concerned that the UART remains "enabled" during sleep and I'm not sure whether it consumes power in that state, even when the CPU is sleeping.

Whatever I do for sleeping, I presume I can call simple_uart_init again when I wake up to set things up again for operation. Is this correct?

Parents
  • Hi Bret,

    simple_uart_init() enables both UART TX and RX (see NRF_UART0->TASKS_STARTTX and NRF_UART0->TASKS_STARTTX). This causes the UART to keep power-consuming HW resources enabled all the time. If you don't need to be able to receive UART data while sleeping, both TX and RX can be disabled before sleeping.

    Note that sd_app_event_wait() only puts the CPU in sleep. Peripherals are kept as you left them, consuming power according to their state. Thus it's not required to run simple_uart_init() once CPU wakes up and execution continues from sd_app_event_wait(). Only stuff explicitly disabled needs to be re-enabled.

    If you are concerned the UART GPIO lines are in an state that can cause leaking, you need to disable the UART (so that it releases the GPIOs) and manually set the pin state. See code example below:

    // Disable UART transmission and reception
    NRF_UART0->TASKS_STOPRX = 1;
    NRF_UART0->TASKS_STOPTX = 1;
    
    // Disable UART to get control of GPIOs
    NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos;
    // Set TXD, RXD, CTS, RTS as high outputs
    // Alternatively use NRF_GPIO->PIN_CNF to set pull resistors
    NRF_GPIO->DIRSET = (1 << UART_TXD_GPIO) | (1 << UART_RXD_GPIO) | (1 << UART_RTS_GPIO) | (1 << UART_CTS_GPIO);
    NRF_GPIO->OUTSET = (1 << UART_TXD_GPIO) | (1 << UART_RXD_GPIO) | (1 << UART_RTS_GPIO) | (1 << UART_CTS_GPIO);
    
    // Enter sleep
    // Note: Still in System ON state. Upon wakeup execution continues from here, and not from reset.
    err_code = sd_app_event_wait();
    // Todo: Check error
    
    // Re-enable UART
    NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos;
    
    // Enable UART transmission and reception
    NRF_UART0->TASKS_STARTRX = 1;
    NRF_UART0->TASKS_STARTTX = 1;
    
Reply
  • Hi Bret,

    simple_uart_init() enables both UART TX and RX (see NRF_UART0->TASKS_STARTTX and NRF_UART0->TASKS_STARTTX). This causes the UART to keep power-consuming HW resources enabled all the time. If you don't need to be able to receive UART data while sleeping, both TX and RX can be disabled before sleeping.

    Note that sd_app_event_wait() only puts the CPU in sleep. Peripherals are kept as you left them, consuming power according to their state. Thus it's not required to run simple_uart_init() once CPU wakes up and execution continues from sd_app_event_wait(). Only stuff explicitly disabled needs to be re-enabled.

    If you are concerned the UART GPIO lines are in an state that can cause leaking, you need to disable the UART (so that it releases the GPIOs) and manually set the pin state. See code example below:

    // Disable UART transmission and reception
    NRF_UART0->TASKS_STOPRX = 1;
    NRF_UART0->TASKS_STOPTX = 1;
    
    // Disable UART to get control of GPIOs
    NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos;
    // Set TXD, RXD, CTS, RTS as high outputs
    // Alternatively use NRF_GPIO->PIN_CNF to set pull resistors
    NRF_GPIO->DIRSET = (1 << UART_TXD_GPIO) | (1 << UART_RXD_GPIO) | (1 << UART_RTS_GPIO) | (1 << UART_CTS_GPIO);
    NRF_GPIO->OUTSET = (1 << UART_TXD_GPIO) | (1 << UART_RXD_GPIO) | (1 << UART_RTS_GPIO) | (1 << UART_CTS_GPIO);
    
    // Enter sleep
    // Note: Still in System ON state. Upon wakeup execution continues from here, and not from reset.
    err_code = sd_app_event_wait();
    // Todo: Check error
    
    // Re-enable UART
    NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos;
    
    // Enable UART transmission and reception
    NRF_UART0->TASKS_STARTRX = 1;
    NRF_UART0->TASKS_STARTTX = 1;
    
Children
No Data
Related