Skip to content

Commit cd54dc6

Browse files
Tomasz BursztykaAnas Nashif
authored andcommitted
samples: Add an SPI driver test application
This application intents to test an SPI driver by looping over MISO/MOSI line where the controller will then send data to itself. It will test various buffer tx/rx schemes. Signed-off-by: Tomasz Bursztyka <[email protected]>
1 parent 19b36ae commit cd54dc6

File tree

5 files changed

+280
-0
lines changed

5 files changed

+280
-0
lines changed

samples/drivers/spi/Makefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Makefile - SPI sample
2+
3+
#
4+
# Copyright (c) 2017 Intel Corporation
5+
#
6+
# SPDX-License-Identifier: Apache-2.0
7+
#
8+
9+
BOARD ?= quark_se_c1000_devboard
10+
CONF_FILE ?= prj_$(BOARD).conf
11+
12+
include $(ZEPHYR_BASE)/Makefile.inc
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CONFIG_SYS_LOG=y
2+
CONFIG_GPIO=y
3+
CONFIG_SPI_LEGACY_API=n
4+
CONFIG_SPI=y
5+
CONFIG_SYS_LOG_SPI_LEVEL=4
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CONFIG_SYS_LOG=y
2+
CONFIG_GPIO=y
3+
CONFIG_SPI_LEGACY_API=n
4+
CONFIG_SPI=y
5+
CONFIG_SPI_QMSI=n
6+
CONFIG_SPI_DW=y
7+
CONFIG_SYS_LOG_SPI_LEVEL=2

samples/drivers/spi/src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
obj-y = spi.o

