@@ -22,6 +22,12 @@ bool needs_downsample[3] = {1};
2222//  downsampling variable - per adc (3)
2323uint8_t  tim_downsample[3 ] = {1 };
2424
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+ 
2531void * _configureADCLowSide (const  void * driver_params, const  int  pinA, const  int  pinB, const  int  pinC){
2632
2733  Stm32CurrentSenseParams* cs_params= new  Stm32CurrentSenseParams {
@@ -56,19 +62,47 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
5662    cs_params->timer_handle ->Instance ->CNT  = cs_params->timer_handle ->Instance ->ARR ;
5763    //  remember that this timer has repetition counter - no need to downasmple
5864    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+     }
5973  }
74+ 
6075  //  set the trigger output event
6176  LL_TIM_SetTriggerOutput (cs_params->timer_handle ->Instance , LL_TIM_TRGO_UPDATE);
6277
6378  //  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+   }
6585
6686  //  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+   }
72106
73107
74108  //  restart all the timers of the driver
@@ -83,32 +117,34 @@ void* _driverSyncLowSide(void* _driver_params, void* _cs_params){
83117
84118//  function reading an ADC value and returning the read voltage
85119float  _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)));
86123  uint8_t  channel_no = 0 ;
87124  for (int  i=0 ; i < 3 ; i++){
88125    if ( pin == ((Stm32CurrentSenseParams*)cs_params)->pins [i]){ //  found in the buffer
89-       # ifdef  SIMPLEFOC_STM32_ADC_INTERRUPT 
126+       if  (use_adc_interrupt){ 
90127        return  adc_val[_adcToIndex (((Stm32CurrentSenseParams*)cs_params)->adc_handle )][channel_no] * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv ;
91-       # else 
128+       } else { 
92129        //  an optimized way to go from i to the channel i=0 -> channel 1, i=1 -> channel 2, i=2 -> channel 3
93130        uint32_t  channel = _getADCInjectedRank (channel_no);
94131        return  HAL_ADCEx_InjectedGetValue (((Stm32CurrentSenseParams*)cs_params)->adc_handle , channel) * ((Stm32CurrentSenseParams*)cs_params)->adc_voltage_conv ;
95-       # endif 
132+       } 
96133    }
97134    if (_isset (((Stm32CurrentSenseParams*)cs_params)->pins [i])) channel_no++;
98135  } 
99136  return  0 ;
100137}
101138
102- #ifdef  SIMPLEFOC_STM32_ADC_INTERRUPT
103139extern  " C"   {
104140  void  HAL_ADCEx_InjectedConvCpltCallback (ADC_HandleTypeDef *AdcHandle){
105141
106142    //  calculate the instance
107143    int  adc_index = _adcToIndex (AdcHandle);
108144
109145    //  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 ;
112148      return ;
113149    }
114150
@@ -117,6 +153,5 @@ extern "C" {
117153    adc_val[adc_index][2 ]=HAL_ADCEx_InjectedGetValue (AdcHandle, ADC_INJECTED_RANK_3);    
118154  }
119155}
120- #endif 
121156
122157#endif 
0 commit comments