Skip to main content
DBurr
Senior
March 4, 2020
Question

Too many ADC interrupt calls added by CubeMX

  • March 4, 2020
  • 1 reply
  • 1429 views

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

This topic has been closed for replies.

1 reply

berendi
Principal
March 4, 2020

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.

DBurr
DBurrAuthor
Senior
March 5, 2020

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

berendi
Principal
March 5, 2020

> 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.