mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 18:57:19 +02:00
ethernet: set DMA owner after all descriptors have configured
This commit is contained in:
@ -451,44 +451,55 @@ uint32_t emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
|
|||||||
if (lastlen) {
|
if (lastlen) {
|
||||||
bufcount++;
|
bufcount++;
|
||||||
}
|
}
|
||||||
|
if (bufcount > CONFIG_ETH_DMA_TX_BUFFER_NUM) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
eth_dma_tx_descriptor_t *desc_iter = hal->tx_desc;
|
||||||
/* A frame is transmitted in multiple descriptor */
|
/* A frame is transmitted in multiple descriptor */
|
||||||
for (uint32_t i = 0; i < bufcount; i++) {
|
for (int i = 0; i < bufcount; i++) {
|
||||||
/* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */
|
/* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */
|
||||||
if (hal->tx_desc->TDES0.Own != EMAC_DMADESC_OWNER_CPU) {
|
if (desc_iter->TDES0.Own != EMAC_DMADESC_OWNER_CPU) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/* Clear FIRST and LAST segment bits */
|
/* Clear FIRST and LAST segment bits */
|
||||||
hal->tx_desc->TDES0.FirstSegment = 0;
|
desc_iter->TDES0.FirstSegment = 0;
|
||||||
hal->tx_desc->TDES0.LastSegment = 0;
|
desc_iter->TDES0.LastSegment = 0;
|
||||||
|
desc_iter->TDES0.InterruptOnComplete = 0;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
/* Setting the first segment bit */
|
/* Setting the first segment bit */
|
||||||
hal->tx_desc->TDES0.FirstSegment = 1;
|
desc_iter->TDES0.FirstSegment = 1;
|
||||||
}
|
}
|
||||||
if (i == (bufcount - 1)) {
|
if (i == (bufcount - 1)) {
|
||||||
/* Setting the last segment bit */
|
/* Setting the last segment bit */
|
||||||
hal->tx_desc->TDES0.LastSegment = 1;
|
desc_iter->TDES0.LastSegment = 1;
|
||||||
/* Enable transmit interrupt */
|
/* Enable transmit interrupt */
|
||||||
hal->tx_desc->TDES0.InterruptOnComplete = 1;
|
desc_iter->TDES0.InterruptOnComplete = 1;
|
||||||
/* Program size */
|
/* Program size */
|
||||||
hal->tx_desc->TDES1.TransmitBuffer1Size = lastlen;
|
desc_iter->TDES1.TransmitBuffer1Size = lastlen;
|
||||||
/* copy data from uplayer stack buffer */
|
/* copy data from uplayer stack buffer */
|
||||||
memcpy((void *)(hal->tx_desc->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, lastlen);
|
memcpy((void *)(desc_iter->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, lastlen);
|
||||||
sentout += lastlen;
|
sentout += lastlen;
|
||||||
} else {
|
} else {
|
||||||
/* Program size */
|
/* Program size */
|
||||||
hal->tx_desc->TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE;
|
desc_iter->TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||||
/* copy data from uplayer stack buffer */
|
/* copy data from uplayer stack buffer */
|
||||||
memcpy((void *)(hal->tx_desc->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, CONFIG_ETH_DMA_BUFFER_SIZE);
|
memcpy((void *)(desc_iter->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, CONFIG_ETH_DMA_BUFFER_SIZE);
|
||||||
sentout += CONFIG_ETH_DMA_BUFFER_SIZE;
|
sentout += CONFIG_ETH_DMA_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
|
|
||||||
hal->tx_desc->TDES0.Own = EMAC_DMADESC_OWNER_DMA;
|
|
||||||
/* Point to next descriptor */
|
/* Point to next descriptor */
|
||||||
|
desc_iter = (eth_dma_tx_descriptor_t *)(desc_iter->Buffer2NextDescAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
|
||||||
|
for (int i = 0; i < bufcount; i++) {
|
||||||
|
hal->tx_desc->TDES0.Own = EMAC_DMADESC_OWNER_DMA;
|
||||||
hal->tx_desc = (eth_dma_tx_descriptor_t *)(hal->tx_desc->Buffer2NextDescAddr);
|
hal->tx_desc = (eth_dma_tx_descriptor_t *)(hal->tx_desc->Buffer2NextDescAddr);
|
||||||
}
|
}
|
||||||
err:
|
|
||||||
hal->dma_regs->dmatxpolldemand = 0;
|
hal->dma_regs->dmatxpolldemand = 0;
|
||||||
return sentout;
|
return sentout;
|
||||||
|
err:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t size, uint32_t *frames_remain)
|
uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t size, uint32_t *frames_remain)
|
||||||
|
Reference in New Issue
Block a user