Skip to content

Commit

Permalink
HAL / LL only PWM driver
Browse files Browse the repository at this point in the history
  • Loading branch information
runger1101001 committed Aug 24, 2024
1 parent 4395c22 commit 1d1c5dd
Show file tree
Hide file tree
Showing 18 changed files with 1,650 additions and 929 deletions.
2 changes: 1 addition & 1 deletion src/current_sense/hardware_specific/stm32/stm32_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ typedef struct Stm32CurrentSenseParams {
int pins[3] = {(int)NOT_SET};
float adc_voltage_conv;
ADC_HandleTypeDef* adc_handle = NP;
HardwareTimer* timer_handle = NP;
TIM_HandleTypeDef* timer_handle = NP;
} Stm32CurrentSenseParams;

#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive

// automating TRGO flag finding - hardware specific
uint8_t tim_num = 0;
while(driver_params->timers[tim_num] != NP && tim_num < 6){
uint32_t trigger_flag = _timerToInjectedTRGO(driver_params->timers[tim_num++]);
while(driver_params->timers_handle[tim_num] != NP && tim_num < 6){
uint32_t trigger_flag = _timerToInjectedTRGO(driver_params->timers_handle[tim_num++]);
if(trigger_flag == _TRGO_NOT_AVAILABLE) continue; // timer does not have valid trgo for injected channels

// if the code comes here, it has found the timer available
// timer does have trgo flag for injected channels
sConfigInjected.ExternalTrigInjecConv = trigger_flag;

// this will be the timer with which the ADC will sync
cs_params->timer_handle = driver_params->timers[tim_num-1];
cs_params->timer_handle = driver_params->timers_handle[tim_num-1];
// done
break;
}
Expand All @@ -99,7 +99,7 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
// display which timer is being used
#ifdef SIMPLEFOC_STM32_DEBUG
// it would be better to use the getTimerNumber from driver
SIMPLEFOC_DEBUG("STM32-CS: injected trigger for timer index: ", get_timer_index(cs_params->timer_handle->getHandle()->Instance) + 1);
SIMPLEFOC_DEBUG("STM32-CS: injected trigger for timer index: ", get_timer_index(cs_params->timer_handle->Instance) + 1);
#endif


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
if (cs_params->timer_handle == NULL) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;

// stop all the timers for the driver
_stopTimers(driver_params->timers, 6);
stm32_pause(driver_params);

// if timer has repetition counter - it will downsample using it
// and it does not need the software downsample
if( IS_TIM_REPETITION_COUNTER_INSTANCE(cs_params->timer_handle->getHandle()->Instance) ){
if( IS_TIM_REPETITION_COUNTER_INSTANCE(cs_params->timer_handle->Instance) ){
// adjust the initial timer state such that the trigger
// - for DMA transfer aligns with the pwm peaks instead of throughs.
// - for interrupt based ADC transfer
// - only necessary for the timers that have repetition counters
cs_params->timer_handle->getHandle()->Instance->CR1 |= TIM_CR1_DIR;
cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR;
cs_params->timer_handle->Instance->CR1 |= TIM_CR1_DIR;
cs_params->timer_handle->Instance->CNT = cs_params->timer_handle->Instance->ARR;
// remember that this timer has repetition counter - no need to downasmple
needs_downsample[_adcToIndex(cs_params->adc_handle)] = 0;
}else{
Expand All @@ -71,7 +71,7 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
}
}
// set the trigger output event
LL_TIM_SetTriggerOutput(cs_params->timer_handle->getHandle()->Instance, LL_TIM_TRGO_UPDATE);
LL_TIM_SetTriggerOutput(cs_params->timer_handle->Instance, LL_TIM_TRGO_UPDATE);

// start the adc
if (use_adc_interrupt){
Expand All @@ -85,7 +85,7 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
}

// restart all the timers of the driver
_startTimers(driver_params->timers, 6);
stm32_resume(driver_params);

// return the cs parameters
// successfully initialized
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,19 @@ uint32_t _getADCChannel(PinName pin)

// timer to injected TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/e156c32db24d69cb4818208ccc28894e2f427cfa/system/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h#L179
uint32_t _timerToInjectedTRGO(HardwareTimer* timer){
if(timer->getHandle()->Instance == TIM1)
uint32_t _timerToInjectedTRGO(TIM_HandleTypeDef* timer){
if(timer->Instance == TIM1)
return ADC_EXTERNALTRIGINJECCONV_T1_TRGO;
#ifdef TIM2 // if defined timer 2
else if(timer->getHandle()->Instance == TIM2)
else if(timer->Instance == TIM2)
return ADC_EXTERNALTRIGINJECCONV_T2_TRGO;
#endif
#ifdef TIM4 // if defined timer 4
else if(timer->getHandle()->Instance == TIM4)
else if(timer->Instance == TIM4)
return ADC_EXTERNALTRIGINJECCONV_T4_TRGO;
#endif
#ifdef TIM5 // if defined timer 5
else if(timer->getHandle()->Instance == TIM5)
else if(timer->Instance == TIM5)
return ADC_EXTERNALTRIGINJECCONV_T5_TRGO;
#endif
else
Expand All @@ -154,15 +154,15 @@ uint32_t _timerToInjectedTRGO(HardwareTimer* timer){

// timer to regular TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/e156c32db24d69cb4818208ccc28894e2f427cfa/system/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h#L331
uint32_t _timerToRegularTRGO(HardwareTimer* timer){
if(timer->getHandle()->Instance == TIM2)
uint32_t _timerToRegularTRGO(TIM_HandleTypeDef* timer){
if(timer->Instance == TIM2)
return ADC_EXTERNALTRIGCONV_T2_TRGO;
#ifdef TIM3 // if defined timer 3
else if(timer->getHandle()->Instance == TIM3)
else if(timer->Instance == TIM3)
return ADC_EXTERNALTRIGCONV_T3_TRGO;
#endif
#ifdef TIM8 // if defined timer 8
else if(timer->getHandle()->Instance == TIM8)
else if(timer->Instance == TIM8)
return ADC_EXTERNALTRIGCONV_T8_TRGO;
#endif
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ uint32_t _getADCChannel(PinName pin);

// timer to injected TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/e156c32db24d69cb4818208ccc28894e2f427cfa/system/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc_ex.h#L179
uint32_t _timerToInjectedTRGO(HardwareTimer* timer);
uint32_t _timerToInjectedTRGO(TIM_HandleTypeDef* timer);

// timer to regular TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/e156c32db24d69cb4818208ccc28894e2f427cfa/system/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h#L331
uint32_t _timerToRegularTRGO(HardwareTimer* timer);
uint32_t _timerToRegularTRGO(TIM_HandleTypeDef* timer);

// function returning index of the ADC instance
int _adcToIndex(ADC_HandleTypeDef *AdcHandle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,16 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive

// automating TRGO flag finding - hardware specific
uint8_t tim_num = 0;
while(driver_params->timers[tim_num] != NP && tim_num < 6){
uint32_t trigger_flag = _timerToInjectedTRGO(driver_params->timers[tim_num++]);
while(driver_params->timers_handle[tim_num] != NP && tim_num < 6){
uint32_t trigger_flag = _timerToInjectedTRGO(driver_params->timers_handle[tim_num++]);
if(trigger_flag == _TRGO_NOT_AVAILABLE) continue; // timer does not have valid trgo for injected channels

// if the code comes here, it has found the timer available
// timer does have trgo flag for injected channels
sConfigInjected.ExternalTrigInjecConv = trigger_flag;

// this will be the timer with which the ADC will sync
cs_params->timer_handle = driver_params->timers[tim_num-1];
cs_params->timer_handle = driver_params->timers_handle[tim_num-1];
// done
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
if (cs_params->timer_handle == NULL) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;

// stop all the timers for the driver
_stopTimers(driver_params->timers, 6);
stm32_pause(driver_params);

// if timer has repetition counter - it will downsample using it
// and it does not need the software downsample
if( IS_TIM_REPETITION_COUNTER_INSTANCE(cs_params->timer_handle->getHandle()->Instance) ){
if( IS_TIM_REPETITION_COUNTER_INSTANCE(cs_params->timer_handle->Instance) ){
// adjust the initial timer state such that the trigger
// - for DMA transfer aligns with the pwm peaks instead of throughs.
// - for interrupt based ADC transfer
// - only necessary for the timers that have repetition counters
cs_params->timer_handle->getHandle()->Instance->CR1 |= TIM_CR1_DIR;
cs_params->timer_handle->getHandle()->Instance->CNT = cs_params->timer_handle->getHandle()->Instance->ARR;
cs_params->timer_handle->Instance->CR1 |= TIM_CR1_DIR;
cs_params->timer_handle->Instance->CNT = cs_params->timer_handle->Instance->ARR;
// remember that this timer has repetition counter - no need to downasmple
needs_downsample[_adcToIndex(cs_params->adc_handle)] = 0;
}else{
Expand All @@ -74,7 +74,7 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
}

// set the trigger output event
LL_TIM_SetTriggerOutput(cs_params->timer_handle->getHandle()->Instance, LL_TIM_TRGO_UPDATE);
LL_TIM_SetTriggerOutput(cs_params->timer_handle->Instance, LL_TIM_TRGO_UPDATE);

// Start the adc calibration
HAL_ADCEx_Calibration_Start(cs_params->adc_handle,ADC_SINGLE_ENDED);
Expand Down Expand Up @@ -122,7 +122,7 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
}

// restart all the timers of the driver
_startTimers(driver_params->timers, 6);
stm32_resume(driver_params);

// return the cs parameters
// successfully initialized
Expand Down
40 changes: 20 additions & 20 deletions src/current_sense/hardware_specific/stm32/stm32g4/stm32g4_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,39 +133,39 @@ uint32_t _getADCChannel(PinName pin)

// timer to injected TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/6588dee03382e73ed42c4a5e473900ab3b79d6e4/system/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_adc_ex.h#L217
uint32_t _timerToInjectedTRGO(HardwareTimer* timer){
if(timer->getHandle()->Instance == TIM1)
uint32_t _timerToInjectedTRGO(TIM_HandleTypeDef* timer){
if(timer->Instance == TIM1)
return ADC_EXTERNALTRIGINJEC_T1_TRGO;
#ifdef TIM2 // if defined timer 2
else if(timer->getHandle()->Instance == TIM2)
else if(timer->Instance == TIM2)
return ADC_EXTERNALTRIGINJEC_T2_TRGO;
#endif
#ifdef TIM3 // if defined timer 3
else if(timer->getHandle()->Instance == TIM3)
else if(timer->Instance == TIM3)
return ADC_EXTERNALTRIGINJEC_T3_TRGO;
#endif
#ifdef TIM4 // if defined timer 4
else if(timer->getHandle()->Instance == TIM4)
else if(timer->Instance == TIM4)
return ADC_EXTERNALTRIGINJEC_T4_TRGO;
#endif
#ifdef TIM6 // if defined timer 6
else if(timer->getHandle()->Instance == TIM6)
else if(timer->Instance == TIM6)
return ADC_EXTERNALTRIGINJEC_T6_TRGO;
#endif
#ifdef TIM7 // if defined timer 7
else if(timer->getHandle()->Instance == TIM7)
else if(timer->Instance == TIM7)
return ADC_EXTERNALTRIGINJEC_T7_TRGO;
#endif
#ifdef TIM8 // if defined timer 8
else if(timer->getHandle()->Instance == TIM8)
else if(timer->Instance == TIM8)
return ADC_EXTERNALTRIGINJEC_T8_TRGO;
#endif
#ifdef TIM15 // if defined timer 15
else if(timer->getHandle()->Instance == TIM15)
else if(timer->Instance == TIM15)
return ADC_EXTERNALTRIGINJEC_T15_TRGO;
#endif
#ifdef TIM20 // if defined timer 15
else if(timer->getHandle()->Instance == TIM20)
else if(timer->Instance == TIM20)
return ADC_EXTERNALTRIGINJEC_T20_TRGO;
#endif
else
Expand All @@ -174,39 +174,39 @@ uint32_t _timerToInjectedTRGO(HardwareTimer* timer){

// timer to regular TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/6588dee03382e73ed42c4a5e473900ab3b79d6e4/system/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_adc.h#L519
uint32_t _timerToRegularTRGO(HardwareTimer* timer){
if(timer->getHandle()->Instance == TIM1)
uint32_t _timerToRegularTRGO(TIM_HandleTypeDef* timer){
if(timer->Instance == TIM1)
return ADC_EXTERNALTRIG_T1_TRGO;
#ifdef TIM2 // if defined timer 2
else if(timer->getHandle()->Instance == TIM2)
else if(timer->Instance == TIM2)
return ADC_EXTERNALTRIG_T2_TRGO;
#endif
#ifdef TIM3 // if defined timer 3
else if(timer->getHandle()->Instance == TIM3)
else if(timer->Instance == TIM3)
return ADC_EXTERNALTRIG_T3_TRGO;
#endif
#ifdef TIM4 // if defined timer 4
else if(timer->getHandle()->Instance == TIM4)
else if(timer->Instance == TIM4)
return ADC_EXTERNALTRIG_T4_TRGO;
#endif
#ifdef TIM6 // if defined timer 6
else if(timer->getHandle()->Instance == TIM6)
else if(timer->Instance == TIM6)
return ADC_EXTERNALTRIG_T6_TRGO;
#endif
#ifdef TIM7 // if defined timer 7
else if(timer->getHandle()->Instance == TIM7)
else if(timer->Instance == TIM7)
return ADC_EXTERNALTRIG_T7_TRGO;
#endif
#ifdef TIM8 // if defined timer 8
else if(timer->getHandle()->Instance == TIM8)
else if(timer->Instance == TIM8)
return ADC_EXTERNALTRIG_T7_TRGO;
#endif
#ifdef TIM15 // if defined timer 15
else if(timer->getHandle()->Instance == TIM15)
else if(timer->Instance == TIM15)
return ADC_EXTERNALTRIG_T15_TRGO;
#endif
#ifdef TIM20 // if defined timer 15
else if(timer->getHandle()->Instance == TIM20)
else if(timer->Instance == TIM20)
return ADC_EXTERNALTRIG_T20_TRGO;
#endif
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ uint32_t _getADCChannel(PinName pin);

// timer to injected TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/6588dee03382e73ed42c4a5e473900ab3b79d6e4/system/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_adc_ex.h#L217
uint32_t _timerToInjectedTRGO(HardwareTimer* timer);
uint32_t _timerToInjectedTRGO(TIM_HandleTypeDef* timer);

// timer to regular TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/6588dee03382e73ed42c4a5e473900ab3b79d6e4/system/Drivers/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal_adc.h#L519
uint32_t _timerToRegularTRGO(HardwareTimer* timer);
uint32_t _timerToRegularTRGO(TIM_HandleTypeDef* timer);

// function returning index of the ADC instance
int _adcToIndex(ADC_HandleTypeDef *AdcHandle);
Expand Down
12 changes: 11 additions & 1 deletion src/drivers/hardware_specific/esp32/esp32_ledc_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ typedef struct ESP32LEDCDriverParams {
} ESP32LEDCDriverParams;



int esp32_gpio_nr(int pin) {
#if defined(BOARD_HAS_PIN_REMAP) && !defined(BOARD_USES_HW_GPIO_NUMBERS)
return digitalPinToGPIONumber(pin);
#else
return pin;
#endif
}


/*
Function to attach a channel to a pin with advanced settings
- freq - pwm frequency
Expand Down Expand Up @@ -96,7 +106,7 @@ bool _ledcAttachChannelAdvanced(uint8_t pin, int _channel, int _group, uint32_t
ledc_channel.channel = channel;
ledc_channel.timer_sel = LEDC_TIMER_0;
ledc_channel.intr_type = LEDC_INTR_DISABLE;
ledc_channel.gpio_num = pin;
ledc_channel.gpio_num = esp32_gpio_nr(pin);
ledc_channel.duty = duty;
ledc_channel.hpoint = 0;
ledc_channel.flags.output_invert = pin_high_level; // 0 is active high, 1 is active low
Expand Down
20 changes: 15 additions & 5 deletions src/drivers/hardware_specific/esp32/esp32_mcpwm_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
#pragma message("SimpleFOC: compiling for ESP32 MCPWM driver")
#pragma message("")


int esp32_gpio_nr(int pin) {
#if defined(BOARD_HAS_PIN_REMAP) && !defined(BOARD_USES_HW_GPIO_NUMBERS)
return digitalPinToGPIONumber(pin);
#else
return pin;
#endif
}


// function setting the high pwm frequency to the supplied pins
// - DC motor - 1PWM setting
// - hardware specific
Expand All @@ -20,7 +30,7 @@ void* _configure1PWM(long pwm_frequency, const int pinA) {
}
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 1PWM in group: "+String(group)+" on timer: "+String(timer));
// configure the timer
int pins[1] = {pinA};
int pins[1] = { esp32_gpio_nr(pinA) };
return _configurePinsMCPWM(pwm_frequency, group, timer, 1, pins);
}

Expand All @@ -42,7 +52,7 @@ void* _configure2PWM(long pwm_frequency, const int pinA, const int pinB) {
// configure the 2pwm on only one group
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 2PWM in group: "+String(group)+" on timer: "+String(timer));
// configure the timer
int pins[2] = {pinA, pinB};
int pins[2] = { esp32_gpio_nr(pinA), esp32_gpio_nr(pinB) };
return _configurePinsMCPWM(pwm_frequency, group, timer, 2, pins);
}else{
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 2PWM as two 1PWM drivers");
Expand Down Expand Up @@ -92,7 +102,7 @@ void* _configure3PWM(long pwm_frequency, const int pinA, const int pinB, const i
}
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 3PWM in group: "+String(group)+" on timer: "+String(timer));
// configure the timer
int pins[3] = {pinA, pinB, pinC};
int pins[3] = { esp32_gpio_nr(pinA), esp32_gpio_nr(pinB), esp32_gpio_nr(pinC) };
return _configurePinsMCPWM(pwm_frequency, group, timer, 3, pins);
}

Expand Down Expand Up @@ -122,7 +132,7 @@ void* _configure4PWM(long pwm_frequency,const int pinA, const int pinB, const in

// the code is a bit huge for what it does
// it just instantiates two 2PMW drivers and combines the returned params
int pins[2][2] = {{pinA, pinB},{pinC, pinD}};
int pins[2][2] = {{ esp32_gpio_nr(pinA), esp32_gpio_nr(pinB) },{ esp32_gpio_nr(pinC), esp32_gpio_nr(pinD) }};
for(int i =0; i<2; i++){
int timer = _findNextTimer(i); //find next available timer in group i
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 2PWM in group: "+String(i)+" on timer: "+String(timer));
Expand Down Expand Up @@ -162,7 +172,7 @@ void* _configure6PWM(long pwm_frequency, float dead_zone, const int pinA_h, cons
}
SIMPLEFOC_ESP32_DRV_DEBUG("Configuring 6PWM in group: "+String(group)+" on timer: "+String(timer));
// configure the timer
int pins[6] = {pinA_h,pinA_l, pinB_h, pinB_l, pinC_h, pinC_l};
int pins[6] = { esp32_gpio_nr(pinA_h), esp32_gpio_nr(pinA_l), esp32_gpio_nr(pinB_h), esp32_gpio_nr(pinB_l), esp32_gpio_nr(pinC_h), esp32_gpio_nr(pinC_l) };
return _configure6PWMPinsMCPWM(pwm_frequency, group, timer, dead_zone, pins);
}

Expand Down
Loading

0 comments on commit 1d1c5dd

Please sign in to comment.