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

How to close UART to save power for nRF52810

Hi,

I'm using SDK v14.2 and s112_5.1.0 for nRF52810 basing on the ble_app_uart example. Now we use the uart to communicate with external MCU. Also we want to close uart to save power when there is no data transmitting. I have used the BSP module to configure a gpio to control the UART, enable the UART when the gpio level is low, disable the UART when the gpio level is high. But if I enabled or disable UART in the bsp_event_handler, it couldn't be successful and it would stop running. Is there any problem with the function? Could you give me some advice how to do is better?

Enabled UART:

void app_uart_open(void){
uint32_t                     err_code;
const app_uart_comm_params_t  comm_params =
{
    .rx_pin_no    = RX_PIN_NUMBER,
    .tx_pin_no    = TX_PIN_NUMBER,
    .rts_pin_no   = RTS_PIN_NUMBER,
    .cts_pin_no   = CTS_PIN_NUMBER,
    .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
    .use_parity   = false,
    .baud_rate    = UARTE_BAUDRATE_BAUDRATE_Baud9600
};

APP_UART_FIFO_INIT(&comm_params,
                   UART_RX_BUF_SIZE,
                   UART_TX_BUF_SIZE,
                   uart_event_handle,
                   APP_IRQ_PRIORITY_LOWEST,
                   err_code);
APP_ERROR_CHECK(err_code);}

Disabled UART:

uint32_t app_uart_close(void){
nrf_drv_uart_uninit(&app_uart_inst);
return NRF_SUCCESS;}

BSP event:

void bsp_event_handler(bsp_event_t event){
switch (event)
{
    case BSP_EVENT_UART_SLEEP:			
	app_uart_close();									
        break;

    case BSP_EVENT_UART_WORK:
    app_uart_open();																							
        break;
}}
Parents
  • Are you using the logger module with UART as backend and without deferred logging? It could be a problem related to my comment from January 11th here. nrf_drv_uart_uninit () is trying to print messages to the logger module, and if you do this over UART I figure that you might get stuck if you call it from the interrupt context of the bsp_event_handler. app_uart_open() will also end up in an error handler if you try to call it more than once without successfully calling nrf_drv_uart_uninit() in between. It could help to either:

    1. Increase the interrupt priority of the UART to e.g. APP_IRQ_PRIORITY_HIGH.
    2. Move your calls to app_uart_close() and app_uart_open() into your maint context.
    3. Use deferred logging and flush the message with NRF_LOG_FLUSH() in your main context. Logger documentation.
  • I have declared uart_status as 'volatile'. Also I use NRF_UARTE0->ENABLE = 8; and NRF_UARTE0->ENABLE = 0; to instead of app_uart_open() and app_uart_close(). I could see the current and it's 2.6uA when disable UART while it's about 650uA when enabled UART. UART could send data after it's enabled. But once use PC to send the UART more than two times, it would get stuck and stop running at the app_error_fault_handler function. That's to say, UART couldn't receive any data after enabled. Could you help me have a test on the ble_app_uart example? Thanks very much.

    This link text is my complete project. I use P0.31 to generate the high or low level to enabled or disable UART.

Reply
  • I have declared uart_status as 'volatile'. Also I use NRF_UARTE0->ENABLE = 8; and NRF_UARTE0->ENABLE = 0; to instead of app_uart_open() and app_uart_close(). I could see the current and it's 2.6uA when disable UART while it's about 650uA when enabled UART. UART could send data after it's enabled. But once use PC to send the UART more than two times, it would get stuck and stop running at the app_error_fault_handler function. That's to say, UART couldn't receive any data after enabled. Could you help me have a test on the ble_app_uart example? Thanks very much.

    This link text is my complete project. I use P0.31 to generate the high or low level to enabled or disable UART.

Children
No Data
Related