diff --git a/drivers/dma/dma_esp32_gdma.c b/drivers/dma/dma_esp32_gdma.c index 7fb5da72b43b618..056c9fd2d7db221 100644 --- a/drivers/dma/dma_esp32_gdma.c +++ b/drivers/dma/dma_esp32_gdma.c @@ -145,33 +145,53 @@ static int dma_esp32_config_rx_descriptor(struct dma_esp32_channel *dma_channel, return -EINVAL; } - if (!esp_ptr_dma_capable((uint32_t *)block->dest_address) + uint32_t dest_address = 0, block_size = 0; + dma_descriptor_t *desc_iter = dma_channel->desc_list; + + for (int i = 0; i < CONFIG_DMA_ESP32_MAX_DESCRIPTOR_NUM; ++i) { + if (block_size == 0) { + + if (!esp_ptr_dma_capable((uint32_t *)block->dest_address) #if defined(CONFIG_ESP_SPIRAM) - && !esp_ptr_dma_ext_capable((uint32_t *)block->dest_address) + && !esp_ptr_dma_ext_capable((uint32_t *)block->dest_address) #endif - ) { - LOG_ERR("Rx buffer not in DMA capable memory: %p", (uint32_t *)block->dest_address); - return -EINVAL; - } + ) { + LOG_ERR("Rx buffer not in DMA capable memory: %p", + (uint32_t *)block->dest_address); + return -EINVAL; + } - dma_descriptor_t *desc_iter = dma_channel->desc_list; + dest_address = block->dest_address; + block_size = block->block_size; + } - for (int i = 0; i < CONFIG_DMA_ESP32_MAX_DESCRIPTOR_NUM; ++i) { - if (block->block_size > DMA_DESCRIPTOR_BUFFER_MAX_SIZE) { - LOG_ERR("Size of block %d is too large", i); - return -EINVAL; + uint32_t buffer_size; + + if (block_size > DMA_DESCRIPTOR_BUFFER_MAX_SIZE) { + buffer_size = DMA_DESCRIPTOR_BUFFER_MAX_SIZE; + } else { + buffer_size = block_size; } + memset(desc_iter, 0, sizeof(dma_descriptor_t)); - desc_iter->buffer = (void *)block->dest_address; - desc_iter->dw0.size = block->block_size; + desc_iter->buffer = (void *)dest_address; + desc_iter->dw0.size = buffer_size; desc_iter->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - if (!block->next_block) { - desc_iter->next = NULL; - break; + + dest_address += buffer_size; + block_size -= buffer_size; + + if (!block_size) { + if (block->next_block) { + block = block->next_block; + } else { + desc_iter->next = NULL; + break; + } } + desc_iter->next = desc_iter + 1; desc_iter += 1; - block = block->next_block; } if (desc_iter->next) { @@ -228,36 +248,55 @@ static int dma_esp32_config_tx_descriptor(struct dma_esp32_channel *dma_channel, return -EINVAL; } - if (!esp_ptr_dma_capable((uint32_t *)block->source_address) + uint32_t source_address = 0, block_size = 0; + dma_descriptor_t *desc_iter = dma_channel->desc_list; + + for (int i = 0; i < CONFIG_DMA_ESP32_MAX_DESCRIPTOR_NUM; ++i) { + if (block_size == 0) { + + if (!esp_ptr_dma_capable((uint32_t *)block->source_address) #if defined(CONFIG_ESP_SPIRAM) - && !esp_ptr_dma_ext_capable((uint32_t *)block->source_address) + && !esp_ptr_dma_ext_capable((uint32_t *)block->source_address) #endif - ) { - LOG_ERR("Tx buffer not in DMA capable memory: %p", - (uint32_t *)block->source_address); - return -EINVAL; - } + ) { + LOG_ERR("Tx buffer not in DMA capable memory: %p", + (uint32_t *)block->source_address); + return -EINVAL; + } - dma_descriptor_t *desc_iter = dma_channel->desc_list; + source_address = block->source_address; + block_size = block->block_size; + } - for (int i = 0; i < CONFIG_DMA_ESP32_MAX_DESCRIPTOR_NUM; ++i) { - if (block->block_size > DMA_DESCRIPTOR_BUFFER_MAX_SIZE) { - LOG_ERR("Size of block %d is too large", i); - return -EINVAL; + uint32_t buffer_size; + + if (block_size > DMA_DESCRIPTOR_BUFFER_MAX_SIZE) { + buffer_size = DMA_DESCRIPTOR_BUFFER_MAX_SIZE; + } else { + buffer_size = block_size; } + memset(desc_iter, 0, sizeof(dma_descriptor_t)); - desc_iter->buffer = (void *)block->source_address; - desc_iter->dw0.size = block->block_size; - desc_iter->dw0.length = block->block_size; + desc_iter->buffer = (void *)source_address; + desc_iter->dw0.size = buffer_size; + desc_iter->dw0.length = buffer_size; desc_iter->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - if (!block->next_block) { - desc_iter->next = NULL; - desc_iter->dw0.suc_eof = 1; - break; + + source_address += buffer_size; + block_size -= buffer_size; + + if (!block_size) { + if (block->next_block) { + block = block->next_block; + } else { + desc_iter->next = NULL; + desc_iter->dw0.suc_eof = 1; + break; + } } + desc_iter->next = desc_iter + 1; desc_iter += 1; - block = block->next_block; } if (desc_iter->next) {