Sleep current during k_sleep()

In a nrf52840 project using Zephyr 3.0 following Zephyr drivers are used:

  • the modbus serial driver(RTU mode) which uses uart1 in interrupt mode
  • the lora-mac driver which uses spi1
  • serial logging on uart0

The application works fine but during inactivity periods the standby current is sometimes much too high: 520uA instead of ~10uA

I know that the uarts don't suspend automatically so immediately before k_sleep() I execute:

pm_device_action_run(uart0, PM_DEVICE_ACTION_SUSPEND);
pm_device_action_run(uart1, PM_DEVICE_ACTION_SUSPEND);

Without success I also tried:

  • executing nrf_uart_errorsrc_get_and_clear() for both uarts before k_sleep().
  • disable logging completely but as well without success.
  • "disable" all unneeded periphery in the device tree.
  • checked thread activity via the Zephyr Thread Analyzer but I could not find excessive activity.
  • executing pm_device_action_run()  for spi1, gpio0, gpio1 , ...
  • modbus_disable() during sleep
  •  ...

Do you have any hints how I could enclose or solve the problem?

Thx  Matthias

  • May transitions on uart1 RXD during k_sleep() be a problem even when before k_sleep() 

    pm_device_action_run(uart1, PM_DEVICE_ACTION_SUSPEND) is a applied?

    (I have to power off the modbus RS485 transciever during sleep so transition on RX might occure...)

  • Hi, sorry for the late response

    Transitions on RX could be causing interrupts, which would be an issue.
    Could you keep the pin stable during sleep to test whether that reduces the current?
    It could also be a good idea to avoid going to sleep while the uart is sending or receiving.

  • Unfortunately I can't prevent transitions on RX without additional logic.

    But I had some progress ...

    By defining 'CONFIG_LOG_MODE_IMMEDIATE=y' and additionally waiting about 50ms (by a additional k_sleep() possibly  to write out the interrupt driven buffer) and thereafter put the uarts into suspend mode as follows:

    while (log_process(false));   // unneeded when CONFIG_LOG_MODE_IMMEDIATE=y

    pm_device_action_run(uart0, PM_DEVICE_ACTION_SUSPEND);
    pm_device_action_run(uart1, PM_DEVICE_ACTION_SUSPEND);
    nrf_uart_errorsrc_get_and_clear((NRF_UART_Type *)0x40002000);
    nrf_uart_errorsrc_get_and_clear((NRF_UART_Type *)0x40002800);
    k_sleep(several minutes)

    ... the standby current will go down to 12uA .

    But unfortunately when enabling the BLE stack by use of 'CONFIG_LOG_MODE_IMMEDIATE' results in following compiler error:
    error: static assertion failed: "Immediate logging on selected backend(s) not supported with the software Link Layer"

    So I had to be disabled logging completely by 'CONFIG_LOG=n' .

    And regarding your suggestion it seems the problem is not caused by the transitions on uart1 (which is used for RS485 Modbus) but by the console logging task.

    I can live with this solution but the 12uA are still a bit high according the nrf52840 product datasheet.

    Shouldn't it about 3uA in SYSTEM-ON mode when using the LF clock (RC or XTAL)?

    What could be the reason for the additional 9uA?

  • Take a look at this guide for optimizing power on nRF52: https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/optimizing-power-on-nrf52-designs

    If you are using a custom board, are there any other chips on the board which may be contributing to this current draw?

    How are you measuring the current? If you are using a PPK could you upload the power profiler trace?

  • Thx for suggestion but I already checked the power optimization guide you referred and took all into account. (Unfortunately there is no nrf52 specific guide for zephyr.)

    I ordered a PPK2 but will have to wait about a month - I will come back if I get it.

Related