Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Reducing libuarte power consumption getting ERROR 3735928559

Hello,

I've been using the libuarte module in my project, and I done a power consumption reading. With libuarte switched on I'm consuming 0.78ma, and with it switched off is in the uA range. This means I need to turn it off when not in use and back on, when I need it.

Essentially I'm intialising/uninitialising the UART based on interrupts. When testing the code I'm getting the error message:

ERROR 3735928559 [Unknown error code] at C:\Users\yyy\Documents\yyy\yyy\nRF5_SDK_17.1.0_ddde560\modules\nrfx\drivers\src\nrfx_gpiote.c:473
PC at: 0x00020ABB

/**@brief  Function for initializing the UART module.
 */
/**@snippet [UART Initialization] */
static void uart_init(void) {
  uint32_t err_code;

  nrf_libuarte_async_config_t nrf_libuarte_async_config = {
      .tx_pin = TX_PIN_NUMBER,
      .rx_pin = RX_PIN_NUMBER,
      .baudrate = NRF_UARTE_BAUDRATE_57600,
      .parity = NRF_UARTE_PARITY_EXCLUDED,
      .hwfc = NRF_UARTE_HWFC_DISABLED,
      .timeout_us = 200,
      .int_prio = APP_IRQ_PRIORITY_LOW};

  err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, uart_event_handler, (void *)&libuarte);
  APP_ERROR_CHECK(err_code);

  nrf_libuarte_async_enable(&libuarte);
}

volatile static bool uart_en_flag = false;

void ble_pdn_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
  NRF_LOG_PROCESS();
  ret_code_t err_code;
  
  if (uart_en_flag)
  NRF_LOG_INFO("Disabling UART");
  uart_en_flag = false;
  nrf_libuarte_async_uninit(&libuarte);
}

void ble_wakeup_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
  NRF_LOG_PROCESS();
    ret_code_t err_code;


  adv_serv_data[1] = 0xAA;
  adv_data_update(adv_serv_data);

  if (!uart_en_flag)
  {
    NRF_LOG_INFO("Enabling UART");
      err_code = nrf_drv_gpiote_init();
  APP_ERROR_CHECK(err_code);

      nrf_libuarte_async_config_t nrf_libuarte_async_config = {
      .tx_pin = TX_PIN_NUMBER,
      .rx_pin = RX_PIN_NUMBER,
      .baudrate = NRF_UARTE_BAUDRATE_57600,
      .parity = NRF_UARTE_PARITY_EXCLUDED,
      .hwfc = NRF_UARTE_HWFC_DISABLED,
      .timeout_us = 200,
      .int_prio = APP_IRQ_PRIORITY_LOW};

  err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, uart_event_handler, (void *)&libuarte);
  APP_ERROR_CHECK(err_code);

  nrf_libuarte_async_enable(&libuarte);

  }

}

/**
 * @brief Function for configuring two interrupt pins, and one output.
 */
static void gpio_init(void) {
  ret_code_t err_code;

  err_code = nrf_drv_gpiote_init();
  APP_ERROR_CHECK(err_code);

  /* Initialse LED as an output */
  nrf_gpio_cfg_output(LED_1);
  nrf_gpio_pin_set(LED_2);

  nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
  in_config.pull = NRF_GPIO_PIN_PULLUP;

  err_code = nrf_drv_gpiote_in_init(BUTTON_1, &in_config, ble_pdn_handler);
  APP_ERROR_CHECK(err_code);

  nrf_drv_gpiote_in_event_enable(BUTTON_1, true);

  err_code = nrf_drv_gpiote_in_init(BUTTON_2, &in_config, ble_wakeup_handler);
  APP_ERROR_CHECK(err_code);

  nrf_drv_gpiote_in_event_enable(BUTTON_2, true);
}

Calling nrf_libuarte_async_uninit(&libuarte) seems to work fine, but when trying to reinitialise the libuarte I'm getting the error above. It looks like from the error it has something to do with gpiote. Am I doing the process of of turning on/off the uart periperhal wrong?

