Skip to content

Commit

Permalink
undate on the alignement logic
Browse files Browse the repository at this point in the history
  • Loading branch information
askuric committed Feb 1, 2024
1 parent 2d09173 commit 6aed780
Showing 1 changed file with 102 additions and 21 deletions.
123 changes: 102 additions & 21 deletions src/drivers/hardware_specific/stm32/stm32_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,30 +204,105 @@ void _stopTimers(HardwareTimer **timers_to_stop, int timer_num)
}


// function finds the appropriate timer source trigger for the master timer index provided
#if defined(STM32G4xx)
// function finds the appropriate timer source trigger for the master/slave timer combination
// returns -1 if no trigger source is found
// currently supports the master timers to be from TIM1 to TIM4 and TIM8
int _getTriggerSourceRegister(HardwareTimer* timer) {
int _getInternalSourceTrigger(HardwareTimer* master, HardwareTimer* slave) { // put master and slave in temp variables to avoid arrows
TIM_TypeDef *TIM_master = master->getHandle()->Instance;
#if defined(TIM1) && defined(LL_TIM_TS_ITR0)
if (timer->getHandle()->Instance == TIM1) return LL_TIM_TS_ITR0;// return TIM_TS_ITR0;
if (TIM_master == TIM1) return LL_TIM_TS_ITR0;// return TIM_TS_ITR0;
#endif
#if defined(TIM2) && defined(LL_TIM_TS_ITR1)
if (timer->getHandle()->Instance == TIM2) return LL_TIM_TS_ITR1;//return TIM_TS_ITR1;
else if (TIM_master == TIM2) return LL_TIM_TS_ITR1;//return TIM_TS_ITR1;
#endif
#if defined(TIM3) && defined(LL_TIM_TS_ITR2)
if (timer->getHandle()->Instance == TIM3) return LL_TIM_TS_ITR2;//return TIM_TS_ITR2;
else if (TIM_master == TIM3) return LL_TIM_TS_ITR2;//return TIM_TS_ITR2;
#endif
#if defined(TIM4) && defined(LL_TIM_TS_ITR3)
if (timer->getHandle()->Instance == TIM4) return LL_TIM_TS_ITR3;//return TIM_TS_ITR3;
else if (TIM_master == TIM4) return LL_TIM_TS_ITR3;//return TIM_TS_ITR3;
#endif
#if defined(TIM5) && defined(LL_TIM_TS_ITR4)
if (timer->getHandle()->Instance == TIM5) return LL_TIM_TS_ITR4;//return TIM_TS_ITR4;
else if (TIM_master == TIM5) return LL_TIM_TS_ITR4;//return TIM_TS_ITR4;
#endif
#if defined(TIM8) && defined(LL_TIM_TS_ITR5)
if (timer->getHandle()->Instance == TIM8) return LL_TIM_TS_ITR5;//return TIM_TS_ITR5;
else if (TIM_master == TIM8) return LL_TIM_TS_ITR5;//return TIM_TS_ITR5;
#endif
return -1;
}
#elif defined(STM32F4xx) || defined(STM32F1xx) || defined(STM32L4xx)

// function finds the appropriate timer source trigger for the master/slave timer combination
// returns -1 if no trigger source is found
// currently supports the master timers to be from TIM1 to TIM4 and TIM8
int _getTriggerSourceRegister(HardwareTimer* master, HardwareTimer* slave) {
// put master and slave in temp variables to avoid arrows
TIM_TypeDef *TIM_master = master->getHandle()->Instance;
TIM_TypeDef *TIM_slave = slave->getHandle()->Instance;
#if defined(TIM1) && defined(LL_TIM_TS_ITR0)
if (TIM_master == TIM1){
if(TIM_slave == TIM2 || TIM_slave == TIM3 || TIM_slave == TIM4) return LL_TIM_TS_ITR0;
#if defined(TIM8)
else if(TIM_slave == TIM8) return LL_TIM_TS_ITR0;
#endif
}
#endif
#if defined(TIM2) && defined(LL_TIM_TS_ITR1)
else if (TIM_master == TIM2){
if(TIM_slave == TIM1 || TIM_slave == TIM3 || TIM_slave == TIM4) return LL_TIM_TS_ITR1;
#if defined(TIM8)
else if(TIM_slave == TIM8) return LL_TIM_TS_ITR1;
#endif
#if defined(TIM5)
else if(TIM_slave == TIM5) return LL_TIM_TS_ITR0;
#endif
}
#endif
#if defined(TIM3) && defined(LL_TIM_TS_ITR2)
else if (TIM_master == TIM3){
if(TIM_slave== TIM1 || TIM_slave == TIM2 || TIM_slave == TIM4) return LL_TIM_TS_ITR2;
#if defined(TIM5)
else if(TIM_slave == TIM5) return LL_TIM_TS_ITR1;
#endif
}
#endif
#if defined(TIM4) && defined(LL_TIM_TS_ITR3)
else if (TIM_master == TIM4){
if(TIM_slave == TIM1 || TIM_slave == TIM2 || TIM_slave == TIM3) return LL_TIM_TS_ITR3;
#if defined(TIM8)
else if(TIM_slave == TIM8) return LL_TIM_TS_ITR2;
#endif
#if defined(TIM5)
else if(TIM_slave == TIM5) return LL_TIM_TS_ITR1;
#endif
}
#endif
#if defined(TIM5)
else if (TIM_master == TIM5){
#if !defined(STM32L4xx) // only difference between F4,F1 and L4
if(TIM_slave == TIM1) return LL_TIM_TS_ITR0;
else if(TIM_slave == TIM3) return LL_TIM_TS_ITR2;
#endif
#if defined(TIM8)
if(TIM_slave == TIM8) return LL_TIM_TS_ITR3;
#endif
}
#endif
#if defined(TIM8)
else if (TIM_master == TIM8){
if(TIM_slave==TIM2) return LL_TIM_TS_ITR1;
else if(TIM_slave ==TIM4 || TIM_slave ==TIM5) return LL_TIM_TS_ITR3;
}
#endif
return -1; // combination not supported
}
#else
// Alignment not supported for this architecture
int _getTriggerSourceRegister(HardwareTimer* master, HardwareTimer* slave) {
return -1;
}
#endif


void _alignTimersNew() {
int numTimers = 0;
Expand Down Expand Up @@ -256,44 +331,50 @@ void _alignTimersNew() {
// if yes, try to align timers
if(numTimers > 1){
// find the master timer
uint8_t masterTimerIndex = 0;
int16_t master_index = -1;
int triggerEvent = -1;
for (int i=0; i<numTimers; i++) {
// check if timer can be master
if(IS_TIM_MASTER_INSTANCE(timers[i]->getHandle()->Instance)) {
// check if timer already configured in TRGO update mode (used for ADC triggering)
// in that case we should not change its TRGO configuration
if(timers[i]->getHandle()->Instance->CR2 & LL_TIM_TRGO_UPDATE) continue;
// check if it has the supported internal trigger
triggerEvent = _getTriggerSourceRegister(timers[i]);
if(triggerEvent == -1) continue; // not supported keep searching
masterTimerIndex = i; // found the master timer
// check if the timer has the supported internal trigger for other timers
for (int slave_i=0; slave_i<numTimers; slave_i++) {
if (i==slave_i) continue; // skip self
// check if it has the supported internal trigger
triggerEvent = _getTriggerSourceRegister(timers[i],timers[slave_i]);
if(triggerEvent == -1) break; // not supported keep searching
}
if(triggerEvent == -1) continue; // cannot be master, keep searching
// otherwise the master has been found, remember the index
master_index = i; // found the master timer
break;
}
}


// if no master timer found do not perform alignment
if (triggerEvent == -1) {
if (master_index == -1) {
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-DRV: ERR: No master timer found, cannot align timers!");
#endif
}else{
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-DRV: Aligning PWM to master timer: ", getTimerNumber(get_timer_index(timers[masterTimerIndex]->getHandle()->Instance)));
SIMPLEFOC_DEBUG("STM32-DRV: Aligning PWM to master timer: ", getTimerNumber(get_timer_index(timers[master_index]->getHandle()->Instance)));
#endif
// make the master timer generate ITRGx event
// if it was already configured in slave mode
LL_TIM_SetSlaveMode(timers[masterTimerIndex]->getHandle()->Instance, LL_TIM_SLAVEMODE_DISABLED );
LL_TIM_SetSlaveMode(timers[master_index]->getHandle()->Instance, LL_TIM_SLAVEMODE_DISABLED );
// Configure the master timer to send a trigger signal on enable
LL_TIM_SetTriggerOutput(timers[masterTimerIndex]->getHandle()->Instance, LL_TIM_TRGO_ENABLE);
LL_TIM_SetTriggerOutput(timers[master_index]->getHandle()->Instance, LL_TIM_TRGO_ENABLE);
// configure other timers to get the input trigger from the master timer
for (int i=0; i<numTimers; i++) {
if (i==masterTimerIndex)
for (int slave_index=0; slave_index < numTimers; slave_index++) {
if (slave_index == master_index)
continue;
// Configure the slave timer to be triggered by the master enable signal
LL_TIM_SetTriggerInput(timers[i]->getHandle()->Instance, triggerEvent);
LL_TIM_SetSlaveMode(timers[i]->getHandle()->Instance, LL_TIM_SLAVEMODE_TRIGGER);
LL_TIM_SetTriggerInput(timers[slave_index]->getHandle()->Instance, _getTriggerSourceRegister(timers[master_index], timers[slave_index]));
LL_TIM_SetSlaveMode(timers[slave_index]->getHandle()->Instance, LL_TIM_SLAVEMODE_TRIGGER);
}
}
}
Expand Down

0 comments on commit 6aed780

Please sign in to comment.