cancel
Showing results for 
Search instead for 
Did you mean: 

How to Toggle a Debug Pin When ADC Conversion Starts in DMA Mode on STM32?

BitCurious
Associate II

Hello,
I am working with an STM32 G4 series microcontroller and using the ADC in DMA mode to handle continuous conversions. My goal is to SET a GPIO (debug pin) at the start of an ADC conversion and RESET it at the end of the conversion.

Currently, I am able to RESET the GPIO pin in the HAL_ADC_ConvCpltCallback() function, which is called after the conversion completes. However, since DMA mode doesn't involve regular polling or interrupt-based conversions for the start, I am unsure where to place the GPIO SET code.

Here are the details of my setup:

  • ADC Trigger Source: TIM2
  • TIM2 Configuration: FCLK = 60 MHz, PSC = 0, ARR = 469 (Triggering ADC at ~128 kHz).
  • DMA Mode: Circular, 12-bit resolution.

Is there a recommended way to toggle or set a debug pin when the ADC conversion process starts? Would I need to modify the HAL driver, or is there a way to do this using timer-based callbacks or HAL functions?

Any guidance, examples, or best practices would be greatly appreciated.

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions

@BitCurious wrote:

what is meant by raw timings? 


As I stated before, you will not get the exact theoretical timings due to the API and interrupt overheads.

+

expected : 250ns; practical : 2.6µs
expected : 600ns; practical : 3.8µs

-> here you are experimenting something in the order of the 100ns which is very short for the CPU and not enough for it to handle that execution.

and:

expected : 10.8µs; practical : 13.16µs 
expected : 4.2µs; practical : 6µs  2us

-> Here you are seeing the impact of the overhead (HAL functions, interrupt). From 2us to 2.6us.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
PS:
1 - This is NOT an online support (https://ols.st.com) but a collaborative space.
2 - Please be polite in your reply. Otherwise, it will be reported as inappropriate and you will be permanently blacklisted from my help.

View solution in original post

6 REPLIES 6
TDK
Guru

Since your sampling is tied to the timer, you could set channel 1 of the timer to go high/low at the times the ADC samples, but you would have to know these times and set them explicitly.

There's no way to call code at the exact moment the ADC starts sampling with DMA. Nor is there a way to tie code at the exact moment sampling stops. HAL_ADC_ConvCpltCallback happens after sampling, but quite a bit after it.

If you feel a post has answered your question, please click "Accept as Solution".

Is it possible to achieve in interrupt mode? By toggling a debug pin at the start and completion of conversion, considering the ADC is not in continuous conversion mode?


@BitCurious wrote:

Is it possible to achieve in interrupt mode? By toggling a debug pin at the start and completion of conversion, considering the ADC is not in continuous conversion mode?


Not at the exact timing of the ADC start and stop but at a rawly timings if the start and the stop: taking into account the overheads.

You can set the IO just before ADC start and reset it in the end of conversion using the end of ADC conversion callback HAL_ADC_ConvCpltCallback().

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
PS:
1 - This is NOT an online support (https://ols.st.com) but a collaborative space.
2 - Please be polite in your reply. Otherwise, it will be reported as inappropriate and you will be permanently blacklisted from my help.

If you toggle the pin in an interrupt, it will not be at the exact start of the conversion due to the way interrupts works. It takes the cpu time to start the interrupt, execute code. This includes some amount of jitter.

And again, from before:

> There's no way to call code at the exact moment the ADC starts sampling with DMA. Nor is there a way to tie code at the exact moment sampling stops. HAL_ADC_ConvCpltCallback happens after sampling, but quite a bit after it.

If you feel a post has answered your question, please click "Accept as Solution".

what is meant by raw timings? 

while (1)
{
    HAL_ADC_Start_IT(&hadc1);
    HAL_GPIO_WritePin(PA9_GPIO_Port, PA9_Pin, GPIO_PIN_SET);
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    HAL_GPIO_WritePin(PA9_GPIO_Port, PA9_Pin, GPIO_PIN_RESET);
    dmaBuffer = HAL_ADC_GetValue(&hadc1);
}

I did tests in multiple configurations, everytime my practical values were always around 3µs more than the theoretical.
expected : 250ns; practical : 2.6µs
expected : 10.8µs; practical : 13.16µs
expected : 4.2µs; practical : 6µs
expected : 600ns; practical : 3.8µs

i felt like there is some offset, and the values that i get are not nearby the theoretical values.


@BitCurious wrote:

what is meant by raw timings? 


As I stated before, you will not get the exact theoretical timings due to the API and interrupt overheads.

+

expected : 250ns; practical : 2.6µs
expected : 600ns; practical : 3.8µs

-> here you are experimenting something in the order of the 100ns which is very short for the CPU and not enough for it to handle that execution.

and:

expected : 10.8µs; practical : 13.16µs 
expected : 4.2µs; practical : 6µs  2us

-> Here you are seeing the impact of the overhead (HAL functions, interrupt). From 2us to 2.6us.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
PS:
1 - This is NOT an online support (https://ols.st.com) but a collaborative space.
2 - Please be polite in your reply. Otherwise, it will be reported as inappropriate and you will be permanently blacklisted from my help.