Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32 HAL-only PWM driver #430

Draft
wants to merge 14 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/current_sense/hardware_specific/stm32/b_g431/b_g431_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void* _configureADCLowSide(const void* driver_params, const int pinA,const int p
Stm32CurrentSenseParams* params = new Stm32CurrentSenseParams {
.pins = { pinA, pinB, pinC },
.adc_voltage_conv = (_ADC_VOLTAGE) / (_ADC_RESOLUTION),
.timer_handle = (HardwareTimer *)(HardwareTimer_Handle[get_timer_index(TIM1)]->__this)
.timer_handle = ((STM32DriverParams*)driver_params)->timers_handle[0],
};

return params;
Expand All @@ -153,21 +153,21 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
Stm32CurrentSenseParams* cs_params = (Stm32CurrentSenseParams*)_cs_params;

// 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.
// 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;
}
// 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);

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

// return the cs parameters
// successfully initialized
Expand Down
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
24 changes: 12 additions & 12 deletions src/current_sense/hardware_specific/stm32/stm32f1/stm32f1_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@

// timer to injected TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/e156c32db24d69cb4818208ccc28894e2f427cfa/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h#L215
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 @@ -28,11 +28,11 @@ uint32_t _timerToInjectedTRGO(HardwareTimer* timer){

// timer to regular TRGO
// https://github.com/stm32duino/Arduino_Core_STM32/blob/e156c32db24d69cb4818208ccc28894e2f427cfa/system/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h#L215
uint32_t _timerToRegularTRGO(HardwareTimer* timer){
if(timer->getHandle()->Instance == TIM3)
uint32_t _timerToRegularTRGO(TIM_HandleTypeDef* timer){
if(timer->Instance == TIM3)
return ADC_EXTERNALTRIGCONV_T3_TRGO;
#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 Expand Up @@ -82,16 +82,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 @@ -105,7 +105,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

// first channel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,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 @@ -79,7 +79,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);
Expand All @@ -96,7 +96,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 @@ -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 @@ -77,8 +77,8 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
// automating TRGO flag finding - hardware specific
uint8_t tim_num = 0;
for (size_t i=0; i<6; i++) {
HardwareTimer *timer_to_check = driver_params->timers[tim_num++];
TIM_TypeDef *instance_to_check = timer_to_check->getHandle()->Instance;
TIM_HandleTypeDef *timer_to_check = driver_params->timers_handle[tim_num++];
TIM_TypeDef *instance_to_check = timer_to_check->Instance;

// bool TRGO_already_configured = instance_to_check->CR2 & LL_TIM_TRGO_UPDATE;
// if(TRGO_already_configured) continue;
Expand Down Expand Up @@ -110,7 +110,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 @@ -42,23 +42,23 @@ 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;
}
// 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
#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
Expand All @@ -68,7 +68,7 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
#endif

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

// return the cs parameters
// successfully initialized
Expand Down
Loading
Loading