samples: boards: stm32: pm: s2ram: add spi
Add SPI transfer in the suspend to ram samples to test SPI PM. Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
This commit is contained in:
parent
b567a7db83
commit
97177ba01a
|
@ -9,6 +9,8 @@ Overview
|
|||
This sample is a minimum application to demonstrate basic power management
|
||||
behavior in a basic blinking LED set up using the :ref:`GPIO API <gpio_api>` in
|
||||
low power context + ADC measurements and entropy.
|
||||
SPI loopback is also available but not yet implemented for Suspend To RAM PM
|
||||
mode.
|
||||
|
||||
.. _stm32-pm-suspend-to-ram-sample-requirements:
|
||||
|
||||
|
|
|
@ -31,6 +31,18 @@
|
|||
/* adjust channel number according to pinmux in board.dts */
|
||||
io-channels = <&adc4 8>;
|
||||
};
|
||||
|
||||
leds: leds {
|
||||
compatible = "gpio-leds";
|
||||
red_led_3: led_3 {
|
||||
gpios = <&gpiob 8 GPIO_ACTIVE_LOW>;
|
||||
label = "User LD2";
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
led2 = &red_led_3;
|
||||
};
|
||||
};
|
||||
|
||||
&lptim1 {
|
||||
|
@ -50,3 +62,18 @@
|
|||
zephyr,resolution = <12>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
dmas = <&gpdma1 0 2 (STM32_DMA_PERIPH_TX | STM32_DMA_PRIORITY_HIGH)
|
||||
&gpdma1 1 1 (STM32_DMA_PERIPH_RX | STM32_DMA_PRIORITY_HIGH)>;
|
||||
dma-names = "tx", "rx";
|
||||
fast@0 {
|
||||
compatible = "test-spi-loopback";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <500000>;
|
||||
};
|
||||
};
|
||||
|
||||
&gpdma1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# Copyright (c) 2024 STMicroelectronics
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
description: |
|
||||
This binding provides resources required to build and run an SPI
|
||||
loopback test under power management conditions
|
||||
|
||||
compatible: "test-spi-loopback"
|
||||
|
||||
include: [spi-device.yaml]
|
|
@ -5,4 +5,7 @@ CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE=n
|
|||
CONFIG_PM_S2RAM=y
|
||||
CONFIG_ADC=y
|
||||
CONFIG_ENTROPY_GENERATOR=y
|
||||
#CONFIG_DEBUG=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_STM32_DMA=y
|
||||
CONFIG_SPI_STM32_INTERRUPT=n
|
||||
CONFIG_SPI_ASYNC=n
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
#include <zephyr/pm/device_runtime.h>
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/drivers/entropy.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define SLEEP_TIME_STOP0_MS 800
|
||||
#define SLEEP_TIME_STOP1_MS 1500
|
||||
|
@ -21,7 +24,7 @@
|
|||
#define SLEEP_TIME_BUSY_MS 2000
|
||||
|
||||
static const struct gpio_dt_spec led =
|
||||
GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
|
||||
GPIO_DT_SPEC_GET(DT_ALIAS(led2), gpios);
|
||||
|
||||
#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
|
||||
!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
|
||||
|
@ -43,6 +46,86 @@ const struct device *rng_dev;
|
|||
|
||||
static uint8_t entropy_buffer[BUFFER_LENGTH] = {0};
|
||||
|
||||
#define SPI_TEST_DEV DT_COMPAT_GET_ANY_STATUS_OKAY(test_spi_loopback)
|
||||
|
||||
#define FRAME_SIZE (8)
|
||||
|
||||
#define SPI_OP(frame_size) SPI_OP_MODE_MASTER | SPI_MODE_CPOL | \
|
||||
SPI_MODE_CPHA | SPI_WORD_SET(frame_size) | SPI_LINES_SINGLE
|
||||
|
||||
static struct spi_dt_spec spi_test_dev = SPI_DT_SPEC_GET(SPI_TEST_DEV, SPI_OP(FRAME_SIZE), 0);
|
||||
|
||||
#define SPI_BUF_SIZE 18
|
||||
|
||||
static const char spi_tx_data[SPI_BUF_SIZE] = "0123456789abcdef-\0";
|
||||
static __aligned(32) char spi_buffer_tx[SPI_BUF_SIZE] __used;
|
||||
static __aligned(32) char spi_buffer_rx[SPI_BUF_SIZE] __used;
|
||||
|
||||
static uint8_t spi_buffer_print_tx[SPI_BUF_SIZE * 5 + 1];
|
||||
static uint8_t spi_buffer_print_rx[SPI_BUF_SIZE * 5 + 1];
|
||||
|
||||
static void to_display_format(const uint8_t *src, size_t size, char *dst)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
sprintf(dst + 5 * i, "0x%02x,", src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int spi_test(void)
|
||||
{
|
||||
const struct spi_buf tx_bufs[] = {
|
||||
{
|
||||
.buf = spi_buffer_tx,
|
||||
.len = SPI_BUF_SIZE,
|
||||
},
|
||||
};
|
||||
const struct spi_buf rx_bufs[] = {
|
||||
{
|
||||
.buf = spi_buffer_rx,
|
||||
.len = SPI_BUF_SIZE,
|
||||
},
|
||||
};
|
||||
const struct spi_buf_set tx = {
|
||||
.buffers = tx_bufs,
|
||||
.count = ARRAY_SIZE(tx_bufs)
|
||||
};
|
||||
const struct spi_buf_set rx = {
|
||||
.buffers = rx_bufs,
|
||||
.count = ARRAY_SIZE(rx_bufs)
|
||||
};
|
||||
|
||||
int ret;
|
||||
|
||||
ret = spi_transceive_dt(&spi_test_dev, &tx, &rx);
|
||||
if (ret) {
|
||||
printk("SPI transceive failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (memcmp(spi_buffer_tx, spi_buffer_rx, SPI_BUF_SIZE)) {
|
||||
to_display_format(spi_buffer_tx, SPI_BUF_SIZE, spi_buffer_print_tx);
|
||||
to_display_format(spi_buffer_rx, SPI_BUF_SIZE, spi_buffer_print_rx);
|
||||
printk("Buffer contents are different\n");
|
||||
printk("tx: %s\n", spi_buffer_print_tx);
|
||||
printk("rx: %s\n", spi_buffer_print_rx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spi_setup(void)
|
||||
{
|
||||
memset(spi_buffer_tx, 0, sizeof(spi_buffer_tx));
|
||||
memcpy(spi_buffer_tx, spi_tx_data, sizeof(spi_tx_data));
|
||||
|
||||
if (!spi_is_ready_dt(&spi_test_dev)) {
|
||||
printk("Fast spi lookback device is not ready\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int adc_test(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -122,6 +205,17 @@ void print_buf(uint8_t *buffer)
|
|||
printk("\n");
|
||||
}
|
||||
|
||||
static void loop(void)
|
||||
{
|
||||
gpio_pin_set_dt(&led, 1);
|
||||
adc_test();
|
||||
if (!IS_ENABLED(CONFIG_PM_S2RAM)) {
|
||||
spi_test();
|
||||
}
|
||||
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
|
||||
gpio_pin_set_dt(&led, 0);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
__ASSERT_NO_MSG(gpio_is_ready_dt(&led));
|
||||
|
@ -131,20 +225,17 @@ int main(void)
|
|||
printk("error: random device not ready");
|
||||
}
|
||||
|
||||
spi_setup();
|
||||
|
||||
printk("Device ready\n");
|
||||
|
||||
while (true) {
|
||||
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
|
||||
adc_test();
|
||||
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
|
||||
gpio_pin_set_dt(&led, 0);
|
||||
loop();
|
||||
k_msleep(SLEEP_TIME_STOP0_MS);
|
||||
printk("Exit Stop0\n");
|
||||
|
||||
gpio_pin_set_dt(&led, 1);
|
||||
adc_test();
|
||||
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
|
||||
gpio_pin_set_dt(&led, 0);
|
||||
loop();
|
||||
k_msleep(SLEEP_TIME_STOP1_MS);
|
||||
printk("Exit Stop1\n");
|
||||
|
||||
|
@ -153,9 +244,7 @@ int main(void)
|
|||
printk("Sync entropy: ");
|
||||
print_buf(entropy_buffer);
|
||||
|
||||
gpio_pin_set_dt(&led, 1);
|
||||
adc_test();
|
||||
k_busy_wait(SLEEP_TIME_BUSY_MS*1000);
|
||||
loop();
|
||||
gpio_pin_configure_dt(&led, GPIO_DISCONNECTED);
|
||||
k_msleep(SLEEP_TIME_STANDBY_MS);
|
||||
printk("Exit Standby\n");
|
||||
|
|
Loading…
Reference in a new issue