Skip to content

Feat current sense check if TRGO set for STM32 #456

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

Merged
merged 2 commits into from
Mar 12, 2025
Merged
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
2 changes: 2 additions & 0 deletions src/current_sense/hardware_specific/stm32/stm32_mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#define STM32_CURRENTSENSE_MCU_DEF
#include "../../hardware_api.h"
#include "../../../common/foc_utils.h"
#include "../../../drivers/hardware_specific/stm32/stm32_mcu.h"
#include "../../../drivers/hardware_specific/stm32/stm32_timerutils.h"

#if defined(_STM32_DEF_)

Expand Down
64 changes: 46 additions & 18 deletions src/current_sense/hardware_specific/stm32/stm32f1/stm32f1_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ uint32_t _timerToRegularTRGO(TIM_HandleTypeDef* timer){

ADC_HandleTypeDef hadc;

/**
* Function initializing the ADC and the injected channels for the low-side current sensing
*
* @param cs_params - current sense parameters
* @param driver_params - driver parameters
*
* @return int - 0 if success
*/
int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params)
{
ADC_InjectionConfTypeDef sConfigInjected;
Expand Down Expand Up @@ -86,6 +94,13 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
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

// check if TRGO used already - if yes use the next timer
if((driver_params->timers_handle[tim_num-1]->Instance->CR2 & LL_TIM_TRGO_ENABLE) || // if used for timer sync
(driver_params->timers_handle[tim_num-1]->Instance->CR2 & LL_TIM_TRGO_UPDATE)) // if used for ADC sync
{
continue;
}

// if the code comes here, it has found the timer available
// timer does have trgo flag for injected channels
sConfigInjected.ExternalTrigInjecConv = trigger_flag;
Expand All @@ -101,12 +116,11 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot sync any timer to injected channels!");
#endif
return -1;
}
// display which timer is being used
}else{
#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->Instance) + 1);
SIMPLEFOC_DEBUG("STM32-CS: Using timer: ", stm32_getTimerNumber(cs_params->timer_handle->Instance));
#endif
}

// first channel
sConfigInjected.InjectedRank = ADC_REGULAR_RANK_1;
Expand All @@ -129,24 +143,38 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
return 0;
}

void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
/**
* Function to initialize the ADC GPIO pins
*
* @param cs_params current sense parameters
* @param pinA pin number for phase A
* @param pinB pin number for phase B
* @param pinC pin number for phase C
* @return int 0 if success, -1 if error
*/
int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
{
uint8_t cnt = 0;
if(_isset(pinA)){
pinmap_pinout(analogInputToPinName(pinA), PinMap_ADC);
cs_params->pins[cnt++] = pinA;
}
if(_isset(pinB)){
pinmap_pinout(analogInputToPinName(pinB), PinMap_ADC);
cs_params->pins[cnt++] = pinB;
}
if(_isset(pinC)){
pinmap_pinout(analogInputToPinName(pinC), PinMap_ADC);
cs_params->pins[cnt] = pinC;
int pins[3] = {pinA, pinB, pinC};
const char* port_names[3] = {"A", "B", "C"};
for(int i=0; i<3; i++){
if(_isset(pins[i])){
// check if pin is an analog pin
if(pinmap_peripheral(analogInputToPinName(pins[i]), PinMap_ADC) == NP){
#ifdef SIMPLEFOC_STM32_DEBUG
SimpleFOCDebug::print("STM32-CS: ERR: Pin ");
SimpleFOCDebug::print(port_names[i]);
SimpleFOCDebug::println(" does not belong to any ADC!");
#endif
return -1;
}
pinmap_pinout(analogInputToPinName(pins[i]), PinMap_ADC);
cs_params->pins[i] = pins[i];
}
}

return 0;
}


extern "C" {
void ADC1_2_IRQHandler(void)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@

#if defined(STM32F1xx)
#include "stm32f1xx_hal.h"
#include "../../../../common/foc_utils.h"
#include "../../../../drivers/hardware_specific/stm32/stm32_mcu.h"
#include "../stm32_mcu.h"

int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params);
void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC);
int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC);

