Weird latency inside the interrupts and DMA, STM32F407 - Page 1
Forum section: electronics / general

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 12, 2018, 05:14:33 pm
content: Hi,I enabled the ADC DMA inside the Timer2 interrupt, and Put '1' for a GPIO PIN, as follows:void TIM2_IRQHandler(void){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, 1);HAL_ADC_Start_DMA(&hadc1, (uint32_t *) buffer, 100);HAL_TIM_IRQHandler(&htim2);}Then inside the ADC interrupt, I wrote '0' for the GPIO PIN and disabled the ADC DMA.void DMA2_Stream0_IRQHandler(void){HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, 0);HAL_ADC_Stop_DMA(&hadc1);HAL_DMA_IRQHandler(&hdma_adc1);}An interrupts latency is around 3 to 4uS. I confirmed it by toggling a PIN inside the timer interrupt with no other code.ADC DMA holds 100 samples which takes around 50uS. In this code the PIN value change is above any code, BUT why the ADC conversion values gets added to the generated pulse?I mean after firing the Timer interrupt + 4uS, I should see a rising edge on the oscilloscope screen, but I see that rising edge after 50uS. The GPIO code is ABOVE ADC code.I test this phase shift with another clean signal with the same frequency by an oscilloscope, then I realized this. The frequency of the ISR pulse is low and 100Hz.That's important for me here is the beginning. because I want to make sure that the ADC conversion starts on-time, not too late.it's weird, why?

author: mikerj
author_rank: Super Contributor
timestamp: July 13, 2018, 07:34:34 am
content: Quote from: VanitarNordic on July 12, 2018, 05:14:33 pmHow do you generate this 'clean' signal to align with the Timer interrupt firing?

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 13, 2018, 08:04:42 am
content: Quote from: mikerj on July 13, 2018, 07:34:34 amWith another timer in PWM mode and kept it fixed at 100Hz. we can make it also with generator, it doesn't matter here.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 13, 2018, 02:34:16 pm
content: Do you mean that if you just comment out "HAL_ADC_Start_DMA(&hadc1, (uint32_t *) buffer, 100);" from TIM2_IRQHandler(), you get a 4 µs latency?

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 13, 2018, 02:59:11 pm
content: Quote from: SiliconWizard on July 13, 2018, 02:34:16 pmif I remove that, the DMA interrupt will not be called, but simple toggling inside the timer interrupt shows its 4uS delay for rising.HAL_ADC_Start_DMA(&hadc1, (uint32_t *) buffer, 100); itself has around 40..45uS delay or something, BUT the weird thing is that this should not matter when the rising edge of the GPIO gets fired before this function.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 13, 2018, 06:24:49 pm
content: Not sure yet about your interrupt latency, but have you looked at the very first interrupt call? (Single shot)About the time HAL_ADC_Start_DMA() takes, I think I got why. Had to dig a little deeper and look at what I did back then.HAL_ADC_Start_DMA() calls ADC_Enable(), which itself has an ADC "stabilization" loop and a calibration loop that probably explain the delay.As I suggested, you should write your own HAL_ADC_Start_DMA()-like function optimized for your needs, and enable the ADC just once at init time, instead of every time as HAL_ADC_Start_DMA() does.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 13, 2018, 06:37:36 pm
content: HAL_ADC_Start_DMA() runs the ADC calibration?!This is again a great example why you shouln't use those totally broken-by-design libraries.The design doesn't need to be much more complex than the simplest LED blinker, and you'll be reading through the complete library implementation and debugging it.The funny part? - The library implementation is like 1000 lines for you to debug, using it is 100 lines of application code, while just writing the whole thing directly islessthan those 100 lines, under your complete control.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 13, 2018, 06:44:44 pm
content: Yep, STM's HAL is a monster. It's a decent starting point when you begin with STM32 micros though. Another benefit is the relative portability of the code across the entire line. But there's also the LL library which is quite a bit less bloated.The good thing is that the whole HAL's source code is available, so it can be a starting point for writing your own code.

author: VanitarNordic
author_rank: Frequent Contributor
timestamp: July 13, 2018, 07:19:10 pm
content: I have no problem with the delay of the HAL_ADC_Start_DMA(&hadc1, (uint32_t *) buffer, 100);it's delay is correct because each conversion takes around 0.5uS and 100 * 0.5uS is 50uSMy problem is that the GPIO PIN change is BEFORE this function. Then it is not clear that this massive delay come from where.When 100 ADC sampling finishes, it calls its DMA interruptThe frequency of timer interrupt is much lower than the DMA interrupt, therefore before the next timer interrupt, definitely the conversions have finished and the DMA interrupt has called