2022-05-21 11:48 AM
I am having a problem using Timer1 DMA to create a waveform used by one of our peripherals. I have set the timer to count up to 65K with a 1uS tick, and channel 4 as a comparator with a toggle output.I am generating the time between pulses in a table, then using DMA to have the timer generate the waveform, For example if I generate a table with 10, 15, and 25, the waveform goes high after 10uS, low after 15uS, and high again after 25uS.
The code below works, but there is a 65mS delay before the waveform starts. I suspect the timer is counting form 0 to 65K, then being reloaded, then the waveform starts. I need the waveform to start immediately. Any idea why this is happening?
void SendMessage(uint32_t message)
{
CreatePeriodTable(message);
MODULE_DATA_EN_HIGH;
TIM1->CR1 &= ~TIM_CR1_CEN; /* Disable the Timer */
TIM1->CNT = 0;
TIM1->CCR4 = 0;
TIM1->CR1 |= TIM_CR1_CEN; /* Enable the Timer */
HAL_TIM_OC_Start_DMA(&htim1, TIM_CHANNEL_4, PeriodTable, TABLE_SIZE);
}
2022-05-21 04:25 PM
It's happening because TIM_CR1_ARPE is enabled and can be solved by triggering TIM_EGR_UG before enabling the timer.
2022-05-21 06:00 PM
TIMx_CR1.ARPE does not influence direct writes to TIMx_CNT, so that's probably not the issue here.
After enabling the counter by setting TIMx_CR1.CEN it starts to count up, so by the time the Cube/HAL function enables DMA in TIMx_DIER, TIMx_CNT is already > 0 so it will match TIMx_CCR4 only after the wraparound.
One way to tackle this would be changing TIMx_CCR4 to 1 and moving the enabling of counter after calling the HAL_TIM_OC_Start_DMA() function.
JW