Skip to content

Commit 9d0ecd1

Browse files
committed
initial support for multiple motors
1 parent e897329 commit 9d0ecd1

File tree

8 files changed

+228
-165
lines changed

8 files changed

+228
-165
lines changed

src/current_sense/hardware_specific/stm32/stm32_adc_utils.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,9 @@ int _findIndexOfLastPinMapADCEntry(int pin) {
115115
// each pin can be connected to multiple ADCs
116116
// the function will try to find a single ADC that can be used for all pins
117117
// if not possible it will return nullptr
118-
ADC_TypeDef* _findBestADCForPins(int numPins, int pins[]) {
118+
ADC_TypeDef* _findBestADCForPins(int numPins, int pins[], ADC_HandleTypeDef adc_handles[]) {
119119

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

123123
// check how many pins are there and are not set
@@ -152,11 +152,19 @@ ADC_TypeDef* _findBestADCForPins(int numPins, int pins[]) {
152152
SimpleFOCDebug::print(i+1);
153153
SimpleFOCDebug::print(" pins: ");
154154
SimpleFOCDebug::println(pins_at_adc[i]);
155+
if (adc_handles[i].Instance != NP) {
156+
SimpleFOCDebug::print("STM32-CS: ADC");
157+
SimpleFOCDebug::print(i+1);
158+
SimpleFOCDebug::println(" already in use!");
159+
}
155160
}
156161
#endif
157162

158163
// now take the first ADC that has all pins connected
159164
for (int i = 0; i < ADC_COUNT; i++) {
165+
if (adc_handles[i].Instance != NP) {
166+
continue; // ADC already in use
167+
}
160168
if (pins_at_adc[i] == no_pins) {
161169
return _indexToADC(i);
162170
}

src/current_sense/hardware_specific/stm32/stm32_adc_utils.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
#include "../../../drivers/hardware_specific/stm32/stm32_mcu.h"
1919
#include "stm32_mcu.h"
2020

21-
22-
2321
/* Exported Functions */
2422
/**
2523
* @brief Return ADC HAL channel linked to a PinName
@@ -43,7 +41,7 @@ int _adcToIndex(ADC_TypeDef *AdcHandle);
4341
// functions helping to find the best ADC channel
4442
int _findIndexOfFirstPinMapADCEntry(int pin);
4543
int _findIndexOfLastPinMapADCEntry(int pin);
46-
ADC_TypeDef* _findBestADCForPins(int num_pins, int pins[]);
44+
ADC_TypeDef* _findBestADCForPins(int num_pins, int pins[], ADC_HandleTypeDef adc_handles[]);
4745

4846

4947
// Structure to hold ADC interrupt configuration per ADC instance

src/current_sense/hardware_specific/stm32/stm32f1/stm32f1_hal.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
#include "../../../../communication/SimpleFOCDebug.h"
66
#include "../stm32_adc_utils.h"
7-
#define _TRGO_NOT_AVAILABLE 12345
87

9-
ADC_HandleTypeDef hadc;
8+
// pointer to the ADC handles used in the project
9+
ADC_HandleTypeDef hadc[ADC_COUNT] = {0};
1010

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

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

27-
if(hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
27+
if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
2828
#ifdef ADC2 // if defined ADC2
29-
else if(hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
29+
else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
3030
#endif
3131
#ifdef ADC3 // if defined ADC3
32-
else if(hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
32+
else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
3333
#endif
3434
else{
3535
#ifdef SIMPLEFOC_STM32_DEBUG
@@ -38,13 +38,15 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
3838
return -1; // error not a valid ADC instance
3939
}
4040

41-
hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;
42-
hadc.Init.ContinuousConvMode = ENABLE;
43-
hadc.Init.DiscontinuousConvMode = DISABLE;
44-
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
45-
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
46-
hadc.Init.NbrOfConversion = 1;
47-
HAL_ADC_Init(&hadc);
41+
auto adc_num = _adcToIndex(adc_instance);
42+
hadc[adc_num].Instance = adc_instance;
43+
hadc[adc_num].Init.ScanConvMode = ADC_SCAN_ENABLE;
44+
hadc[adc_num].Init.ContinuousConvMode = ENABLE;
45+
hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
46+
hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START;
47+
hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
48+
hadc[adc_num].Init.NbrOfConversion = 1;
49+
HAL_ADC_Init(&hadc[adc_num]);
4850
/**Configure for the selected ADC regular channel to be converted.
4951
*/
5052

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

104106
sConfigInjected.InjectedRank = _getADCInjectedRank(channel_no++);
105-
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc.Instance);
106-
if (HAL_ADCEx_InjectedConfigChannel(&hadc, &sConfigInjected) != HAL_OK){
107+
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc[adc_num].Instance);
108+
if (HAL_ADCEx_InjectedConfigChannel(&hadc[adc_num], &sConfigInjected) != HAL_OK){
107109
#ifdef SIMPLEFOC_STM32_DEBUG
108110
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc.Instance));
109111
#endif
110112
return -1;
111113
}
112114
}
113-
cs_params->adc_handle = &hadc;
115+
cs_params->adc_handle = &hadc[adc_num];
114116
return 0;
115117
}
116118

