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