Skip to content

Commit 9bbc789

Browse files
nordic-baminordic-piks
authored andcommitted
tests: drivers: Test SPIM with Clock Control active
Test nrf54h slow SPIM the Clock Control is active and used Signed-off-by: Bartosz Miller <[email protected]>
1 parent 828d896 commit 9bbc789

File tree

5 files changed

+204
-0
lines changed

5 files changed

+204
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
11+
project(spim_clock_control)
12+
13+
target_sources(app PRIVATE src/main.c)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/* Required loopbacks:
8+
* P0.07 <-> P0.06
9+
*/
10+
11+
&pinctrl {
12+
dut_spi_default: dut_spi_default {
13+
group1 {
14+
psels = <NRF_PSEL(SPIM_SCK, 0, 0)>,
15+
<NRF_PSEL(SPIM_MOSI, 0, 7)>,
16+
<NRF_PSEL(SPIM_MISO, 0, 6)>;
17+
};
18+
};
19+
20+
dut_spi_sleep: dut_spi_sleep {
21+
group1 {
22+
psels = <NRF_PSEL(SPIM_SCK, 0, 0)>,
23+
<NRF_PSEL(SPIM_MISO, 0, 6)>,
24+
<NRF_PSEL(SPIM_MOSI, 0, 7)>;
25+
low-power-enable;
26+
};
27+
};
28+
};
29+
30+
dut_spi: &spi130 {
31+
compatible = "nordic,nrf-spim";
32+
status = "okay";
33+
pinctrl-0 = <&dut_spi_default>;
34+
pinctrl-1 = <&dut_spi_sleep>;
35+
pinctrl-names = "default", "sleep";
36+
overrun-character = <0x00>;
37+
memory-regions = <&cpuapp_dma_region>;
38+
cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
39+
zephyr,pm-device-runtime-auto;
40+
41+
dut_spi_dt: test-spi-dev@0 {
42+
compatible = "vnd,spi-device";
43+
reg = <0>;
44+
spi-max-frequency = <DT_FREQ_M(1)>;
45+
};
46+
};
47+
48+
&fll16m {
49+
status = "okay";
50+
};
51+
52+
&exmif {
53+
status = "disabled";
54+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_SPI=y
2+
3+
CONFIG_CLOCK_CONTROL=y
4+
CONFIG_ZTEST=y
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/drivers/spi.h>
9+
#include <zephyr/linker/devicetree_regions.h>
10+
#include <zephyr/devicetree/clocks.h>
11+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
12+
#include <zephyr/ztest.h>
13+
14+
/* SPI MODE 0 */
15+
#define SPI_MODE (SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE | SPI_TRANSFER_MSB)
16+
17+
#define DUT_SPI_NODE DT_NODELABEL(dut_spi)
18+
#define TEST_BUFFER_SIZE 512
19+
#define REQUEST_SERVING_WAIT_TIME_US 10000
20+
21+
static struct spi_dt_spec spim_spec = SPI_DT_SPEC_GET(DT_NODELABEL(dut_spi_dt), SPI_MODE, 0);
22+
const struct device *const fll16m_dev = DEVICE_DT_GET(DT_NODELABEL(fll16m));
23+
24+
#define MEMORY_SECTION(node) \
25+
COND_CODE_1(DT_NODE_HAS_PROP(node, memory_regions), \
26+
(__attribute__((__section__( \
27+
LINKER_DT_NODE_REGION_NAME(DT_PHANDLE(node, memory_regions)))))), \
28+
())
29+
30+
static uint8_t tx_buffer[TEST_BUFFER_SIZE] MEMORY_SECTION(DT_BUS(DT_NODELABEL(dut_spi_dt)));
31+
static uint8_t rx_buffer[TEST_BUFFER_SIZE] MEMORY_SECTION(DT_BUS(DT_NODELABEL(dut_spi_dt)));
32+
33+
const struct nrf_clock_spec fll16m_open_loop_mode = {
34+
.frequency = MHZ(16),
35+
.accuracy = NRF_CLOCK_CONTROL_ACCURACY_PPM(20000),
36+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
37+
};
38+
39+
const struct nrf_clock_spec fll16m_bypass_mode = {
40+
.frequency = MHZ(16),
41+
.accuracy = NRF_CLOCK_CONTROL_ACCURACY_PPM(30),
42+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
43+
};
44+
45+
static void request_clock_spec(const struct device *clk_dev, const struct nrf_clock_spec *clk_spec)
46+
{
47+
int ret = 0;
48+
int res = 0;
49+
struct onoff_client cli;
50+
uint32_t rate;
51+
52+
TC_PRINT("Clock: %s, requesting frequency=%d, accuracy=%d, precision=%d\n", clk_dev->name,
53+
clk_spec->frequency, clk_spec->accuracy, clk_spec->precision);
54+
sys_notify_init_spinwait(&cli.notify);
55+
ret = nrf_clock_control_request(clk_dev, clk_spec, &cli);
56+
zassert_true((ret >= 0 && ret <= 2),
57+
"Clock control request response outside of range, ret = %d\n", ret);
58+
do {
59+
ret = sys_notify_fetch_result(&cli.notify, &res);
60+
k_yield();
61+
} while (ret == -EAGAIN);
62+
zassert_ok(ret, "ret != 0, ret = %d\n", ret);
63+
zassert_ok(res, "ret != 0, ret = %d\n", res);
64+
ret = clock_control_get_rate(clk_dev, NULL, &rate);
65+
if (ret != -ENOSYS) {
66+
zassert_ok(ret, "ret != 0, ret = %d\n", ret);
67+
zassert_equal(rate, clk_spec->frequency,
68+
"Clock frequency != requested frequnecy\n");
69+
k_busy_wait(REQUEST_SERVING_WAIT_TIME_US);
70+
}
71+
}
72+
73+
static void *test_setup(void)
74+
{
75+
zassert_true(spi_is_ready_dt(&spim_spec), "SPIM device is not ready");
76+
77+
return NULL;
78+
}
79+
80+
static void set_buffers(void)
81+
{
82+
memset(tx_buffer, 0x8B, TEST_BUFFER_SIZE);
83+
memset(rx_buffer, 0xFF, TEST_BUFFER_SIZE);
84+
}
85+
86+
static void test_spim_with_clock_control(void)
87+
{
88+
int err;
89+
90+
struct spi_buf tx_spi_buf = {.buf = tx_buffer, .len = TEST_BUFFER_SIZE};
91+
struct spi_buf_set tx_spi_buf_set = {.buffers = &tx_spi_buf, .count = 1};
92+
93+
struct spi_buf rx_spi_buf = {.buf = rx_buffer, .len = TEST_BUFFER_SIZE};
94+
struct spi_buf_set rx_spi_buf_set = {.buffers = &rx_spi_buf, .count = 1};
95+
96+
set_buffers();
97+
98+
err = spi_transceive_dt(&spim_spec, &tx_spi_buf_set, &rx_spi_buf_set);
99+
zassert_ok(err, "SPI transceive failed: %d\n", err);
100+
101+
zassert_mem_equal(tx_buffer, rx_buffer, TEST_BUFFER_SIZE, "TX buffer != RX buffer\n");
102+
}
103+
104+
ZTEST(spim_clock_control, test_spim_with_clock_control_active_fll16m_open_loop)
105+
{
106+
request_clock_spec(fll16m_dev, &fll16m_open_loop_mode);
107+
test_spim_with_clock_control();
108+
}
109+
110+
ZTEST(spim_clock_control, test_spim_with_clock_control_active_fll16m_bypass)
111+
{
112+
request_clock_spec(fll16m_dev, &fll16m_bypass_mode);
113+
test_spim_with_clock_control();
114+
}
115+
116+
ZTEST_SUITE(spim_clock_control, NULL, test_setup, NULL, NULL, NULL);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
common:
2+
sysbuild: true
3+
depends_on: gpio
4+
harness: ztest
5+
tags:
6+
- drivers
7+
- spim
8+
- ci_tests_drivers_spi
9+
10+
tests:
11+
drivers.spim_clock_control:
12+
platform_allow:
13+
- nrf54h20dk/nrf54h20/cpuapp
14+
integration_platforms:
15+
- nrf54h20dk/nrf54h20/cpuapp
16+
harness_config:
17+
fixture: gpio_loopback

0 commit comments

Comments
 (0)