SimpleFOClibrary 2.4.0
Loading...
Searching...
No Matches
stm32f1_hal.cpp
Go to the documentation of this file.
1#include "stm32f1_hal.h"
2
3#if defined(STM32F1xx)
4
5#include "../../../../communication/SimpleFOCDebug.h"
6#include "../stm32_adc_utils.h"
7
8// pointer to the ADC handles used in the project
9ADC_HandleTypeDef hadc[ADC_COUNT] = {0};
10
11ADC_HandleTypeDef* _get_adc_handles(){
12 return hadc;
13}
14
15
16
17/**
18 * Function initializing the ADC for the regular channels for the low-side current sensing
19 *
20 * @param adc_instance - ADC instance to initialize
21 *
22 * @return int - 0 if success
23 */
24int _adc_init_regular(ADC_TypeDef* adc_instance)
25{
26
27 if(adc_instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE();
28#ifdef ADC2 // if defined ADC2
29 else if(adc_instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE();
30#endif
31#ifdef ADC3 // if defined ADC3
32 else if(adc_instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE();
33#endif
34 else{
35#ifdef SIMPLEFOC_STM32_DEBUG
36 SIMPLEFOC_DEBUG("STM32-CS: ERR: Pin does not belong to any ADC!");
37#endif
38 return -1; // error not a valid ADC instance
39 }
40
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]);
50
51return 0;
52}
53
54/**
55 * Function initializing the ADC and the injected channels for the low-side current sensing
56 *
57 * @param cs_params - current sense parameters
58 * @param driver_params - driver parameters
59 *
60 * @return int - 0 if success
61 */
62int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params)
63{
64 ADC_InjectionConfTypeDef sConfigInjected;
65
66 /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
67 */
68 auto adc_instance = _findBestADCForInjectedPins(3, cs_params->pins, hadc);
69
70 if(adc_instance == NP){
71#ifdef SIMPLEFOC_STM32_DEBUG
72 SIMPLEFOC_DEBUG("STM32-CS: ERR: Pin does not belong to any ADC!");
73#endif
74 return -1; // error not a valid ADC instance
75 }
76
77 if( _adc_init_regular(adc_instance) != 0){
78 return -1;
79 }
80
81 auto adc_num = _adcToIndex(adc_instance);
82 hadc[adc_num].Instance = adc_instance;
83 hadc[adc_num].Init.ScanConvMode = ADC_SCAN_ENABLE;
84 hadc[adc_num].Init.ContinuousConvMode = DISABLE;
85 hadc[adc_num].Init.DiscontinuousConvMode = DISABLE;
86 hadc[adc_num].Init.ExternalTrigConv = ADC_SOFTWARE_START;
87 hadc[adc_num].Init.DataAlign = ADC_DATAALIGN_RIGHT;
88 hadc[adc_num].Init.NbrOfConversion = 1;
89 HAL_ADC_Init(&hadc[adc_num]);
90 /**Configure for the selected ADC regular channel to be converted.
91 */
92
93 /**Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
94 */
95 sConfigInjected.InjectedNbrOfConversion = 0;
96 for(int pin_no=0; pin_no<3; pin_no++){
97 if(_isset(cs_params->pins[pin_no])){
98 sConfigInjected.InjectedNbrOfConversion++;
99 }
100 }
101 sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_1CYCLE_5;
102 sConfigInjected.AutoInjectedConv = DISABLE;
103 sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
104 sConfigInjected.InjectedOffset = 0;
105
106 // automating TRGO flag finding - hardware specific
107 uint8_t tim_num = 0;
108 while(driver_params->timers_handle[tim_num] != NP && tim_num < 6){
109 uint32_t trigger_flag = _timerToInjectedTRGO(driver_params->timers_handle[tim_num++]);
110 if(trigger_flag == _TRGO_NOT_AVAILABLE) continue; // timer does not have valid trgo for injected channels
111
112 // check if TRGO used already - if yes use the next timer
113 if((driver_params->timers_handle[tim_num-1]->Instance->CR2 & LL_TIM_TRGO_ENABLE) || // if used for timer sync
114 (driver_params->timers_handle[tim_num-1]->Instance->CR2 & LL_TIM_TRGO_UPDATE)) // if used for ADC sync
115 {
116 continue;
117 }
118
119 // if the code comes here, it has found the timer available
120 // timer does have trgo flag for injected channels
121 sConfigInjected.ExternalTrigInjecConv = trigger_flag;
122
123 // this will be the timer with which the ADC will sync
124 cs_params->timer_handle = driver_params->timers_handle[tim_num-1];
125 // done
126 break;
127 }
128 if( cs_params->timer_handle == NP ){
129 // not possible to use these timers for low-side current sense
130 #ifdef SIMPLEFOC_STM32_DEBUG
131 SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot sync any timer to injected channels!");
132 #endif
133 return -1;
134 }else{
135 #ifdef SIMPLEFOC_STM32_DEBUG
136 SIMPLEFOC_DEBUG("STM32-CS: Using timer: ", stm32_getTimerNumber(cs_params->timer_handle->Instance));
137 #endif
138 }
139
140
141 uint8_t channel_no = 0;
142 for(int i=0; i<3; i++){
143 // skip if not set
144 if (!_isset(cs_params->pins[i])) continue;
145
146 sConfigInjected.InjectedRank = _getADCInjectedRank(channel_no++);
147 sConfigInjected.InjectedChannel = _getADCChannel(analogInputToPinName(cs_params->pins[i]), hadc[adc_num].Instance);
148#ifdef SIMPLEFOC_STM32_DEBUG
149 SIMPLEFOC_DEBUG("STM32-CS: ADC channel: ", (int)STM_PIN_CHANNEL(pinmap_function(PinMap_ADC[i].pin, PinMap_ADC)));
150#endif
151 if (HAL_ADCEx_InjectedConfigChannel(&hadc[adc_num], &sConfigInjected) != HAL_OK){
152 #ifdef SIMPLEFOC_STM32_DEBUG
153 SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init injected channel: ", (int)_getADCChannel(analogInputToPinName(cs_params->pins[i]) , hadc[adc_num].Instance));
154 #endif
155 return -1;
156 }
157 }
158 cs_params->adc_handle = &hadc[adc_num];
159 return 0;
160}
161
162/**
163 * Function to initialize the ADC GPIO pins
164 *
165 * @param cs_params current sense parameters
166 * @param pinA pin number for phase A
167 * @param pinB pin number for phase B
168 * @param pinC pin number for phase C
169 * @return int 0 if success, -1 if error
170 */
171int _adc_gpio_init(Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
172{
173 int pins[3] = {pinA, pinB, pinC};
174 const char* port_names[3] = {"A", "B", "C"};
175 for(int i=0; i<3; i++){
176 if(_isset(pins[i])){
177 // check if pin is an analog pin
178 if(pinmap_peripheral(analogInputToPinName(pins[i]), PinMap_ADC) == NP){
179#if defined(SIMPLEFOC_STM32_DEBUG) && !defined(SIMPLEFOC_DISABLE_DEBUG)
180 SimpleFOCDebug::print("STM32-CS: ERR: Pin ");
181 SimpleFOCDebug::print(port_names[i]);
182 SimpleFOCDebug::println(" does not belong to any ADC!");
183#endif
184 return -1;
185 }
186 pinmap_pinout(analogInputToPinName(pins[i]), PinMap_ADC);
187 cs_params->pins[i] = pins[i];
188 }
189 }
190 return 0;
191}
192
193
194extern "C" {
195 void ADC1_2_IRQHandler(void)
196 {
197 if (hadc[0].Instance != NP)
198 HAL_ADC_IRQHandler(&hadc[0]);
199 if (hadc[1].Instance != NP)
200 HAL_ADC_IRQHandler(&hadc[1]);
201 }
202#ifdef ADC3
203 void ADC3_IRQHandler(void)
204 {
205 if (hadc[2].Instance != NP)
206 HAL_ADC_IRQHandler(&hadc[2]);
207 }
208#endif
209}
210
211#endif
#define SIMPLEFOC_DEBUG(msg,...)
static void print(const char *msg)
static void println()
const int const int const int pinC
#define _isset(a)
Definition foc_utils.h:13