2023-10-18 01:01 AM - edited 2023-10-23 02:03 AM
Hi ST community,
For a project I would like to generate two interdependent PWM signals (Sa and Sw in the attached figure) with the STM32G0. The constraints/tasks are as follows:
The times for tSa,off and tSa,on are thus adjusted every 300us. The time tSw,on is limited cycle by cycle by the active break.
Following limitations I had to mention:
I will not present my previous approaches now, in order not to influence your ideas.
I look forward to your feedback.
Br, Stefan
Solved! Go to Solution.
2023-10-24 02:29 AM
2023-10-18 06:04 AM
2023-10-18 06:21 AM
Thx for your input TDK.
Some thoughts/Questions:
Br, Stefan
2023-10-18 06:40 AM - edited 2023-10-18 06:41 AM
> How is it possible with this concept to limit the on time of the Sw (tSw,on) with a comparator signal (active break)?
So when a comparator goes high, you want the pulse to be low? Not sure, but there's likely a way. Definitely a solution in hardware with an AND gate.
> How can I make sure / find the time when the timer just rolls over? An Interrupt may be too slow and not possible in the final application.
Assuming CCR1 is the timer value of the start of the first blue pulse:
100us is plenty of time to change a few registers.
2023-10-18 06:58 AM
Hi TDK, thx again for your input.
Thx & Br
Stefan
2023-10-18 08:06 AM
Timer period starts at beginning of Tsa,off. Tsa,on generated using Combined PWM mode as TDK said above. Tsw,on normally generated using the plain PWM2 mode on one channel, as timer period ends with end of Tsw,on.
Premature end of Tsw,on accomplished through feeding COMP output to TIx or ETR (see TIMx_TISEL or TIMx_AF1 registers), setting that signal as Slave-mode controller's input (TIMx_SMCR.TS) and setting Slave-mode controller to Reset in TIMx_SMCR.SMS.
Update all required TIMx_CCRx together with TIMx_ARR in Update interrupt (or learn how to use Update-triggered "burst" DMA through the TIMx_DMAR/DCR mechanism). Enabling ARR/CCRx preset (TIMx_CR1.ARPE & TIMx_CCMRx.OCxPE) helps.
JW
2023-10-18 09:15 AM
> I fully understand the logic of your propose, is there a function (callback function) which pops up when CNT < CCR1? Or what is your idea to monitor this?
Literally read the register and wait for the condition. The update event happens when CNT=0. You could also use that, but it is subject to more delay.
__disable_irq();
while (TIM1->CNT < TIM1->CCR1);
while (TIM1->CNT >= TIM1->CCR1);
TIM1->CCR1 = x;
TIM1->CCR2 = x;
TIM1->CCR3 = x;
TIM1->CCR4 = x;
TIM1->ARR = x;
__enable_irq();
Or follow the idea from @waclawek.jan to us DMA to do the same on the update event, which will be even faster. Better solution, harder to program, though.
2023-10-18 12:41 PM
Ok now I got you. And I see that I miss to mention another critical limitiation. In the final application I'm not allowed to poll something in the while loop. All 300us I have some us time to do my magic (e.g., set the registers). I guess in this case the polling does not work, right? I also think it needs serval clk cycles to set the registers, by an clk of 48MHz also given at the moment it is car to set registers within some 100ns. So my thought's was that must be done within the periphery / hardware. What do you think?
2023-10-18 12:46 PM
Thx jan for your feedback. I have to think about that. We tried in a similar project the DMA-Burst mode function, do you have that in mind?
Br, Stefan
2023-10-19 02:40 AM
> DMA-Burst mode function
Yes, although I don't like the word "burst" as in DMA context that may mean several very different things. That's why I'm referring to the TIMx_DMAR/DCR register pair, that's unambiguous.
By using preloaded ARR and CCRx registers, the time window for update is one whole timer cycle, from Update to Update. Although, even with DMA, don't expect 5 registers (ARR..CCR3) to be updated within 400ns.
Tackle this one step at a time. For testing, you can modify the ARR/CCRx registers in Update interrupt, working with longer pulses/period; proceed to DMA later.
Final word, if you plan to use Cube/HAL for this, well, just don't.
JW