Skip to content

Commit 41a996d

Browse files
nordic-pikrkartben
authored andcommitted
samples: drivers: Add spis_wakeup sample
Sample showing how to use the additional wakeup signal in nordic,nrf-spis driver. The application, configured as a SPIS, is put to sleep while waiting for an SPI transmission. An external device working as a SPIM and also handling the wakeup signal wakes the application up just before the transmission starts. Signed-off-by: Piotr Krzyzanowski <[email protected]>
1 parent 30ff07f commit 41a996d

File tree

11 files changed

+400
-0
lines changed

11 files changed

+400
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
6+
cmake_minimum_required(VERSION 3.20.0)
7+
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
10+
if(NOT SYSBUILD)
11+
message(FATAL_ERROR
12+
" This is a multi-image application that should be built using sysbuild.\n"
13+
" Add --sysbuild argument to west build command to prepare all the images.")
14+
endif()
15+
16+
project(spis_wakeup)
17+
18+
target_sources(app PRIVATE src/main.c)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
.. zephyr:code-sample:: spis-wakeup
2+
:name: SPIS wake up
3+
:relevant-api: spi_interface
4+
5+
Reduce current consumption by handling the wake line while using an SPIS.
6+
7+
Overview
8+
********
9+
10+
Sample showing how to use the additional wake line in nrf-spis driver. The application, configured
11+
as a SPIS, is put to sleep while waiting for an SPI transmission. An external device (other core in
12+
this sample) working as a SPIM and also handling the wake line wakes the application up just before
13+
the transmission starts. To simulate two separate devices the Nordic Semiconductor nRF54H20 DK has
14+
been used and SPIS / SPIM drivers are controlled by two independent cores:
15+
16+
- nrf54h20dk/nrf54h20/cpuapp works as a SPIS controller device
17+
- nrf54h20dk/nrf54h20/cpurad works as a SPIM controller device
18+
19+
20+
Requirements
21+
************
22+
23+
This sample can be run on multicore SoCs like nRF54H20 and requires additional wiring as below.
24+
25+
Wiring
26+
******
27+
28+
Wires (jumpers) for connecting SPIS and SPIM devices are needed:
29+
30+
- SPIS WAKE <-> WAKE SPIM
31+
- SPIS CS <-----> CS SPIM
32+
- SPIS SCK <---> SCK SPIM
33+
- SPIS MOSI <-> MOSI SPIM
34+
- SPIS MISO <-> MISO SPIM
35+
36+
Building and Running
37+
********************
38+
39+
The code can be found in :zephyr_file:`samples/boards/nordic/spis_wakeup`.
40+
41+
To build and flash the application:
42+
43+
.. zephyr-app-commands::
44+
:zephyr-app: samples/boards/nordic/spis_wakeup
45+
:board: nrf54h20dk/nrf54h20/cpuapp
46+
:goals: build flash
47+
:compact:
48+
49+
Sample Output
50+
=============
51+
52+
nrf54h20/cpuapp:
53+
54+
.. code-block:: console
55+
56+
[00:00:00.272,217] <inf> spi_wakeup: Hello world from [email protected]/nrf54h20/cpuapp
57+
[00:00:00.272,241] <inf> spi_wakeup: SPIS: waiting for SPI transfer; going to sleep...
58+
[00:00:02.274,192] <inf> spi_wakeup: SPIS: woken up by nrf54h20/cpurad
59+
[00:00:02.274,215] <inf> spi_wakeup: SPIS: will be active for 500ms after transfer
60+
61+
nrf54h20/cpurad:
62+
63+
.. code-block:: console
64+
65+
[00:00:00.272,195] <inf> spi_wakeup: Hello world from [email protected]/nrf54h20/cpurad
66+
[00:00:00.272,219] <inf> spi_wakeup: SPIM: going to sleep for 1.5s...
67+
[00:00:01.772,352] <inf> spi_wakeup: SPIM: will be active for 500ms before transfer
68+
[00:00:02.273,456] <inf> spi_wakeup: SPIM: transferring the CONFIG_BOARD_QUALIFIERS: 'nrf54h20/cpurad'
69+
70+
References
71+
**********
72+
73+
:zephyr_file:`dts/bindings/spi/nordic,nrf-spi-common.yaml`
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
/ {
7+
aliases {
8+
led = &led0;
9+
spis = &spi130;
10+
/delete-property/ led1;
11+
/delete-property/ sw0;
12+
/delete-property/ sw1;
13+
/delete-property/ sw2;
14+
/delete-property/ sw3;
15+
};
16+
/delete-node/ buttons;
17+
};
18+
19+
/delete-node/ &led1;
20+
21+
&exmif {
22+
status = "disabled";
23+
};
24+
25+
&gpiote130 {
26+
status = "okay";
27+
owned-channels = <0>;
28+
};
29+
30+
&pinctrl {
31+
spi130_default_alt: spi130_default_alt {
32+
group1 {
33+
psels = <NRF_PSEL(SPIS_SCK, 0, 0)>,
34+
<NRF_PSEL(SPIS_MOSI, 0, 6)>,
35+
<NRF_PSEL(SPIS_MISO, 0, 8)>,
36+
<NRF_PSEL(SPIS_CSN, 0, 10)>;
37+
};
38+
};
39+
40+
spi130_sleep_alt: spi130_sleep_alt {
41+
group1 {
42+
psels = <NRF_PSEL(SPIS_SCK, 0, 0)>,
43+
<NRF_PSEL(SPIS_MOSI, 0, 6)>,
44+
<NRF_PSEL(SPIS_MISO, 0, 8)>,
45+
<NRF_PSEL(SPIS_CSN, 0, 10)>;
46+
low-power-enable;
47+
};
48+
};
49+
};
50+
51+
&spi130 {
52+
compatible = "nordic,nrf-spis";
53+
status = "okay";
54+
def-char = <0x00>;
55+
pinctrl-0 = <&spi130_default_alt>;
56+
pinctrl-1 = <&spi130_sleep_alt>;
57+
pinctrl-names = "default", "sleep";
58+
wake-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
59+
memory-regions = <&cpuapp_dma_region>;
60+
/delete-property/rx-delay-supported;
61+
/delete-property/rx-delay;
62+
};
63+
64+
&uart136 {
65+
zephyr,pm-device-runtime-auto;
66+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CONFIG_SPI=y
2+
CONFIG_SPI_SLAVE=y
3+
CONFIG_GPIO=y
4+
5+
CONFIG_PM=y
6+
CONFIG_PM_S2RAM=y
7+
CONFIG_PM_S2RAM_CUSTOM_MARKING=y
8+
CONFIG_PM_DEVICE=y
9+
CONFIG_PM_DEVICE_RUNTIME=y
10+
11+
CONFIG_ASSERT=y
12+
13+
CONFIG_LOG=y
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
common:
2+
sysbuild: true
3+
depends_on: spi
4+
5+
sample:
6+
name: SPI wakeup sample
7+
tests:
8+
sample.drivers.spis.wakeup:
9+
tags:
10+
- spi
11+
platform_allow:
12+
- nrf54h20dk/nrf54h20/cpuapp
13+
integration_platforms:
14+
- nrf54h20dk/nrf54h20/cpuapp
15+
harness: console
16+
harness_config:
17+
fixture: spi_loopback
18+
type: multi_line
19+
ordered: true
20+
regex:
21+
- ".*SPIS: waiting for SPI transfer"
22+
- ".*SPIS: woken up by"
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <zephyr/kernel.h>
7+
#include <zephyr/logging/log.h>
8+
#include <zephyr/drivers/spi.h>
9+
#include <zephyr/drivers/gpio.h>
10+
11+
#define BUF_SIZE 32
12+
static const struct device *spis_dev = DEVICE_DT_GET(DT_ALIAS(spis));
13+
static const struct spi_config spis_config = {.operation = SPI_OP_MODE_SLAVE | SPI_WORD_SET(8)};
14+
15+
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led), gpios);
16+
17+
LOG_MODULE_REGISTER(spi_wakeup);
18+
19+
int main(void)
20+
{
21+
bool status;
22+
static char rx_buffer[BUF_SIZE];
23+
struct spi_buf rx_spi_bufs = {.buf = rx_buffer, .len = sizeof(rx_buffer)};
24+
struct spi_buf_set rx_spi_buf_set = {.buffers = &rx_spi_bufs, .count = 1};
25+
26+
LOG_INF("Hello world from %s", CONFIG_BOARD_TARGET);
27+
28+
status = gpio_is_ready_dt(&led);
29+
__ASSERT(status, "Error: GPIO Device not ready");
30+
31+
status = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
32+
__ASSERT(status == 0, "Could not configure led GPIO");
33+
34+
status = device_is_ready(spis_dev);
35+
__ASSERT(status, "Error: SPI device is not ready");
36+
37+
while (1) {
38+
memset(rx_buffer, 0x00, sizeof(rx_buffer));
39+
LOG_INF("SPIS: waiting for SPI transfer; going to sleep...");
40+
gpio_pin_set_dt(&led, 0);
41+
spi_read(spis_dev, &spis_config, &rx_spi_buf_set);
42+
gpio_pin_set_dt(&led, 1);
43+
LOG_INF("SPIS: woken up by %s", rx_buffer);
44+
LOG_INF("SPIS: will be active for 500ms after transfer");
45+
k_busy_wait(500000);
46+
}
47+
48+
return 0;
49+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
6+
if(SB_CONFIG_SOC_NRF54H20)
7+
# Add remote project
8+
ExternalZephyrProject_Add(
9+
APPLICATION wakeup_trigger
10+
SOURCE_DIR ${APP_DIR}/wakeup_trigger
11+
BOARD ${SB_CONFIG_BOARD}/${SB_CONFIG_SOC}/cpurad
12+
BOARD_REVISION ${BOARD_REVISION}
13+
)
14+
endif()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Copyright (c) 2025 Nordic Semiconductor ASA
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
6+
cmake_minimum_required(VERSION 3.20.0)
7+
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
10+
project(wakeup_trigger)
11+
12+
target_sources(app PRIVATE src/main.c)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
/ {
7+
aliases {
8+
led = &led1;
9+
};
10+
11+
leds {
12+
compatible = "gpio-leds";
13+
led1: led_1 {
14+
gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>;
15+
label = "Green LED 1";
16+
};
17+
};
18+
};
19+
20+
&gpiote130 {
21+
status = "okay";
22+
owned-channels = <1>;
23+
};
24+
25+
&gpio0 {
26+
status = "okay";
27+
};
28+
29+
&gpio9 {
30+
status = "okay";
31+
};
32+
33+
&pinctrl {
34+
spi131_default_alt: spi131_default_alt {
35+
group1 {
36+
psels = <NRF_PSEL(SPIM_SCK, 0, 1)>,
37+
<NRF_PSEL(SPIM_MOSI, 0, 7)>,
38+
<NRF_PSEL(SPIM_MISO, 0, 9)>;
39+
};
40+
};
41+
42+
spi131_sleep_alt: spi131_sleep_alt {
43+
group1 {
44+
psels = <NRF_PSEL(SPIM_SCK, 0, 1)>,
45+
<NRF_PSEL(SPIM_MOSI, 0, 7)>,
46+
<NRF_PSEL(SPIM_MISO, 0, 9)>;
47+
low-power-enable;
48+
};
49+
};
50+
};
51+
52+
&spi131 {
53+
compatible = "nordic,nrf-spim";
54+
status = "okay";
55+
pinctrl-0 = <&spi131_default_alt>;
56+
pinctrl-1 = <&spi131_sleep_alt>;
57+
pinctrl-names = "default", "sleep";
58+
overrun-character = <0x00>;
59+
cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
60+
wake-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
61+
zephyr,pm-device-runtime-auto;
62+
memory-regions = <&cpurad_dma_region>;
63+
spim_dt: spi-device@0 {
64+
compatible = "vnd,spi-device";
65+
reg = <0>;
66+
spi-max-frequency = <DT_FREQ_M(8)>;
67+
};
68+
};
69+
70+
&uart135 {
71+
zephyr,pm-device-runtime-auto;
72+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CONFIG_SPI=y
2+
CONFIG_SPI_NRFX_WAKE_TIMEOUT_US=500
3+
CONFIG_GPIO=y
4+
5+
CONFIG_PM=y
6+
CONFIG_PM_S2RAM=y
7+
CONFIG_PM_S2RAM_CUSTOM_MARKING=y
8+
CONFIG_PM_DEVICE=y
9+
CONFIG_PM_DEVICE_RUNTIME=y
10+
11+
CONFIG_ASSERT=y
12+
13+
CONFIG_LOG=y

0 commit comments

Comments
 (0)