Open loop 6 step PWM generation

To understand better SimpleFOC I decided to recode the Open Loop 6 step commutation software on my stm32 with CubeIDE.
My question is how SimpleFOC software is generating 3 shifted PWM signals from the same timer ?
Is it linked with CCR values ?

Have you checked the documentation ?

Yep - you are right about it using CCR:

All 3xpwm are on the same timer (different channels), all centre aligned. All pwm running at the same frequency. From this perspective they are not shifted.

They share an autoreload count I forget the exact calculations but it somthing like pwm clock / desired PWM frequency * 2 . e.g 60mhz/20000 * 2 = 1500. The 2x is because centre aligned counts up then down taking twice as long). So every 3000 counts the timer will start at zero go up to 1500 and back down to 0.

Now we just need to change how long each channel is activated for. This, I think is done in capture/compare register. With 6 step commutation - assuming 120 degree trapezoidal, We have 3 states ON/OFF/HIZ e.g. looking at electrical angle 0 → 360

angle       dutyA, dutyB, dutyC
0-59        1500,  0,     Hi-Z
60-119      1500,  HI-Z , 0
120 - 179   HI-Z,  1500,  0
180 - 239   0,     1500,  HI-Z
240 - 299   0,     HI-Z,  1500
300 - 359   HI-Z,  0,     1500

The above will be using full voltage (dangerous!) . For Hi-Z it could be set to zero (from a timer perspective) but we have disabled that phase (assuming your gate driver has the capability of putting each phase to hi-z).

Take the above with a pinch of salt (be careful) - I’m just a hobbyist not an expert. If your gate drive doesn’t have shoot through protection, then I wouldn’t try this out as you’ll likely damage your mosfets before you work out the correct pattern.

The above assumes a 3PWM. You’d need to adjust for 6PWM

Thank you very much.
Thanks for the caution advices, for now I don’t use any power, just my nucleo board and oscilloscope so I shoul dnot burn anything.
I am using 3 PWM too.
The thing I don’t get on your explanation is “now we just need to change how long each channel is activated for”. For me, if we change that we change duty cycle, so each phase won’t be activated for same time on a period. And in my opinion that is not what we should aim for. But I may be wrong.

What you look for is called space vector pwm or svpwm. Look it up

I think SVPWM is the use of V0 and V7 vectors to be able to virtually lower the Kv value of the motor, I am not sure that this is needed to implement the simple open loop 6 step control. But I may be wrong.

6 step and svpwm are just 2 types of modulation
It’s all handled here

Ok, so my precise question is : do you know ho pwm are generated at the stm32 timer level to do a 6 step commutation ?

the code I shared calculates the duty cycles.
Owen shared how the duty cycles are applied to the timer channels.

The library does not support 6-step commutation.

Setting the PWM to the timers is not a big problem, it’s just unfortunately very complicated to configure the timers in STM32 HAL. Owen has already linked the code that does it.

The problem is to know when to switch between the steps in 6-step commutation. Normally this is done by BEMF sensing, which our library does not support. With BEMF sensing, you can detect the BEMF zero-crossings and use these to drive the switching between the 6-step states.

If you decide to implement this in combination with SimpleFOC, we would be very happy to see your results!

isn’t 6step just trapezoidal ?

In principle it has the same pattern as what we have in FOCModulationType::Trapezoid_120. So if you just want open-loop 6-step commutation, then you can just choose this modulation type.

But for closed loop, the expectation is normally that 6-step is driven by BEMF detection, and not a position sensor. That’s the part we don’t support. If you’re happy to read a position sensor, and drive the 6-step based on that, then again you can just choose the modulation type FOCModulationType::Trapezoid_120. But personally I don’t see an advantage here for most setups compared to the default SinePWM modulation.

I think he is just learning/experimenting, so he started with open-loop 6step.

Thanks for you support !
As Candas said, in fact I am for now just doing some open loop, but yes if one day I have bemf foc results I won’t forget to show you.
For now my question was just how the pwm is generated at the controller level. I wasn’t able to see that directly on Owen’s code but I am investigating.

Please read the documentation for STM32 timers. The PWM is generated by the timer (hardware peripheral), so there is no real firmware involvement to drive the PWM as in bit banging. You just set some configuration bits and away it goes. The firmware is then just adjusting the CCR registers so that the PWM output is sinusoidal.