drivers: spi: esp32xx: Fix word size limiting transaction

Word size setting limited any SPI transaction to the frame
size. In addition to making the SPI inefficient this
broke drivers that set the word size. It appears that most
drivers use a one byte (8) size for this setting.
This change respects what I think is the intended use of
the word size setting. That is to set the length of
each element in a tx/rx buffer struct.

Signed-off-by: Dean Sellers <dsellers@evos.com.au>
This commit is contained in:
Dean Sellers 2023-05-01 16:19:26 +10:00 committed by Carles Cufí
parent 4ffff549de
commit 47f4218ea5
2 changed files with 19 additions and 16 deletions

View file

@ -67,20 +67,21 @@ static int IRAM_ATTR spi_esp32_transfer(const struct device *dev)
spi_hal_context_t *hal = &data->hal;
spi_hal_dev_config_t *hal_dev = &data->dev_config;
spi_hal_trans_config_t *hal_trans = &data->trans_config;
size_t chunk_len = spi_context_max_continuous_chunk(&data->ctx);
size_t chunk_len_bytes = spi_context_max_continuous_chunk(&data->ctx) * data->dfs;
size_t max_buf_sz =
cfg->dma_enabled ? SPI_DMA_MAX_BUFFER_SIZE : SOC_SPI_MAXIMUM_BUFFER_SIZE;
size_t transfer_len = data->word_size ? data->dfs : MIN(chunk_len, max_buf_sz);
size_t bit_len = transfer_len << 3;
size_t transfer_len_bytes = MIN(chunk_len_bytes, max_buf_sz);
size_t bit_len = transfer_len_bytes << 3;
uint8_t *rx_temp = NULL;
uint8_t *tx_temp = NULL;
uint8_t dma_len_tx = data->word_size ? data->dfs : ctx->tx_len;
uint8_t dma_len_rx = data->word_size ? data->dfs : ctx->rx_len;
uint8_t dma_len_tx = MIN(ctx->tx_len * data->dfs, SPI_DMA_MAX_BUFFER_SIZE);
uint8_t dma_len_rx = MIN(ctx->rx_len * data->dfs, SPI_DMA_MAX_BUFFER_SIZE);
if (cfg->dma_enabled) {
/* bit_len needs to be at least one byte long when using DMA */
bit_len = !bit_len ? 8 : bit_len;
if (ctx->tx_buf && !esp_ptr_dma_capable((uint32_t *)&ctx->tx_buf[0])) {
LOG_DBG("Tx buffer not DMA capable");
tx_temp = k_malloc(dma_len_tx);
if (!tx_temp) {
LOG_ERR("Error allocating temp buffer Tx");
@ -94,6 +95,7 @@ static int IRAM_ATTR spi_esp32_transfer(const struct device *dev)
* multiples of 32 bits to avoid heap
* corruption.
*/
LOG_DBG("Rx buffer not DMA capable");
rx_temp = k_calloc(((dma_len_rx << 3) + 31) / 8, sizeof(uint8_t));
if (!rx_temp) {
LOG_ERR("Error allocating temp buffer Rx");
@ -120,7 +122,7 @@ static int IRAM_ATTR spi_esp32_transfer(const struct device *dev)
/* send data */
spi_hal_user_start(hal);
spi_context_update_tx(&data->ctx, data->dfs, transfer_len/data->dfs);
spi_context_update_tx(&data->ctx, data->dfs, transfer_len_bytes/data->dfs);
while (!spi_hal_usr_is_done(hal)) {
/* nop */
@ -130,10 +132,10 @@ static int IRAM_ATTR spi_esp32_transfer(const struct device *dev)
spi_hal_fetch_result(hal);
if (rx_temp) {
memcpy(&ctx->rx_buf[0], rx_temp, transfer_len);
memcpy(&ctx->rx_buf[0], rx_temp, transfer_len_bytes);
}
spi_context_update_rx(&data->ctx, data->dfs, transfer_len/data->dfs);
spi_context_update_rx(&data->ctx, data->dfs, transfer_len_bytes/data->dfs);
k_free(tx_temp);
k_free(rx_temp);
@ -351,14 +353,16 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
return 0;
}
static inline uint8_t spi_esp32_get_frame_size(const struct device *dev,
const struct spi_config *spi_cfg)
static inline uint8_t spi_esp32_get_frame_size(const struct spi_config *spi_cfg)
{
struct spi_esp32_data *data = dev->data;
uint8_t dfs = SPI_WORD_SIZE_GET(spi_cfg->operation);
data->word_size = SPI_WORD_SIZE_GET(spi_cfg->operation);
return data->word_size ? data->word_size >> 3 : 1;
dfs /= 8;
if ((dfs == 0) || (dfs > 4)) {
LOG_WRN("Unsupported dfs, 1-byte size will be used");
dfs = 1;
}
return dfs;
}
static int transceive(const struct device *dev,
@ -389,7 +393,7 @@ static int transceive(const struct device *dev,
goto done;
}
data->dfs = spi_esp32_get_frame_size(dev, spi_cfg);
data->dfs = spi_esp32_get_frame_size(spi_cfg);
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, data->dfs);

View file

@ -52,7 +52,6 @@ struct spi_esp32_data {
int irq_line;
lldesc_t dma_desc_tx;
lldesc_t dma_desc_rx;
uint8_t word_size;
};
#endif /* ZEPHYR_DRIVERS_SPI_ESP32_SPIM_H_ */