Parents
  • Hi,

    The error code mean an assert occurred. By looking in the mentioned file and line, this is caused by the second assert check in nrfx_gpiote_set_task_get():

    nrf_gpiote_tasks_t nrfx_gpiote_set_task_get(nrfx_gpiote_pin_t pin)
    {
        NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
        NRFX_ASSERT(pin_in_use_by_te(pin));
    
        return TE_SET_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
    }

    This could mean that the requested pin is not configured by the GPIOTE at the moment when it is being used by libUARTE. I do not know exactly how this could happen, but if there is some logic error in your code, it could cause issues.

    Do you get the error when running the function nrf_libuarte_async_init, or could it be from a different function? Can you provide the call stack when this error occurs? You can set a breakpoint in the app_error_handler()/app_error_fault_handler() to read out the call stack with the debugger. 

    It looks like you are missing some curtly brackets in your ble_pdn_handler() function. As it is now, you will always uninit libUARTE, regardless of the value of the uart_en_flag variable. I'm not sure if this is related to your problem, but it should likely be fixed.

    You should also not need to call nrf_drv_gpiote_init() when initializing libUARTE, unless you have uninitialized it somewhere else (which I can't see that you are doing in the posted code).

    Can you post your full code, for us to be sure how the flow looks?

    Best regards,
    Jørgen

Reply
  • Hi,

    The error code mean an assert occurred. By looking in the mentioned file and line, this is caused by the second assert check in nrfx_gpiote_set_task_get():

    nrf_gpiote_tasks_t nrfx_gpiote_set_task_get(nrfx_gpiote_pin_t pin)
    {
        NRFX_ASSERT(nrf_gpio_pin_present_check(pin));
        NRFX_ASSERT(pin_in_use_by_te(pin));
    
        return TE_SET_IDX_TO_TASK_ADDR((uint32_t)channel_port_get(pin));
    }

    This could mean that the requested pin is not configured by the GPIOTE at the moment when it is being used by libUARTE. I do not know exactly how this could happen, but if there is some logic error in your code, it could cause issues.

    Do you get the error when running the function nrf_libuarte_async_init, or could it be from a different function? Can you provide the call stack when this error occurs? You can set a breakpoint in the app_error_handler()/app_error_fault_handler() to read out the call stack with the debugger. 

    It looks like you are missing some curtly brackets in your ble_pdn_handler() function. As it is now, you will always uninit libUARTE, regardless of the value of the uart_en_flag variable. I'm not sure if this is related to your problem, but it should likely be fixed.

    You should also not need to call nrf_drv_gpiote_init() when initializing libUARTE, unless you have uninitialized it somewhere else (which I can't see that you are doing in the posted code).

    Can you post your full code, for us to be sure how the flow looks?

    Best regards,
    Jørgen

Children
  • I've attached my project, and I put the code to how it originally was, and getting a different error:

    <info> app_timer: RTC: initialized.
    <debug> nrf_sdh: State request: 0x00000000
    <debug> nrf_sdh: Notify observer 0x0002FB0C => ready
    <debug> nrf_sdh: State change: 0x00000000
    <debug> nrf_sdh: State change: 0x00000001
    <debug> nrf_sdh_ble: RAM starts at 0x20002730
    <debug> nrf_ble_lesc: Initialized nrf_crypto.
    <debug> nrf_ble_lesc: Initialized nrf_ble_lesc.
    <debug> nrf_ble_lesc: Generating ECC key pair
    <info> app: Fast advertising.
    <info> app: Disabling UART
    <info> app: Enabling UART
    <error> app: ERROR 3735928559 [Unknown error code] at C:\Users\yyy\Desktop\test_project\nRF5_SDK_17.1.0_ddde560\modules\nrfx\drivers\src\nrfx_timer.c:179
    PC at: 0x00021557
    <error> app: End of error report

    Code works without dealing with the unitialising/reinitialising the uart. By default it's turned on, however I need to change it to be turned off initially. However, how it is the nrf_libuarte_async_init() does work on startup. Looking at the logs, when I press the button to uninitialise it, it seems to work. But pressing the other button to reinitialise it seems to cause the error.

    test_project.zip

  • Most likely you get this error because you call nrf_libuarte_async_enable() after a nrf_libuarte_async_uninit(), without first calling nrf_libuarte_async_init(). The timer used by libUARTE async is setup in the init function, and it will be uninitialized at the time you try to enable the async function.

  • Ok, but if I replace the in nrf_libuarte_async_enable() the ble_wakeup_handler to uart_init(), i get the original error about nrfx_gpiote.c:473.

    I get this same error if I call nrf_libuarte_async_init() first then nrf_libuarte_async_enable(), in the ble_wakeup_handler().

  • Did you check the call stack using the debugger when the problem occurs?

    Do you print logs whenever you init and uninit the UART? Is there any problems seen in the log?

    Have you tried moving the init/uninit out og the interrupt/event handlers, to make sure there is no interrupt priority problem causing one of the functions to be called when the other is executing?

    If you are not able to resolve it, I can try to reproduce using your code.

  • Call stack looks like in the image below. Looks like it's failing at: NRFX_ASSERT(pin_in_use_by_te(pin));

    I haven't tried moving it out the interrupt, but will give it a go.

Related