contiki-ng
contiki-ng copied to clipboard
NRF52840 radio power on/off operation improvement
Currently the nrf52840 radio driver switches off the radio by powering off the whole radio peripheral, erasing the radio's config registers during each cycle. A better approach would be powering down only the radio circuitry while retaining the stored register configs. This can be done using the radio's DISABLE task command.
This pull request replaces clearing of the POWER register with DISABLE.
Setting up the radio registers every time was an intentional design decision for this port, as while this is not used in contiki-ng, it allows for use of the radio peripheral by other applications during MAC downtime (i.e. between TSCH slots) without worrying about restoring state correctly.
Is there a benefit you see to disabling the peripheral instead?
All right. So you intend for multiple stacks over the radio, each with their own radio configuration. Then I certainly agree that the config registers must be restored every time the radio is switched on.
But I still prefer switching on/off the radio with RXEN and DISABLE to powering on/off it completely. The main reason is that, according to the radio states described in the nRF52840 product specification, the DISABLE command puts the radio into the DISABLED state, which generates an DISABLED event. That event can be used to trigger an interrupt, another radio task (predefined in the SHORTS register), or other debugging mechanisms. Powering off the radio directly does not generate such an event.
A potential advantage of powering the radio completely off is saving a little extra power. But I guess that benefit comes into play only when the radio duty cycle is extremely low. And the documentation says that, in the DISABLED state, "No operations are going on inside the radio and the power consumption is at a minimum".
Can we reach a conclusion on this PR? @alexstanoev what did you think about the explanation from @zhitaoh?
I'm aware of downstream users that rely on the current radio behavior; without toggling the power register the radio registers may be in an inconsistent state if modified by a concurrent protocol stack.
A middle ground that will fire the DISABLED event is to issue nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE)
in off()
, poll for the DISABLED event and then turn off the peripheral's power.
I have updated the pull request as @alexstanoev suggested. This should preserve the original behaviour. The delta is quite small now, so I hope we can close this case reasonably fast.
Regarding the multi-stack use case Alex described, I think ideally there will be a test case or a code example, and some documentation, to explicitly outline the requirements for safe stack switching.
I have also implemented a few other power-saving optimizations on this radio driver, and have tested them on a single Contiki TSCH stack. Ensuring the modifications do not break the currently under-documented multistack use case, however, seem to require a test case. But let's not get distracted here and leave the discussion to another thread.