cancel
Showing results for 
Search instead for 
Did you mean: 

Too many ADC interrupt calls added by CubeMX

DBurr
Senior

Hi, I've got some code that uses both ADC1 and ADC3 that I've generated with STM32CubeMX. For both ADCs I want to use interrupts. With this configuration however the CubeMX auto-generated code adds 2 separate calls to the same HAL interrupt handler, one for each ADC. How can I differentiate which ADC interrupt has actually triggered? And is there a way to get STM32CubeMX to not add multiple calls to the same function? This functionality that it's created if left in could definitely make the code misbehave. I noticed a similar thing with the auto-generated code for handling GPIO external interrupts on lines 5 to 15: if you have interrupts enabled for GPIOs on pins 5, 6 and 7, the interrupt service function will call the HAL interrupt handler 3 times, once for each GPIO even if only one interrupt has occurred.

Thanks,

Doug Burrell

6 REPLIES 6
berendi
Principal

The IRQ handlers should pass a handle as an argument to the HAL handler function, something like this

void ADC1_IRQHandler(void) {
    HAL_ADC_IRQHandler(&handle_to_adc1);
}
void ADC3_IRQHandler(void) {
    HAL_ADC_IRQHandler(&handle_to_adc3);
}

so the HAL function can figure out which peripheral has triggered the interrupt call. Every time it's called.

> the interrupt service function will call the HAL interrupt handler 3 times, once for each GPIO even if only one interrupt has occurred.

HAL was not designed with efficiency in mind. If nobody is holding a gun to your head, or forcing you to use it otherwise, start implementing your own interrupt handlers. Read the data register, put it into a volatile array (fixing a serious bug in HAL), clear interrupt flags if necessary, done. Then go on, remove HAL from other time-critical parts of your program.

The problem with the auto-generated code is that there is only 1 IRQ handler for all ADCs:

void ADC_IRQHandler(void)
{
  /* USER CODE BEGIN ADC_IRQn 0 */
 
  /* USER CODE END ADC_IRQn 0 */
  HAL_ADC_IRQHandler(&hadc1);
  HAL_ADC_IRQHandler(&hadc3);
  /* USER CODE BEGIN ADC_IRQn 1 */
 
  /* USER CODE END ADC_IRQn 1 */
}

and it doesn't seem like they thought about the fact that there might be more than one ADC in use at a time when they designed how it gets generated in this case... So anyway, yes I think I'm going to have to craft my own handler and read the data registers to determine which ADC caused the interrupt. It's just frustrating that ST has made such a buggy HAL!

Thanks,

Doug Burrell

> there is only 1 IRQ handler for all ADCs

Oops, I've missed that.

The HAL ADC handler would hopefully just return after checking some flags if the interrupt is triggered by the other ADC. It works (usually), just painfully slow.

The HAL ADC handler gets implemented by the user, so basically it's left to the user to handle the buggy auto-generated code. Might as well just not use the auto-generated code in the first place.

> Might as well just not use the auto-generated code in the first place.

The value of Cube-generated code, at least in a commercial context, is proportional to it's price.

Yes, that's 100% true!