I have a STM32F411 board and want to output a PWM signal using timers/PWM/DMA: once every 2 ms a, 16 pulses are sent, each representing one bit. Each pulse has a period of ~3 microseconds with varying duty cycle.
To change the duty cycle, I write to a 32-bit output capture/compare register (TIMx->CCRx) via a DMA transfer from a buffer in memory (the buffer contains 16 32-bit integers). Essentially, the output is HIGH as long as the timer's counter is smaller than this register value, then it changes to LOW until the timer overflows.
I have two questions:
I'd appreciate any pointers!
Btw, I use libopencm3.
However, you can have TIMx_CCRx preload switched on, if the related TIMx_CCMRx.OCxPE bit is set. In that case, processor or DMA is not writing to the "working" TIMx_CCRx register (against which TIMx_CNT is compared), but into an "intermediate" register (ST uses a different nomenclature, but IMO that's more confusing). The value from "intermediate" register is copied into the "working" register upon the next Update event (usually upon the timer "rollover", when TIMx_CNT reaches TIMx_ARR and then goes to 0). But even in this case, if you write twice to TIMx_CCRx within one TIM period, both writes go into the "intermediate" register and the second one overwrites the first one.
But you don't need to be worried by two writes per period at all. Unless you run at some extreme clocks, the DMA mechanism together with the above preload ensures, that there's only one DMA transfer per period. Just don't trigger the DMA by the CC itself (as I see so often in examples and in Cube/HAL), but by Update.