Skip to content

Commit d9007a0

Browse files
Tomasz BursztykaAnas Nashif
authored andcommitted
samples/spi: Add an asynchronous call test
This gives a quicke example on how to use SPI asynchronous calls with kernel's k_poll API. Signed-off-by: Tomasz Bursztyka <[email protected]>
1 parent 587dd5d commit d9007a0

File tree

3 files changed

+86
-6
lines changed

3 files changed

+86
-6
lines changed

samples/drivers/spi/prj_em_starterkit.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ CONFIG_GPIO=y
33
CONFIG_SPI_LEGACY_API=n
44
CONFIG_SPI=y
55
CONFIG_SYS_LOG_SPI_LEVEL=4
6+
CONFIG_POLL=y

samples/drivers/spi/prj_quark_se_c1000_devboard.conf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ CONFIG_SPI_LEGACY_API=n
44
CONFIG_SPI=y
55
CONFIG_SPI_QMSI=n
66
CONFIG_SPI_DW=y
7-
CONFIG_SYS_LOG_SPI_LEVEL=2
7+
CONFIG_POLL=y
8+
CONFIG_SYS_LOG_SPI_LEVEL=4

samples/drivers/spi/src/spi.c

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#define SYS_LOG_LEVEL SYS_LOG_LEVEL_INFO
7+
#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
88
#include <logging/sys_log.h>
99

1010
#include <zephyr.h>
@@ -112,6 +112,8 @@ static int spi_complete_loop(struct spi_config *spi_conf)
112112
return -1;
113113
}
114114

115+
SYS_LOG_DBG("Passed");
116+
115117
return 0;
116118
}
117119

@@ -142,6 +144,8 @@ static int spi_rx_half_start(struct spi_config *spi_conf)
142144
return -1;
143145
}
144146

147+
SYS_LOG_DBG("Passed");
148+
145149
return 0;
146150
}
147151

@@ -176,6 +180,8 @@ static int spi_rx_half_end(struct spi_config *spi_conf)
176180
return -1;
177181
}
178182

183+
SYS_LOG_DBG("Passed");
184+
179185
return 0;
180186
}
181187

@@ -216,12 +222,75 @@ static int spi_rx_every_4(struct spi_config *spi_conf)
216222
return -1;
217223
}
218224

225+
SYS_LOG_DBG("Passed");
226+
219227
return 0;
220228
}
221229

230+
static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER();
231+
static struct k_poll_event async_evt =
232+
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
233+
K_POLL_MODE_NOTIFY_ONLY,
234+
&async_sig);
235+
static struct k_sem caller = K_SEM_INITIALIZER(caller, 0, 1);
236+
static char __noinit spi_async_stack[256];
237+
static int result = 1;
238+
239+
static void spi_async_call_cb(struct k_poll_event *async_evt,
240+
struct k_sem *caller_sem,
241+
void *unused)
242+
{
243+
SYS_LOG_DBG("Polling...");
244+
245+
while (1) {
246+
k_poll(async_evt, 1, K_MSEC(100));
247+
248+
result = async_evt->signal->result;
249+
k_sem_give(caller_sem);
250+
251+
/* Reinitializing for next call */
252+
async_evt->signal->signaled = 0;
253+
async_evt->state = K_POLL_STATE_NOT_READY;
254+
}
255+
}
256+
257+
static int spi_async_call(struct spi_config *spi_conf)
258+
{
259+
struct spi_buf tx = {
260+
.buf = buffer_tx,
261+
.len = BUF_SIZE,
262+
};
263+
struct spi_buf rx = {
264+
.buf = buffer_rx,
265+
.len = BUF_SIZE,
266+
};
267+
const struct spi_buf *tx_bufs[] = { &tx, NULL };
268+
struct spi_buf *rx_bufs[] = { &rx, NULL };
269+
int ret;
270+
271+
ret = spi_transceive_async(spi_conf, tx_bufs, rx_bufs, &async_sig);
272+
if (ret) {
273+
SYS_LOG_ERR("Code %d", ret);
274+
return -1;
275+
}
276+
277+
k_sem_take(&caller, K_FOREVER);
278+
279+
if (result) {
280+
SYS_LOG_ERR("Call code %d", ret);
281+
return -1;
282+
}
283+
284+
SYS_LOG_DBG("Passed");
285+
286+
return 0;
287+
}
222288

223289
void main(void)
224290
{
291+
struct k_thread async_thread;
292+
k_tid_t async_thread_id;
293+
225294
SYS_LOG_INF("SPI test on buffex TX/RX %p/%p", buffer_tx, buffer_rx);
226295

227296
if (cs_ctrl_gpio_config(spi_slow.cs) ||
@@ -237,19 +306,28 @@ void main(void)
237306

238307
spi_fast.dev = spi_slow.dev;
239308

309+
async_thread_id = k_thread_create(&async_thread, spi_async_stack, 256,
310+
(k_thread_entry_t)spi_async_call_cb,
311+
&async_evt, &caller, NULL,
312+
K_PRIO_COOP(7), 0, 0);
313+
240314
if (spi_complete_loop(&spi_slow) ||
241315
spi_rx_half_start(&spi_slow) ||
242316
spi_rx_half_end(&spi_slow) ||
243-
spi_rx_every_4(&spi_slow)) {
244-
return;
317+
spi_rx_every_4(&spi_slow) ||
318+
spi_async_call(&spi_slow)) {
319+
goto end;
245320
}
246321

247322
if (spi_complete_loop(&spi_fast) ||
248323
spi_rx_half_start(&spi_fast) ||
249324
spi_rx_half_end(&spi_fast) ||
250-
spi_rx_every_4(&spi_fast)) {
251-
return;
325+
spi_rx_every_4(&spi_fast) ||
326+
spi_async_call(&spi_fast)) {
327+
goto end;
252328
}
253329

254330
SYS_LOG_INF("All tx/rx passed");
331+
end:
332+
k_thread_cancel(async_thread_id);
255333
}

0 commit comments

Comments
 (0)