Skip to content

Commit

Permalink
test: add test for SPI
Browse files Browse the repository at this point in the history
use configuration from sample

Signed-off-by: Robert Gałat <[email protected]>
  • Loading branch information
RobertGalatNordic committed Oct 18, 2024
1 parent 029f0cf commit 1da4f17
Show file tree
Hide file tree
Showing 15 changed files with 608 additions and 0 deletions.
14 changes: 14 additions & 0 deletions tests/functional/spi_endless/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(spi_endless)

FILE(GLOB app_sources src/*.c)

target_sources(app PRIVATE ${app_sources})
24 changes: 24 additions & 0 deletions tests/functional/spi_endless/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

config ROLE_HOST
int "Change test behaviour depending on Host/Device role"
default 1
help
Change test behaviour.
0: Device - returns data received previously
1: Host - generates data, sends it to the Device, confirms that received data is correct

config PAYLOAD_LEN
int "lenth of payload"
default 64

config DELAY_BETWEEN_PACKETS_MS
int "lenth of payload"
default 1
range 0 60000

source "Kconfig.zephyr"
77 changes: 77 additions & 0 deletions tests/functional/spi_endless/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
Test description:

Test consists of 2 boards connected with jumper wires according to schematic below.
One of the board should be flashed with host variant, and another with Device variant of the test.

The host performs SPI xfer operation (bidirectional write/read).
Device listens to the host transmisions.
Every message received by Device is transmitted in the next xfer operation.

host sends deterministic values. first payload is the slice of the random table (table containing random bytes).
and every subsequent transfers from host consists of the previopus payload increased by 1 ( byte by byte)

so the valid communication looks as follows ( 3 B transfer example )

MOSI |12 23 34 | 13 24 35 | 14 25 36
MISO |00 00 00 | 12 23 34 | 13 24 35

The host expects to reveice on N th mesasge the conetent send on N-1.
The Slave can also assert the data it received, because the mechanism of creating new message is dependent on previous message
So it can also detect, if the host failed to send data correctly, if on MOSI line the values of each byte are not bigger by 1 from the previous transmision.

Building instructions:

Please consult testcase.yaml for manual build
But for most cases it is easier to use twister for building:

`west twister -p nrf52840dk/nrf52840 -p nrf54l15dk/nrf54l15/cpuapp -T .`

connection schematic:

Host Device
nrf54l15 nrf52840

GND - GND
vddio - VIO_REF
2.6 - 1.2 SPIM_SCK
1.11 - 1.4 SPIM_MISO
2.8 - 1.8 SPIM_MOSI
2.10 - 1.10 CS


The twister builds 2 variants, but at this time only described above configuration was tested

Flash the Development kits:
Device variant for 52
and host variant for 54

Configuration options:
There are overlays to change speed of the host (default 8Mhz) *does not require rebuild for Device
There is Kconfig to change delay between messages ( default 1ms ) * does not require rebuild for Device
There is Kconfig to change the amount of data to send (default 64) * Requires rebuild for both Device and host

Observe the output on the serial of 54


The issue:


```
[00:00:52.818,041] <err> host: readed
32 cd 0a 93 5c 98 bb d7 27 ff 50 63 5e 44 43 fe |2...\... '.Pc^DC.
76 8d 4b ad 68 47 46 c6 9d 70 1d ed e0 34 66 36 |v.K.hGF. .p...4f6
08 de bb 15 ea 09 ee 2b 2e ad 74 1b 4a a2 5e ba |.......+ ..t.J.^.
22 e5 3c 51 5f 69 95 1f c4 bc 5f 80 00 05 d7 4f |".<Q_i.. .._....O
[00:00:52.818,053] <err> host: expected
32 cd 0a 93 5c 98 bb d7 27 ff 50 63 5e 44 43 cf |2...\... '.Pc^DC.
fc ed 1a 97 5a d0 8e 8d 8d 3a e0 3b db c0 68 cc |....Z... .:.;..h.
6c 11 bd 76 2b d4 13 dc 56 5d 5a e8 36 95 44 bd |l..v+... V]Z.6.D.
74 45 ca 78 a2 be d3 2a 3f 89 78 99 c6 9f 8b ae |tE.x...* ?.x.....
```

Snippet of logs from the host.
This log shows that the host read 64 Bytes , but only first 14B were maching the expected values.
The log suggests that every transfer fail the comparason of the expected read values.

The analysis of the trace gathered by external logic analyzer suggests, that Device sends correct data on MISO line,
so the logical conclusion is that the host faild to read it correctly.
9 changes: 9 additions & 0 deletions tests/functional/spi_endless/boards/1mhz.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

&dut_spi_dt {
spi-max-frequency = <1000000>;
};
9 changes: 9 additions & 0 deletions tests/functional/spi_endless/boards/2mhz.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

&dut_spi_dt {
spi-max-frequency = <2000000>;
};
9 changes: 9 additions & 0 deletions tests/functional/spi_endless/boards/4mhz.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

&dut_spi_dt {
spi-max-frequency = <4000000>;
};
9 changes: 9 additions & 0 deletions tests/functional/spi_endless/boards/8mhz.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

&dut_spi_dt {
spi-max-frequency = <8000000>;
};
69 changes: 69 additions & 0 deletions tests/functional/spi_endless/boards/nrf52840dk_nrf52840.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

&pinctrl {
spi1_default_alt: spi1_default_alt {
group1 {
psels = <NRF_PSEL(SPIS_SCK, 1, 2)>,
<NRF_PSEL(SPIS_MISO, 1, 4)>,
<NRF_PSEL(SPIS_MOSI, 1, 8)>,
<NRF_PSEL(SPIS_CSN, 1, 10)>;
};
};

spi1_sleep_alt: spi1_sleep_alt {
group1 {
psels = <NRF_PSEL(SPIS_SCK, 1, 2)>,
<NRF_PSEL(SPIS_MISO, 1, 4)>,
<NRF_PSEL(SPIS_MOSI, 1, 8)>,
<NRF_PSEL(SPIS_CSN, 1, 10)>;
low-power-enable;
};
};

spi2_default_alt: spi2_default_alt {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
<NRF_PSEL(SPIM_MISO, 1, 14)>,
<NRF_PSEL(SPIM_MOSI, 1, 13)>;
};
};

spi2_sleep_alt: spi2_sleep_alt{
group1 {
psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
<NRF_PSEL(SPIM_MISO, 1, 14)>,
<NRF_PSEL(SPIM_MOSI, 1, 13)>;
low-power-enable;
};
};

};

&spi2 {
status = "okay";
pinctrl-0 = <&spi2_default_alt>;
pinctrl-1 = <&spi2_sleep_alt>;
pinctrl-names = "default", "sleep";
overrun-character = <0x00>;
cs-gpios = <&gpio1 0x8 GPIO_ACTIVE_LOW>;
dut_spi_dt: test-spi-dev@0 {
compatible = "vnd,spi-device";
reg = <0>;
spi-max-frequency = <DT_FREQ_M(8)>;
};
};

dut_spis: &spi1 {
compatible = "nordic,nrf-spis";
status = "okay";
def-char = <0x00>;
pinctrl-0 = <&spi1_default_alt>;
pinctrl-1 = <&spi1_sleep_alt>;
pinctrl-names = "default", "sleep";
/delete-property/rx-delay-supported;
/delete-property/rx-delay;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

&pinctrl {
spi21_default_alt: spi21_default_alt {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 2, 6)>,
<NRF_PSEL(SPIM_MISO, 1, 11)>,
<NRF_PSEL(SPIM_MOSI, 2, 8)>;
};
};

spi21_sleep_alt: spi21_sleep_alt {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 2, 6)>,
<NRF_PSEL(SPIM_MISO, 1, 11)>,
<NRF_PSEL(SPIM_MOSI, 2, 8)>;
low-power-enable;
};
};
spi30_default_alt: spi30_default_alt {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 0, 3)>,
<NRF_PSEL(SPIM_MISO, 0, 2)>,
<NRF_PSEL(SPIM_MOSI, 0, 1)>,
<NRF_PSEL(SPIS_CSN, 0, 0)>;
};
};

spi30_sleep_alt: spi30_sleep_alt {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 0, 3)>,
<NRF_PSEL(SPIM_MISO, 0, 2)>,
<NRF_PSEL(SPIM_MOSI, 0, 1)>,
<NRF_PSEL(SPIS_CSN, 0, 0)>;
low-power-enable;
};
};


};

&gpio2 {
status = "okay";
};
&gpio1 {
status = "okay";
};
&gpio0 {
status = "okay";
};

&spi21 {
status = "okay";
pinctrl-0 = <&spi21_default_alt>;
pinctrl-1 = <&spi21_sleep_alt>;
pinctrl-names = "default", "sleep";
overrun-character = <0x00>;
cs-gpios = <&gpio2 0xa GPIO_ACTIVE_LOW>;
dut_spi_dt: test-spi-dev@0 {
compatible = "vnd,spi-device";
reg = <0>;
spi-max-frequency = <DT_FREQ_M(8)>;
};
};


dut_spis: &spi30 {
compatible = "nordic,nrf-spis";
status = "okay";
def-char = <0x00>;
pinctrl-0 = <&spi30_default_alt>;
pinctrl-1 = <&spi30_sleep_alt>;
pinctrl-names = "default", "sleep";
/delete-property/rx-delay-supported;
/delete-property/rx-delay;
};




// /////////////////
12 changes: 12 additions & 0 deletions tests/functional/spi_endless/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

CONFIG_SPI=y
CONFIG_SPI_SLAVE=y
CONFIG_GPIO=y
CONFIG_SPI_ASYNC=y
CONFIG_LOG=y
CONFIG_SPI_LOG_LEVEL_INF=y
66 changes: 66 additions & 0 deletions tests/functional/spi_endless/src/device.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <stdint.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(device, LOG_LEVEL_INF);

#include <zephyr/kernel.h>
#include <zephyr/drivers/spi.h>
extern uint8_t random_table[];

void device_start(const struct device *dev, const struct spi_config *cfg)
{
static uint8_t tx[CONFIG_PAYLOAD_LEN] = { 0 };
static uint8_t rx[CONFIG_PAYLOAD_LEN] = { 0 };
static uint8_t rx_expect[CONFIG_PAYLOAD_LEN] = { 0 };
memcpy(rx_expect, random_table, CONFIG_PAYLOAD_LEN);

struct spi_buf tx_buff[] = {
{
.buf = tx,
.len = CONFIG_PAYLOAD_LEN,
},
};

struct spi_buf_set tx_set = { .buffers = tx_buff, .count = 1 };

struct spi_buf rx_buff[] = {
{
.buf = rx,
.len = CONFIG_PAYLOAD_LEN,
},
};
struct spi_buf_set rx_set = { .buffers = rx_buff, .count = 1 };
size_t packet_number = 0;

while (true) {
int ret = spi_transceive(dev, cfg, &tx_set, &rx_set);
if (ret <= 0) {
LOG_ERR("spi_transceive_dt returned %d", ret);
}
LOG_INF("received packet number %d", packet_number++);

int cmp = memcmp(rx, rx_expect, CONFIG_PAYLOAD_LEN);
if (cmp != 0) {
LOG_ERR("Received unexpected payload");
LOG_HEXDUMP_ERR(rx, CONFIG_PAYLOAD_LEN, "received");
LOG_HEXDUMP_ERR(rx_expect, CONFIG_PAYLOAD_LEN, "expected");
LOG_ERR("Fail");
} else {
// LOG_INF("OK");
}

// prepare tx for next response
memcpy(tx, rx, CONFIG_PAYLOAD_LEN);
// LOG_HEXDUMP_INF(rx, CONFIG_PAYLOAD_LEN, "received");
// calculate what will be next rx payload
for (size_t i = 0; i < CONFIG_PAYLOAD_LEN; i++) {
uint8_t expected_val = rx[i] + 1;
rx_expect[i] = expected_val;
}
}
}
Loading

0 comments on commit 1da4f17

Please sign in to comment.