Skip to content

Commit

Permalink
api/spi: Change transceive functions signature
Browse files Browse the repository at this point in the history
Instead of NULL terminated buffer arrays, let's add a parameter for each
that tells the number of spi_buf in it.

It adds a little bit more complexity in driver's side (spi_context.h)
but not on user side (bufer one has to take care of providing the NULL
pointer at the end of the array, now he requires to give the count).

This will saves a significant amount of bytes in more complex setup than
the current dumb spi driver sample.

Fix and Use size_t everywhere (spi_context.h was using u32_t).

Signed-off-by: Tomasz Bursztyka <[email protected]>
  • Loading branch information
Tomasz Bursztyka authored and Anas Nashif committed Jun 1, 2017
1 parent 7d13261 commit cced7fd
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 131 deletions.
62 changes: 36 additions & 26 deletions drivers/spi/spi_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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);
}

Expand All @@ -187,17 +193,19 @@ 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;
}
} else if (ctx->tx_buf) {
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
Expand All @@ -216,17 +224,19 @@ 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;
}
} else if (ctx->rx_buf) {
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
Expand Down
33 changes: 22 additions & 11 deletions drivers/spi/spi_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;

Expand Down Expand Up @@ -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 */

Expand Down
87 changes: 53 additions & 34 deletions include/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,21 @@ 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
* @brief Callback API for asynchronous I/O
* 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);

/**
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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);
}

/**
Expand All @@ -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
Expand All @@ -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);
}

/**
Expand All @@ -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
Expand All @@ -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 */

Expand Down
Loading

0 comments on commit cced7fd

Please sign in to comment.