#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void* _configureADCLowSide(const void* driver_params, const int pinA, const int
.pins={(int)NOT_SET,(int)NOT_SET,(int)NOT_SET},
.adc_voltage_conv = (_ADC_VOLTAGE_F1) / (_ADC_RESOLUTION_F1)
};
_adc_gpio_init(cs_params, pinA,pinB,pinC);
if(_adc_gpio_init(cs_params, pinA,pinB,pinC) != 0) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
if(_adc_init(cs_params, (STM32DriverParams*)driver_params) != 0) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
return cs_params;
}
Expand Down
64 changes: 46 additions & 18 deletions src/current_sense/hardware_specific/stm32/stm32f4/stm32f4_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

ADC_HandleTypeDef hadc;

/**
* Function initializing the ADC and the injected channels for the low-side current sensing
*
* @param cs_params - current sense parameters
* @param driver_params - driver parameters
*
* @return int - 0 if success
*/
int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params)
{
ADC_InjectionConfTypeDef sConfigInjected;
Expand Down Expand Up @@ -80,6 +88,13 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
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

// check if TRGO used already - if yes use the next timer
if((driver_params->timers_handle[tim_num-1]->Instance->CR2 & LL_TIM_TRGO_ENABLE) || // if used for timer sync
(driver_params->timers_handle[tim_num-1]->Instance->CR2 & LL_TIM_TRGO_UPDATE)) // if used for ADC sync
{
continue;
}

// if the code comes here, it has found the timer available
// timer does have trgo flag for injected channels
sConfigInjected.ExternalTrigInjecConv = trigger_flag;
Expand All @@ -95,12 +110,11 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot sync any timer to injected channels!");
#endif
return -1;
}else{
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: Using timer: ", stm32_getTimerNumber(cs_params->timer_handle->Instance));
#endif
}
// 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->Instance) + 1);
#endif


// first channel
Expand Down Expand Up @@ -139,21 +153,35 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
return 0;
}

void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
/**
* Function to initialize the ADC GPIO pins
*
* @param cs_params current sense parameters
* @param pinA pin number for phase A
* @param pinB pin number for phase B
* @param pinC pin number for phase C
* @return int 0 if success, -1 if error
*/
int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
{
uint8_t cnt = 0;
if(_isset(pinA)){
pinmap_pinout(analogInputToPinName(pinA), PinMap_ADC);
cs_params->pins[cnt++] = pinA;
}
if(_isset(pinB)){
pinmap_pinout(analogInputToPinName(pinB), PinMap_ADC);
cs_params->pins[cnt++] = pinB;
}
if(_isset(pinC)){
pinmap_pinout(analogInputToPinName(pinC), PinMap_ADC);
cs_params->pins[cnt] = pinC;
int pins[3] = {pinA, pinB, pinC};
const char* port_names[3] = {"A", "B", "C"};
for(int i=0; i<3; i++){
if(_isset(pins[i])){
// check if pin is an analog pin
if(pinmap_peripheral(analogInputToPinName(pins[i]), PinMap_ADC) == NP){
#ifdef SIMPLEFOC_STM32_DEBUG
SimpleFOCDebug::print("STM32-CS: ERR: Pin ");
SimpleFOCDebug::print(port_names[i]);
SimpleFOCDebug::println(" does not belong to any ADC!");
#endif
return -1;
}
pinmap_pinout(analogInputToPinName(pins[i]), PinMap_ADC);
cs_params->pins[i] = pins[i];
}
}
return 0;
}

extern "C" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@

#if defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#include "../../../../common/foc_utils.h"
#include "../../../../drivers/hardware_specific/stm32/stm32_mcu.h"
#include "../stm32_mcu.h"
#include "stm32f4_utils.h"

int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params);
void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC);
int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC);

#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void* _configureADCLowSide(const void* driver_params, const int pinA, const int
.pins={(int)NOT_SET,(int)NOT_SET,(int)NOT_SET},
.adc_voltage_conv = (_ADC_VOLTAGE_F4) / (_ADC_RESOLUTION_F4)
};
_adc_gpio_init(cs_params, pinA,pinB,pinC);
if(_adc_gpio_init(cs_params, pinA,pinB,pinC) != 0) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
if(_adc_init(cs_params, (STM32DriverParams*)driver_params) != 0) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
return cs_params;
}
Expand Down
68 changes: 47 additions & 21 deletions src/current_sense/hardware_specific/stm32/stm32f7/stm32f7_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

