STM32 start counter from IRQ - Page 1
Forum section: electronics / general

author: dietert1
author_rank: Super Contributor
timestamp: April 12, 2022, 07:58:01 pm
content: Title says what i want to do.It's a STM32L053R8 (Nucleo64) and i am using a DAC with circular DMA to generate an analog waveform. Now i want to use a PWM timer to generate some digital output signals synchronous to the DMA cycle. Can i use two pins to route the DMA interrupt to the PWM timer trigger input? Is there on-chip circuitry to make that connection?Regards, Dieter

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 12, 2022, 08:08:14 pm
content: Not completely clear.Do you want to enable/disable the pwm timer when the dma transfer is done? Enable the dma interrupt and handle the PWM when the ISR is called.Or want to transfer the dma data to the pwm register, so it makes the analog waveform?

author: Kleinstein
author_rank: Super Contributor
timestamp: April 12, 2022, 08:48:37 pm
content: I dont' think the synchronization would work this way. The DMA interrupt may be delayed by a few cycles and there is soms delay from data transfer to the DAC and the actual DAC update. I don't think the DMA interupt signal can be used for anything different from triggering the interrrupt. A SW solution would add even more uncertainty.The more logical way would be to have a timer to trigger the DAC. It would than need an extra sample counting, e.g. with a 2nd timer to trigger on a specific sample. One may still have to check if this works. In some cases the STM32 are a bit stupid as one signal can be used for 1 target only. The L053 also does not have that many timers.

author: dietert1
author_rank: Super Contributor
timestamp: April 12, 2022, 09:57:12 pm
content: The DAC and its cyclic DMA have to run continuously for jitter free waveform generation. The DAC gets triggered by a timer, and the DMA feeds data from an array to the DAC holding register.Yes, the DMA interrupt will be jittery, so no good idea to use it for waveform generation.Maybe i will try to disable interrupts to start the timer that triggers the DAC and the PWM timer "at the same time". There will be a small and constant number of instructions as timing error, but the PWM timer and the source address in the DMA should remain phase locked to each other. Maybe it's enough to implement the DMA interrupt and use the CPU to check whether PWM timer and DMA remained "in phase". In case something went wrong there should be a recovery procedure.Regards, Dieter

