simplefoc / Arduino-FOC

Arduino FOC for BLDC and Stepper motors - Arduino Based Field Oriented Control Algorithm Library
https://docs.simplefoc.com
MIT License
1.94k stars 510 forks source link

Feat stm32 synctimers #374

Closed askuric closed 4 months ago

askuric commented 5 months ago

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 emits TRGO_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 trigger TRGO_UPDATE and TRGO_ENABLE at the same time) event and there, I've given the priority to the ADC code to find the timer which can trigger the TRGO_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

Candas1 commented 5 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.

image

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

askuric commented 5 months ago

stm32g4

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

stm32f4

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

stm32f1

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

stm32l4

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

Remarks

askuric commented 4 months ago

Merging :D