From f5bf7df50ccb0a5fe930eed58d4e83aa0e45ad53 Mon Sep 17 00:00:00 2001 From: Andriy Gelman Date: Sun, 12 Jan 2025 15:34:24 -0500 Subject: [PATCH] drivers: dma_xmc4xxx: Support calling dma_stop() after dma_config() In the dma loop_transfer test (test_loop_repeated_start_stop()), the order of calls is dma_config() -> dma_stop() -> dma_start(). This currently does not work on xmc4xxx because after calling dma_stop(), the dma would be in a suspended state. Fix this by leaving the suspended state before exiting dma_stop(). Also don't clear the context (dma_channel->dlr_line and dma_channel->cb) that was setup by dma_config(). Signed-off-by: Andriy Gelman --- drivers/dma/dma_xmc4xxx.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dma_xmc4xxx.c b/drivers/dma/dma_xmc4xxx.c index 3e89ea85fd8..2a93d645458 100644 --- a/drivers/dma/dma_xmc4xxx.c +++ b/drivers/dma/dma_xmc4xxx.c @@ -221,6 +221,7 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct config->source_burst_length / 4 << GPDMA0_CH_CTLL_SRC_MSIZE_Pos | BIT(GPDMA0_CH_CTLL_INT_EN_Pos); + dma->CH[channel].CFGH = 0; if (config->channel_direction == MEMORY_TO_PERIPHERAL || config->channel_direction == PERIPHERAL_TO_MEMORY) { uint8_t request_source = XMC4XXX_DMA_GET_REQUEST_SOURCE(config->dma_slot); @@ -315,8 +316,14 @@ static int dma_xmc4xxx_config(const struct device *dev, uint32_t channel, struct static int dma_xmc4xxx_start(const struct device *dev, uint32_t channel) { const struct dma_xmc4xxx_config *dev_cfg = dev->config; + struct dma_xmc4xxx_data *dev_data = dev->data; + uint8_t dlr_line = dev_data->channels[channel].dlr_line; LOG_DBG("Starting channel %d", channel); + if (dlr_line != DLR_LINE_UNSET && (DLR->LNEN & BIT(dlr_line)) == 0) { + DLR->LNEN |= BIT(dlr_line); + } + XMC_DMA_CH_Enable(dev_cfg->dma, channel); return 0; } @@ -341,10 +348,8 @@ static int dma_xmc4xxx_stop(const struct device *dev, uint32_t channel) DLR->LNEN &= ~BIT(dma_channel->dlr_line); } - dma_channel->dlr_line = DLR_LINE_UNSET; - dma_channel->cb = NULL; - XMC_DMA_CH_Disable(dma, channel); + XMC_DMA_CH_Resume(dma, channel); return 0; }