samples: boards: nrf: Add nrf2_clock_control sample

Add a sample that presents how the custom nrf2_clock_control API
introduced for nRF54H20 can be used for the various clocks which
are supported by it.

Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
This commit is contained in:
Andrzej Głąbek 2024-07-29 13:50:54 +02:00 committed by Anas Nashif
commit 0898764d31
12 changed files with 256 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(nrf_clock_control)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,38 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
config SAMPLE_CLOCK_FREQUENCY_HZ
int "Frequency specification to request from clock in Hz"
default 0
help
0 -> ignore frequency
>0 -> use at minimum selected frequency. To select the
highest supported frequency use UINT32_MAX.
config SAMPLE_CLOCK_ACCURACY_PPM
int "Accuracy specification to request from clock in PPM"
default 0
help
0 -> ignore accuracy
1 -> use max accuracy
>1 -> use at minimum selected accuracy
config SAMPLE_CLOCK_PRECISION
int "Precision specification to request from clock"
default 0
help
0 -> low precision
1 -> high precision
config SAMPLE_PRE_REQUEST_TIMEOUT
int "Time to wait after boot before requesting clock specs in seconds"
default 2
help
The distributed clock domains may need time to initialize
before a clock request can be met.
config SAMPLE_KEEP_REQUEST_TIMEOUT
int "Time to keep request alive in seconds"
default 2
source "Kconfig.zephyr"

View file

@ -0,0 +1,6 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
CONFIG_CLOCK_CONTROL_NRF2=y
CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ=320000000

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/{
aliases {
sample-clock = &cpuapp_hsfll;
};
};

View file

@ -0,0 +1,6 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
CONFIG_CLOCK_CONTROL_NRF2=y
CONFIG_SAMPLE_CLOCK_ACCURACY_PPM=30

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/{
aliases {
sample-clock = &fll16m;
};
};

View file

@ -0,0 +1,7 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
CONFIG_CLOCK_CONTROL_NRF2=y
CONFIG_SAMPLE_CLOCK_ACCURACY_PPM=20
CONFIG_SAMPLE_CLOCK_PRECISION=1

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/{
aliases {
sample-clock = &lfclk;
};
};

View file

@ -0,0 +1,6 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
CONFIG_CLOCK_CONTROL_NRF2=y
CONFIG_SAMPLE_CLOCK_ACCURACY_PPM=30

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/{
aliases {
sample-device = &uart135;
};
};
&uart135 {
status = "okay";
};

View file

@ -0,0 +1,31 @@
sample:
name: Clock control sample
common:
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
harness: console
harness_config:
type: one_line
regex:
- "clock spec request released"
tests:
sample.boards.nrf.clock_control.fll16m:
filter: dt_nodelabel_enabled("fll16m")
extra_args:
- CONF_FILE="configs/fll16m.conf"
- DTC_OVERLAY_FILE="configs/fll16m.overlay"
sample.boards.nrf.clock_control.lfclk:
filter: dt_nodelabel_enabled("lfclk")
extra_args:
- CONF_FILE="configs/lfclk.conf"
- DTC_OVERLAY_FILE="configs/lfclk.overlay"
sample.boards.nrf.clock_control.uart135:
filter: dt_nodelabel_enabled("uart135")
extra_args:
- CONF_FILE="configs/uart135.conf"
- DTC_OVERLAY_FILE="configs/uart135.overlay"
sample.boards.nrf.clock_control.cpuapp_hsfll:
filter: dt_nodelabel_enabled("cpuapp_hsfll")
extra_args:
- CONF_FILE="configs/cpuapp_hsfll.conf"
- DTC_OVERLAY_FILE="configs/cpuapp_hsfll.overlay"

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/kernel.h>
#include <zephyr/devicetree/clocks.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#if DT_NODE_EXISTS(DT_ALIAS(sample_device))
#define SAMPLE_CLOCK_NODE DT_CLOCKS_CTLR(DT_ALIAS(sample_device))
#elif DT_NODE_EXISTS(DT_ALIAS(sample_clock))
#define SAMPLE_CLOCK_NODE DT_ALIAS(sample_clock)
#endif
#define SAMPLE_CLOCK_NAME DT_NODE_FULL_NAME(SAMPLE_CLOCK_NODE)
#define SAMPLE_NOTIFY_TIMEOUT K_SECONDS(2)
#define SAMPLE_PRE_REQUEST_TIMEOUT K_SECONDS(CONFIG_SAMPLE_PRE_REQUEST_TIMEOUT)
#define SAMPLE_KEEP_REQUEST_TIMEOUT K_SECONDS(CONFIG_SAMPLE_KEEP_REQUEST_TIMEOUT)
const struct device *sample_clock_dev = DEVICE_DT_GET(SAMPLE_CLOCK_NODE);
static K_SEM_DEFINE(sample_sem, 0, 1);
static void sample_notify_cb(struct onoff_manager *mgr,
struct onoff_client *cli,
uint32_t state,
int res)
{
ARG_UNUSED(mgr);
ARG_UNUSED(cli);
ARG_UNUSED(state);
ARG_UNUSED(res);
k_sem_give(&sample_sem);
}
int main(void)
{
struct onoff_client cli;
int ret;
int res;
int64_t req_start_uptime;
int64_t req_stop_uptime;
printk("\n");
printk("clock name: %s\n", SAMPLE_CLOCK_NAME);
printk("minimum frequency request: %uHz\n", CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ);
printk("minimum accuracy request: %uPPM\n", CONFIG_SAMPLE_CLOCK_ACCURACY_PPM);
printk("minimum precision request: %u\n", CONFIG_SAMPLE_CLOCK_PRECISION);
const struct nrf_clock_spec spec = {
.frequency = CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ,
.accuracy = CONFIG_SAMPLE_CLOCK_ACCURACY_PPM,
.precision = CONFIG_SAMPLE_CLOCK_PRECISION,
};
sys_notify_init_callback(&cli.notify, sample_notify_cb);
k_sleep(SAMPLE_PRE_REQUEST_TIMEOUT);
printk("\n");
printk("requesting minimum clock specs\n");
req_start_uptime = k_uptime_get();
ret = nrf_clock_control_request(sample_clock_dev, &spec, &cli);
if (ret < 0) {
printk("minimum clock specs could not be met\n");
return 0;
}
ret = k_sem_take(&sample_sem, SAMPLE_NOTIFY_TIMEOUT);
if (ret < 0) {
printk("timed out waiting for clock to meet request\n");
return 0;
}
req_stop_uptime = k_uptime_get();
ret = sys_notify_fetch_result(&cli.notify, &res);
if (ret < 0) {
printk("sys notify fetch failed\n");
return 0;
}
if (res < 0) {
printk("failed to apply request to clock\n");
return 0;
}
printk("request applied to clock in %llims\n", req_stop_uptime - req_start_uptime);
k_sleep(SAMPLE_KEEP_REQUEST_TIMEOUT);
printk("\n");
printk("releasing requested clock specs\n");
ret = nrf_clock_control_release(sample_clock_dev, &spec);
if (ret < 0) {
printk("failed to release requested clock specs\n");
return 0;
}
printk("clock spec request released\n");
return 0;
}