2022-02-28 10:26 PM
Hi all,
I wanted to make use of LPTIM1 module of STM32H723ZG for generating 1ms interrupt.
Clock frequency used 64Mhz (HSI).
Environment: Nucleo 144 STM32H723ZG
Prescaler: Divide by 128
Auto reload register value: 500u
Below is the code snippet of init function:
void Timer_driver_init(void)
{
// Enable the peripheral clock for LPTIM1
RCC->APB1LENR = RCC_APB1LENR_LPTIM1EN;
// NVIC initialization
NVIC_EnableIRQ(LPTIM1_IRQn);
// Configure LPTIM
TIMER->CFGR |= TIMER_INTERNAL_CLK | TIMER_COUNTERSOURCE_INTERNAL|
TIMER_SOFTWARE_TRIGGER | TIMER_UPDATE_IMMEDIATE ;
// Update Prescaler
TIMER->CFGR |= TIMER_PRESCALER ;
// Update the Auto Reload Register
TIMER->ARR = TIMER_PERIOD;
// Enable Auto Reload Match interrupt
TIMER->IER |= LPTIM_IER_ARRMIE;
// Enable the LPTIM module
TIMER->CR |= LPTIM_CR_ENABLE;
// Wait for timer counter to be enabled
while ((TIMER->CR & LPTIM_CR_ENABLE) != LPTIM_CR_ENABLE);
// Start the counter once it is enabled
TIMER->CR |= LPTIM_CR_CNTSTRT;
}
Interrupt Handler callback:
void Timer_driver_irqHandler(void)
{
static uint16_t HwTimer_tick_count_l_u16 = 0U;
if(TIMER->ISR & LPTIM_ISR_ARRM)
{
// Autoreload match clear flag
TIMER->ICR |= LPTIM_ICR_ARRMCF;
d_HwTimer_counter_mS_u16++; // Increment mS counter
HwTimer_tick_count_l_u16++;
if(HwTimer_tick_count_l_u16 == 1000U)
{
d_HwTimer_counter_S_u16++; // Increment S counter
HwTimer_tick_count_l_u16 = 0;
}
}
}
Problem: The timer interrupt is too frequent, its not generating at 1ms.
Kindly help me with this issue.
Thanking you in advance.
Regards
Arrhenius
Solved! Go to Solution.
2022-03-02 06:25 AM
Seems unlikely that CNT=0 in both examples. If you reload registers, can you see it change value?
> TIMER->ARR = TIMER_PERIOD;
> TIMER->CR |= LPTIM_CR_ENABLE;
You're touching ARR before the counter is enabled, which is not allowed:
2022-03-01 06:24 AM
How often is it triggering? What happens if you increase the period?
> TIMER->ICR |= LPTIM_ICR_ARRMCF;
ICR is write-only, this should be
TIMER->ICR = LPTIM_ICR_ARRMCF;
but unlikely that's the issue.
2022-03-01 08:43 AM
Hi @TDK,
Thanks for responding.
How often is it triggering?
A: It's getting triggered in few microseconds. Didn't measure the exact value.
What happens if you increase the period?
A:Even if I increase the period I can notice that the interrupt triggers little slowly. but still it cannot match 1ms.
ICR is write-only, this should be
Yes, your observation is right. ICR is write only register. But the statement is clearing the Autoreload match clear flag.
2022-03-01 02:23 PM
Please read out and check/post LPTIM registers content.
JW
2022-03-01 10:52 PM
2022-03-02 03:38 AM
CFGR is zero, so your setup (including prescaler setup) apparently does not work.
Check the symbols you are using there; or, better, use consistently symbols from CMSIS-mandated device header.
Also note, that peripheral registers may not be available immediately after peripheral's clock being switched on in RCC, read Clock switches and gating subchapter of RCC chapter in RM.
JW
2022-03-02 04:57 AM
CFGR is zero because I was trying out different combinations.
Attached is the updated configuration with DIV/128 Prescaler.
I am using CMSIS header file.
I agree with your point on peripheral registers may not be available immediately, In my case there's sufficient time and that's the reason I am able to write something in the register.
2022-03-02 06:25 AM
Seems unlikely that CNT=0 in both examples. If you reload registers, can you see it change value?
> TIMER->ARR = TIMER_PERIOD;
> TIMER->CR |= LPTIM_CR_ENABLE;
You're touching ARR before the counter is enabled, which is not allowed:
2022-03-10 07:56 PM
Hi @TDK ,
Yeah you were right. I missed out with the sequence.
I got it working now. Thanks a lot.