Skip to content

Commit a81e33b

Browse files
nordic-krchmeijemac
authored andcommitted
samples: boards: nrf: system_off: Add nrf54h20 support
1 parent 1365e9d commit a81e33b

File tree

13 files changed

+263
-7
lines changed

13 files changed

+263
-7
lines changed

drivers/timer/nrf_grtc_timer.c

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ uint64_t z_nrf_grtc_timer_startup_value_get(void)
368368
return grtc_start_value;
369369
}
370370

371-
#if defined(CONFIG_POWEROFF) && defined(CONFIG_NRF_GRTC_START_SYSCOUNTER)
371+
#if defined(CONFIG_POWEROFF)
372+
#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER)
372373
int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)
373374
{
374375
nrfx_err_t err_code;
@@ -430,6 +431,91 @@ int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)
430431
k_spin_unlock(&lock, key);
431432
return 0;
432433
}
434+
#else
435+
int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)
436+
{
437+
//nrfx_err_t err_code;
438+
//static uint8_t systemoff_channel;
439+
//uint64_t now = counter();
440+
//nrfx_grtc_sleep_config_t sleep_cfg;
441+
/* Minimum time that ensures valid execution of system-off procedure. */
442+
//uint32_t minimum_latency_us;
443+
uint32_t chan;
444+
//int ret;
445+
446+
// nrfx_grtc_sleep_configuration_get(&sleep_cfg);
447+
// minimum_latency_us =
448+
// (sleep_cfg.waketime + sleep_cfg.timeout) * USEC_PER_SEC / LFCLK_FREQUENCY_HZ +
449+
// CONFIG_NRF_GRTC_SYSCOUNTER_SLEEP_MINIMUM_LATENCY;
450+
// sleep_cfg.auto_mode = false;
451+
// nrfx_grtc_sleep_configure(&sleep_cfg);
452+
453+
// if (minimum_latency_us > wake_time_us) {
454+
// return -EINVAL;
455+
// }
456+
457+
//k_spinlock_key_t key = k_spin_lock(&lock);
458+
459+
// err_code = nrfx_grtc_channel_alloc(&systemoff_channel);
460+
// if (err_code != NRFX_SUCCESS) {
461+
// k_spin_unlock(&lock, key);
462+
// return -ENOMEM;
463+
// }
464+
//(void)nrfx_grtc_syscounter_cc_int_disable(systemoff_channel);
465+
// ret = compare_set(systemoff_channel,
466+
// now + wake_time_us * sys_clock_hw_cycles_per_sec() / USEC_PER_SEC, NULL,
467+
// NULL);
468+
// if (ret < 0) {
469+
// k_spin_unlock(&lock, key);
470+
// return ret;
471+
// }
472+
// for (uint32_t grtc_chan_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
473+
for (uint32_t grtc_chan_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
474+
grtc_chan_mask > 0; grtc_chan_mask &= ~BIT(chan)) {
475+
/* Clear all GRTC channels except the systemoff_channel. */
476+
chan = u32_count_trailing_zeros(grtc_chan_mask);
477+
// if (chan != systemoff_channel) {
478+
nrfx_grtc_syscounter_cc_disable(chan);
479+
//}
480+
}
481+
#if 0
482+
#if defined(CONFIG_SOC_NRF54H20_CPUAPP)
483+
for (uint32_t grtc_chan_mask = 0x70;
484+
grtc_chan_mask > 0; grtc_chan_mask &= ~BIT(chan)) {
485+
/* Clear all GRTC channels except the systemoff_channel. */
486+
chan = u32_count_trailing_zeros(grtc_chan_mask);
487+
// if (chan != systemoff_channel) {
488+
nrfx_grtc_syscounter_cc_disable(chan);
489+
// }
490+
}
491+
#endif
492+
#if defined(CONFIG_SOC_NRF54H20_CPURAD)
493+
//for (uint32_t grtc_chan_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK;
494+
for (uint32_t grtc_chan_mask = 0xFF80;
495+
grtc_chan_mask > 0; grtc_chan_mask &= ~BIT(chan)) {
496+
/* Clear all GRTC channels except the systemoff_channel. */
497+
chan = u32_count_trailing_zeros(grtc_chan_mask);
498+
//if (chan != systemoff_channel) {
499+
nrfx_grtc_syscounter_cc_disable(chan);
500+
//}
501+
}
502+
#endif
503+
#endif
504+
// /* Make sure that wake_time_us was not triggered yet. */
505+
// if (nrfx_grtc_syscounter_compare_event_check(systemoff_channel)) {
506+
// k_spin_unlock(&lock, key);
507+
// return -EINVAL;
508+
// }
509+
510+
// /* This mechanism ensures that stored CC value is latched. */
511+
//uint32_t wait_time =
512+
// nrfy_grtc_timeout_get(NRF_GRTC) * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 32768 +
513+
// MAX_CC_LATCH_WAIT_TIME_US;
514+
k_busy_wait(1000);
515+
// k_spin_unlock(&lock, key);
516+
return 0;
517+
}
518+
#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */
433519
#endif /* CONFIG_POWEROFF */
434520

