From 7b379f47fae429a9e7d9b278401bf15b11fb5202 Mon Sep 17 00:00:00 2001 From: Fabrice DJIATSA Date: Wed, 15 Jan 2025 13:44:48 +0100 Subject: [PATCH] drivers: dma: add linked list in dmau5 driver - Init linked list node and structure - configure source and destination address - Setting gpdma request mode - Configure linked list node and structure for continous transfer, enable half transfert irq. Signed-off-by: Fabrice DJIATSA co-authored-by: Lubos Koudelka --- drivers/dma/dma_stm32u5.c | 56 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/dma/dma_stm32u5.c b/drivers/dma/dma_stm32u5.c index e83a2312f5b..b6be9a762c3 100644 --- a/drivers/dma/dma_stm32u5.c +++ b/drivers/dma/dma_stm32u5.c @@ -353,6 +353,13 @@ static int dma_stm32_configure(const struct device *dev, LL_DMA_InitTypeDef DMA_InitStruct; int ret; + /* Linked list Node and structure initialization */ + static LL_DMA_LinkNodeTypeDef Node_GPDMA_Channel; + LL_DMA_InitLinkedListTypeDef DMA_InitLinkedListStruct; + LL_DMA_InitNodeTypeDef NodeConfig; + + LL_DMA_ListStructInit(&DMA_InitLinkedListStruct); + LL_DMA_NodeStructInit(&NodeConfig); LL_DMA_StructInit(&DMA_InitStruct); /* Give channel from index 0 */ @@ -408,16 +415,6 @@ static int dma_stm32_configure(const struct device *dev, return -EINVAL; } - /* Continuous transfers are supported by hardware but not implemented - * by this driver - */ - if (config->head_block->source_reload_en || - config->head_block->dest_reload_en) { - LOG_ERR("source_reload_en and dest_reload_en not " - "implemented."); - return -EINVAL; - } - stream->busy = true; stream->dma_callback = config->dma_callback; stream->direction = config->channel_direction; @@ -436,8 +433,9 @@ static int dma_stm32_configure(const struct device *dev, DMA_InitStruct.SrcAddress = config->head_block->source_address; DMA_InitStruct.DestAddress = config->head_block->dest_address; - DMA_InitStruct.BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST; - DMA_InitStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; + NodeConfig.SrcAddress = config->head_block->source_address; + NodeConfig.DestAddress = config->head_block->dest_address; + NodeConfig.BlkDataLength = config->head_block->block_size; ret = dma_stm32_get_priority(config->channel_priority, &DMA_InitStruct.Priority); @@ -502,18 +500,40 @@ static int dma_stm32_configure(const struct device *dev, /* The request ID is stored in the dma_slot */ DMA_InitStruct.Request = config->dma_slot; - LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct); + if (config->head_block->source_reload_en == 0) { + /* Initialize the DMA structure in non-cyclic mode only */ + LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct); + } else {/* cyclic mode */ + /* Setting GPDMA request */ + NodeConfig.DestDataWidth = DMA_InitStruct.DestDataWidth; + NodeConfig.SrcDataWidth = DMA_InitStruct.SrcDataWidth; + NodeConfig.DestIncMode = DMA_InitStruct.DestIncMode; + NodeConfig.SrcIncMode = DMA_InitStruct.SrcIncMode; + NodeConfig.Direction = DMA_InitStruct.Direction; + NodeConfig.Request = DMA_InitStruct.Request; + + /* Continuous transfers with Linked List */ + stream->cyclic = true; + LL_DMA_List_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitLinkedListStruct); + LL_DMA_CreateLinkNode(&NodeConfig, &Node_GPDMA_Channel); + LL_DMA_ConnectLinkNode(&Node_GPDMA_Channel, LL_DMA_CLLR_OFFSET5, + &Node_GPDMA_Channel, LL_DMA_CLLR_OFFSET5); + LL_DMA_SetLinkedListBaseAddr(dma, dma_stm32_id_to_stream(id), + (uint32_t)&Node_GPDMA_Channel); + LL_DMA_ConfigLinkUpdate(dma, dma_stm32_id_to_stream(id), + (LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | + LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR | + LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR), + (uint32_t)&Node_GPDMA_Channel); + + LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id)); + } LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_USE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_ULE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_DTE(dma, dma_stm32_id_to_stream(id)); - /* Enable Half-Transfer irq if circular mode is enabled */ - if (config->head_block->source_reload_en) { - LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id)); - } - return ret; }