@@ -22,6 +22,12 @@ bool needs_downsample[3] = {1};
22
22
// downsampling variable - per adc (3)
23
23
uint8_t tim_downsample[3 ] = {1 };
24
24
25
+ #ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
26
+ uint8_t use_adc_interrupt = 1 ;
27
+ #else
28
+ uint8_t use_adc_interrupt = 0 ;
29
+ #endif
30
+
25
31
void * _configureADCLowSide (const void * driver_params, const int pinA, const int pinB, const int pinC){
26
32
27
33
Stm32CurrentSenseParams* cs_params= new Stm32CurrentSenseParams {
@@ -56,19 +62,47 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
56
62
cs_params->timer_handle ->Instance ->CNT = cs_params->timer_handle ->Instance ->ARR ;
57
63
// remember that this timer has repetition counter - no need to downasmple
58
64
needs_downsample[_adcToIndex (cs_params->adc_handle )] = 0 ;
65
+ }else {
66
+ if (!use_adc_interrupt){
67
+ // If the timer has no repetition counter, it needs to use the interrupt to downsample for low side sensing
68
+ use_adc_interrupt = 1 ;
69
+ #ifdef SIMPLEFOC_STM32_DEBUG
70
+ SIMPLEFOC_DEBUG (" STM32-CS: timer has no repetition counter, ADC interrupt has to be used" );
71
+ #endif
72
+ }
59
73
}
74
+
60
75
// set the trigger output event
61
76
LL_TIM_SetTriggerOutput (cs_params->timer_handle ->Instance , LL_TIM_TRGO_UPDATE);
62
77
63
78
// Start the adc calibration
64
- HAL_ADCEx_Calibration_Start (cs_params->adc_handle , ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);
79
+ if (HAL_ADCEx_Calibration_Start (cs_params->adc_handle , ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED) != HAL_OK){
80
+ #ifdef SIMPLEFOC_STM32_DEBUG
81
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot calibrate ADC!" );
82
+ #endif
83
+ return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
84
+ }
65
85
66
86
// start the adc
67
- #ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
68
- HAL_ADCEx_InjectedStart_IT (cs_params->adc_handle );
69
- #else
70
- HAL_ADCEx_InjectedStart (cs_params->adc_handle );
71
- #endif
87
+ if (use_adc_interrupt){
88
+ // enable interrupt
89
+ HAL_NVIC_SetPriority (ADC_IRQn, 0 , 0 );
90
+ HAL_NVIC_EnableIRQ (ADC_IRQn);
91
+
92
+ if (HAL_ADCEx_InjectedStart_IT (cs_params->adc_handle ) != HAL_OK){
93
+ #ifdef SIMPLEFOC_STM32_DEBUG
94
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot start injected channels in interrupt mode!" );
95
+ #endif
96
+ return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
97
+ }
98
+ }else {
99
+ if (HAL_ADCEx_InjectedStart (cs_params->adc_handle ) != HAL_OK){
100
+ #ifdef SIMPLEFOC_STM32_DEBUG
101
+ SIMPLEFOC_DEBUG (" STM32-CS: ERR: cannot start injected channels!" );
102
+ #endif
103
+ return SIMPLEFOC_CURRENT_SENSE_INIT_FAILED;
104
+ }
105
+ }
72
106
73
107
74
108
// restart all the timers of the driver
@@ -83,32 +117,34 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
83
117
84
118
// function reading an ADC value and returning the read voltage
85
119
float _readADCVoltageLowSide (const int pin, const void * cs_params){
120
+ // print all values in the buffer
121
+ // SIMPLEFOC_DEBUG("adc_a:", (int)HAL_ADCEx_InjectedGetValue(((Stm32CurrentSenseParams*)cs_params)->adc_handle, _getADCInjectedRank(0)));
122
+ // SIMPLEFOC_DEBUG("adc_b:", (int)HAL_ADCEx_InjectedGetValue(((Stm32CurrentSenseParams*)cs_params)->adc_handle, _getADCInjectedRank(1)));
86
123
uint8_t channel_no = 0 ;
87
124
for (int i=0 ; i < 3 ; i++){
88
125
if ( pin == ((Stm32CurrentSenseParams*)cs_params)->pins [i]){ // found in the buffer
89
- # ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
126
+ if (use_adc_interrupt){
90
127
return adc_val[_adcToIndex (((Stm32CurrentSenseParams*)cs_params)->adc_handle )][channel_no] * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv ;
91
- # else
128
+ } else {
92
129
// an optimized way to go from i to the channel i=0 -> channel 1, i=1 -> channel 2, i=2 -> channel 3
93
130
uint32_t channel = _getADCInjectedRank (channel_no);
94
131
return HAL_ADCEx_InjectedGetValue (((Stm32CurrentSenseParams*)cs_params)->adc_handle , channel) * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv ;
95
- # endif
132
+ }
96
133
}
97
134
if (_isset (((Stm32CurrentSenseParams*)cs_params)->pins [i])) channel_no++;
98
135
}
99
136
return 0 ;
100
137
}
101
138
102
- #ifdef SIMPLEFOC_STM32_ADC_INTERRUPT
103
139
extern " C" {
104
140
void HAL_ADCEx_InjectedConvCpltCallback (ADC_HandleTypeDef *AdcHandle){
105
141
106
142
// calculate the instance
107
143
int adc_index = _adcToIndex (AdcHandle);
108
144
109
145
// if the timer han't repetition counter - downsample two times
110
- if ( needs_downsample[adc_index] && tim_downsample[adc_index]++ > 0 ) {
111
- tim_downsample[adc_index] = 0 ;
146
+ if ( needs_downsample[adc_index] && tim_downsample[adc_index]++ > 1 ) {
147
+ tim_downsample[adc_index] = 1 ;
112
148
return ;
113
149
}
114
150
@@ -117,6 +153,5 @@ extern "C" {
117
153
adc_val[adc_index][2 ]=HAL_ADCEx_InjectedGetValue (AdcHandle, ADC_INJECTED_RANK_3);
118
154
}
119
155
}
120
- #endif
121
156
122
157
#endif
0 commit comments