2025-04-26 1:28 PM
Hi all,
I have an application where I'm trying to use input capture to capture pulse intervals in a specific period of time. At maximum, the pulses will happen frequently enough that I can't use the straight interrupt capture with HAL_TIM_IC_Start_IT, as it will starve out other tasks. My thought is to use a DMA engine with HAL_TIM_IC_Start_DMA. At the moment, the DMA interrupt triggers when the data buffer is full. However, since I need to record over a specific period, this isn't sufficient - in that period there may be no events, or less than one buffer's worth of data. What I'm thinking is something like this (please pardon the pseudocode):
HAL_TIM_Base_Start_IT(tim1); //start timer to measure period
HAL_TIM_IC_Start_DMA(tim2); //start input capture
while(1) //handle other tasks while waiting on input capture
{
//do other things here
}
//input capture period timer has elapsed, so stop capture and store data
base_time_interrupt()
{
//stop IC
HAL_TIM_IC_Stop_DMA();
//DMA input capture data from peripheral
//get number of samples captured
}
Is this possible, or is there another viable option to gather this data? If this is possible, what needs to be done?
Some implementation details:
I'm using the STM32G474RE on the NUCLEO-G474R board. I'm using STM32CubeIDE configuration utility to set up and configure the peripherals, and using TIM2 CH3 for the input capture.
Solved! Go to Solution.
2025-04-27 6:41 AM
"DMA with HAL_TIM_IC_Stop_DMA() will transfer"
No, it would not. Do transfer yourself.
What is not clear, if data lost is critical, I think two input capture processes using two timers may be better option, than stopping one for data manipulation would not interrupt data flow since secondary runs.
"we're looking to store the total number of pulses received, the intervals between those pulses, and the number of pulses received in a given timeframe"
Counting non-zero in data buff provides number of pulses received, subtracting value-N from value-N+1 gives interval in timers ticks.
2025-04-26 6:17 PM
What frequency?
The PWM Input mode uses two channels (off one pin) to measure Frequency and Duty
You can also free-run a TIM, and have it time stamp pulses, and use DMA as a means to build a list, at quite significant rates.
2025-04-27 4:50 AM
I'm looking at frequencies between 500khz and 1MHz, but it's not a consistent signal - over a set period of time I could have zero pulses or many.
WRT free-running a TIM, my impression is that that is what the TIM input capture mode does. Are you suggesting something different? My problem is that the DMA operation is triggered when it has filled the buffer by timestamping a set number of pulses, but I need to get to the count and data at a given rate regardless of whether the buffer is full or not.
WRT to PWM, I don't need the extra information (freq + pw), and I think I'd still have the same question of how to prematurely trigger the DMA to return the data from the peripheral to local memory.
2025-04-27 5:51 AM
I'd reserve two buffers.
Start DMA, in circular mode with buf-0, and sample data as in any real-time application like audio etc, when two interrupts -half complete -full complete tels which half of buffer just filled. Copy data and zero content.
If no interrupt in a while -secondary timer as watch clock to time interval, than stop dma and restart immediately pointing to buf-1, so minimum data lost during switching over.
Examine content buf-0 . What ever is not 0 is last sampled data
Tell more about application, sure there possibility of another solution
2025-04-27 6:26 AM
I think this is pretty close to what I'm looking for. I think the important part is that if there's no half- or full-complete interrupt, stopping the DMA with HAL_TIM_IC_Stop_DMA() will transfer whatever data had been captured up to that point - is that true?
This application boils down to a pulse counter - we're looking to store the total number of pulses received, the intervals between those pulses, and the number of pulses received in a given timeframe.
2025-04-27 6:41 AM
"DMA with HAL_TIM_IC_Stop_DMA() will transfer"
No, it would not. Do transfer yourself.
What is not clear, if data lost is critical, I think two input capture processes using two timers may be better option, than stopping one for data manipulation would not interrupt data flow since secondary runs.
"we're looking to store the total number of pulses received, the intervals between those pulses, and the number of pulses received in a given timeframe"
Counting non-zero in data buff provides number of pulses received, subtracting value-N from value-N+1 gives interval in timers ticks.
2025-04-27 6:56 AM
I see, this is what I was looking for. Thanks for your help!