Skip to content
Open
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
12 changes: 10 additions & 2 deletions src/current_sense/hardware_specific/stm32/stm32_adc_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ int _findIndexOfLastPinMapADCEntry(int pin) {
// each pin can be connected to multiple ADCs
// the function will try to find a single ADC that can be used for all pins
// if not possible it will return nullptr
ADC_TypeDef* _findBestADCForPins(int numPins, int pins[]) {
ADC_TypeDef* _findBestADCForPins(int numPins, int pins[], ADC_HandleTypeDef adc_handles[]) {

// assuning that there is less than 8 ADCs
// assuning that there is at most 5 ADCs
uint8_t pins_at_adc[ADC_COUNT] = {0};

// check how many pins are there and are not set
Expand Down Expand Up @@ -152,11 +152,19 @@ ADC_TypeDef* _findBestADCForPins(int numPins, int pins[]) {
SimpleFOCDebug::print(i+1);
SimpleFOCDebug::print(" pins: ");
SimpleFOCDebug::println(pins_at_adc[i]);
if (adc_handles[i].Instance != NP) {
SimpleFOCDebug::print("STM32-CS: ADC");
SimpleFOCDebug::print(i+1);
SimpleFOCDebug::println(" already in use!");
}
}
#endif

// now take the first ADC that has all pins connected
for (int i = 0; i < ADC_COUNT; i++) {
if (adc_handles[i].Instance != NP) {
continue; // ADC already in use
}
if (pins_at_adc[i] == no_pins) {
return _indexToADC(i);
}
Expand Down
4 changes: 1 addition & 3 deletions src/current_sense/hardware_specific/stm32/stm32_adc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
#include "../../../drivers/hardware_specific/stm32/stm32_mcu.h"
#include "stm32_mcu.h"



/* Exported Functions */
/**
* @brief Return ADC HAL channel linked to a PinName
Expand All @@ -43,7 +41,7 @@ int _adcToIndex(ADC_TypeDef *AdcHandle);
// functions helping to find the best ADC channel
int _findIndexOfFirstPinMapADCEntry(int pin);
int _findIndexOfLastPinMapADCEntry(int pin);
ADC_TypeDef* _findBestADCForPins(int num_pins, int pins[]);
ADC_TypeDef* _findBestADCForPins(int num_pins, int pins[], ADC_HandleTypeDef adc_handles[]);


// Structure to hold ADC interrupt configuration per ADC instance
Expand Down
2 changes: 1 addition & 1 deletion src/current_sense/hardware_specific/stm32/stm32_mcu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#define _ADC_RESOLUTION 1024.0f

// function reading an ADC value and returning the read voltage
void* _configureADCInline(const void* driver_params, const int pinA,const int pinB,const int pinC){
__attribute__((weak)) void* _configureADCInline(const void* driver_params, const int pinA,const int pinB,const int pinC){
_UNUSED(driver_params);

if( _isset(pinA) ) pinMode(pinA, INPUT);
Expand Down
48 changes: 30 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 @@ -4,9 +4,9 @@

#include "../../../../communication/SimpleFOCDebug.h"
#include "../stm32_adc_utils.h"
#define _TRGO_NOT_AVAILABLE 12345

ADC_HandleTypeDef hadc;
// pointer to the ADC handles used in the project
ADC_HandleTypeDef hadc[ADC_COUNT] = {0};

/**
* Function initializing the ADC and the injected channels for the low-side current sensing
Expand All @@ -22,14 +22,14 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive

/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = _findBestADCForPins(3, cs_params->pins);
auto adc_instance = _findBestADCForPins(3, cs_params->pins, hadc);

if(hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
#ifdef ADC2 // if defined ADC2
else if(hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
#endif
#ifdef ADC3 // if defined ADC3
else if(hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
#endif
else{
#ifdef SIMPLEFOC_STM32_DEBUG
Expand All @@ -38,13 +38,15 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
return -1; // error not a valid ADC instance
}

hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc);
auto adc_num = _adcToIndex(adc_instance);
hadc[adc_num].Instance = adc_instance;
hadc[adc_num].Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc[adc_num].Init.ContinuousConvMode = ENABLE;
hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc[adc_num].Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc[adc_num]);
/**Configure for the selected ADC regular channel to be converted.
*/

Expand Down Expand Up @@ -102,15 +104,15 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
if (!_isset(cs_params->pins[i])) continue;

sConfigInjected.InjectedRank = _getADCInjectedRank(channel_no++);
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc.Instance);
if (HAL_ADCEx_InjectedConfigChannel(&hadc, &sConfigInjected) != HAL_OK){
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc[adc_num].Instance);
if (HAL_ADCEx_InjectedConfigChannel(&hadc[adc_num], &sConfigInjected) != HAL_OK){
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc.Instance));
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc[adc_num].Instance));
#endif
return -1;
}
}
cs_params->adc_handle = &hadc;
cs_params->adc_handle = &hadc[adc_num];
return 0;
}

