esp32s3/dma: Set the DMA descriptor according to RX or TX operation

According to RX/TX operation, the DMA descriptors (inlink/outlink)
should be set differently. When setting the inlink, the `suc_eof`
field must be cleared by software (it will be set by hardware when
a packet is received). Similarly, the `length` field will be set
by hardware a packet is received.
This commit is contained in:
Tiago Medicci Serrano 2023-08-30 10:10:33 -03:00 • committed by Xiang Xiao
parent e7eeb99139
commit 45d17551b3
5 changed files with 39 additions and 14 deletions

View file

@ -178,6 +178,7 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e periph,
* num - Number of DMA descriptors
* pbuf - RX/TX buffer pointer
* len - RX/TX buffer length
* tx - true: TX mode (transmitter); false: RX mode (receiver)
*
* Returned Value:
* Bound pbuf data bytes
@ -185,7 +186,7 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e periph,
****************************************************************************/
uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
uint8_t *pbuf, uint32_t len)
uint8_t *pbuf, uint32_t len, bool tx)
{
int i;
uint32_t regval;
@ -207,9 +208,18 @@ uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
buf_len = ALIGN_UP(data_len, sizeof(uintptr_t));
dmadesc[i].ctrl = (data_len << ESP32S3_DMA_CTRL_DATALEN_S) |
(buf_len << ESP32S3_DMA_CTRL_BUFLEN_S) |
ESP32S3_DMA_CTRL_OWN;
dmadesc[i].ctrl = ESP32S3_DMA_CTRL_OWN;
/* Only set Data Length if it's a TX buffer. Otherwise, it will be
* written automatically by hardware.
*/
if (tx)
{
dmadesc[i].ctrl |= (data_len << ESP32S3_DMA_CTRL_DATALEN_S);
}
dmadesc[i].ctrl |= (buf_len << ESP32S3_DMA_CTRL_BUFLEN_S);
dmadesc[i].pbuf = pdata;
dmadesc[i].next = &dmadesc[i + 1];
@ -222,7 +232,15 @@ uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
pdata += data_len;
}
dmadesc[i].ctrl |= ESP32S3_DMA_CTRL_EOF;
/* suc_eof (defined by ESP32S3_DMA_CTRL_EOF) is set by software
* only in transmit descriptor.
*/
if (tx)
{
dmadesc[i].ctrl |= ESP32S3_DMA_CTRL_EOF;
}
dmadesc[i].next = NULL;
return len - bytes;
@ -236,9 +254,9 @@ uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
* inlink/outlink to the corresponding GDMA_<IN/OUT>LINK_ADDR_CHn register
*
* Input Parameters:
* dmadesc - Pointer of the previously bound inlink/outlink
* chan - DMA channel of the receiver/transmitter
* tx - true: TX mode (transmitter); false: RX mode (receiver)
* dmadesc - Pointer of the previously bound inlink/outlink
*
* Returned Value:
* None

View file

@ -150,6 +150,7 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e periph,
* num - Number of DMA descriptors
* pbuf - RX/TX buffer pointer
* len - RX/TX buffer length
* tx - true: TX mode (transmitter); false: RX mode (receiver)
*
* Returned Value:
* Bound pbuf data bytes
@ -157,7 +158,7 @@ int32_t esp32s3_dma_request(enum esp32s3_dma_periph_e periph,
****************************************************************************/
uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
uint8_t *pbuf, uint32_t len);
uint8_t *pbuf, uint32_t len, bool tx);
/****************************************************************************
* Name: esp32s3_dma_load
@ -167,9 +168,9 @@ uint32_t esp32s3_dma_setup(struct esp32s3_dmadesc_s *dmadesc, uint32_t num,
* inlink/outlink to the corresponding GDMA_<IN/OUT>LINK_ADDR_CHn register
*
* Input Parameters:
* dmadesc - Pointer of the previously bound inlink/outlink
* chan - DMA channel of the receiver/transmitter
* tx - true: TX mode (transmitter); false: RX mode (receiver)
* dmadesc - Pointer of the previously bound inlink/outlink
*
* Returned Value:
* None

View file

@ -978,7 +978,8 @@ static int esp32s3_qspi_memory(struct qspi_dev_s *dev,
esp32s3_dma_setup(priv->dma_desc,
QSPI_DMA_DESC_NUM,
(uint8_t *)meminfo->buffer,
meminfo->buflen);
meminfo->buflen
true);
esp32s3_dma_load(priv->dma_desc, priv->dma_channel, true);
esp32s3_dma_enable(priv->dma_channel, true);
}
@ -993,7 +994,8 @@ static int esp32s3_qspi_memory(struct qspi_dev_s *dev,
esp32s3_dma_setup(priv->dma_desc,
QSPI_DMA_DESC_NUM,
(uint8_t *)meminfo->buffer,
meminfo->buflen);
meminfo->buflen
false);
esp32s3_dma_load(priv->dma_desc, priv->dma_channel, false);
esp32s3_dma_enable(priv->dma_channel, false);
}

View file

@ -904,7 +904,8 @@ static void esp32s3_spi_dma_exchange(struct esp32s3_spi_priv_s *priv,
esp32s3_spi_set_regbits(SPI_DMA_CONF_REG(priv->config->id),
SPI_DMA_TX_ENA_M);
n = esp32s3_dma_setup(priv->dma_txdesc, SPI_DMA_DESC_NUM, tp, bytes);
n = esp32s3_dma_setup(priv->dma_txdesc, SPI_DMA_DESC_NUM,
tp, bytes, true);
esp32s3_dma_load(priv->dma_txdesc, channel, true);
esp32s3_dma_enable(channel, true);
@ -921,7 +922,8 @@ static void esp32s3_spi_dma_exchange(struct esp32s3_spi_priv_s *priv,
esp32s3_spi_set_regbits(SPI_DMA_CONF_REG(priv->config->id),
SPI_DMA_RX_ENA_M);
esp32s3_dma_setup(priv->dma_rxdesc, SPI_DMA_DESC_NUM, rp, bytes);
esp32s3_dma_setup(priv->dma_rxdesc, SPI_DMA_DESC_NUM,
rp, bytes, false);
esp32s3_dma_load(priv->dma_rxdesc, channel, false);
esp32s3_dma_enable(channel, false);

View file

@ -903,7 +903,8 @@ static void spislave_setup_rx_dma(struct spislave_priv_s *priv)
esp32s3_dma_setup(priv->dma_rxdesc,
SPI_DMA_DESC_NUM,
priv->rx_buffer + priv->rx_length,
length);
length
false);
esp32s3_dma_load(priv->dma_rxdesc, priv->dma_channel, false);
priv->rx_dma_offset = priv->rx_length;
@ -946,7 +947,8 @@ static void spislave_setup_tx_dma(struct spislave_priv_s *priv)
esp32s3_dma_setup(priv->dma_txdesc,
SPI_DMA_DESC_NUM,
priv->tx_buffer,
SPI_SLAVE_BUFSIZE);
SPI_SLAVE_BUFSIZE
true);
esp32s3_dma_load(priv->dma_txdesc, priv->dma_channel, true);
spislave_dma_tx_fifo_reset(priv);