Closed askuric closed 4 months ago
Hi Antun,
Just as a FYI, the hoverboard FOC firmware is also using this feature to run DUAL FOC, but there is another trick. If you just align the timers, One motor will be sampled in the middle of the ON time, and the other motor a bit later.
The trick is to start the timers with a different counter value, to account for the time it takes to sample the phase currents for one motor.
So both motor's phase current is sampled a the righ time.
Another thing I tried is to use the same trick to run both timers half a PWM period appart, and swap the adc channels from one motor to another in the interrupt, but it's much more tricky.
[EDIT] Sorry, one more clarification. This is of course in case you sample with a single ADC, second timer should be shifted by the time it takes to sample and convert the 2 phase currents ADC 1 : Motor1-Ia, Motor1-Ib, Motor2-Ia, Motor2-Ib
But with 2 ADCs, it's not needed: ADC 1 : Motor1-Ia, Motor1-Ib ADC 2 : Motor2-Ia, Motor2-Ib Is this setup actually already possible with SFOC ? It's a different ADC per motor, being triggered by a different Timer TRGO event. I can try this on a hoverboard controller.
[EDIT2] This approach requires the shifting the timer as well by the time it takes to sample and convert on phase current, and needs allowing multiple ADC for the same current sense instance. It makes the sampling synchronous/shorter. That how the hoverboard firmware works ADC 1 : Motor1-Ia, Motor2-Ia ADC 2 : Motor1-Ib, Motor2-Ib
TIMx | TIM1 | TIM2 | TIM3 | TIM4 | TIM5 | TIM8 |
---|---|---|---|---|---|---|
ITR0 | Reserved | TIM1 | TIM1 | TIM1 | TIM1 | TIM1 |
ITR1 | TIM2 | Reserved | TIM2 | TIM2 | TIM2 | TIM2 |
ITR2 | TIM3 | TIM3 | Reserved | TIM3 | TIM3 | TIM3 |
ITR3 | TIM4 | TIM4 | TIM4 | Reserved | TIM4 | TIM4 |
ITR4 | TIM5 | TIM5 | TIM5 | TIM5 | Reserved | TIM5 |
ITR5 | TIM8 | TIM8 | TIM8 | TIM8 | TIM8 | Reserved |
TIMx | TIM1 | TIM2 | TIM3 | TIM4 | TIM5 | TIM8 |
---|---|---|---|---|---|---|
ITR0 | TIM5 | TIM1 | TIM1 | TIM1 | TIM2 | TIM1 |
ITR1 | TIM2 | TIM8(if available) | TIM2 | TIM2 | TIM3 | TIM2 |
ITR2 | TIM3 | TIM3 | TIM5 | TIM3 | TIM4 | TIM4 |
ITR3 | TIM4 | TIM4 | TIM4 | TIM8(if available) | TIM8(if available) | TIM5 |
TIMx | TIM1 | TIM2 | TIM3 | TIM4 | TIM5 | TIM8 |
---|---|---|---|---|---|---|
ITR0 | TIM5 | TIM1 | TIM1 | TIM1 | TIM2 | TIM1 |
ITR1 | TIM2 | TIM8(if available) | TIM2 | TIM2 | TIM3 | TIM2 |
ITR2 | TIM3 | TIM3 | TIM5 | TIM3 | TIM4 | TIM4 |
ITR3 | TIM4 | TIM4 | TIM4 | TIM8(if available) | TIM8(if available) | TIM5 |
TIMx | TIM1 | TIM2 | TIM3 | TIM4 | TIM5 | TIM8 |
---|---|---|---|---|---|---|
ITR0 | TIM15 | TIM1 | TIM1 | TIM1 | TIM2 | TIM1 |
ITR1 | TIM2 | TIM8(if available) | TIM2 | TIM2 | TIM3 | TIM2 |
ITR2 | TIM3 | TIM3 | TIM15 | TIM3 | TIM4 | TIM4 |
ITR3 | TIM4 | TIM4 | TIM4 | TIM8(if available) | TIM8(if available) | TIM5 |
Merging :D
This branch proposes a code which synchronizes all the stm32 timers. It enables using multiple timers per motor and producing sync center aligned PWM (2pwm, 3pwm, 4pwm and 6pwm).
The proposed code will attempt to sync all the timers used for pwm (even if they are used with multiple motors).
The code works well with the low-side current sensing as well, this is especially a big change for simplefocshield based setups used with nucleos, as they usually never use only one timer for 3 pwm signals. Now they are aligned and the current measurement is much better.
Basically the code in the funciton
_alignTimersNew()
which now finds the master timer between the used timers and all the other timers are configured as slave ones that are started at the same time as the master one. To start the slaves the master timer emitsTRGO_ENABLE
event. If there is no timer that can be master timer, the timers are not synchronized, and the debug error is shown (but the driver is initialised anyway). If we use low-side current sensing at the same time, the adc sync requiresTRGO_UPDATE
(cannot triggerTRGO_UPDATE
andTRGO_ENABLE
at the same time) event and there, I've given the priority to the ADC code to find the timer which can trigger theTRGO_UPDATE
. Once the timer and the ADC are configured for current sensing the timer synchronization is attempted by finding the timer between the other ones (the ones not used for sync with the ADC) which can be the master and the others are configured to be the slaves.This code now allows to have the trully synced software 6pwm and use it properly with low-side current sensing.
I've just tested the code for hardware 6pwm (even with low-side current sensing) on f4, g4 and f1 boards. It seems to work as expected. 😄
Some potential "wild-west" use-cases