Skip to content

Commit

Permalink
drivers: spi: spi_mcux_lpspi: enable CONFIG_SPI_ASYNC mode with DMA
Browse files Browse the repository at this point in the history
add DMA async support.

Signed-off-by: Derek Snell <[email protected]>
  • Loading branch information
DerekSnell committed Sep 10, 2024
1 parent 9046900 commit 3a9a411
Showing 1 changed file with 44 additions and 6 deletions.
50 changes: 44 additions & 6 deletions drivers/spi/spi_mcux_lpspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,26 +322,64 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg,
}
}
#if CONFIG_SPI_ASYNC
int ret;

if (data->ctx.asynchronous &&
((data->status_flags & SPI_MCUX_LPSPI_DMA_DONE_FLAG) ==
SPI_MCUX_LPSPI_DMA_DONE_FLAG)) {
/* dma_size of completed transfers were the same for TX and RX */
size_t dma_size = data->ctx.tx_len;

spi_context_update_tx(&data->ctx, 1, dma_size);
spi_context_update_rx(&data->ctx, 1, dma_size);

if (data->ctx.tx_len == 0 && data->ctx.rx_len == 0) {
spi_context_complete(&data->ctx, spi_dev, 0);
return;
}

/* Restart DMA for next buffer */
/* Load dma blocks of equal length */
size_t dma_size = MIN(data->ctx.tx_len, data->ctx.rx_len);
dma_size = MIN(data->ctx.tx_len, data->ctx.rx_len);

if (dma_size == 0) {
dma_size = MAX(data->ctx.tx_len, data->ctx.rx_len);
}

spi_context_update_tx(&data->ctx, 1, dma_size);
spi_context_update_rx(&data->ctx, 1, dma_size);
/* Clear status flags */
data->status_flags = 0U;

if (data->ctx.tx_len == 0 && data->ctx.rx_len == 0) {
spi_context_complete(&data->ctx, spi_dev, 0);
/* Restart the RX DMA */
ret = dma_reload(dev,
data->dma_rx.channel,
data->dma_rx.dma_blk_cfg.source_address,
(uint32_t) data->ctx.rx_buf,
dma_size);
if (ret != 0) {
LOG_ERR("RX dma_reload() failed with error %x.", ret);
data->status_flags |= SPI_MCUX_LPSPI_DMA_ERROR_FLAG;
}

/* Restart the TX DMA */
ret = dma_reload(dev,
data->dma_tx.channel,
(uint32_t) data->ctx.tx_buf,
data->dma_tx.dma_blk_cfg.dest_address,
dma_size);
if (ret != 0) {
LOG_ERR("TX dma_reload() failed with error %x.", ret);
data->status_flags |= SPI_MCUX_LPSPI_DMA_ERROR_FLAG;
}

return;
}
#endif

if (!data->ctx.asynchronous) {
spi_context_complete(&data->ctx, spi_dev, 0);
}
#else
spi_context_complete(&data->ctx, spi_dev, 0);
#endif /* CONFIG_SPI_ASYNC */
}

static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len)
Expand Down

0 comments on commit 3a9a411

Please sign in to comment.