author: wek
author_rank: Frequent Contributor
timestamp: April 13, 2022, 07:07:49 am
content: Quote from: dietert1 on April 12, 2022, 09:57:12 pmExactly this is why timers in STM32 have master-slave interconnection. You can start one from the other, or both from a third. And can't you simply trigger DAC from the same timer which generates the PWM?JW

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 13, 2022, 03:57:36 pm
content: For the DMA transfer mode: Use timer DMA burst feature.- Allows updating from 1 to 4 timer registers at once, synced, in a single DMA transaction.- If your're using only one PWM channel, use 1 transfer length size.- DMA size is absolute: Set a DMA transfer size of 100. For burst size=1,the timer will be update 100 times, but for burst size=2, it'll be 50 times, doing 2 transfers each time.For the DMA requesr source: Use the Timer Update DMA request.- Triggered when the timer timebase is elapsed (Timer resetted, new PWM cycle starts)- DMA request timing will be constant, contrary to capture/compare request which happens when the compare register matches the counter.- Additionally, PWM could be set to run much faster to provide easier/better filtering using the repetition counter (It's like a flag postscaler), but not available in all STM32, checking your's, it seems it's lacking it.I did something similar in myWAV PWM audio test.Check the CubeMX project for timer/dma details, also Core/Src/pwmAudio.c and Core/Inc/pwmAudio.h- Uses Timer1, enabling channels 1 & 2 in PWM mode.- DMA request: Timer Update- Timer (PWM) timebase is 384KHz.- Ajusts the repetition counter for the different sample rates ( ex. 8 for 48KHz , 384/8=48KHz ).- Burst mode pointing to CCR1, BURST size=2, so each Timer DMA Update request will make 2 transfers: source->CCR1, source[x+1]->CCR2, thus making perfectly synced, stereo PWM audio.So, I have PCMbuffer, organized as Left-Right-Left-Right....Set the DMA Burst:Code:HAL_TIM_DMABurst_MultiWriteStart(&htim1, TIM_DMABASE_CCR1, TIM_DMA_UPDATE, (uint32_t*)&PCMbuffer, TIM_DMABURSTLENGTH_2TRANSFERS, PCMsize);That will update CCR1+CCR2 576 times.At 288, you'll get the DMA-half-transfer interrupt, and after 576, the dma full-transfer complete ISR.I use DMA circular mode so it never stops, even if I stop updating the buffer. Will cause the classic computer hang loop noise.For you specific application, you can use circular mode disabling source address increase, so it'll always read the same memory position, and you can disbale the Timer and DMA interrupts, you don't need to handle anything.The whole stm32 memory space can be used to feed the DMA, so you could use ex. the DAC register to transfer the last DAC value to the PWM.What's your sample rate? That MCU is pretty slow, 32MHz max, so you will need to ether:- Sacrifice resolution: 8 bit allows to 125Ksps- Sacrifice samplerate: 16 bit allows only 488spsIt seems Timer 2 can do everything:- Run PWM- Trigger the Timer DMA burst- Use TRGO signal to trigger DAC DMA

author: dietert1
author_rank: Super Contributor
timestamp: April 14, 2022, 12:17:57 am
content: Thanks for your hints to DMA burst mode.The CPU runs at 6 MHz, output frequency is 600 Hz.The solution i found now uses Tim6 to trigger the DAC (and its DMA) and Tim2 to generate the PWM signals. In order to synchronize DAC and PWM i am using the fourth channel of Tim2 in capture mode with Comparator2 to trigger on a feature in the DAC output waveform. So there is a wire from the DAC output pin to the comparator input pin. The capture interrupt handler implements error recovery in case one of the two timers or the DMA source address counter falls out of sync (primitive PLL).Code:#include "main.h"// 2022-04-13 DT// PLL locks Tim2 PWM onto DMA DAC using comparator 2extern TIM_HandleTypeDef htim2;// count adjustments to detect residual jitterstatic uint32_t iNUp=0L,iNDown=0L;#define PhaseOffset 5#define FrequCenter 10004#define FrequHalf 5002void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {if ((FrequHalf < htim2.Instance->CCR4)|| (htim2.Instance->CCR4 < PhaseOffset)) {htim2.Instance->ARR = FrequCenter+1;iNUp++;}else if (htim2.Instance->CCR4 == PhaseOffset)htim2.Instance->ARR = FrequCenter;else {htim2.Instance->ARR = FrequCenter-1;iNDown++;}}Regards, DieterPS: The scope is a Tek 2465 that i have more than 25 years.

author: DavidAlfa
author_rank: Super Contributor
timestamp: April 14, 2022, 01:47:00 am
content: I think you could get it done by using Timer 2 alone:Timer2 -> Update DMA request -> DMA Burst -> CCR (PWM)-> TRGO -> DAC Trigger -> DAC DMA RequestAlthough I don't completely understand your waveforms, seems like the DAC runs faster than the PWM?In that case yeah, won't be that easy.

author: dietert1
author_rank: Super Contributor
timestamp: April 14, 2022, 12:28:22 pm
content: Yes, in the scope example the DAC does 15 samples in one PWM timer cycle. In fact the DAC signal controls a current source and the PWM signals control a MUX that routes the current.Regards, Dieter

author: pcprogrammer
author_rank: Super Contributor
timestamp: April 14, 2022, 12:42:55 pm
content: Have a look at the code here:https://github.com/pecostm32/STM32F303_Sine_Square_GeneratorIt is for a STM32F303 but the basics will most likely be the same for your device.The DMA is used to make the sine wave via the DAC and coupled timers with DMA are used to make the phase shifted square waves. Changing the timer square outputs to PWM should be easy.