1
+ #include " stm32f7_hal.h"
2
+
3
+ #if defined(STM32F7xx)
4
+
5
+ // #define SIMPLEFOC_STM32_DEBUG
6
+
7
+ #include " ../../../../communication/SimpleFOCDebug.h"
8
+ #define _TRGO_NOT_AVAILABLE 12345
9
+
10
+ ADC_HandleTypeDef hadc;
11
+
12
+ int _adc_init (Stm32CurrentSenseParams* cs_params, const STM32DriverParams* driver_params)
13
+ {
14
+ ADC_InjectionConfTypeDef sConfigInjected ;
15
+
16
+ // check if all pins belong to the same ADC
17
+ ADC_TypeDef* adc_pin1 = (ADC_TypeDef*)pinmap_peripheral (analogInputToPinName (cs_params->pins [0 ]), PinMap_ADC);
18
+ ADC_TypeDef* adc_pin2 = (ADC_TypeDef*)pinmap_peripheral (analogInputToPinName (cs_params->pins [1 ]), PinMap_ADC);
19
+ ADC_TypeDef* adc_pin3 = _isset (cs_params->pins [2 ]) ? (ADC_TypeDef*)pinmap_peripheral (analogInputToPinName (cs_params->pins [2 ]), PinMap_ADC) : nullptr ;
20
+ if ( (adc_pin1 != adc_pin2) || ( (adc_pin3) && (adc_pin1 != adc_pin3) )){
21
+ #ifdef SIMPLEFOC_STM32_DEBUG
22
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: Analog pins dont belong to the same ADC!" );
23
+ #endif
24
+ return -1 ;
25
+ }
26
+
27
+
28
+ /* *Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
29
+ */
30
+ hadc.Instance = (ADC_TypeDef *)pinmap_peripheral (analogInputToPinName (cs_params->pins [0 ]), PinMap_ADC);
31
+
32
+ if (hadc.Instance == ADC1) __HAL_RCC_ADC1_CLK_ENABLE ();
33
+ #ifdef ADC2 // if defined ADC2
34
+ else if (hadc.Instance == ADC2) __HAL_RCC_ADC2_CLK_ENABLE ();
35
+ #endif
36
+ #ifdef ADC3 // if defined ADC3
37
+ else if (hadc.Instance == ADC3) __HAL_RCC_ADC3_CLK_ENABLE ();
38
+ #endif
39
+ else {
40
+ #ifdef SIMPLEFOC_STM32_DEBUG
41
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: Pin does not belong to any ADC!" );
42
+ #endif
43
+ return -1 ; // error not a valid ADC instance
44
+ }
45
+
46
+ #ifdef SIMPLEFOC_STM32_DEBUG
47
+ SIMPLEFOC_DEBUG (" STM32-CS: Using ADC: " , _adcToIndex (&hadc)+1 );
48
+ #endif
49
+
50
+ hadc.Init .ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
51
+ hadc.Init .Resolution = ADC_RESOLUTION_12B;
52
+ hadc.Init .ScanConvMode = ENABLE;
53
+ hadc.Init .ContinuousConvMode = DISABLE;
54
+ hadc.Init .DiscontinuousConvMode = DISABLE;
55
+ hadc.Init .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
56
+ hadc.Init .ExternalTrigConv = ADC_SOFTWARE_START; // for now
57
+ hadc.Init .DataAlign = ADC_DATAALIGN_RIGHT;
58
+ hadc.Init .NbrOfConversion = 1 ;
59
+ hadc.Init .DMAContinuousRequests = DISABLE;
60
+ hadc.Init .EOCSelection = ADC_EOC_SINGLE_CONV;
61
+ if ( HAL_ADC_Init (&hadc) != HAL_OK){
62
+ #ifdef SIMPLEFOC_STM32_DEBUG
63
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init ADC!" );
64
+ #endif
65
+ return -1 ;
66
+ }
67
+
68
+ /* *Configures for the selected ADC injected channel its corresponding rank in the sequencer and its sample time
69
+ */
70
+ sConfigInjected .InjectedNbrOfConversion = _isset (cs_params->pins [2 ]) ? 3 : 2 ;
71
+ sConfigInjected .InjectedSamplingTime = ADC_SAMPLETIME_3CYCLES;
72
+ sConfigInjected .ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONVEDGE_RISINGFALLING;
73
+ sConfigInjected .AutoInjectedConv = DISABLE;
74
+ sConfigInjected .InjectedDiscontinuousConvMode = DISABLE;
75
+ sConfigInjected .InjectedOffset = 0 ;
76
+
77
+ // automating TRGO flag finding - hardware specific
78
+ uint8_t tim_num = 0 ;
79
+ for (size_t i=0 ; i<6 ; i++) {
80
+ HardwareTimer *timer_to_check = driver_params->timers [tim_num++];
81
+ TIM_TypeDef *instance_to_check = timer_to_check->getHandle ()->Instance ;
82
+
83
+ // bool TRGO_already_configured = instance_to_check->CR2 & LL_TIM_TRGO_UPDATE;
84
+ // if(TRGO_already_configured) continue;
85
+
86
+ uint32_t trigger_flag = _timerToInjectedTRGO (timer_to_check);
87
+ if (trigger_flag == _TRGO_NOT_AVAILABLE) continue ; // timer does not have valid trgo for injected channels
88
+
89
+ // if the code comes here, it has found the timer available
90
+ // timer does have trgo flag for injected channels
91
+ sConfigInjected .ExternalTrigInjecConv = trigger_flag;
92
+
93
+ // this will be the timer with which the ADC will sync
94
+ cs_params->timer_handle = timer_to_check;
95
+ if (!IS_TIM_REPETITION_COUNTER_INSTANCE (instance_to_check)) {
96
+ // workaround for errata 2.2.1 in ES0290 Rev 7
97
+ // https://www.st.com/resource/en/errata_sheet/es0290-stm32f74xxx-and-stm32f75xxx-device-limitations-stmicroelectronics.pdf
98
+ __HAL_RCC_DAC_CLK_ENABLE ();
99
+ }
100
+ // done
101
+ break ;
102
+ }
103
+ if ( cs_params->timer_handle == NP ){
104
+ // not possible to use these timers for low-side current sense
105
+ #ifdef SIMPLEFOC_STM32_DEBUG
106
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot sync any timer to injected channels!" );
107
+ #endif
108
+ return -1 ;
109
+ }
110
+ // display which timer is being used
111
+ #ifdef SIMPLEFOC_STM32_DEBUG
112
+ // it would be better to use the getTimerNumber from driver
113
+ SIMPLEFOC_DEBUG (" STM32-CS: injected trigger for timer index: " , get_timer_index (cs_params->timer_handle ->getHandle ()->Instance ) + 1 );
114
+ #endif
115
+
116
+
117
+ // first channel
118
+ sConfigInjected .InjectedRank = ADC_INJECTED_RANK_1;
119
+ sConfigInjected .InjectedChannel = _getADCChannel (analogInputToPinName (cs_params->pins [0 ]));
120
+ if (HAL_ADCEx_InjectedConfigChannel (&hadc, &sConfigInjected ) != HAL_OK){
121
+ #ifdef SIMPLEFOC_STM32_DEBUG
122
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init injected channel: " , (int )_getADCChannel (analogInputToPinName (cs_params->pins [0 ])) );
123
+ #endif
124
+ return -1 ;
125
+ }
126
+
127
+ // second channel
128
+ sConfigInjected .InjectedRank = ADC_INJECTED_RANK_2;
129
+ sConfigInjected .InjectedChannel = _getADCChannel (analogInputToPinName (cs_params->pins [1 ]));
130
+ if (HAL_ADCEx_InjectedConfigChannel (&hadc, &sConfigInjected ) != HAL_OK){
131
+ #ifdef SIMPLEFOC_STM32_DEBUG
132
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init injected channel: " , (int )_getADCChannel (analogInputToPinName (cs_params->pins [1 ]))) ;
133
+ #endif
134
+ return -1 ;
135
+ }
136
+
137
+ // third channel - if exists
138
+ if (_isset (cs_params->pins [2 ])){
139
+ sConfigInjected .InjectedRank = ADC_INJECTED_RANK_3;
140
+ sConfigInjected .InjectedChannel = _getADCChannel (analogInputToPinName (cs_params->pins [2 ]));
141
+ if (HAL_ADCEx_InjectedConfigChannel (&hadc, &sConfigInjected ) != HAL_OK){
142
+ #ifdef SIMPLEFOC_STM32_DEBUG
143
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot init injected channel: " , (int )_getADCChannel (analogInputToPinName (cs_params->pins [2 ]))) ;
144
+ #endif
145
+ return -1 ;
146
+ }
147
+ }
148
+
149
+ #ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
150
+ // enable interrupt
151
+ HAL_NVIC_SetPriority (ADC_IRQn, 0 , 0 );
152
+ HAL_NVIC_EnableIRQ (ADC_IRQn);
153
+ #endif
154
+
155
+ cs_params->adc_handle = &hadc;
156
+ return 0 ;
157
+ }
158
+
159
+ void _adc_gpio_init (Stm32CurrentSenseParams* cs_params, const int pinA, const int pinB, const int pinC)
160
+ {
161
+ uint8_t cnt = 0 ;
162
+ if (_isset (pinA)){
163
+ pinmap_pinout (analogInputToPinName (pinA), PinMap_ADC);
164
+ cs_params->pins [cnt++] = pinA;
165
+ }
166
+ if (_isset (pinB)){
167
+ pinmap_pinout (analogInputToPinName (pinB), PinMap_ADC);
168
+ cs_params->pins [cnt++] = pinB;
169
+ }
170
+ if (_isset (pinC)){
171
+ pinmap_pinout (analogInputToPinName (pinC), PinMap_ADC);
172
+ cs_params->pins [cnt] = pinC;
173
+ }
174
+ }
175
+
176
+ #ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
177
+ extern " C" {
178
+ void ADC_IRQHandler (void )
179
+ {
180
+ HAL_ADC_IRQHandler (&hadc);
181
+ }
182
+ }
183
+ #endif
184
+
185
+ #endif
0 commit comments