435521
uint32_t sys_clock_cycle_get_32(void)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright 2024 Nordic Semiconductor ASA
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
source "share/sysbuild/Kconfig"
6+
7+
config REMOTE_CORE_BOARD
8+
string
9+
default "nrf54h20dk/nrf54h20/cpurad" if $(BOARD) = "nrf54h20dk"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
&uart135 {
2+
zephyr,pm-device-runtime-auto;
3+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
CONFIG_PM=y
12
CONFIG_PM_DEVICE=y
3+
CONFIG_PM_DEVICE_RUNTIME=y
4+
CONFIG_UART_ASYNC_API=y
25
CONFIG_GPIO=y
6+
CONFIG_NRF_REGTOOL_VERBOSITY=2
37
CONFIG_CRC=y
48
CONFIG_POWEROFF=y
59
CONFIG_HWINFO=y
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(nrf_system_off_remote)
7+
8+
target_sources(app PRIVATE src/main.c)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
&uart135 {
2+
status = "disabled";
3+
zephyr,pm-device-runtime-auto;
4+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CONFIG_PM=y
2+
CONFIG_PM_DEVICE=y
3+
CONFIG_PM_DEVICE_RUNTIME=y
4+
CONFIG_POWEROFF=y
5+
CONFIG_UART_ASYNC_API=y
6+
CONFIG_SERIAL=n
7+
CONFIG_CONSOLE=n
8+
CONFIG_UART_CONSOLE=n
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Copyright (c) 2024 Nordic Semiconductor ASA
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <zephyr/kernel.h>
7+
#include <zephyr/device.h>
8+
#include <zephyr/pm/device.h>
9+
#include <zephyr/pm/device_runtime.h>
10+
#include <zephyr/sys/poweroff.h>
11+
#include <hal/nrf_memconf.h>
12+
#include <zephyr/drivers/timer/nrf_grtc_timer.h>
13+
14+
int main(void)
15+
{
16+
17+
18+
if (IS_ENABLED(CONFIG_CONSOLE)) {
19+
printf("%s system off demo. Ready for system off.\n", CONFIG_BOARD);
20+
}
21+
22+
z_nrf_grtc_wakeup_prepare(1000);
23+
24+
if (0) {
25+
/*nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_MASK, false);*/
26+
/*nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_MASK, false);*/
27+
k_sleep(K_FOREVER);
28+
} else {
29+
/*nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_MASK, false);*/
30+
/*nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_MASK, false);*/
31+
32+
sys_poweroff();
33+
}
34+
35+
return 0;
36+
}

samples/boards/nordic/system_off/src/main.c

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
#include <zephyr/sys/util.h>
2020

2121
#define NON_WAKEUP_RESET_REASON (RESET_PIN | RESET_SOFTWARE | RESET_POR | RESET_DEBUG)
22+
#include <zephyr/pm/device_runtime.h>
23+
#include <hal/nrf_gpio.h>
24+
#include <hal/nrf_memconf.h>
2225

2326
#if defined(CONFIG_GRTC_WAKEUP_ENABLE)
2427
#include <zephyr/drivers/timer/nrf_grtc_timer.h>
@@ -31,12 +34,15 @@ static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);
3134
static const struct device *comp_dev = DEVICE_DT_GET(DT_NODELABEL(comp));
3235
#endif
3336

37+
static const struct gpio_dt_spec sw1 = GPIO_DT_SPEC_GET(DT_ALIAS(sw1), gpios);
38+
static const uint32_t port_sw1 = DT_PROP(DT_GPIO_CTLR_BY_IDX(DT_ALIAS(sw1), gpios, 0), port);
39+
3440
int print_reset_cause(uint32_t reset_cause)
3541
{
3642
int32_t ret;
3743
uint32_t supported;
3844

39-
ret = hwinfo_get_supported_reset_cause((uint32_t *) &supported);
45+
ret = hwinfo_get_supported_reset_cause((uint32_t *)&supported);
4046

4147
if (ret || !(reset_cause & supported)) {
4248
return -ENOTSUP;
@@ -60,16 +66,33 @@ int main(void)
6066
int rc;
6167
uint32_t reset_cause;
6268
const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
69+
uint32_t nrf_pin_sw1 = 32 * port_sw1 + sw1.pin;
70+
bool do_poweroff = true;
6371

6472
if (!device_is_ready(cons)) {
6573
printf("%s: device not ready.\n", cons->name);
6674
return 0;
6775
}
6876

77+
/* TODO: this is always set and locks entering power off after gpio wakeup */
78+
// if (nrf_gpio_pin_latch_get(nrf_pin_sw1)) {
79+
// nrf_gpio_pin_latch_clear(nrf_pin_sw1);
80+
// do_poweroff = false;
81+
// }
82+
6983
printf("\n%s system off demo\n", CONFIG_BOARD);
7084
hwinfo_get_reset_cause(&reset_cause);
7185
rc = print_reset_cause(reset_cause);
7286

87+
#if defined(CONFIG_SOC_NRF54H20_CPUAPP)
88+
/* Temporary set gpio default if sense is set, prevent 300uA additional current after wakeup */
89+
for (int i = 0; i < 12; i++) {
90+
if (nrf_gpio_pin_sense_get(i) != GPIO_PIN_CNF_SENSE_Disabled) {
91+
nrf_gpio_cfg_default(i);
92+
}
93+
}
94+
#endif
95+
7396
if (rc < 0) {
7497
printf("Reset cause not supported.\n");
7598
return 0;
@@ -97,13 +120,16 @@ int main(void)
97120
printf("Retained data not supported\n");
98121
}
99122

123+
124+
k_sleep(K_MSEC(4000));
125+
100126
#if defined(CONFIG_GRTC_WAKEUP_ENABLE)
101127
int err = z_nrf_grtc_wakeup_prepare(DEEP_SLEEP_TIME_S * USEC_PER_SEC);
102128

103129
if (err < 0) {
104-
printk("Unable to prepare GRTC as a wake up source (err = %d).\n", err);
130+
printf("Unable to prepare GRTC as a wake up source (err = %d).\n", err);
105131
} else {
106-
printk("Entering system off; wait %u seconds to restart\n", DEEP_SLEEP_TIME_S);
132+
printf("Entering system off; wait %u seconds to restart\n", DEEP_SLEEP_TIME_S);
107133
}
108134
#endif
109135
#if defined(CONFIG_GPIO_WAKEUP_ENABLE)
@@ -119,14 +145,29 @@ int main(void)
119145
printf("Could not configure sw0 GPIO interrupt (%d)\n", rc);
120146
return 0;
121147
}
122-
123-
printf("Entering system off; press sw0 to restart\n");
124148
#endif
125149
#if defined(CONFIG_LPCOMP_WAKEUP_ENABLE)
126150
comparator_set_trigger(comp_dev, COMPARATOR_TRIGGER_BOTH_EDGES);
127151
comparator_trigger_is_pending(comp_dev);
128152
printf("Entering system off; change signal level at comparator input to restart\n");
129153
#endif
154+
rc = gpio_pin_configure_dt(&sw1, GPIO_INPUT);
155+
if (rc < 0) {
156+
printf("Could not configure sw1 GPIO (%d)\n", rc);
157+
return 0;
158+
}
159+
160+
rc = gpio_pin_interrupt_configure_dt(&sw1, GPIO_INT_LEVEL_ACTIVE);
161+
if (rc < 0) {
162+
printf("Could not configure sw0 GPIO interrupt (%d)\n", rc);
163+
return 0;
164+
}
165+
166+
if (do_poweroff) {
167+
printf("Entering system off; press sw0 or sw1 to restart\n");
168+
} else {
169+
printf("Button sw1 pressed, not entering system off\n");
170+
}
130171

131172
rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);
132173
if (rc < 0) {
@@ -140,6 +181,18 @@ int main(void)
140181
retained_update();
141182
}
142183

184+
185+
if (do_poweroff) {
186+
#if CONFIG_SOC_NRF54H20_CPUAPP
187+
/* Local RAM0 (TCM) is currently not used so retention can be disabled. */
188+
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_MASK, false);
189+
nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_MASK, false);
190+
#endif
191+
sys_poweroff();
192+
} else {
193+
k_sleep(K_FOREVER);
194+
}
195+
143196
hwinfo_clear_reset_cause();
144197
sys_poweroff();
145198

0 commit comments

Comments
 (0)