@@ -149,8 +151,18 @@ int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int
149151
extern "C" {
150152
void ADC1_2_IRQHandler(void)
151153
{
152-
HAL_ADC_IRQHandler(&hadc);
154+
if (hadc[0].Instance != NP)
155+
HAL_ADC_IRQHandler(&hadc[0]);
156+
if (hadc[1].Instance != NP)
157+
HAL_ADC_IRQHandler(&hadc[1]);
153158
}
159+
#ifdef ADC3
160+
void ADC3_IRQHandler(void)
161+
{
162+
if (hadc[2].Instance != NP)
163+
HAL_ADC_IRQHandler(&hadc[2]);
164+
}
165+
#endif
154166
}
155167

156168
#endif

src/current_sense/hardware_specific/stm32/stm32f4/stm32f4_hal.cpp

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
//#define SIMPLEFOC_STM32_DEBUG
66

77
#include "../../../../communication/SimpleFOCDebug.h"
8-
#define _TRGO_NOT_AVAILABLE 12345
98

10-
ADC_HandleTypeDef hadc;
9+
// pointer to the ADC handles used in the project
10+
ADC_HandleTypeDef hadc[ADC_COUNT] = {0};
1111

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

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

28-
if(hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
28+
if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
2929
#ifdef ADC2 // if defined ADC2
30-
else if(hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
30+
else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
3131
#endif
3232
#ifdef ADC3 // if defined ADC3
33-
else if(hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
33+
else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
3434
#endif
3535
else{
3636
#ifdef SIMPLEFOC_STM32_DEBUG
@@ -39,22 +39,26 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
3939
return -1; // error not a valid ADC instance
4040
}
4141

42+
int adc_num = _adcToIndex(adc_instance);
43+
4244
#ifdef SIMPLEFOC_STM32_DEBUG
43-
SIMPLEFOC_DEBUG("STM32-CS: Using ADC: ", _adcToIndex(&hadc)+1);
45+
SIMPLEFOC_DEBUG("STM32-CS: Using ADC: ", adc_num+1);
4446
#endif
4547

46-
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
47-
hadc.Init.Resolution = ADC_RESOLUTION_12B;
48-
hadc.Init.ScanConvMode = ENABLE;
49-
hadc.Init.ContinuousConvMode = ENABLE;
50-
hadc.Init.DiscontinuousConvMode = DISABLE;
51-
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
52-
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
53-
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
54-
hadc.Init.NbrOfConversion = 1;
55-
hadc.Init.DMAContinuousRequests = DISABLE;
56-
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
57-
if ( HAL_ADC_Init(&hadc) != HAL_OK){
48+
hadc[adc_num].Instance = adc_instance;
49+
50+
hadc[adc_num].Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
51+
hadc[adc_num].Init.Resolution = ADC_RESOLUTION_12B;
52+
hadc[adc_num].Init.ScanConvMode = ENABLE;
53+
hadc[adc_num].Init.ContinuousConvMode = ENABLE;
54+
hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
55+
hadc[adc_num].Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
56+
hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
57+
hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
58+
hadc[adc_num].Init.NbrOfConversion = 1;
59+
hadc[adc_num].Init.DMAContinuousRequests = DISABLE;
60+
hadc[adc_num].Init.EOCSelection = ADC_EOC_SINGLE_CONV;
61+
if ( HAL_ADC_Init(&hadc[adc_num]) != HAL_OK){
5862
#ifdef SIMPLEFOC_STM32_DEBUG
5963
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init ADC!");
6064
#endif
@@ -115,15 +119,15 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
115119
if (!_isset(cs_params->pins[i])) continue;
116120

117121
sConfigInjected.InjectedRank = _getADCInjectedRank(channel_no++);
118-
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc.Instance);
119-
if (HAL_ADCEx_InjectedConfigChannel(&hadc, &sConfigInjected) != HAL_OK){
122+
sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc[adc_num].Instance);
123+
if (HAL_ADCEx_InjectedConfigChannel(&hadc[adc_num], &sConfigInjected) != HAL_OK){
120124
#ifdef SIMPLEFOC_STM32_DEBUG
121-
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc.Instance));
125+
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc[adc_num].Instance));
122126
#endif
123127
return -1;
124128
}
125129
}
126-
cs_params->adc_handle = &hadc;
130+
cs_params->adc_handle = &hadc[adc_num];
127131
return 0;
128132
}
129133

