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

  • Hi, I'm sorry for not getting back to you sooner. Because of summer vacations there are some delays in our response time. I will answer all your questions later tonight. Sorry for the inconvenience.

  • Hi Stian, that is all right. Thank you for your answer.

  • Hi,

    1. Yes on nRF53 you have System ON, System OFF, and Force OFF for the network core.
      In System ON the CPU can be running or it can be idle, and the sub-mode "constant latency" can be enabled or disabled. Constant latency keeps some of the high frequency clocks running, so that going from idle to run mode happens faster, i.e. CPU ready to execute code faster when it wakes up.
      1.  
        • The chip enters system off with the PM_STATE_SOFT_OFF as shown in the system_off sample.
        • The chip is always in system ON, if nothing else is specified
        • I don't see any references to Constant Latency in zephyr, so I would assume that you will have to write to the TASKS_CONSTLAT register. I will have to check.
        • You control the power state of the peripherals using device_get_binding(). The only relevant power modes for the peripherals are either PM_DEVICE_STATE_LOW_POWER or PM_DEVICE_STATE_ACTIVE, as far as I know.
        • I would not control the state of the CPU with device_get_binding(). Because the CPU really does not have any "states", in that sense. Either it's executing code or it waits in a WFE state, and this is controlled by Zephyr. System OFF is referring the complete state of the chip, not just the CPU. And in constant latency mode, you keep some HF clocks running, but the CPU operation/state is basically the same as in "low power" mode.
      2. Correct. I guess you can use __WFE(), but that is not recommended. k_cpu_idle is basically a WFE in the end, but it checks some things before going to WFE. That's part of how zephyr handles CPU idle, and it should always be used. Of course there are other functions you can use to put the CPU to sleep, e.g. k_msleep to specify a sleep period, or just let the thread run to the end I.e. If you don't have a for-loop at the end of main(), zephyr will automatically put the CPU to idle, and wait for other threads to wake it up. So, you are not required to have a main loop, as in the old SDK.
      3. Since zephyr is used by many different platforms there are lots of states that are not relevant to the nRF53. The only relevant states is ACTIVE and LOW_POWER, and possibly OFF, as far as I know. But these are peripheral states, not CPU/system states. And the states are more in the higher layer/driver context, not so much at the hardware layer, which is documented in the PS.
    2. There are no KConfig options for NETWORK.FORCEOFF, but it would have to be set during code initialization anyways. Of course it would be possible to turn off the network core a bit earlier in the process before it enters main if a config option was implemented, but I guess you can do that yourself as well if you want, by editing the startup files.

     Hope that answers some of your questions. Feel free to ask more if something is unclear.

  • Hi Stian,

    thank you for your answers.

    I have some follow-up questions:

    1. I don't see any references to Constant Latency in zephyr, so I would assume that you will have to write to the TASKS_CONSTLAT register. I will have to check.
      In the code below, I set the system first in the Constant Latency and later in the Low Power submode.

       //CPU and all peripherals are Idle
            NRF_POWER_NS->TASKS_CONSTLAT = 0x0001;     //Set system in power submode Constant Latency
            
            [some other code]
            NRF_POWER_NS->TASKS_CONSTLAT = 0x0000;     //Deactivate submode Constant Latency
            NRF_POWER_NS->TASKS_LOWPWR = 0x0001;       //Set system in power submode Low Power

    The product specification states that "In System ON mode, when the CPU and all peripherals are IDLE, the system can reside in one of two power submodes." (Chapter 4.1.1 - Power Submodes).
    What would happen if either of the submodes was set while the CPU and/or all peripherals are not in IDLE? Does an error occur? Is there any function/register to check that the submode was set successfully?

    2. You control the power state of the peripherals using device_get_binding(). The only relevant power modes for the peripherals are either PM_DEVICE_STATE_LOW_POWER or PM_DEVICE_STATE_ACTIVE, as far as I know.

    The product specification states that "peripherals can be in an idle and run state" (Chapter 4.1 - System ON Mode).
    I assume that PM_DEVICE_STATE_ACTIVE corresponds to the run state and PM_DEVICE_STATE_LOW_POWER to the idle state.

    Thanks again.

Related