ADC_HandleTypeDef hadc;

/**
* Function initializing the ADC and the injected channels for the low-side current sensing
*
* @param cs_params - current sense parameters
* @param driver_params - driver parameters
*
* @return int - 0 if success
*/
int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params)
{
ADC_InjectionConfTypeDef sConfigInjected;
Expand Down Expand Up @@ -80,12 +88,16 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
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;

uint32_t trigger_flag = _timerToInjectedTRGO(timer_to_check);
if(trigger_flag == _TRGO_NOT_AVAILABLE) continue; // timer does not have valid trgo for injected channels

// check if TRGO used already - if yes use the next timer
if((timer_to_check->Instance->CR2 & LL_TIM_TRGO_ENABLE) || // if used for timer sync
(timer_to_check->Instance->CR2 & LL_TIM_TRGO_UPDATE)) // if used for ADC sync
{
continue;
}

// if the code comes here, it has found the timer available
// timer does have trgo flag for injected channels
sConfigInjected.ExternalTrigInjecConv = trigger_flag;
Expand All @@ -106,12 +118,11 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot sync any timer to injected channels!");
#endif
return -1;
}else{
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: Using timer: ", stm32_getTimerNumber(cs_params->timer_handle->Instance));
#endif
}
// 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->Instance) + 1);
#endif


// first channel
Expand Down Expand Up @@ -156,21 +167,36 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
return 0;
}

void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)

/**
* Function to initialize the ADC GPIO pins
*
* @param cs_params current sense parameters
* @param pinA pin number for phase A
* @param pinB pin number for phase B
* @param pinC pin number for phase C
* @return int 0 if success, -1 if error
*/
int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
{
uint8_t cnt = 0;
if(_isset(pinA)){
pinmap_pinout(analogInputToPinName(pinA), PinMap_ADC);
cs_params->pins[cnt++] = pinA;
}
if(_isset(pinB)){
pinmap_pinout(analogInputToPinName(pinB), PinMap_ADC);
cs_params->pins[cnt++] = pinB;
}
if(_isset(pinC)){
pinmap_pinout(analogInputToPinName(pinC), PinMap_ADC);
cs_params->pins[cnt] = pinC;
int pins[3] = {pinA, pinB, pinC};
const char* port_names[3] = {"A", "B", "C"};
for(int i=0; i<3; i++){
if(_isset(pins[i])){
// check if pin is an analog pin
if(pinmap_peripheral(analogInputToPinName(pins[i]), PinMap_ADC) == NP){
#ifdef SIMPLEFOC_STM32_DEBUG
SimpleFOCDebug::print("STM32-CS: ERR: Pin ");
SimpleFOCDebug::print(port_names[i]);
SimpleFOCDebug::println(" does not belong to any ADC!");
#endif
return -1;
}
pinmap_pinout(analogInputToPinName(pins[i]), PinMap_ADC);
cs_params->pins[i] = pins[i];
}
}
return 0;
}

#ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@

#if defined(STM32F7xx)
#include "stm32f7xx_hal.h"
#include "../../../../common/foc_utils.h"
#include "../../../../drivers/hardware_specific/stm32/stm32_mcu.h"
#include "../stm32_mcu.h"
#include "stm32f7_utils.h"

int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params);
void _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC);
int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC);

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void* _configureADCLowSide(const void* driver_params, const int pinA, const int
.pins={(int)NOT_SET,(int)NOT_SET,(int)NOT_SET},
.adc_voltage_conv = (_ADC_VOLTAGE) / (_ADC_RESOLUTION)
};
_adc_gpio_init(cs_params, pinA,pinB,pinC);
if(_adc_gpio_init(cs_params, pinA,pinB,pinC) != 0) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
if(_adc_init(cs_params, (STM32DriverParams*)driver_params) != 0) return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
return cs_params;
}
Expand Down
Loading