1+ #include " stm32l4_hal.h"
2+
3+ #if defined(STM32L4xx)
4+
5+ #include " ../../../../communication/SimpleFOCDebug.h"
6+
7+ #define SIMPLEFOC_STM32_DEBUG
8+
9+ ADC_HandleTypeDef hadc;
10+
11+ int _adc_init (Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params)
12+ {
13+ ADC_InjectionConfTypeDef sConfigInjected ;
14+
15+ // check if all pins belong to the same ADC
16+ ADC_TypeDef* adc_pin1 = (ADC_TypeDef*)pinmap_peripheral (analogInputToPinName (cs_params->pins [0 ]), PinMap_ADC);
17+ ADC_TypeDef* adc_pin2 = (ADC_TypeDef*)pinmap_peripheral (analogInputToPinName (cs_params->pins [1 ]), PinMap_ADC);
18+ ADC_TypeDef* adc_pin3 = _isset (cs_params->pins [2 ]) ? (ADC_TypeDef*)pinmap_peripheral (analogInputToPinName (cs_params->pins [2 ]), PinMap_ADC) : nullptr ;
19+ if ( (adc_pin1 != adc_pin2) || ( (adc_pin3) && (adc_pin1 != adc_pin3) )){
20+ #ifdef SIMPLEFOC_STM32_DEBUG
21+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: Analog pins dont belong to the same ADC!" );
22+ #endif
23+ return -1 ;
24+ }
25+
26+
27+ /* *Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
28+ */
29+ hadc.Instance = (ADC_TypeDef *)pinmap_peripheral (analogInputToPinName (cs_params->pins [0 ]), PinMap_ADC);
30+
31+ if (hadc.Instance == ADC1) {
32+ #ifdef __HAL_RCC_ADC1_CLK_ENABLE
33+ __HAL_RCC_ADC1_CLK_ENABLE ();
34+ #endif
35+ #ifdef __HAL_RCC_ADC12_CLK_ENABLE
36+ __HAL_RCC_ADC12_CLK_ENABLE ();
37+ #endif
38+ }
39+ #ifdef ADC2
40+ else if (hadc.Instance == ADC2) {
41+ #ifdef __HAL_RCC_ADC2_CLK_ENABLE
42+ __HAL_RCC_ADC2_CLK_ENABLE ();
43+ #endif
44+ #ifdef __HAL_RCC_ADC12_CLK_ENABLE
45+ __HAL_RCC_ADC12_CLK_ENABLE ();
46+ #endif
47+ }
48+ #endif
49+ #ifdef ADC3
50+ else if (hadc.Instance == ADC3) {
51+ #ifdef __HAL_RCC_ADC3_CLK_ENABLE
52+ __HAL_RCC_ADC3_CLK_ENABLE ();
53+ #endif
54+ #ifdef __HAL_RCC_ADC34_CLK_ENABLE
55+ __HAL_RCC_ADC34_CLK_ENABLE ();
56+ #endif
57+ #if defined(ADC345_COMMON)
58+ __HAL_RCC_ADC345_CLK_ENABLE ();
59+ #endif
60+ }
61+ #endif
62+ #ifdef ADC4
63+ else if (hadc.Instance == ADC4) {
64+ #ifdef __HAL_RCC_ADC4_CLK_ENABLE
65+ __HAL_RCC_ADC4_CLK_ENABLE ();
66+ #endif
67+ #ifdef __HAL_RCC_ADC34_CLK_ENABLE
68+ __HAL_RCC_ADC34_CLK_ENABLE ();
69+ #endif
70+ #if defined(ADC345_COMMON)
71+ __HAL_RCC_ADC345_CLK_ENABLE ();
72+ #endif
73+ }
74+ #endif
75+ #ifdef ADC5
76+ else if (hadc.Instance == ADC5) {
77+ #if defined(ADC345_COMMON)
78+ __HAL_RCC_ADC345_CLK_ENABLE ();
79+ #endif
80+ }
81+ #endif
82+ else {
83+ #ifdef SIMPLEFOC_STM32_DEBUG
84+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: Pin does not belong to any ADC!" );
85+ #endif
86+ return -1 ; // error not a valid ADC instance
87+ }
88+
89+ #ifdef SIMPLEFOC_STM32_DEBUG
90+ SIMPLEFOC_DEBUG (" STM32-CS: Using ADC: " , _adcToIndex (&hadc)+1 );
91+ #endif
92+
93+ hadc.Init .ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
94+ hadc.Init .Resolution = ADC_RESOLUTION_12B;
95+ hadc.Init .ScanConvMode = ADC_SCAN_ENABLE;
96+ hadc.Init .ContinuousConvMode = DISABLE;
97+ hadc.Init .LowPowerAutoWait = DISABLE;
98+ hadc.Init .DiscontinuousConvMode = DISABLE;
99+ hadc.Init .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
100+ hadc.Init .ExternalTrigConv = ADC_SOFTWARE_START; // for now
101+ hadc.Init .DataAlign = ADC_DATAALIGN_RIGHT;
102+ hadc.Init .NbrOfConversion = 2 ;
103+ hadc.Init .DMAContinuousRequests = DISABLE;
104+ hadc.Init .EOCSelection = ADC_EOC_SINGLE_CONV;
105+ hadc.Init .Overrun = ADC_OVR_DATA_PRESERVED;
106+ if ( HAL_ADC_Init (&hadc) != HAL_OK){
107+ #ifdef SIMPLEFOC_STM32_DEBUG
108+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init ADC!" );
109+ #endif
110+ return -1 ;
111+ }
112+
113+ /* *Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
114+ */
115+ sConfigInjected .InjectedNbrOfConversion = _isset (cs_params->pins [2 ]) ? 3 : 2 ;
116+ sConfigInjected .InjectedSamplingTime = ADC_SAMPLETIME_2CYCLES_5;
117+ sConfigInjected .ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;
118+ sConfigInjected .AutoInjectedConv = DISABLE;
119+ sConfigInjected .InjectedSingleDiff = ADC_SINGLE_ENDED;
120+ sConfigInjected .InjectedDiscontinuousConvMode = DISABLE;
121+ sConfigInjected .InjectedOffsetNumber = ADC_OFFSET_NONE;
122+ sConfigInjected .InjectedOffset = 0 ;
123+ sConfigInjected .InjecOversamplingMode = DISABLE;
124+ sConfigInjected .QueueInjectedContext = DISABLE;
125+
126+ // automating TRGO flag finding - hardware specific
127+ uint8_t tim_num = 0 ;
128+ while (driver_params->timers [tim_num] != NP && tim_num < 6 ){
129+ uint32_t trigger_flag = _timerToInjectedTRGO (driver_params->timers [tim_num++]);
130+ if (trigger_flag == _TRGO_NOT_AVAILABLE) continue ; // timer does not have valid trgo for injected channels
131+
132+ // if the code comes here, it has found the timer available
133+ // timer does have trgo flag for injected channels
134+ sConfigInjected .ExternalTrigInjecConv = trigger_flag;
135+
136+ // this will be the timer with which the ADC will sync
137+ cs_params->timer_handle = driver_params->timers [tim_num-1 ];
138+ // done
139+ break ;
140+ }
141+ if ( cs_params->timer_handle == NP ){
142+ // not possible to use these timers for low-side current sense
143+ #ifdef SIMPLEFOC_STM32_DEBUG
144+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot sync any timer to injected channels!" );
145+ #endif
146+ return -1 ;
147+ }
148+
149+
150+ // first channel
151+ sConfigInjected .InjectedRank = ADC_INJECTED_RANK_1;
152+ sConfigInjected .InjectedChannel = _getADCChannel (analogInputToPinName (cs_params->pins [0 ]));
153+ if (HAL_ADCEx_InjectedConfigChannel (&hadc, &sConfigInjected ) != HAL_OK){
154+ #ifdef SIMPLEFOC_STM32_DEBUG
155+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init injected channel: " , (int )_getADCChannel (analogInputToPinName (cs_params->pins [0 ])) );
156+ #endif
157+ return -1 ;
158+ }
159+
160+ // second channel
161+ sConfigInjected .InjectedRank = ADC_INJECTED_RANK_2;
162+ sConfigInjected .InjectedChannel = _getADCChannel (analogInputToPinName (cs_params->pins [1 ]));
163+ if (HAL_ADCEx_InjectedConfigChannel (&hadc, &sConfigInjected ) != HAL_OK){
164+ #ifdef SIMPLEFOC_STM32_DEBUG
165+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init injected channel: " , (int )_getADCChannel (analogInputToPinName (cs_params->pins [1 ]))) ;
166+ #endif
167+ return -1 ;
168+ }
169+
170+ // third channel - if exists
171+ if (_isset (cs_params->pins [2 ])){
172+ sConfigInjected .InjectedRank = ADC_INJECTED_RANK_3;
173+ sConfigInjected .InjectedChannel = _getADCChannel (analogInputToPinName (cs_params->pins [2 ]));
174+ if (HAL_ADCEx_InjectedConfigChannel (&hadc, &sConfigInjected ) != HAL_OK){
175+ #ifdef SIMPLEFOC_STM32_DEBUG
176+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init injected channel: " , (int )_getADCChannel (analogInputToPinName (cs_params->pins [2 ]))) ;
177+ #endif
178+ return -1 ;
179+ }
180+ }
181+
182+
183+
184+ if (hadc.Instance == ADC1) {
185+ // enable interrupt
186+ HAL_NVIC_SetPriority (ADC1_2_IRQn, 0 , 0 );
187+ HAL_NVIC_EnableIRQ (ADC1_2_IRQn);
188+ }
189+ #ifdef ADC2
190+ else if (hadc.Instance == ADC2) {
191+ // enable interrupt
192+ HAL_NVIC_SetPriority (ADC1_2_IRQn, 0 , 0 );
193+ HAL_NVIC_EnableIRQ (ADC1_2_IRQn);
194+ }
195+ #endif
196+ #ifdef ADC3
197+ else if (hadc.Instance == ADC3) {
198+ // enable interrupt
199+ HAL_NVIC_SetPriority (ADC3_IRQn, 0 , 0 );
200+ HAL_NVIC_EnableIRQ (ADC3_IRQn);
201+ }
202+ #endif
203+ #ifdef ADC4
204+ else if (hadc.Instance == ADC4) {
205+ // enable interrupt
206+ HAL_NVIC_SetPriority (ADC4_IRQn, 0 , 0 );
207+ HAL_NVIC_EnableIRQ (ADC4_IRQn);
208+ }
209+ #endif
210+ #ifdef ADC5
211+ else if (hadc.Instance == ADC5) {
212+ // enable interrupt
213+ HAL_NVIC_SetPriority (ADC5_IRQn, 0 , 0 );
214+ HAL_NVIC_EnableIRQ (ADC5_IRQn);
215+ }
216+ #endif
217+
218+ cs_params->adc_handle = &hadc;
219+ return 0 ;
220+ }
221+
222+ void _adc_gpio_init (Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
223+ {
224+ uint8_t cnt = 0 ;
225+ if (_isset (pinA)){
226+ pinmap_pinout (analogInputToPinName (pinA), PinMap_ADC);
227+ cs_params->pins [cnt++] = pinA;
228+ }
229+ if (_isset (pinB)){
230+ pinmap_pinout (analogInputToPinName (pinB), PinMap_ADC);
231+ cs_params->pins [cnt++] = pinB;
232+ }
233+ if (_isset (pinC)){
234+ pinmap_pinout (analogInputToPinName (pinC), PinMap_ADC);
235+ cs_params->pins [cnt] = pinC;
236+ }
237+ }
238+
239+ extern " C" {
240+ void ADC1_2_IRQHandler (void )
241+ {
242+ HAL_ADC_IRQHandler (&hadc);
243+ }
244+ #ifdef ADC3
245+ void ADC3_IRQHandler (void )
246+ {
247+ HAL_ADC_IRQHandler (&hadc);
248+ }
249+ #endif
250+
251+ #ifdef ADC4
252+ void ADC4_IRQHandler (void )
253+ {
254+ HAL_ADC_IRQHandler (&hadc);
255+ }
256+ #endif
257+
258+ #ifdef ADC5
259+ void ADC5_IRQHandler (void )
260+ {
261+ HAL_ADC_IRQHandler (&hadc);
262+ }
263+ #endif
264+ }
265+
266+ #endif
0 commit comments