@@ -160,7 +164,10 @@ int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int
160164
extern "C" {
161165
void ADC_IRQHandler(void)
162166
{
163-
HAL_ADC_IRQHandler(&hadc);
167+
for(int adc_num=0; adc_num<ADC_COUNT; adc_num++){
168+
if(hadc[adc_num].Instance == NP) continue;
169+
HAL_ADC_IRQHandler(&hadc[adc_num]);
170+
}
164171
}
165172
}
166173

src/current_sense/hardware_specific/stm32/stm32f7/stm32f7_hal.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
//#define SIMPLEFOC_STM32_DEBUG
66

77
#include "../../../../communication/SimpleFOCDebug.h"
8-
#define _TRGO_NOT_AVAILABLE 12345
98

10-
ADC_HandleTypeDef hadc;
9+
// pointer to the ADC handles used in the project
10+
ADC_HandleTypeDef hadc[ADC_COUNT] = {0};
1111

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

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

28-
if(hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
28+
if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
2929
#ifdef ADC2 // if defined ADC2
30-
else if(hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
30+
else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
3131
#endif
3232
#ifdef ADC3 // if defined ADC3
33-
else if(hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
33+
else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
3434
#endif
3535
else{
3636
#ifdef SIMPLEFOC_STM32_DEBUG
3737
SIMPLEFOC_DEBUG("STM32-CS: ERR: Pin does not belong to any ADC!");
3838
#endif
3939
return -1; // error not a valid ADC instance
4040
}
41+
42+
int adc_num = _adcToIndex(adc_instance);
4143

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

46-
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
47-
hadc.Init.Resolution = ADC_RESOLUTION_12B;
48-
hadc.Init.ScanConvMode = ENABLE;
49-
hadc.Init.ContinuousConvMode = DISABLE;
50-
hadc.Init.DiscontinuousConvMode = DISABLE;
51-
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
52-
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
53-
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
54-
hadc.Init.NbrOfConversion = 1;
55-
hadc.Init.DMAContinuousRequests = DISABLE;
56-
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
57-
if ( HAL_ADC_Init(&hadc) != HAL_OK){
48+
hadc[adc_num].Instance = adc_instance;
49+
hadc[adc_num].Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
50+
hadc[adc_num].Init.Resolution = ADC_RESOLUTION_12B;
51+
hadc[adc_num].Init.ScanConvMode = ENABLE;
52+
hadc[adc_num].Init.ContinuousConvMode = DISABLE;
53+
hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
54+
hadc[adc_num].Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
55+
hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START; // for now
56+
hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
57+
hadc[adc_num].Init.NbrOfConversion = 1;
58+
hadc[adc_num].Init.DMAContinuousRequests = DISABLE;
59+
hadc[adc_num].Init.EOCSelection = ADC_EOC_SINGLE_CONV;
60+
if ( HAL_ADC_Init(&hadc[adc_num]) != HAL_OK){
5861
#ifdef SIMPLEFOC_STM32_DEBUG
5962
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init ADC!");
6063
#endif
@@ -123,16 +126,16 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
123126
if (!_isset(cs_params->pins[i])) continue;
124127

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

135-
cs_params->adc_handle = &hadc;
138+
cs_params->adc_handle = &hadc[adc_num];
136139
return 0;
137140
}
138141

@@ -172,7 +175,10 @@ int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int
172175
extern "C" {
173176
void ADC_IRQHandler(void)
174177
{
175-
HAL_ADC_IRQHandler(&hadc);
178+
for(int adc_num=0; adc_num<ADC_COUNT; adc_num++){
179+
if(hadc[adc_num].Instance == NP) continue;
180+
HAL_ADC_IRQHandler(&hadc[adc_num]);
181+
}
176182
}
177183
}
178184

0 commit comments

Comments
 (0)