STM32 gotchas
79.If TIM is set to downcounter, 0% PWM is not possible

The STM32 timers are primarily up-counters. In that capacity, when a channel is set to Output Compare and PWM1 mode is selected (PWM2 being simply inversion of PWM1), setting respective TIMx_CCRx register to 0 results in 0% PWM and setting it to value higher than is content of TIMx_ARR results in 100% PWM.

Some "better equipped" timers however feature also an up-down ("center aligned") counting mode. This in case of multiple channels being set to PWM, allows them to have their pulses "spread out" around one center point, for whatever that might be needed.

In this mode, a period lasts twice the number of clocks set in ARR. The designers - again for unknown reason - decided, that they need also the generated PWM pulse to be an even number of clocks. Therefore the condition to change the output level is different for counting up and counting down: if TIMx_CCRx is set to N, while counting up, output level is changed when TIMx_CNT changes from N-1 to N; whereas while counting down, output level is changed when TIMx_CNT changes from N+1 to N. Or, as in RM the TIMx_CCMR1.OC1M description for PWM1 mode states:

In upcounting, channel 1 is active as long as TIMx_CNT<TIMx_CCR1 else inactive. In downcounting, channel 1 is inactive (OC1REF=0) as long as TIMx_CNT>TIMx_CCR1 else active (OC1REF=1).

In the marginal case, when in up-down (center-aligned) mode TIMx_CCRx is set to 0, output duty is 0%. It may appear, that when downcounting, output level should change from 0 to 1 when counting from 1 to 0, but - again somewhat arbitrarily - the direction bit changes at the same moment, making the period while CNT==0 being already in the upcounting portion, thus preserving the output level at 0.

Timers, which have the up-down (center-aligned) mode, already have the downcounting mechanism, so it's logical that they can also be set to down-only ("edge-aligned", as opposed to "center-aligned") counting mode. The consequence of the described mechanism is, that if in that mode TIMx_CCRx is set to 0, the transition of TIMx_CNT from 1 to 0 indeed makes the output to go high for one clock period. In other words, there is no way to set 0% PWM in the downcounting mode.

This behaviour is explicitly documented in Downcounting configuration section of PWM mode subchapter of the TIM chapter in RM, but it's surprising nonetheles.