samples: nordic: system_off: use retained_mem on all targets
Using bare-metal approach for retention configuration
is no longer compatible with sys_poweroff() implementation.
Signed-off-by: Nikodem Kastelik <nikodem.kastelik@nordicsemi.no>
diff --git a/samples/boards/nordic/system_off/CMakeLists.txt b/samples/boards/nordic/system_off/CMakeLists.txt
index 1cff779..a4105e4 100644
--- a/samples/boards/nordic/system_off/CMakeLists.txt
+++ b/samples/boards/nordic/system_off/CMakeLists.txt
@@ -5,6 +5,6 @@
project(nrf_system_off)
target_sources(app PRIVATE src/main.c)
-if (CONFIG_APP_USE_NRF_RETENTION OR CONFIG_APP_USE_RETAINED_MEM)
+if(CONFIG_APP_USE_RETAINED_MEM)
target_sources(app PRIVATE src/retained.c)
endif()
diff --git a/samples/boards/nordic/system_off/Kconfig b/samples/boards/nordic/system_off/Kconfig
index 6500baf..c7b4a9f 100644
--- a/samples/boards/nordic/system_off/Kconfig
+++ b/samples/boards/nordic/system_off/Kconfig
@@ -3,23 +3,9 @@
mainmenu "Nordic SYSTEM_OFF demo"
-choice
- prompt "Use retention"
- optional
-
-config APP_USE_NRF_RETENTION
- bool "Use state retention in system off using nRF POWER"
- depends on SOC_COMPATIBLE_NRF52X && CRC
- help
- On some Nordic chips this application supports retaining
- memory while in system off using POWER peripheral.
- Select this to enable the feature.
-
config APP_USE_RETAINED_MEM
bool "Use state retention in system off using retained_mem driver"
- depends on RETAINED_MEM
-
-endchoice
+ select RETAINED_MEM
config GPIO_WAKEUP_ENABLE
bool "Use button to wake up device from system off"
diff --git a/samples/boards/nordic/system_off/README.rst b/samples/boards/nordic/system_off/README.rst
index 7c98a4e..5124d08 100644
--- a/samples/boards/nordic/system_off/README.rst
+++ b/samples/boards/nordic/system_off/README.rst
@@ -13,10 +13,10 @@
RAM Retention
=============
-This sample can also can demonstrate RAM retention. By selecting
-``CONFIG_APP_USE_NRF_RETENTION=y`` or ``CONFIG_APP_USE_RETAINED_MEM=y``
-state related to number of boots, number of times system off was entered,
-and total uptime since initial power-on are retained in a checksummed data structure.
+This sample can also demonstrate RAM retention.
+By selecting ``CONFIG_APP_USE_RETAINED_MEM=y`` state related to number of boots,
+number of times system off was entered, and total uptime since initial power-on
+are retained in a checksummed data structure.
RAM is configured to keep the containing section powered while in system-off mode.
Requirements
diff --git a/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay b/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay
new file mode 100644
index 0000000..c203d90
--- /dev/null
+++ b/samples/boards/nordic/system_off/boards/nrf52840dk_nrf52840.overlay
@@ -0,0 +1,22 @@
+/ {
+ sram0@2003f000 {
+ compatible = "zephyr,memory-region", "mmio-sram";
+ reg = <0x2003f000 DT_SIZE_K(4)>;
+ zephyr,memory-region = "RetainedMem";
+ status = "okay";
+
+ retainedmem0: retainedmem {
+ compatible = "zephyr,retained-ram";
+ status = "okay";
+ };
+ };
+
+ aliases {
+ retainedmemdevice = &retainedmem0;
+ };
+};
+
+&sram0 {
+ /* Shrink SRAM size to avoid overlap with retained memory region */
+ reg = <0x20000000 DT_SIZE_K(252)>;
+};
diff --git a/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay b/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay
new file mode 100644
index 0000000..13e2e99
--- /dev/null
+++ b/samples/boards/nordic/system_off/boards/nrf52dk_nrf52832.overlay
@@ -0,0 +1,22 @@
+/ {
+ sram0@20007000 {
+ compatible = "zephyr,memory-region", "mmio-sram";
+ reg = <0x20007000 DT_SIZE_K(4)>;
+ zephyr,memory-region = "RetainedMem";
+ status = "okay";
+
+ retainedmem0: retainedmem {
+ compatible = "zephyr,retained-ram";
+ status = "okay";
+ };
+ };
+
+ aliases {
+ retainedmemdevice = &retainedmem0;
+ };
+};
+
+&sram0 {
+ /* Shrink SRAM size to avoid overlap with retained memory region */
+ reg = <0x20000000 DT_SIZE_K(28)>;
+};
diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp.overlay
similarity index 100%
rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp_retained_mem.overlay
rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l05_cpuapp.overlay
diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp.overlay
similarity index 100%
rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp_retained_mem.overlay
rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l10_cpuapp.overlay
diff --git a/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay b/samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp.overlay
similarity index 100%
rename from samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay
rename to samples/boards/nordic/system_off/boards/nrf54l15dk_nrf54l15_cpuapp.overlay
diff --git a/samples/boards/nordic/system_off/sample.yaml b/samples/boards/nordic/system_off/sample.yaml
index 33db0a6..4732871 100644
--- a/samples/boards/nordic/system_off/sample.yaml
+++ b/samples/boards/nordic/system_off/sample.yaml
@@ -23,33 +23,18 @@
- "system off demo"
- "Retained data not supported"
- "Entering system off; press sw0 to restart"
- sample.boards.nrf.system_off.nrf_retained:
+ sample.boards.nrf.system_off.retained_mem:
integration_platforms:
- nrf52840dk/nrf52840
platform_allow:
- nrf52840dk/nrf52840
- nrf52dk/nrf52832
- extra_configs:
- - CONFIG_APP_USE_NRF_RETENTION=y
- harness: console
- harness_config:
- type: multi_line
- ordered: true
- regex:
- - "system off demo"
- - "Retained data: INVALID"
- - "Boot count: 1"
- - "Off count: 0"
- - "Active Ticks:"
- - "Entering system off; press sw0 to restart"
- sample.boards.nrf.system_off.retained_mem:
- extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay"
- platform_allow:
+ - nrf54l15dk/nrf54l05/cpuapp
+ - nrf54l15dk/nrf54l10/cpuapp
- nrf54l15dk/nrf54l15/cpuapp
- nrf54l20pdk/nrf54l20/cpuapp
extra_configs:
- CONFIG_APP_USE_RETAINED_MEM=y
- - CONFIG_RETAINED_MEM=y
harness: console
harness_config:
type: multi_line
@@ -63,6 +48,8 @@
- "Entering system off; press sw0 to restart"
sample.boards.nrf.system_off.grtc_wakeup:
platform_allow:
+ - nrf54l15dk/nrf54l05/cpuapp
+ - nrf54l15dk/nrf54l10/cpuapp
- nrf54l15dk/nrf54l15/cpuapp
- nrf54l20pdk/nrf54l20/cpuapp
extra_configs:
@@ -83,15 +70,15 @@
- "Retained data not supported"
- "Entering system off; wait 2 seconds to restart"
sample.boards.nrf.system_off.retained_mem.grtc_wakeup:
- extra_args: DTC_OVERLAY_FILE="boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay"
platform_allow:
+ - nrf54l15dk/nrf54l05/cpuapp
+ - nrf54l15dk/nrf54l10/cpuapp
- nrf54l15dk/nrf54l15/cpuapp
- nrf54l20pdk/nrf54l20/cpuapp
extra_configs:
- CONFIG_APP_USE_RETAINED_MEM=y
- CONFIG_GRTC_WAKEUP_ENABLE=y
- CONFIG_GPIO_WAKEUP_ENABLE=n
- - CONFIG_RETAINED_MEM=y
harness: console
harness_config:
type: multi_line
@@ -135,7 +122,7 @@
extra_args:
- "DTC_OVERLAY_FILE=
boards/nrf54l15dk_nrf54l15_cpuapp_comparator.overlay;
- boards/nrf54l15dk_nrf54l15_cpuapp_retained_mem.overlay"
+ boards/nrf54l15dk_nrf54l15_cpuapp.overlay"
platform_allow:
- nrf54l15dk/nrf54l15/cpuapp
extra_configs:
diff --git a/samples/boards/nordic/system_off/src/main.c b/samples/boards/nordic/system_off/src/main.c
index 3e8e084..e8617be 100644
--- a/samples/boards/nordic/system_off/src/main.c
+++ b/samples/boards/nordic/system_off/src/main.c
@@ -40,7 +40,7 @@
printf("\n%s system off demo\n", CONFIG_BOARD);
- if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
+ if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
bool retained_ok = retained_validate();
/* Increment for this boot attempt and update. */
@@ -92,7 +92,7 @@
return 0;
}
- if (IS_ENABLED(CONFIG_APP_USE_NRF_RETENTION) || IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
+ if (IS_ENABLED(CONFIG_APP_USE_RETAINED_MEM)) {
/* Update the retained state */
retained.off_count += 1;
retained_update();
diff --git a/samples/boards/nordic/system_off/src/retained.c b/samples/boards/nordic/system_off/src/retained.c
index 66f6a35..316ec16 100644
--- a/samples/boards/nordic/system_off/src/retained.c
+++ b/samples/boards/nordic/system_off/src/retained.c
@@ -15,147 +15,24 @@
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/crc.h>
-#if CONFIG_APP_USE_NRF_RETENTION
-#include <hal/nrf_power.h>
-
-/* nRF52 RAM (really, RAM AHB slaves) are partitioned as:
- * * Up to 8 blocks of two 4 KiBy byte "small" sections
- * * A 9th block of with 32 KiBy "large" sections
- *
- * At time of writing the maximum number of large sections is 6, all
- * within the first large block. Theoretically there could be more
- * sections in the 9th block, and possibly more blocks.
- */
-
-/* Inclusive address of RAM start */
-#define SRAM_BEGIN (uintptr_t)DT_REG_ADDR(DT_NODELABEL(sram0))
-
-/* Exclusive address of RAM end */
-#define SRAM_END (SRAM_BEGIN + (uintptr_t)DT_REG_SIZE(DT_NODELABEL(sram0)))
-
-/* Size of a controllable RAM section in the small blocks */
-#define SMALL_SECTION_SIZE 4096
-
-/* Number of controllable RAM sections in each of the lower blocks */
-#define SMALL_SECTIONS_PER_BLOCK 2
-
-/* Span of a small block */
-#define SMALL_BLOCK_SIZE (SMALL_SECTIONS_PER_BLOCK * SMALL_SECTION_SIZE)
-
-/* Number of small blocks */
-#define SMALL_BLOCK_COUNT 8
-
-/* Span of the SRAM area covered by small sections */
-#define SMALL_SECTION_SPAN (SMALL_BLOCK_COUNT * SMALL_BLOCK_SIZE)
-
-/* Inclusive address of the RAM range covered by large sections */
-#define LARGE_SECTION_BEGIN (SRAM_BEGIN + SMALL_SECTION_SPAN)
-
-/* Size of a controllable RAM section in large blocks */
-#define LARGE_SECTION_SIZE 32768
-
-#elif CONFIG_APP_USE_RETAINED_MEM
+#if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(retainedmemdevice))
const static struct device *retained_mem_device = DEVICE_DT_GET(DT_ALIAS(retainedmemdevice));
-#endif
-
-/* Set or clear RAM retention in SYSTEM_OFF for the provided object.
- *
- * @param ptr pointer to the start of the retainable object
- *
- * @param len length of the retainable object
- *
- * @param enable true to enable retention, false to clear retention
- */
-static int ram_range_retain(const void *ptr,
- size_t len,
- bool enable)
-{
- int rc = 0;
-
-#if CONFIG_APP_USE_NRF_RETENTION
- /* This only works for nRF52 with the POWER module.
- * The other Nordic chips use a different low-level API,
- * which is not currently used by this variant.
- */
- uintptr_t addr = (uintptr_t)ptr;
- uintptr_t addr_end = addr + len;
-
- /* Error if the provided range is empty or doesn't lie
- * entirely within the SRAM address space.
- */
- if ((len == 0U)
- || (addr < SRAM_BEGIN)
- || (addr > (SRAM_END - len))) {
- return -EINVAL;
- }
-
- /* Iterate over each section covered by the range, setting the
- * corresponding RAM OFF retention bit in the parent block.
- */
- do {
- uintptr_t block_base = SRAM_BEGIN;
- uint32_t section_size = SMALL_SECTION_SIZE;
- uint32_t sections_per_block = SMALL_SECTIONS_PER_BLOCK;
- bool is_large = (addr >= LARGE_SECTION_BEGIN);
- uint8_t block = 0;
-
- if (is_large) {
- block = 8;
- block_base = LARGE_SECTION_BEGIN;
- section_size = LARGE_SECTION_SIZE;
-
- /* RAM[x] supports only 16 sections, each its own bit
- * for POWER (0..15) and RETENTION (16..31). We don't
- * know directly how many sections are present, so
- * assume they all are; the true limit will be
- * determined by the SRAM size.
- */
- sections_per_block = 16;
- }
-
- uint32_t section = (addr - block_base) / section_size;
-
- if (section >= sections_per_block) {
- block += section / sections_per_block;
- section %= sections_per_block;
- }
-
- uint32_t section_mask =
- (POWER_RAM_POWERSET_S0RETENTION_On
- << (section + POWER_RAM_POWERSET_S0RETENTION_Pos));
-
- if (enable) {
- nrf_power_rampower_mask_on(NRF_POWER, block, section_mask);
- } else {
- nrf_power_rampower_mask_off(NRF_POWER, block, section_mask);
- }
-
- /* Move to the first address in the next section. */
- addr += section_size - (addr % section_size);
- } while (addr < addr_end);
-#elif CONFIG_APP_USE_RETAINED_MEM
- /* Retention setting cannot be controlled runtime with retained_mem API */
- (void)enable;
- rc = retained_mem_write(retained_mem_device, 0, ptr, len);
#else
- #error "Unsupported retention setting"
+#error "retained_mem region not defined"
#endif
- return rc;
-}
-
-/* Retained data must be defined in a no-init section to prevent the C
- * runtime initialization from zeroing it before anybody can see it.
- * It is not necesarry when retained_mem driver is utilized
- * as in this case retained data is stored in an area not initialized in runtime.
- */
-__noinit struct retained_data retained;
+struct retained_data retained;
#define RETAINED_CRC_OFFSET offsetof(struct retained_data, crc)
#define RETAINED_CHECKED_SIZE (RETAINED_CRC_OFFSET + sizeof(retained.crc))
bool retained_validate(void)
{
+ int rc;
+
+ rc = retained_mem_read(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained));
+ __ASSERT_NO_MSG(rc == 0);
+
/* The residue of a CRC is what you get from the CRC over the
* message catenated with its CRC. This is the post-final-xor
* residue for CRC-32 (CRC-32/ISO-HDLC) which Zephyr calls
@@ -174,19 +51,13 @@
/* Reset to accrue runtime from this session. */
retained.uptime_latest = 0;
- /* Reconfigure to retain the state during system off, regardless of
- * whether validation succeeded. Although these values can sometimes
- * be observed to be preserved across System OFF, the product
- * specification states they are not retained in that situation, and
- * that can also be observed.
- */
- (void)ram_range_retain(&retained, RETAINED_CHECKED_SIZE, true);
-
return valid;
}
void retained_update(void)
{
+ int rc;
+
uint64_t now = k_uptime_ticks();
retained.uptime_sum += (now - retained.uptime_latest);
@@ -196,4 +67,7 @@
RETAINED_CRC_OFFSET);
retained.crc = sys_cpu_to_le32(crc);
+
+ rc = retained_mem_write(retained_mem_device, 0, (uint8_t *)&retained, sizeof(retained));
+ __ASSERT_NO_MSG(rc == 0);
}