samples/drivers/spi/src/spi.c

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
/*
2+
* Copyright (c) 2017 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define SYS_LOG_LEVEL SYS_LOG_LEVEL_INFO
8+
#include <logging/sys_log.h>
9+
10+
#include <zephyr.h>
11+
#include <misc/printk.h>
12+
#include <string.h>
13+
14+
#include <spi.h>
15+
16+
#define SPI_CS &spi_cs
17+
18+
#if defined(CONFIG_SOC_QUARK_SE_C1000)
19+
20+
#define SPI_DRV_NAME CONFIG_SPI_0_NAME
21+
#define SPI_SLAVE 1
22+
#define CS_CTRL_GPIO_DRV_NAME CONFIG_GPIO_QMSI_0_NAME
23+
24+
struct spi_cs_control spi_cs = {
25+
.gpio_pin = 25,
26+
.delay = 0
27+
};
28+
29+
#elif defined(CONFIG_SOC_QUARK_SE_C1000_SS)
30+
31+
#define SPI_DRV_NAME CONFIG_SPI_0_NAME
32+
#define SPI_SLAVE 0
33+
#define CS_CTRL_GPIO_DRV_NAME CONFIG_GPIO_DW_0_NAME
34+
35+
struct spi_cs_control spi_cs = {
36+
.gpio_pin = 0,
37+
.delay = 0
38+
};
39+
40+
#elif defined(CONFIG_SOC_EM7D) || defined(CONFIG_SOC_EM9D)
41+
42+
#define SPI_DRV_NAME CONFIG_SPI_0_NAME
43+
#define SPI_SLAVE 0
44+
45+
#undef SPI_CS
46+
#define SPI_CS NULL
47+
#define CS_CTRL_GPIO_DRV_NAME ""
48+
49+
#else
50+
#undef SPI_CS
51+
#define SPI_CS NULL
52+
#define CS_CTRL_GPIO_DRV_NAME ""
53+
#endif
54+
55+
#define BUF_SIZE 17
56+
u8_t buffer_tx[] = "0123456789abcdef\0";
57+
u8_t buffer_rx[BUF_SIZE] = {};
58+
59+
struct spi_config spi_slow = {
60+
.frequency = 128000,
61+
.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
62+
SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
63+
.slave = SPI_SLAVE,
64+
.cs = SPI_CS,
65+
};
66+
67+
struct spi_config spi_fast = {
68+
.frequency = 16000000,
69+
.operation = SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
70+
SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE,
71+
.slave = SPI_SLAVE,
72+
.cs = SPI_CS,
73+
};
74+
75+
struct device *spi_dev;
76+
77+
static int cs_ctrl_gpio_config(struct spi_cs_control *cs)
78+
{
79+
if (cs) {
80+
cs->gpio_dev = device_get_binding(CS_CTRL_GPIO_DRV_NAME);
81+
if (!cs->gpio_dev) {
82+
SYS_LOG_ERR("Cannot find %s!\n",
83+
CS_CTRL_GPIO_DRV_NAME);
84+
return -1;
85+
}
86+
}
87+
88+
return 0;
89+
}
90+
91+
static int spi_complete_loop(struct spi_config *spi_conf)
92+
{
93+
struct spi_buf tx = {
94+
.buf = buffer_tx,
95+
.len = BUF_SIZE,
96+
};
97+
struct spi_buf rx = {
98+
.buf = buffer_rx,
99+
.len = BUF_SIZE,
100+
};
101+
const struct spi_buf *tx_bufs[] = { &tx, NULL };
102+
struct spi_buf *rx_bufs[] = { &rx, NULL };
103+
int ret;
104+
105+
ret = spi_transceive(spi_dev, spi_conf, tx_bufs, rx_bufs);
106+
if (ret) {
107+
SYS_LOG_ERR("Code %d", ret);
108+
return -1;
109+
}
110+
111+
if (memcmp(buffer_tx, buffer_rx, BUF_SIZE)) {
112+
SYS_LOG_ERR("Buffer contents are different %s vs %s",
113+
buffer_tx, buffer_rx);
114+
return -1;
115+
}
116+
117+
return 0;
118+
}
119+
120+
static int spi_rx_half_start(struct spi_config *spi_conf)
121+
{
122+
struct spi_buf tx = {
123+
.buf = buffer_tx,
124+
.len = BUF_SIZE,
125+
};
126+
struct spi_buf rx = {
127+
.buf = buffer_rx,
128+
.len = 8,
129+
};
130+
const struct spi_buf *tx_bufs[] = { &tx, NULL };
131+
struct spi_buf *rx_bufs[] = { &rx, NULL };
132+
int ret;
133+
134+
memset(buffer_rx, 0, BUF_SIZE);
135+
136+
ret = spi_transceive(spi_dev, spi_conf, tx_bufs, rx_bufs);
137+
if (ret) {
138+
SYS_LOG_ERR("Code %d", ret);
139+
return -1;
140+
}
141+
142+
if (memcmp(buffer_tx, buffer_rx, 8)) {
143+
SYS_LOG_ERR("Buffer contents are different");
144+
return -1;
145+
}
146+
147+
return 0;
148+
}
149+
150+
static int spi_rx_half_end(struct spi_config *spi_conf)
151+
{
152+
struct spi_buf tx = {
153+
.buf = buffer_tx,
154+
.len = BUF_SIZE,
155+
};
156+
struct spi_buf rx_1st_half = {
157+
.buf = NULL,
158+
.len = 8,
159+
};
160+
struct spi_buf rx_last_half = {
161+
.buf = buffer_rx,
162+
.len = 8,
163+
};
164+
const struct spi_buf *tx_bufs[] = { &tx, NULL };
165+
struct spi_buf *rx_bufs[] = { &rx_1st_half, &rx_last_half, NULL };
166+
int ret;
167+
168+
memset(buffer_rx, 0, BUF_SIZE);
169+
170+
ret = spi_transceive(spi_dev, spi_conf, tx_bufs, rx_bufs);
171+
if (ret) {
172+
SYS_LOG_ERR("Code %d", ret);
173+
return -1;
174+
}
175+
176+
if (memcmp(buffer_tx+8, buffer_rx, 8)) {
177+
SYS_LOG_ERR("Buffer contents are different");
178+
return -1;
179+
}
180+
181+
return 0;
182+
}
183+
184+
static int spi_rx_every_4(struct spi_config *spi_conf)
185+
{
186+
struct spi_buf tx = {
187+
.buf = buffer_tx,
188+
.len = BUF_SIZE,
189+
};
190+
struct spi_buf rx_start = {
191+
.buf = NULL,
192+
.len = 4,
193+
};
194+
struct spi_buf rx_1 = {
195+
.buf = buffer_rx,
196+
.len = 4,
197+
};
198+
struct spi_buf rx_2 = {
199+
.buf = buffer_rx+4,
200+
.len = 4,
201+
};
202+
const struct spi_buf *tx_bufs[] = { &tx, NULL };
203+
struct spi_buf *rx_bufs[] = { &rx_start, &rx_1,
204+
&rx_start, &rx_2, NULL };
205+
int ret;
206+
207+
memset(buffer_rx, 0, BUF_SIZE);
208+
209+
ret = spi_transceive(spi_dev, spi_conf, tx_bufs, rx_bufs);
210+
if (ret) {
211+
SYS_LOG_ERR("Code %d", ret);
212+
return -1;
213+
}
214+
215+
if (memcmp(buffer_tx+4, buffer_rx, 4) ||
216+
memcmp(buffer_tx+12, buffer_rx+4, 4)) {
217+
SYS_LOG_ERR("Buffer contents are different");
218+
return -1;
219+
}
220+
221+
return 0;
222+
}
223+
224+
225+
void main(void)
226+
{
227+
SYS_LOG_INF("SPI test on buffex TX/RX %p/%p", buffer_tx, buffer_rx);
228+
229+
if (cs_ctrl_gpio_config(spi_slow.cs) ||
230+
cs_ctrl_gpio_config(spi_fast.cs)) {
231+
return;
232+
}
233+
234+
spi_dev = device_get_binding(SPI_DRV_NAME);
235+
if (!spi_dev) {
236+
SYS_LOG_ERR("Cannot find %s!\n", SPI_DRV_NAME);
237+
return;
238+
}
239+
240+
if (spi_complete_loop(&spi_slow) ||
241+
spi_rx_half_start(&spi_slow) ||
242+
spi_rx_half_end(&spi_slow) ||
243+
spi_rx_every_4(&spi_slow)) {
244+
return;
245+
}
246+
247+
if (spi_complete_loop(&spi_fast) ||
248+
spi_rx_half_start(&spi_fast) ||
249+
spi_rx_half_end(&spi_fast) ||
250+
spi_rx_every_4(&spi_fast)) {
251+
return;
252+
}
253+
254+
SYS_LOG_INF("All tx/rx passed");
255+
}

0 commit comments

Comments
 (0)