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