1313#define  _ADC_VOLTAGE_F1  3 .3f 
1414#define  _ADC_RESOLUTION_F1  4096 .0f 
1515
16- //  array of values of 4 injected channels per adc instance (3)
17- uint32_t  adc_val[3 ][4 ]={0 };
18- //  does adc interrupt need a downsample - per adc (3)
19- bool  needs_downsample[3 ] = {0 };
20- //  downsampling variable - per adc (3)
21- uint8_t  tim_downsample[3 ] = {0 };
16+ //  array of values of 4 injected channels per adc instance (5)
17+ uint32_t  adc_val[5 ][4 ]={0 };
2218
2319#ifdef  SIMPLEFOC_STM32_ADC_INTERRUPT
24- uint8_t  use_adc_interrupt =  1 ; 
20+ # define   USE_ADC_INTERRUPT   1 
2521#else 
26- uint8_t  use_adc_interrupt =  0 ; 
22+ # define   USE_ADC_INTERRUPT   0 
2723#endif 
2824
25+ //  structure containing the configuration of the adc interrupt
26+ Stm32AdcInterruptConfig adc_interrupt_config[5 ] = {
27+   {0 , 0 , USE_ADC_INTERRUPT}, //  ADC1
28+   {0 , 0 , USE_ADC_INTERRUPT}, //  ADC2
29+   {0 , 0 , USE_ADC_INTERRUPT}, //  ADC3
30+   {0 , 0 , USE_ADC_INTERRUPT}, //  ADC4
31+   {0 , 0 , USE_ADC_INTERRUPT}  //  ADC5
32+ };
33+ 
34+ 
2935void * _configureADCLowSide (const  void * driver_params, const  int  pinA, const  int  pinB, const  int  pinC){
3036
3137  Stm32CurrentSenseParams* cs_params= new  Stm32CurrentSenseParams {
@@ -48,47 +54,13 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
4854  //  stop all the timers for the driver
4955  stm32_pause (driver_params);
5056
51-   //  If DIR is 0 (upcounting), the next event is high-side active (PWM rising edge)
52-   //  If DIR is 1 (downcounting), the next event is low-side active (PWM falling edge)
53-   bool  next_event_high_side = (cs_params->timer_handle ->Instance ->CR1  & TIM_CR1_DIR) == 0 ;
54-   
55-   //  if timer has repetition counter - it will downsample using it
56-   //  and it does not need the software downsample
57-   if ( IS_TIM_REPETITION_COUNTER_INSTANCE (cs_params->timer_handle ->Instance ) ){
58-     //  adjust the initial timer state such that the trigger 
59-     //    - only necessary for the timers that have repetition counters
60-     //    - basically make sure that the next trigger event is the one that is expected (high-side first then low-side)
61- 
62-     //  set the direction and the 
63-     for (int  i=0 ; i< 6 ; i++){
64-       if (driver_params->timers_handle [i] == NP) continue ; //  skip if not set
65-       if (next_event_high_side){
66-         //  Set DIR bit to 0 (downcounting)
67-         driver_params->timers_handle [i]->Instance ->CR1  |= TIM_CR1_DIR;
68-         //  Set CNT to ARR so it starts upcounting from the top
69-         driver_params->timers_handle [i]->Instance ->CNT  =  driver_params->timers_handle [i]->Instance ->ARR ;
70-       }else {
71-         //  Set DIR bit to 0 (upcounting)
72-         driver_params->timers_handle [i]->Instance ->CR1  &= ~TIM_CR1_DIR;
73-         //  Set CNT to ARR so it starts upcounting from zero
74-         driver_params->timers_handle [i]->Instance ->CNT  = 0 ;//  driver_params->timers_handle[i]->Instance->ARR;
75-       }
76-     }
77-   }else {
78-     if (!use_adc_interrupt){
79-       //  If the timer has no repetition counter, it needs to use the interrupt to downsample for low side sensing
80-       use_adc_interrupt = 1 ;
81-       uint8_t  adc_index  = _adcToIndex (cs_params->adc_handle );
82-       //  remember that this timer does not have the repetition counter - need to downasmple
83-       needs_downsample[adc_index] = 1 ;
84- 
85-       if (next_event_high_side) //  Next event is high-side active
86-         tim_downsample[adc_index] = 0 ; //  skip the next interrupt (and every second one)
87-       else  //  Next event is low-side active
88-         tim_downsample[adc_index] = 1 ; //  read the next one (and every second one after)
89-       
90-       SIMPLEFOC_DEBUG (" STM32-CS: timer has no repetition counter, ADC interrupt has to be used"  );
91-     }
57+   //  get the index of the adc
58+   int  adc_index = _adcToIndex (cs_params->adc_handle );
59+ 
60+   bool  tim_interrupt = _initTimerInterruptDownsampling (cs_params, driver_params, adc_interrupt_config[adc_index]);
61+   if (tim_interrupt) {
62+   //  error in the timer interrupt initialization
63+     SIMPLEFOC_DEBUG (" STM32-CS: timer has no repetition counter, ADC interrupt has to be used"  );
9264  }
9365
9466  //  set the trigger output event
@@ -98,7 +70,7 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
9870  HAL_ADCEx_Calibration_Start (cs_params->adc_handle );
9971
10072  //  start the adc 
101-   if (use_adc_interrupt){
73+   if (adc_interrupt_config[adc_index]. use_adc_interrupt ){
10274    HAL_NVIC_SetPriority (ADC1_2_IRQn, 0 , 0 );
10375    HAL_NVIC_EnableIRQ (ADC1_2_IRQn);
10476
@@ -120,38 +92,16 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
12092
12193//  function reading an ADC value and returning the read voltage
12294float  _readADCVoltageLowSide (const  int  pin, const  void * cs_params){
123-   uint8_t  channel_no = 0 ;
124-   for (int  i=0 ; i < 3 ; i++){
125-     if ( pin == ((Stm32CurrentSenseParams*)cs_params)->pins [i]){ //  found in the buffer
126-       if  (use_adc_interrupt){
127-         return  adc_val[_adcToIndex (((Stm32CurrentSenseParams*)cs_params)->adc_handle )][channel_no] * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv ;
128-       }else { 
129-         //  an optimized way to go from i to the channel i=0 -> channel 1, i=1 -> channel 2, i=2 -> channel 3
130-         uint32_t  channel = _getADCInjectedRank (channel_no);
131-         return  HAL_ADCEx_InjectedGetValue (((Stm32CurrentSenseParams*)cs_params)->adc_handle , channel) * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv ;
132-       }
133-     }
134-     if (_isset (((Stm32CurrentSenseParams*)cs_params)->pins [i])) channel_no++;
135-   } 
136-   return  0 ;
95+   uint8_t  adc_index = (uint8_t )_adcToIndex (((Stm32CurrentSenseParams*)cs_params)->adc_handle );
96+   return  _readADCInjectedChannelVoltage (pin, (void *)cs_params, adc_interrupt_config[adc_index], adc_val[adc_index]); 
13797}
13898
13999extern  " C"   {
140100  void  HAL_ADCEx_InjectedConvCpltCallback (ADC_HandleTypeDef *AdcHandle){
141-     //  calculate the instance
142-     int  adc_index = _adcToIndex (AdcHandle);
143- 
144-     //  if the timer han't repetition counter - downsample two times
145-     if ( needs_downsample[adc_index] && tim_downsample[adc_index]++ > 0 ) {
146-       tim_downsample[adc_index] = 0 ;
147-       return ;
148-     }
149- 
150-     adc_val[adc_index][0 ]=HAL_ADCEx_InjectedGetValue (AdcHandle, ADC_INJECTED_RANK_1);
151-     adc_val[adc_index][1 ]=HAL_ADCEx_InjectedGetValue (AdcHandle, ADC_INJECTED_RANK_2);
152-     adc_val[adc_index][2 ]=HAL_ADCEx_InjectedGetValue (AdcHandle, ADC_INJECTED_RANK_3);
153-     adc_val[adc_index][3 ]=HAL_ADCEx_InjectedGetValue (AdcHandle, ADC_INJECTED_RANK_4);
101+     uint8_t  adc_index = (uint8_t )_adcToIndex (AdcHandle);
102+     _handleInjectedConvCpltCallback (AdcHandle, adc_interrupt_config[adc_index], adc_val[adc_index]);
154103  }
155104}
156105
106+ 
157107#endif 
0 commit comments