Skip to content

Commit e0ae956

Browse files
nordic-baminordic-piks
authored andcommitted
tests: drivers: spi: Add test case for MLTPAN-57 workaround
The MLTPAN-57 test case workaround uses fast SPIM (SPIM00) Signed-off-by: Bartosz Miller <[email protected]>
1 parent 8f72435 commit e0ae956

File tree

3 files changed

+173
-12
lines changed

3 files changed

+173
-12
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
&pinctrl {
8+
dut_spi_default: dut_spi_default {
9+
group1 {
10+
psels = <NRF_PSEL(SPIM_SCK, 2, 1)>,
11+
<NRF_PSEL(SPIM_MISO, 2, 4)>,
12+
<NRF_PSEL(SPIM_MOSI, 2, 2)>;
13+
};
14+
};
15+
16+
dut_spi_sleep: dut_spi_sleep {
17+
group1 {
18+
psels = <NRF_PSEL(SPIM_SCK, 2, 1)>,
19+
<NRF_PSEL(SPIM_MISO, 2, 4)>,
20+
<NRF_PSEL(SPIM_MOSI, 2, 2)>;
21+
low-power-enable;
22+
};
23+
};
24+
};
25+
26+
dut_spi_fast: &spi00 {
27+
compatible = "nordic,nrf-spim";
28+
status = "okay";
29+
pinctrl-0 = <&dut_spi_default>;
30+
pinctrl-1 = <&dut_spi_sleep>;
31+
pinctrl-names = "default", "sleep";
32+
overrun-character = <0x00>;
33+
zephyr,pm-device-runtime-auto;
34+
cs-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
35+
36+
dut_spi_dt: test-spi-dev@0 {
37+
compatible = "vnd,spi-device";
38+
reg = <0>;
39+
spi-max-frequency = <DT_FREQ_M(16)>;
40+
};
41+
};
42+
43+
&gpio2 {
44+
status = "okay";
45+
};
46+
47+
tst_timer: &timer20 {
48+
status = "okay";
49+
};
50+
51+
&dppic20 {
52+
status = "okay";
53+
};
54+
55+
&mx25r64 {
56+
status = "disabled";
57+
};

tests/drivers/spi/spim_pan/src/main.c

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,23 @@
1616

1717
/* SPI MODE 0 */
1818
#define SPI_MODE (SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE | SPI_TRANSFER_MSB)
19+
20+
#if DT_NODE_EXISTS(DT_NODELABEL(dut_spi_fast))
21+
#define DUT_SPI_NODE DT_NODELABEL(dut_spi_fast)
22+
#define DUT_SPI_FAST 1
23+
#define TEST_BUFFER_SIZE 4
24+
#define MX25R64_RDID 0x9F
25+
#define MX25R64_MFG_ID 0xC2
26+
#define MX25R64_MEM_TYPE 0x28
27+
#define MX25R64_MEM_DENSITY 0x17
28+
#define MAX_READ_REPEATS 10
29+
#else
30+
#define DUT_SPI_NODE DT_NODELABEL(dut_spi)
1931
#define TEST_BUFFER_SIZE 64
32+
#endif
2033

2134
static struct spi_dt_spec spim_spec = SPI_DT_SPEC_GET(DT_NODELABEL(dut_spi_dt), SPI_MODE, 0);
22-
NRF_SPIM_Type *spim_reg = (NRF_SPIM_Type *)DT_REG_ADDR(DT_NODELABEL(dut_spi));
35+
NRF_SPIM_Type *spim_reg = (NRF_SPIM_Type *)DT_REG_ADDR(DUT_SPI_NODE);
2336

2437
static nrfx_timer_t test_timer = NRFX_TIMER_INSTANCE(DT_REG_ADDR(DT_NODELABEL(tst_timer)));
2538

@@ -71,6 +84,8 @@ static uint32_t configure_test_timer(nrfx_timer_t *timer)
7184

