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

Some questions about nRF53 and nRF Connect SDK

Hello Nordic Team,

as a newbie in the Nordic world, I have been reading the nRF Connect SDK and Zephyr documentation as well as testing some of the samples on my nRF5340DK. However, I still have some (mainly conceptual) questions:

  1. Power management
    According to the Product Specification, there are three modes of operation: System On (run, idle(constant latency, low power)), System Off and Force-Off (only for the Network Core).

    1. How can I switch between the different states? If i understood correctly, for the old SDK (nRF SDK5), Softdevice provided the necessary functions. Now with nRF Connect SDK, we have Zephyr-Power Management but also the possibility to modify the registers directly (e.g. TASKS_CONSTLAT, TASKS_LOWPWR, SYSTEMOFF). Unfortunately, I cannot quite understand how to procede and the difference between the two methods.

      Please correct any of the following assumptions, if I am wrong.
      -> Using Zephyr, we first retrieve the device struct with device_get_binding(). With that method we can then individually set the state of any CPU/peripheral defined in the device tree.
      -> By directly using the registers, we can make the core state idle-low power or idle-constant latency. This means, that we are setting all peripherals and the cpu in the same state at the same time.

      Is it enough with e.g. NRF_POWER->TASKS_CONSTLAT? Are there any examples of directly modifying the registers?
      Does Zephyr have any equivalent API for that?

    2. The function k_cpu_idle, makes the CPU idle. Are there any other ways to make the CPU Idle (e.g. running WFI or WFE instructions)?

    3. In sample zephyr/samples/boards/nrf/system_off, the UART is set to different power modes using the function pm_device_state_set().
      I noticed that the state is set using the defines from zephyr/include/pm/device.h: PM_DEVICE_STATE_ACTIVE, PM_DEVICE_STATE_LOW_POWER, PM_DEVICE_STATE_SUSPEND, PM_DEVICE_STATE_FORCE_SUSPEND, PM_DEVICE_STATE_OFF.
      Do these states really correspond to the modes of operation described in the Product Specification? If so, how?

  2. Working with a dual core
    1. I assume that both CPUs start at the same time after a power up. Using NETWORK.FORCEOFF we can decide that the network core does not start after a reset.
      Can the prj.conf or KConfig files be somehow modified to replicate the behaviour of NETWORK.FORCEOFF from the very beginning?. This means, that the network core would never start, not even after a power up.

Sorry if some of the questions do not make much sense. I am still processing so much information!
Many thanks in advance! Slight smile

  • Hello

    1. The TASKS_xx registers can only be written 1 (not 0), and it can not be read to see the status of the register.

      So in this case, you write to TASKS_CONSTLAT to enable constant latency, and to TASKS_LOWPWR to disable constant latency. You code should look like this:
      NRF_POWER_NS->TASKS_CONSTLAT = 1;     //Set system in power submode Constant Latency
      [some other code]
      NRF_POWER_NS->TASKS_LOWPWR = 1;       //Deactivate submode Constant Latency and set system in power submode Low Power
      The CPU itself is used to execute the code above, so the CPU will never be "idle" when the chip changes from LOWPWR to CONSTLAT or vice versa. The system state is changed immediately when the CPU writes to one of the two TASKS_xx registers.

      You do not need to call LOWPWR every time the chip is going to sleep. You should look at this as: either CONSTLAT is enabled, or it's not.

      I can try to explain the following statement: "In System ON mode, when the CPU and all peripherals are IDLE, the system can reside in one of two power submodes."

      If we first consider the LOWPWR scenario:
      - The CPU is idle, clocks and most resources are turned off
      - An interrupt occurs
      - The clocks and resources needed for the CPU to run is started. This takes some time
      - The CPU executes code requested by the interrupt
      - When it finishes, the CPU goes back to idle (WFE)
      - Clocks and resources are turned off.

      Then the CONSTLAT scenario:
      - The CPU is idle. Clocks and resources needed by the CPU are still running
      - An interrupt occurs
      - The CPU executes code requested by the interrupt immediately.
      - When it finishes, the CPU goes back to idle (WFE)

      So, what the statement means is that CONSTLAT will not have any effect if the CPU is already running, because the resources that CONSTLAT is keeping alive is always running when the CPU is executing code. That's why we are talking about CONSTLAT as a mode the chip will reside in when being in idle.

      Anyways, CPU being idle or not is handled by the Zephyr OS, and is not something the developer should worry too much about. The questions you should ask regarding Constant Latency being enabled or not is the following:

      - Does my code have very strict timing requirements that actually need constant latency mode?
      - And, am I willing to sacrifice the low idle current?

      If not, you do not need to worry about either the CONSTLAT or the LOWPWR register.
    2. Yes, peripherals can be in idle or run state. They are in idle when only the ENABLE register is set to 1, and in run state when e.g. the RX line is waiting for incoming data. This is the low layer hardware specification of being in "active" vs "idle" mode.

      However, the zephyr LOW_POWER vs ACTIVE state is not always directly translatable to the hardware modes. It really depends on the peripheral being used. For most peripherals LOW_POWER actually means "disabled" (i.e. ENABLE register = 0), because there are no reason to keep the device enabled if it is not being used. For some peripherals ACTIVE means that it is waiting for incoming data (e.g. UART and SPI slave), while peripherals that initiates the transaction (like SPI/TWI master), does not need to keep any RX lines active, so then ACTIVE just means that the peripheral is initialized and ready to be used, and might not necessarily consume any current.

      But yes, in general I would say that this statement is correct: "I assume that PM_DEVICE_STATE_ACTIVE corresponds to the run state and PM_DEVICE_STATE_LOW_POWER to the idle state."
Related