Help with STM32H7A3 low power timer
I have the low power timer LPTIM1 working on a STM32H7A3 but the way I have to clear the IRQs is a little confusing. Here's my IRQHandler:
void LPTIM1_IRQHandler(void)
{
//Disable LPTIM1
CLEAR_BIT(LPTIM1->CR, 0x01);
//Clear IRQs
LL_LPTIM_ClearFlag_ARRM(LPTIM1);
LL_LPTIM_ClearFlag_CMPM(LPTIM1);
//Enable LPTIM1
SET_BIT(LPTIM1->CR, 0x01);
LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
lptim1TestTimerCallBack();
}I don't understand why I have to disable LPTIM1 before clearing the ARRM and CMPM IRQ flags. Nothing I've found in the reference manual says I need to do this. But if I don't, LPTIM1_IRQHandler keeps getting called with no delay. If I do the enable/disable dance, LPTIM1 function as I expect. If I understand correctly, disabling LPTIM1 stops the counter while I clear the IRQs. In this case, that little bit of added delay isn't a big issue but it doesn't seem right and I'd like to understand what I'm doing wrong.
Right now my lptim1TestTimerCallBack() doesn't do anything significant but it will in the future. Here it is anyway.
void lptim1TestTimerCallBack()
{
std::cout << "Hit LPTIM1Test lptim1TestTimerCallBack at systick: " << std::to_string(systickCtr) << std::endl;
timerCallBackCounter++;
hitTimerCallback = true;
};Here's my test program where I initialize the timer and start it up.
TEST(CPFTestGroup, LPTIM1Test)
{
SystemClock::configSystemClock();
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
/* Peripheral clock enable */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
/* LPTIM1 interrupt Init */
NVIC_SetPriority(LPTIM1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
NVIC_EnableIRQ(LPTIM1_IRQn);
LL_LPTIM_Disable(LPTIM1);
LL_LPTIM_SetClockSource(LPTIM1, LL_LPTIM_CLK_SOURCE_INTERNAL);
LL_LPTIM_SetPrescaler(LPTIM1, LL_LPTIM_PRESCALER_DIV128);
LL_LPTIM_SetPolarity(LPTIM1, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
LL_LPTIM_SetUpdateMode(LPTIM1, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
LL_LPTIM_SetCounterMode(LPTIM1, LL_LPTIM_COUNTER_MODE_INTERNAL);
LL_LPTIM_TrigSw(LPTIM1);
LL_LPTIM_SetInput1Src(LPTIM1, LL_LPTIM_INPUT1_SRC_GPIO);
LL_LPTIM_SetInput2Src(LPTIM1, LL_LPTIM_INPUT2_SRC_GPIO);
LL_LPTIM_ClearFlag_ARRM(LPTIM1);
LL_LPTIM_EnableIT_ARRM(LPTIM1);
LL_LPTIM_ClearFlag_CMPM(LPTIM1);
LL_LPTIM_EnableIT_CMPM(LPTIM1);
LL_LPTIM_Enable(LPTIM1);
LL_LPTIM_SetAutoReload(LPTIM1, 1024);
LL_LPTIM_SetCompare(LPTIM1, 1024);
LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
std::cout << "LPTIM1Test started at systick: " << std::to_string(systickCtr) << std::endl;
for (int i = 0; i < 1000000; i++)
{
LL_mDelay(1);
}
}For completeness, here's my configSystemClock function
void SystemClock::configSystemClock()
{
SystemClock_Config();
}
void SystemClock_Config(void)
{
/*AXI clock gating */
RCC->CKGAENR = 0xFFFFFFFF;
LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3)
{
}
LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
while (LL_PWR_IsActiveFlag_VOS() == 0)
{
}
LL_RCC_HSE_Enable();
/* Wait till HSE is ready */
while (LL_RCC_HSE_IsReady() != 1)
{
}
LL_PWR_EnableBkUpAccess();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_LOW);
LL_RCC_LSE_Enable();
/* Wait till LSE is ready */
while (LL_RCC_LSE_IsReady() != 1)
{
}
LL_RCC_HSE_EnableCSS();
LL_RCC_LSE_EnableCSS();
LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
LL_RCC_PLL1P_Enable();
LL_RCC_PLL1Q_Enable();
LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
LL_RCC_PLL1_SetM(3);
LL_RCC_PLL1_SetN(70);
LL_RCC_PLL1_SetP(2);
LL_RCC_PLL1_SetQ(35);
LL_RCC_PLL1_SetR(2);
LL_RCC_PLL1_Enable();
/* Wait till PLL is ready */
while (LL_RCC_PLL1_IsReady() != 1)
{
}
/* Intermediate AHB prescaler 2 when target frequency clock is higher than 80 MHz */
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
/* Wait till System clock is ready */
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
{
}
LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_16);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_16);
LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_1);
LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_1);
LL_SetSystemCoreClock(280000000);
/* Update the time base */
if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
{
SystemClock_Error_Handler();
}
LL_RCC_HSE_EnableCSS();
LL_RCC_LSE_EnableCSS();
}Thanks
