From d9007a09f8c1fb5bc23a380602b315c526465194 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Mon, 8 May 2017 14:27:10 +0200 Subject: [PATCH] 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 --- samples/drivers/spi/prj_em_starterkit.conf | 1 + .../spi/prj_quark_se_c1000_devboard.conf | 3 +- samples/drivers/spi/src/spi.c | 88 +++++++++++++++++-- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/samples/drivers/spi/prj_em_starterkit.conf b/samples/drivers/spi/prj_em_starterkit.conf index 7e80af17d97..e14de939e20 100644 --- a/samples/drivers/spi/prj_em_starterkit.conf +++ b/samples/drivers/spi/prj_em_starterkit.conf @@ -3,3 +3,4 @@ CONFIG_GPIO=y CONFIG_SPI_LEGACY_API=n CONFIG_SPI=y CONFIG_SYS_LOG_SPI_LEVEL=4 +CONFIG_POLL=y diff --git a/samples/drivers/spi/prj_quark_se_c1000_devboard.conf b/samples/drivers/spi/prj_quark_se_c1000_devboard.conf index 75f7ecb5644..c4d7de515d7 100644 --- a/samples/drivers/spi/prj_quark_se_c1000_devboard.conf +++ b/samples/drivers/spi/prj_quark_se_c1000_devboard.conf @@ -4,4 +4,5 @@ CONFIG_SPI_LEGACY_API=n CONFIG_SPI=y CONFIG_SPI_QMSI=n CONFIG_SPI_DW=y -CONFIG_SYS_LOG_SPI_LEVEL=2 +CONFIG_POLL=y +CONFIG_SYS_LOG_SPI_LEVEL=4 diff --git a/samples/drivers/spi/src/spi.c b/samples/drivers/spi/src/spi.c index dbe2eb65d95..9ad226b964d 100644 --- a/samples/drivers/spi/src/spi.c +++ b/samples/drivers/spi/src/spi.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#define SYS_LOG_LEVEL SYS_LOG_LEVEL_INFO +#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG #include #include @@ -112,6 +112,8 @@ static int spi_complete_loop(struct spi_config *spi_conf) return -1; } + SYS_LOG_DBG("Passed"); + return 0; } @@ -142,6 +144,8 @@ static int spi_rx_half_start(struct spi_config *spi_conf) return -1; } + SYS_LOG_DBG("Passed"); + return 0; } @@ -176,6 +180,8 @@ static int spi_rx_half_end(struct spi_config *spi_conf) return -1; } + SYS_LOG_DBG("Passed"); + return 0; } @@ -216,12 +222,75 @@ static int spi_rx_every_4(struct spi_config *spi_conf) return -1; } + SYS_LOG_DBG("Passed"); + return 0; } +static struct k_poll_signal async_sig = K_POLL_SIGNAL_INITIALIZER(); +static struct k_poll_event async_evt = + K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, + K_POLL_MODE_NOTIFY_ONLY, + &async_sig); +static struct k_sem caller = K_SEM_INITIALIZER(caller, 0, 1); +static char __noinit spi_async_stack[256]; +static int result = 1; + +static void spi_async_call_cb(struct k_poll_event *async_evt, + struct k_sem *caller_sem, + void *unused) +{ + SYS_LOG_DBG("Polling..."); + + while (1) { + k_poll(async_evt, 1, K_MSEC(100)); + + result = async_evt->signal->result; + k_sem_give(caller_sem); + + /* Reinitializing for next call */ + async_evt->signal->signaled = 0; + async_evt->state = K_POLL_STATE_NOT_READY; + } +} + +static int spi_async_call(struct spi_config *spi_conf) +{ + struct spi_buf tx = { + .buf = buffer_tx, + .len = BUF_SIZE, + }; + struct spi_buf rx = { + .buf = buffer_rx, + .len = BUF_SIZE, + }; + const struct spi_buf *tx_bufs[] = { &tx, NULL }; + struct spi_buf *rx_bufs[] = { &rx, NULL }; + int ret; + + ret = spi_transceive_async(spi_conf, tx_bufs, rx_bufs, &async_sig); + if (ret) { + SYS_LOG_ERR("Code %d", ret); + return -1; + } + + k_sem_take(&caller, K_FOREVER); + + if (result) { + SYS_LOG_ERR("Call code %d", ret); + return -1; + } + + SYS_LOG_DBG("Passed"); + + return 0; +} void main(void) { + struct k_thread async_thread; + k_tid_t async_thread_id; + SYS_LOG_INF("SPI test on buffex TX/RX %p/%p", buffer_tx, buffer_rx); if (cs_ctrl_gpio_config(spi_slow.cs) || @@ -237,19 +306,28 @@ void main(void) spi_fast.dev = spi_slow.dev; + async_thread_id = k_thread_create(&async_thread, spi_async_stack, 256, + (k_thread_entry_t)spi_async_call_cb, + &async_evt, &caller, NULL, + K_PRIO_COOP(7), 0, 0); + if (spi_complete_loop(&spi_slow) || spi_rx_half_start(&spi_slow) || spi_rx_half_end(&spi_slow) || - spi_rx_every_4(&spi_slow)) { - return; + spi_rx_every_4(&spi_slow) || + spi_async_call(&spi_slow)) { + goto end; } if (spi_complete_loop(&spi_fast) || spi_rx_half_start(&spi_fast) || spi_rx_half_end(&spi_fast) || - spi_rx_every_4(&spi_fast)) { - return; + spi_rx_every_4(&spi_fast) || + spi_async_call(&spi_fast)) { + goto end; } SYS_LOG_INF("All tx/rx passed"); +end: + k_thread_cancel(async_thread_id); }