Expand Down Expand Up @@ -149,8 +151,18 @@ int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int
extern "C" {
void ADC1_2_IRQHandler(void)
{
HAL_ADC_IRQHandler(&hadc);
if (hadc[0].Instance != NP)
HAL_ADC_IRQHandler(&hadc[0]);
if (hadc[1].Instance != NP)
HAL_ADC_IRQHandler(&hadc[1]);
}
#ifdef ADC3
void ADC3_IRQHandler(void)
{
if (hadc[2].Instance != NP)
HAL_ADC_IRQHandler(&hadc[2]);
}
#endif
}

#endif
55 changes: 31 additions & 24 deletions src/current_sense/hardware_specific/stm32/stm32f4/stm32f4_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
//#define SIMPLEFOC_STM32_DEBUG

#include "../../../../communication/SimpleFOCDebug.h"
#define _TRGO_NOT_AVAILABLE 12345

ADC_HandleTypeDef hadc;
// pointer to the ADC handles used in the project
ADC_HandleTypeDef hadc[ADC_COUNT] = {0};

/**
* Function initializing the ADC and the injected channels for the low-side current sensing
Expand All @@ -23,14 +23,14 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive

/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = _findBestADCForPins(3, cs_params->pins);
auto adc_instance = _findBestADCForPins(3, cs_params->pins, hadc);

if(hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
#ifdef ADC2 // if defined ADC2
else if(hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
#endif
#ifdef ADC3 // if defined ADC3
else if(hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
#endif
else{
#ifdef SIMPLEFOC_STM32_DEBUG
Expand All @@ -39,22 +39,26 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
return -1; // error not a valid ADC instance
}

int adc_num = _adcToIndex(adc_instance);

#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: Using ADC: ", _adcToIndex(&hadc)+1);
SIMPLEFOC_DEBUG("STM32-CS: Using ADC: ", adc_num+1);
#endif

hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = ENABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = 1;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if ( HAL_ADC_Init(&hadc) != HAL_OK){
hadc[adc_num].Instance = adc_instance;

hadc[adc_num].Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc[adc_num].Init.Resolution = ADC_RESOLUTION_12B;
hadc[adc_num].Init.ScanConvMode = ENABLE;
hadc[adc_num].Init.ContinuousConvMode = ENABLE;
hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
hadc[adc_num].Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc[adc_num].Init.NbrOfConversion = 1;
hadc[adc_num].Init.DMAContinuousRequests = DISABLE;
hadc[adc_num].Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if ( HAL_ADC_Init(&hadc[adc_num]) != HAL_OK){
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init ADC!");
#endif
Expand Down Expand Up @@ -115,15 +119,15 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
if (!_isset(cs_params->pins[i])) continue;

sConfigInjected.InjectedRank = _getADCInjectedRank(channel_no++);
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc.Instance);
if (HAL_ADCEx_InjectedConfigChannel(&hadc, &sConfigInjected) != HAL_OK){
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc[adc_num].Instance);
if (HAL_ADCEx_InjectedConfigChannel(&hadc[adc_num], &sConfigInjected) != HAL_OK){
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc.Instance));
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc[adc_num].Instance));
#endif
return -1;
}
}
cs_params->adc_handle = &hadc;
cs_params->adc_handle = &hadc[adc_num];
return 0;
}

Expand Down Expand Up @@ -160,7 +164,10 @@ int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int
extern "C" {
void ADC_IRQHandler(void)
{
HAL_ADC_IRQHandler(&hadc);
for(int adc_num=0; adc_num<ADC_COUNT; adc_num++){
if(hadc[adc_num].Instance == NP) continue;
HAL_ADC_IRQHandler(&hadc[adc_num]);
}
}
}

Expand Down
54 changes: 30 additions & 24 deletions src/current_sense/hardware_specific/stm32/stm32f7/stm32f7_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
//#define SIMPLEFOC_STM32_DEBUG

#include "../../../../communication/SimpleFOCDebug.h"
#define _TRGO_NOT_AVAILABLE 12345

ADC_HandleTypeDef hadc;
// pointer to the ADC handles used in the project
ADC_HandleTypeDef hadc[ADC_COUNT] = {0};

/**
* Function initializing the ADC and the injected channels for the low-side current sensing
Expand All @@ -23,38 +23,41 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive

/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = _findBestADCForPins(3, cs_params->pins);
auto adc_instance = _findBestADCForPins(3, cs_params->pins, hadc);

if(hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
#ifdef ADC2 // if defined ADC2
else if(hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
#endif
#ifdef ADC3 // if defined ADC3
else if(hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
#endif
else{
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: ERR: Pin does not belong to any ADC!");
#endif
return -1; // error not a valid ADC instance
}

int adc_num = _adcToIndex(adc_instance);

#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: Using ADC: ", _adcToIndex(&hadc)+1);
SIMPLEFOC_DEBUG("STM32-CS: Using ADC: ", adc_num+1);
#endif

hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.ScanConvMode = ENABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.NbrOfConversion = 1;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if ( HAL_ADC_Init(&hadc) != HAL_OK){
hadc[adc_num].Instance = adc_instance;
hadc[adc_num].Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc[adc_num].Init.Resolution = ADC_RESOLUTION_12B;
hadc[adc_num].Init.ScanConvMode = ENABLE;
hadc[adc_num].Init.ContinuousConvMode = DISABLE;
hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
hadc[adc_num].Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc[adc_num].Init.NbrOfConversion = 1;
hadc[adc_num].Init.DMAContinuousRequests = DISABLE;
hadc[adc_num].Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if ( HAL_ADC_Init(&hadc[adc_num]) != HAL_OK){
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init ADC!");
#endif
Expand Down Expand Up @@ -123,16 +126,16 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
if (!_isset(cs_params->pins[i])) continue;

sConfigInjected.InjectedRank = _getADCInjectedRank(channel_no++);
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc.Instance);
if (HAL_ADCEx_InjectedConfigChannel(&hadc, &sConfigInjected) != HAL_OK){
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc[adc_num].Instance);
if (HAL_ADCEx_InjectedConfigChannel(&hadc[adc_num], &sConfigInjected) != HAL_OK){
#ifdef SIMPLEFOC_STM32_DEBUG
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc.Instance));
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc[adc_num].Instance));
#endif
return -1;
}
}

cs_params->adc_handle = &hadc;
cs_params->adc_handle = &hadc[adc_num];
return 0;
}

Expand Down Expand Up @@ -172,7 +175,10 @@ int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int
extern "C" {
void ADC_IRQHandler(void)
{
HAL_ADC_IRQHandler(&hadc);
for(int adc_num=0; adc_num<ADC_COUNT; adc_num++){
if(hadc[adc_num].Instance == NP) continue;
HAL_ADC_IRQHandler(&hadc[adc_num]);
}
}
}

Expand Down
Loading