From 08cd6209516c5d657b63318e70241c3599130cf8 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Sat, 15 Mar 2025 19:34:28 +0100 Subject: [PATCH] Audio: stm32_dac: fixed missing restore of output idle level after stream end On CKS32F407 the external trigger source for a DAC channel needs to be disabled in order for the writes to the DAC data registers to be effective. This is coherent with the STM32F4 reference manual, but the STM32 devices update the DAC output on a register write wether the external trigger is enabled or not. --- platform/drivers/audio/stm32_dac.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/drivers/audio/stm32_dac.cpp b/platform/drivers/audio/stm32_dac.cpp index 0688a121..8ccb26c2 100644 --- a/platform/drivers/audio/stm32_dac.cpp +++ b/platform/drivers/audio/stm32_dac.cpp @@ -74,8 +74,12 @@ struct ChannelState chState[] = static void stopTransfer(const uint8_t chNum) { channels[chNum].tim.stop(); - *channels[chNum].dacReg = chState[chNum].idleLevel; chState[chNum].ctx->running = 0; + + // If the data register is written when the external trigger is still + // enabled, the DAC output may not be udated. + DAC->CR &= ~(DAC_CR_TEN1 << (chNum * 16)); + *channels[chNum].dacReg = chState[chNum].idleLevel; } /** @@ -125,7 +129,6 @@ void stm32dac_init(const uint8_t instance, const uint16_t idleLevel) DAC->DHR12R1 = idleLevel; DAC->CR |= DAC_CR_DMAEN1 // Enable DMA | 0x00 // TIM6 as trigger source for CH1 - | DAC_CR_TEN1 // Enable trigger input | DAC_CR_EN1; // Enable CH1 } break; @@ -138,7 +141,6 @@ void stm32dac_init(const uint8_t instance, const uint16_t idleLevel) DAC->DHR12R2 = idleLevel; DAC->CR |= DAC_CR_DMAEN2 // Enable DMA | DAC_CR_TSEL2_1 // TIM7 as trigger source for CH2 - | DAC_CR_TEN2 // Enable trigger input | DAC_CR_EN2; // Enable CH2 } break; @@ -203,6 +205,7 @@ static int stm32dac_start(const uint8_t instance, const void *config, ctx->bufSize, circ); // Configure DAC trigger + DAC->CR |= (DAC_CR_TEN1 << (instance * 16)); channels[instance].tim.setUpdateFrequency(ctx->sampleRate); channels[instance].tim.start();