diff --git a/drivers/spi/spi_context.h b/drivers/spi/spi_context.h index f2ee333286f0e1..d774019efd2c23 100644 --- a/drivers/spi/spi_context.h +++ b/drivers/spi/spi_context.h @@ -29,13 +29,15 @@ struct spi_context { struct k_poll_signal *signal; bool asynchronous; #endif - const struct spi_buf **current_tx; - struct spi_buf **current_rx; + const struct spi_buf *current_tx; + size_t tx_count; + struct spi_buf *current_rx; + size_t rx_count; void *tx_buf; - u32_t tx_len; + size_t tx_len; void *rx_buf; - u32_t rx_len; + size_t rx_len; }; #define SPI_CONTEXT_INIT_LOCK(_data, _ctx_name) \ @@ -144,36 +146,40 @@ static inline void spi_context_cs_control(struct spi_context *ctx, bool on) } static inline void spi_context_buffers_setup(struct spi_context *ctx, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs, + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count, uint8_t dfs) { - SYS_LOG_DBG("tx_bufs %p (%p) - rx_bufs %p (%p) - %u", - tx_bufs, tx_bufs ? *tx_bufs : NULL, - rx_bufs, rx_bufs ? *rx_bufs : NULL, dfs); + SYS_LOG_DBG("tx_bufs %p (%zu) - rx_bufs %p (%zu) - %u", + tx_bufs, tx_count, rx_bufs, rx_count, dfs); ctx->current_tx = tx_bufs; + ctx->tx_count = tx_count; ctx->current_rx = rx_bufs; + ctx->rx_count = rx_count; - if (*tx_bufs) { - ctx->tx_buf = (*tx_bufs)->buf; - ctx->tx_len = (*tx_bufs)->len/dfs; + if (tx_bufs) { + ctx->tx_buf = tx_bufs->buf; + ctx->tx_len = tx_bufs->len / dfs; } else { ctx->tx_buf = NULL; ctx->tx_len = 0; } - if (*rx_bufs) { - ctx->rx_buf = (*rx_bufs)->buf; - ctx->rx_len = (*rx_bufs)->len/dfs; + if (rx_bufs) { + ctx->rx_buf = rx_bufs->buf; + ctx->rx_len = rx_bufs->len / dfs; } else { ctx->rx_buf = NULL; ctx->rx_len = 0; } - SYS_LOG_DBG("current_tx %p, current_rx %p," - " tx buf/len %p/%u, rx buf/len %p/%u", - ctx->current_tx, ctx->current_rx, + SYS_LOG_DBG("current_tx %p (%zu), current_rx %p (%zu)," + " tx buf/len %p/%zu, rx buf/len %p/%zu", + ctx->current_tx, ctx->tx_count, + ctx->current_rx, ctx->rx_count, ctx->tx_buf, ctx->tx_len, ctx->rx_buf, ctx->rx_len); } @@ -187,9 +193,11 @@ void spi_context_update_tx(struct spi_context *ctx, uint8_t dfs) ctx->tx_len--; if (!ctx->tx_len) { ctx->current_tx++; - if (*ctx->current_tx) { - ctx->tx_buf = (*ctx->current_tx)->buf; - ctx->tx_len = (*ctx->current_tx)->len/dfs; + ctx->tx_count--; + + if (ctx->tx_count) { + ctx->tx_buf = ctx->current_tx->buf; + ctx->tx_len = ctx->current_tx->len / dfs; } else { ctx->tx_buf = NULL; } @@ -197,7 +205,7 @@ void spi_context_update_tx(struct spi_context *ctx, uint8_t dfs) ctx->tx_buf += dfs; } - SYS_LOG_DBG("tx buf/len %p/%u", ctx->tx_buf, ctx->tx_len); + SYS_LOG_DBG("tx buf/len %p/%zu", ctx->tx_buf, ctx->tx_len); } static ALWAYS_INLINE @@ -216,9 +224,11 @@ void spi_context_update_rx(struct spi_context *ctx, uint8_t dfs) ctx->rx_len--; if (!ctx->rx_len) { ctx->current_rx++; - if (*ctx->current_rx) { - ctx->rx_buf = (*ctx->current_rx)->buf; - ctx->rx_len = (*ctx->current_rx)->len/dfs; + ctx->rx_count--; + + if (ctx->rx_count) { + ctx->rx_buf = ctx->current_rx->buf; + ctx->rx_len = ctx->current_rx->len / dfs; } else { ctx->rx_buf = NULL; } @@ -226,7 +236,7 @@ void spi_context_update_rx(struct spi_context *ctx, uint8_t dfs) ctx->rx_buf += dfs; } - SYS_LOG_DBG("rx buf/len %p/%u", ctx->rx_buf, ctx->rx_len); + SYS_LOG_DBG("rx buf/len %p/%zu", ctx->rx_buf, ctx->rx_len); } static ALWAYS_INLINE diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index e65d1f2272f62a..81d794aeb6508b 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -251,8 +251,10 @@ static int spi_dw_configure(const struct spi_dw_config *info, } static int transceive(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs, + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count, bool asynchronous, struct k_poll_signal *signal) { @@ -277,7 +279,8 @@ static int transceive(struct spi_config *config, } /* Set buffers info */ - spi_context_buffers_setup(&spi->ctx, tx_bufs, rx_bufs, spi->dfs); + spi_context_buffers_setup(&spi->ctx, tx_bufs, tx_count, + rx_bufs, rx_count, spi->dfs); spi->fifo_diff = 0; @@ -317,23 +320,31 @@ static int transceive(struct spi_config *config, } static int spi_dw_transceive(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs) + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count) { - SYS_LOG_DBG("%p, %p, %p", config->dev, tx_bufs, rx_bufs); + SYS_LOG_DBG("%p, %p (%zu), %p (%zu)", + config->dev, tx_bufs, tx_count, rx_bufs, rx_count); - return transceive(config, tx_bufs, rx_bufs, false, NULL); + return transceive(config, tx_bufs, tx_count, + rx_bufs, rx_count, false, NULL); } #ifdef CONFIG_POLL static int spi_dw_transceive_async(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs, + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count, struct k_poll_signal *async) { - SYS_LOG_DBG("%p, %p, %p, %p", config->dev, tx_bufs, rx_bufs, async); + SYS_LOG_DBG("%p, %p (%zu), %p (%zu), %p", + config->dev, tx_bufs, tx_count, rx_bufs, rx_count, async); - return transceive(config, tx_bufs, rx_bufs, true, async); + return transceive(config, tx_bufs, tx_count, + rx_bufs, rx_count, true, async); } #endif /* CONFIG_POLL */ diff --git a/include/spi.h b/include/spi.h index 6a7058f963b989..b6e93523226ef0 100644 --- a/include/spi.h +++ b/include/spi.h @@ -190,8 +190,10 @@ struct spi_buf { * See spi_transceive() for argument descriptions */ typedef int (*spi_api_io)(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs); + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count); /** * @typedef spi_api_io @@ -199,8 +201,10 @@ typedef int (*spi_api_io)(struct spi_config *config, * See spi_transceive_async() for argument descriptions */ typedef int (*spi_api_io_async)(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs, + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count, struct k_poll_signal *async); /** @@ -229,20 +233,24 @@ struct spi_driver_api { * Note: This function is synchronous. * * @param config Pointer to a valid spi_config structure instance. - * @param tx_bufs NULL terminated buffer array where data to be sent - * originates from, or NULL if none. - * @param rx_bufs NULL terminated buffer array where data to be read - * will be written to, or NULL if none. + * @param tx_bufs Buffer array where data to be sent originates from, + * or NULL if none. + * @param tx_count Number of element in the tx_bufs array. + * @param rx_bufs Buffer array where data to be read will be written to, + * or NULL if none. + * @param rx_count Number of element in the rx_bufs array. * * @retval 0 If successful, negative errno code otherwise. */ static inline int spi_transceive(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs) + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count) { const struct spi_driver_api *api = config->dev->driver_api; - return api->transceive(config, tx_bufs, rx_bufs); + return api->transceive(config, tx_bufs, tx_count, rx_bufs, rx_count); } /** @@ -251,17 +259,18 @@ static inline int spi_transceive(struct spi_config *config, * Note: This function is synchronous. * * @param config Pointer to a valid spi_config structure instance. - * @param rx_bufs NULL terminated buffer array where data to be read - * will be written to. + * @param rx_bufs Buffer array where data to be read will be written to. + * @param rx_count Number of element in the rx_bufs array. * * @retval 0 If successful, negative errno code otherwise. */ static inline int spi_read(struct spi_config *config, - struct spi_buf **rx_bufs) + struct spi_buf *rx_bufs, + size_t rx_count) { const struct spi_driver_api *api = config->dev->driver_api; - return api->transceive(config, NULL, rx_bufs); + return api->transceive(config, NULL, 0, rx_bufs, rx_count); } /** @@ -270,17 +279,18 @@ static inline int spi_read(struct spi_config *config, * Note: This function is synchronous. * * @param config Pointer to a valid spi_config structure instance. - * @param tx_bufs NULL terminated buffer array where data to be sent - * originates from. + * @param tx_bufs Buffer array where data to be sent originates from. + * @param tx_count Number of element in the tx_bufs array. * * @retval 0 If successful, negative errno code otherwise. */ static inline int spi_write(struct spi_config *config, - const struct spi_buf **tx_bufs) + const struct spi_buf *tx_bufs, + size_t tx_count) { const struct spi_driver_api *api = config->dev->driver_api; - return api->transceive(config, tx_bufs, NULL); + return api->transceive(config, tx_bufs, tx_count, NULL, 0); } #ifdef CONFIG_POLL @@ -290,10 +300,12 @@ static inline int spi_write(struct spi_config *config, * Note: This function is asynchronous. * * @param config Pointer to a valid spi_config structure instance. - * @param tx_bufs NULL terminated buffer array where data to be sent - * originates from, or NULL if none. - * @param rx_bufs NULL terminated buffer array where data to be read - * will be written to, or NULL if none. + * @param tx_bufs Buffer array where data to be sent originates from, + * or NULL if none. + * @param tx_count Number of element in the tx_bufs array. + * @param rx_bufs Buffer array where data to be read will be written to, + * or NULL if none. + * @param rx_count Number of element in the rx_bufs array. * @param async A pointer to a valid and ready to be signaled * struct k_poll_signal. (Note: if NULL this function will not * notify the end of the transaction, and whether it went @@ -302,13 +314,16 @@ static inline int spi_write(struct spi_config *config, * @retval 0 If successful, negative errno code otherwise. */ static inline int spi_transceive_async(struct spi_config *config, - const struct spi_buf **tx_bufs, - struct spi_buf **rx_bufs, + const struct spi_buf *tx_bufs, + size_t tx_count, + struct spi_buf *rx_bufs, + size_t rx_count, struct k_poll_signal *async) { const struct spi_driver_api *api = config->dev->driver_api; - return api->transceive_async(config, tx_bufs, rx_bufs, async); + return api->transceive_async(config, tx_bufs, tx_count, + rx_bufs, rx_count, async); } /** @@ -317,8 +332,8 @@ static inline int spi_transceive_async(struct spi_config *config, * Note: This function is asynchronous. * * @param config Pointer to a valid spi_config structure instance. - * @param rx_bufs NULL terminated buffer array where data to be read - * will be written to. + * @param rx_bufs Buffer array where data to be read will be written to. + * @param rx_count Number of element in the rx_bufs array. * @param async A pointer to a valid and ready to be signaled * struct k_poll_signal. (Note: if NULL this function will not * notify the end of the transaction, and whether it went @@ -327,12 +342,14 @@ static inline int spi_transceive_async(struct spi_config *config, * @retval 0 If successful, negative errno code otherwise. */ static inline int spi_read_async(struct spi_config *config, - struct spi_buf **rx_bufs, + struct spi_buf *rx_bufs, + size_t rx_count, struct k_poll_signal *async) { const struct spi_driver_api *api = config->dev->driver_api; - return api->transceive_async(config, NULL, rx_bufs, async); + return api->transceive_async(config, NULL, 0, + rx_bufs, rx_count, async); } /** @@ -341,8 +358,8 @@ static inline int spi_read_async(struct spi_config *config, * Note: This function is asynchronous. * * @param config Pointer to a valid spi_config structure instance. - * @param tx_bufs NULL terminated buffer array where data to be sent - * originates from. + * @param tx_bufs Buffer array where data to be sent originates from. + * @param tx_count Number of element in the tx_bufs array. * @param async A pointer to a valid and ready to be signaled * struct k_poll_signal. (Note: if NULL this function will not * notify the end of the transaction, and whether it went @@ -351,12 +368,14 @@ static inline int spi_read_async(struct spi_config *config, * @retval 0 If successful, negative errno code otherwise. */ static inline int spi_write_async(struct spi_config *config, - const struct spi_buf **tx_bufs, + const struct spi_buf *tx_bufs, + size_t tx_count, struct k_poll_signal *async) { const struct spi_driver_api *api = config->dev->driver_api; - return api->transceive_async(config, tx_bufs, NULL, async); + return api->transceive_async(config, tx_bufs, tx_count, + NULL, 0, async); } #endif /* CONFIG_POLL */ diff --git a/samples/drivers/spi/src/spi.c b/samples/drivers/spi/src/spi.c index c80c431154e0c1..828436c72df34a 100644 --- a/samples/drivers/spi/src/spi.c +++ b/samples/drivers/spi/src/spi.c @@ -88,19 +88,22 @@ static int cs_ctrl_gpio_config(struct spi_cs_control *cs) static int spi_complete_loop(struct spi_config *spi_conf) { - struct spi_buf tx = { - .buf = buffer_tx, - .len = BUF_SIZE, + const struct spi_buf tx_bufs[] = { + { + .buf = buffer_tx, + .len = BUF_SIZE, + }, }; - struct spi_buf rx = { - .buf = buffer_rx, - .len = BUF_SIZE, + struct spi_buf rx_bufs[] = { + { + .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(spi_conf, tx_bufs, rx_bufs); + ret = spi_transceive(spi_conf, tx_bufs, ARRAY_SIZE(tx_bufs), + rx_bufs, ARRAY_SIZE(rx_bufs)); if (ret) { SYS_LOG_ERR("Code %d", ret); return ret; @@ -119,21 +122,24 @@ static int spi_complete_loop(struct spi_config *spi_conf) static int spi_rx_half_start(struct spi_config *spi_conf) { - struct spi_buf tx = { - .buf = buffer_tx, - .len = BUF_SIZE, + const struct spi_buf tx_bufs[] = { + { + .buf = buffer_tx, + .len = BUF_SIZE, + }, }; - struct spi_buf rx = { - .buf = buffer_rx, - .len = 8, + struct spi_buf rx_bufs[] = { + { + .buf = buffer_rx, + .len = 8, + }, }; - const struct spi_buf *tx_bufs[] = { &tx, NULL }; - struct spi_buf *rx_bufs[] = { &rx, NULL }; int ret; memset(buffer_rx, 0, BUF_SIZE); - ret = spi_transceive(spi_conf, tx_bufs, rx_bufs); + ret = spi_transceive(spi_conf, tx_bufs, ARRAY_SIZE(tx_bufs), + rx_bufs, ARRAY_SIZE(rx_bufs)); if (ret) { SYS_LOG_ERR("Code %d", ret); return -1; @@ -151,25 +157,28 @@ static int spi_rx_half_start(struct spi_config *spi_conf) static int spi_rx_half_end(struct spi_config *spi_conf) { - struct spi_buf tx = { - .buf = buffer_tx, - .len = BUF_SIZE, + const struct spi_buf tx_bufs[] = { + { + .buf = buffer_tx, + .len = BUF_SIZE, + }, }; - struct spi_buf rx_1st_half = { - .buf = NULL, - .len = 8, + struct spi_buf rx_bufs[] = { + { + .buf = NULL, + .len = 8, + }, + { + .buf = buffer_rx, + .len = 8, + }, }; - struct spi_buf rx_last_half = { - .buf = buffer_rx, - .len = 8, - }; - const struct spi_buf *tx_bufs[] = { &tx, NULL }; - struct spi_buf *rx_bufs[] = { &rx_1st_half, &rx_last_half, NULL }; int ret; memset(buffer_rx, 0, BUF_SIZE); - ret = spi_transceive(spi_conf, tx_bufs, rx_bufs); + ret = spi_transceive(spi_conf, tx_bufs, ARRAY_SIZE(tx_bufs), + rx_bufs, ARRAY_SIZE(rx_bufs)); if (ret) { SYS_LOG_ERR("Code %d", ret); return -1; @@ -187,37 +196,43 @@ static int spi_rx_half_end(struct spi_config *spi_conf) static int spi_rx_every_4(struct spi_config *spi_conf) { - struct spi_buf tx = { - .buf = buffer_tx, - .len = BUF_SIZE, - }; - struct spi_buf rx_start = { - .buf = NULL, - .len = 4, - }; - struct spi_buf rx_1 = { - .buf = buffer_rx, - .len = 4, + const struct spi_buf tx_bufs[] = { + { + .buf = buffer_tx, + .len = BUF_SIZE, + }, }; - struct spi_buf rx_2 = { - .buf = buffer_rx+4, - .len = 4, + struct spi_buf rx_bufs[] = { + { + .buf = NULL, + .len = 4, + }, + { + .buf = buffer_rx, + .len = 4, + }, + { + .buf = NULL, + .len = 4, + }, + { + .buf = buffer_rx + 4, + .len = 4, + }, }; - const struct spi_buf *tx_bufs[] = { &tx, NULL }; - struct spi_buf *rx_bufs[] = { &rx_start, &rx_1, - &rx_start, &rx_2, NULL }; int ret; memset(buffer_rx, 0, BUF_SIZE); - ret = spi_transceive(spi_conf, tx_bufs, rx_bufs); + ret = spi_transceive(spi_conf, tx_bufs, ARRAY_SIZE(tx_bufs), + rx_bufs, ARRAY_SIZE(rx_bufs)); if (ret) { SYS_LOG_ERR("Code %d", ret); return -1; } - if (memcmp(buffer_tx+4, buffer_rx, 4) || - memcmp(buffer_tx+12, buffer_rx+4, 4)) { + if (memcmp(buffer_tx + 4, buffer_rx, 4) || + memcmp(buffer_tx + 12, buffer_rx + 4, 4)) { SYS_LOG_ERR("Buffer contents are different"); return -1; } @@ -256,19 +271,22 @@ static void spi_async_call_cb(struct k_poll_event *async_evt, static int spi_async_call(struct spi_config *spi_conf) { - struct spi_buf tx = { - .buf = buffer_tx, - .len = BUF_SIZE, + const struct spi_buf tx_bufs[] = { + { + .buf = buffer_tx, + .len = BUF_SIZE, + }, }; - struct spi_buf rx = { - .buf = buffer_rx, - .len = BUF_SIZE, + struct spi_buf rx_bufs[] = { + { + .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); + ret = spi_transceive_async(spi_conf, tx_bufs, ARRAY_SIZE(tx_bufs), + rx_bufs, ARRAY_SIZE(rx_bufs), &async_sig); if (ret) { SYS_LOG_ERR("Code %d", ret); return -1;