7285
ZTEST(spim_pan, test_spim_mltpan_8_workaround)
7386
{
87+
Z_TEST_SKIP_IFDEF(DUT_SPI_FAST);
88+
7489
int err;
7590

7691
struct spi_buf tx_spi_buf = {.buf = tx_buffer, .len = TEST_BUFFER_SIZE};
@@ -99,6 +114,8 @@ ZTEST(spim_pan, test_spim_mltpan_8_workaround)
99114

100115
ZTEST(spim_pan, test_spim_mltpan_55_workaround)
101116
{
117+
Z_TEST_SKIP_IFDEF(DUT_SPI_FAST);
118+
102119
int err;
103120

104121
uint8_t ppi_channel;
@@ -132,6 +149,7 @@ ZTEST(spim_pan, test_spim_mltpan_55_workaround)
132149

133150
timer_cc_before = nrfx_timer_capture(&test_timer, NRF_TIMER_CC_CHANNEL0);
134151
err = spi_transceive_dt(&spim_spec, &tx_spi_buf_set, &rx_spi_buf_set);
152+
zassert_ok(err, "SPI transceive failed: %d\n", err);
135153
timer_cc_after = nrfx_timer_capture(&test_timer, NRF_TIMER_CC_CHANNEL0);
136154

137155
TC_PRINT("Timer count before: %u, timer count after: %u\n", timer_cc_before,
@@ -142,4 +160,79 @@ ZTEST(spim_pan, test_spim_mltpan_55_workaround)
142160
zassert_mem_equal(tx_buffer, rx_buffer, TEST_BUFFER_SIZE - 1, "TX buffer != RX buffer\n");
143161
}
144162

163+
/*
164+
* Reference: MLTPAN-57
165+
* SPIM00 does not operate as expected
166+
* SPIM00 is the fast SPIM instance
167+
* Requires workaround
168+
*/
169+
170+
ZTEST(spim_pan, test_spim_mltpan_57_workaround)
171+
{
172+
Z_TEST_SKIP_IFNDEF(DUT_SPI_FAST);
173+
#if defined(DUT_SPI_FAST)
174+
int err;
175+
176+
uint8_t ppi_channel;
177+
178+
uint32_t domain_id;
179+
nrfx_gppi_handle_t gppi_handle;
180+
181+
uint32_t timer_cc_before, timer_cc_after, tx_amount;
182+
183+
uint32_t timer_task;
184+
uint32_t spim_event;
185+
186+
memset(tx_buffer, 0xFF, TEST_BUFFER_SIZE);
187+
tx_buffer[0] = MX25R64_RDID;
188+
189+
domain_id = nrfx_gppi_domain_id_get((uint32_t)test_timer.p_reg);
190+
ppi_channel = nrfx_gppi_channel_alloc(domain_id);
191+
zassert_true(ppi_channel > 0, "Failed to allocate GPPI channel");
192+
193+
timer_task = configure_test_timer(&test_timer);
194+
spim_event = nrf_spim_event_address_get(spim_reg, NRF_SPIM_EVENT_END);
195+
196+
zassert_ok(nrfx_gppi_conn_alloc(spim_event, timer_task, &gppi_handle),
197+
"Failed to allocate DPPI connection\n");
198+
nrfx_gppi_conn_enable(gppi_handle);
199+
200+
struct spi_buf tx_spi_buf = {.buf = tx_buffer, .len = TEST_BUFFER_SIZE};
201+
struct spi_buf_set tx_spi_buf_set = {.buffers = &tx_spi_buf, .count = 1};
202+
203+
struct spi_buf rx_spi_buf = {.buf = rx_buffer, .len = TEST_BUFFER_SIZE};
204+
struct spi_buf_set rx_spi_buf_set = {.buffers = &rx_spi_buf, .count = 1};
205+
206+
for (int i = 0; i < MAX_READ_REPEATS; i++) {
207+
TC_PRINT("RDID attempt %u\n", i + 1);
208+
209+
timer_cc_before = nrfx_timer_capture(&test_timer, NRF_TIMER_CC_CHANNEL0);
210+
err = spi_transceive_dt(&spim_spec, &tx_spi_buf_set, &rx_spi_buf_set);
211+
timer_cc_after = nrfx_timer_capture(&test_timer, NRF_TIMER_CC_CHANNEL0);
212+
TC_PRINT("SPIM prescaler: %u\n", spim_reg->PRESCALER);
213+
zassert_ok(err, "SPI transceive failed: %d\n", err);
214+
215+
tx_amount = nrf_spim_tx_amount_get(spim_reg);
216+
TC_PRINT("END events count: %u\n", timer_cc_after - timer_cc_before);
217+
TC_PRINT("TX.AMOUNT: %u\n", tx_amount);
218+
219+
zassert_equal(timer_cc_after - timer_cc_before, 1,
220+
"END event has not been generated\n");
221+
zassert_equal(tx_amount, ARRAY_SIZE(tx_buffer), "TX.AMOUNT != TX Buffer size\n");
222+
223+
for (int i = 0; i < ARRAY_SIZE(rx_buffer); i++) {
224+
TC_PRINT("rx_buffer[%d] = 0x%x\n", i, rx_buffer[i]);
225+
}
226+
227+
/* First RX byte is dummy */
228+
zassert_equal(rx_buffer[1], MX25R64_MFG_ID,
229+
"Read MX25R64 device ID is different than expected\n");
230+
zassert_equal(rx_buffer[2], MX25R64_MEM_TYPE,
231+
"Read MX25R64 memory type is different than expected\n");
232+
zassert_equal(rx_buffer[3], MX25R64_MEM_DENSITY,
233+
"Read MX25R64 memory density is different than expected\n");
234+
}
235+
#endif
236+
}
237+
145238
ZTEST_SUITE(spim_pan, NULL, test_setup, NULL, NULL, NULL);

tests/drivers/spi/spim_pan/testcase.yaml

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,31 @@ common:
22
sysbuild: true
33
depends_on: gpio
44
harness: ztest
5-
harness_config:
6-
fixture: gpio_loopback
75
tags:
86
- drivers
97
- spim
108
- ci_tests_drivers_spi
11-
platform_allow:
12-
- nrf54h20dk/nrf54h20/cpuapp
13-
- nrf54l15dk/nrf54l15/cpuapp
14-
- nrf54lm20dk/nrf54lm20a/cpuapp
15-
- nrf54ls05dk/nrf54ls05b/cpuapp
16-
- nrf54lv10dk/nrf54lv10a/cpuapp
17-
integration_platforms:
18-
- nrf54l15dk/nrf54l15/cpuapp
199

2010
tests:
21-
drivers.spim_pan: {}
11+
drivers.spim_pan:
12+
platform_allow:
13+
- nrf54h20dk/nrf54h20/cpuapp
14+
- nrf54l15dk/nrf54l15/cpuapp
15+
- nrf54lm20dk/nrf54lm20a/cpuapp
16+
- nrf54ls05dk/nrf54ls05b/cpuapp
17+
- nrf54lv10dk/nrf54lv10a/cpuapp
18+
integration_platforms:
19+
- nrf54l15dk/nrf54l15/cpuapp
20+
harness_config:
21+
fixture: gpio_loopback
22+
23+
drivers.spim_pan.fast:
24+
platform_allow:
25+
- nrf54l15dk/nrf54l15/cpuapp
26+
- nrf54lm20dk/nrf54lm20a/cpuapp
27+
integration_platforms:
28+
- nrf54lm20dk/nrf54lm20a/cpuapp
29+
extra_args:
30+
- DTC_OVERLAY_FILE='boards/nrf54lxx_cpuapp_fast.overlay'
31+
harness_config:
32+
fixture: external_flash

0 commit comments

Comments
 (0)