xtensa/esp32: Use Polling instead of DMA for transfers below threshold
Also refactored code to remove a confusing duplicate "dma_chan" field which had the same purpose of the "use_dma" boolean.
This commit is contained in:
parent
d397e90b9d
commit
dc7a0b0a5c
@ -636,6 +636,14 @@ config SPI_SLAVE_BUFSIZE
|
||||
default 2048
|
||||
depends on SPI_SLAVE
|
||||
|
||||
config ESP32_SPI_DMATHRESHOLD
|
||||
int "SPI DMA threshold"
|
||||
default 64
|
||||
depends on ESP32_SPI2_DMA || ESP32_SPI3_DMA
|
||||
---help---
|
||||
When SPI DMA is enabled, DMA transfers whose size are below the
|
||||
defined threshold will be performed by polling logic.
|
||||
|
||||
if ESP32_SPI2
|
||||
|
||||
config ESP32_SPI2_CSPIN
|
||||
|
@ -108,7 +108,7 @@ struct esp32_spi_config_s
|
||||
uint32_t rst_bit; /* SPI reset bit */
|
||||
|
||||
bool use_dma; /* Use DMA */
|
||||
uint8_t dma_chan_s; /* DMA channel regitser shift */
|
||||
uint8_t dma_chan_s; /* DMA channel register shift */
|
||||
uint8_t dma_chan; /* DMA channel */
|
||||
uint32_t dma_clk_bit; /* DMA clock enable bit */
|
||||
uint32_t dma_rst_bit; /* DMA reset bit */
|
||||
@ -153,10 +153,6 @@ struct esp32_spi_priv_s
|
||||
/* Actual SPI send/receive bits once transmission */
|
||||
|
||||
uint8_t nbits;
|
||||
|
||||
/* Copy from config to speed up checking */
|
||||
|
||||
uint8_t dma_chan;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -802,7 +798,7 @@ static void esp32_spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
* calculated buffer length.
|
||||
*/
|
||||
|
||||
if (!priv->dma_chan)
|
||||
if (!priv->config->use_dma)
|
||||
{
|
||||
esp32_spi_set_reg(priv, SPI_MISO_DLEN_OFFSET,
|
||||
(priv->nbits - 1) << SPI_USR_MISO_DBITLEN_S);
|
||||
@ -920,10 +916,10 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv,
|
||||
esp32_spi_set_reg(priv, SPI_DMA_CONF_OFFSET, SPI_DMA_RESET_MASK);
|
||||
esp32_spi_reset_regbits(priv, SPI_DMA_CONF_OFFSET, SPI_DMA_RESET_MASK);
|
||||
|
||||
n = esp32_dma_init(s_dma_txdesc[priv->dma_chan - 1],
|
||||
n = esp32_dma_init(s_dma_txdesc[priv->config->dma_chan - 1],
|
||||
SPI_DMADESC_NUM, tp, bytes, 0);
|
||||
|
||||
regval = (uint32_t)s_dma_txdesc[priv->dma_chan - 1] &
|
||||
regval = (uintptr_t)s_dma_txdesc[priv->config->dma_chan - 1] &
|
||||
SPI_OUTLINK_ADDR_V;
|
||||
esp32_spi_set_reg(priv, SPI_DMA_OUT_LINK_OFFSET,
|
||||
regval | SPI_OUTLINK_START_M);
|
||||
@ -939,10 +935,10 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv,
|
||||
|
||||
if (rp)
|
||||
{
|
||||
esp32_dma_init(s_dma_rxdesc[priv->dma_chan - 1],
|
||||
esp32_dma_init(s_dma_rxdesc[priv->config->dma_chan - 1],
|
||||
SPI_DMADESC_NUM, rp, bytes, 1);
|
||||
|
||||
regval = (uint32_t)s_dma_rxdesc[priv->dma_chan - 1] &
|
||||
regval = (uintptr_t)s_dma_rxdesc[priv->config->dma_chan - 1] &
|
||||
SPI_INLINK_ADDR_V;
|
||||
esp32_spi_set_reg(priv, SPI_DMA_IN_LINK_OFFSET,
|
||||
regval | SPI_INLINK_START_M);
|
||||
@ -983,7 +979,7 @@ static void esp32_spi_dma_exchange(FAR struct esp32_spi_priv_s *priv,
|
||||
* Name: esp32_spi_poll_send
|
||||
*
|
||||
* Description:
|
||||
* Exchange one word on SPI by polling mode.
|
||||
* Send one word on SPI by polling mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - SPI private state data
|
||||
@ -1016,37 +1012,11 @@ static uint32_t esp32_spi_poll_send(FAR struct esp32_spi_priv_s *priv,
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_spi_dma_send
|
||||
*
|
||||
* Description:
|
||||
* Exchange one word on SPI by SPI DMA mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* wd - The word to send. the size of the data is determined by the
|
||||
* number of bits selected for the SPI interface.
|
||||
*
|
||||
* Returned Value:
|
||||
* Received value
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t esp32_spi_dma_send(FAR struct esp32_spi_priv_s *priv,
|
||||
uint32_t wd)
|
||||
{
|
||||
uint32_t rd;
|
||||
|
||||
esp32_spi_dma_exchange(priv, &wd, &rd, 1);
|
||||
|
||||
return rd;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_spi_send
|
||||
*
|
||||
* Description:
|
||||
* Exchange one word on SPI.
|
||||
* Send one word on SPI.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
@ -1061,18 +1031,8 @@ static uint32_t esp32_spi_dma_send(FAR struct esp32_spi_priv_s *priv,
|
||||
static uint32_t esp32_spi_send(FAR struct spi_dev_s *dev, uint32_t wd)
|
||||
{
|
||||
FAR struct esp32_spi_priv_s *priv = (FAR struct esp32_spi_priv_s *)dev;
|
||||
uint32_t rd;
|
||||
|
||||
if (priv->dma_chan)
|
||||
{
|
||||
rd = esp32_spi_dma_send(priv, wd);
|
||||
}
|
||||
else
|
||||
{
|
||||
rd = esp32_spi_poll_send(priv, wd);
|
||||
}
|
||||
|
||||
return rd;
|
||||
return esp32_spi_poll_send(priv, wd);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1164,7 +1124,13 @@ static void esp32_spi_exchange(FAR struct spi_dev_s *dev,
|
||||
{
|
||||
FAR struct esp32_spi_priv_s *priv = (FAR struct esp32_spi_priv_s *)dev;
|
||||
|
||||
if (priv->dma_chan)
|
||||
#ifdef CONFIG_ESP32_SPI_DMATHRESHOLD
|
||||
size_t thld = CONFIG_ESP32_SPI_DMATHRESHOLD;
|
||||
#else
|
||||
size_t thld = 0;
|
||||
#endif
|
||||
|
||||
if (priv->config->use_dma && nwords > thld)
|
||||
{
|
||||
esp32_spi_dma_exchange(priv, txbuffer, rxbuffer, nwords);
|
||||
}
|
||||
@ -1339,7 +1305,7 @@ static void esp32_spi_init(FAR struct spi_dev_s *dev)
|
||||
esp32_spi_set_reg(priv, SPI_CTRL_OFFSET, 0);
|
||||
esp32_spi_set_reg(priv, SPI_CTRL2_OFFSET, (0 << SPI_HOLD_TIME_S));
|
||||
|
||||
if (priv->dma_chan)
|
||||
if (config->use_dma)
|
||||
{
|
||||
nxsem_init(&priv->sem_isr, 0, 0);
|
||||
nxsem_set_protocol(&priv->sem_isr, SEM_PRIO_NONE);
|
||||
@ -1380,7 +1346,7 @@ static void esp32_spi_deinit(FAR struct spi_dev_s *dev)
|
||||
{
|
||||
FAR struct esp32_spi_priv_s *priv = (FAR struct esp32_spi_priv_s *)dev;
|
||||
|
||||
if (priv->dma_chan)
|
||||
if (priv->config->use_dma)
|
||||
{
|
||||
modifyreg32(DPORT_PERIP_CLK_EN_REG, priv->config->dma_clk_bit, 0);
|
||||
}
|
||||
@ -1392,7 +1358,6 @@ static void esp32_spi_deinit(FAR struct spi_dev_s *dev)
|
||||
priv->actual = 0;
|
||||
priv->mode = SPIDEV_MODE0;
|
||||
priv->nbits = 0;
|
||||
priv->dma_chan = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1468,15 +1433,6 @@ FAR struct spi_dev_s *esp32_spibus_initialize(int port)
|
||||
}
|
||||
|
||||
if (priv->config->use_dma)
|
||||
{
|
||||
priv->dma_chan = priv->config->dma_chan;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->dma_chan = 0;
|
||||
}
|
||||
|
||||
if (priv->dma_chan)
|
||||
{
|
||||
priv->cpuint = esp32_alloc_levelint(1);
|
||||
if (priv->cpuint < 0)
|
||||
@ -1543,7 +1499,7 @@ int esp32_spibus_uninitialize(FAR struct spi_dev_s *dev)
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
if (priv->dma_chan)
|
||||
if (priv->config->use_dma)
|
||||
{
|
||||
up_disable_irq(priv->cpuint);
|
||||
esp32_detach_peripheral(priv->config->cpu,
|
||||
|
Loading…
x
Reference in New Issue
Block a user