cancel
Showing results for 
Search instead for 
Did you mean: 

LPTIM not generating interrupts using HAL_LPTIM_Counter_Start_IT from STM32H7xx_HAL_Driver.

AJame.1
Associate II

I'm trying to generate periodic interrupts with an LPTIM on an STM32H723. I'm using HAL_LPTIM_Counter_Start_IT() from the STM32H7xx_HAL_Driver. My interrupt handler is never being called. I've confirmed that my interrupt handler is in the vector table and at the offset specified in the STM32H723 reference manual. Here's my code for starting up LPTIM1.

void lptim1_start(void)
{
  uint32_t  period = 500;
 
  hlptim1.Instance             = LPTIM1;
  hlptim1.Init.Clock.Source    = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
  hlptim1.Init.Trigger.Source  = LPTIM_TRIGSOURCE_SOFTWARE;
  hlptim1.Init.OutputPolarity  = LPTIM_OUTPUTPOLARITY_HIGH;
  hlptim1.Init.UpdateMode      = LPTIM_UPDATE_IMMEDIATE;
  hlptim1.Init.CounterSource   = LPTIM_COUNTERSOURCE_INTERNAL;
  hlptim1.Init.Input1Source    = LPTIM_INPUT1SOURCE_GPIO;
  hlptim1.Init.Input2Source    = LPTIM_INPUT2SOURCE_GPIO;
 
  HAL_LPTIM_Init(&hlptim1);
 
  HAL_LPTIM_RegisterCallback(&hlptim1, HAL_LPTIM_AUTORELOAD_MATCH_CB_ID, my_callback);
 
  HAL_LPTIM_Counter_Start_IT(&hlptim1, period);
}
 
void LPTIM1_IRQHandler(void)
{
  HAL_LPTIM_IRQHandler(&hlptim1);
}

And just for reference, here's the HAL_LPTIM_Counter_Start_IT() code:

/**
  * @brief  Start the Counter mode in interrupt mode.
  * @param  hlptim LPTIM handle
  * @param  Period Specifies the Autoreload value.
  *         This parameter must be a value between 0x0000 and 0xFFFF.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_LPTIM_Counter_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Period)
{
  /* Check the parameters */
  assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
  assert_param(IS_LPTIM_PERIOD(Period));
 
  /* Set the LPTIM state */
  hlptim->State = HAL_LPTIM_STATE_BUSY;
 
  /* If clock source is not ULPTIM clock and counter source is external, then it must not be prescaled */
  if ((hlptim->Init.Clock.Source != LPTIM_CLOCKSOURCE_ULPTIM)
      && (hlptim->Init.CounterSource == LPTIM_COUNTERSOURCE_EXTERNAL))
  {
    /* Check if clock is prescaled */
    assert_param(IS_LPTIM_CLOCK_PRESCALERDIV1(hlptim->Init.Clock.Prescaler));
    /* Set clock prescaler to 0 */
    hlptim->Instance->CFGR &= ~LPTIM_CFGR_PRESC;
  }
 
  /* Enable the Peripheral */
  __HAL_LPTIM_ENABLE(hlptim);
 
  /* Clear flag */
  __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARROK);
 
  /* Load the period value in the autoreload register */
  __HAL_LPTIM_AUTORELOAD_SET(hlptim, Period);
 
  /* Wait for the completion of the write operation to the LPTIM_ARR register */
  if (LPTIM_WaitForFlag(hlptim, LPTIM_FLAG_ARROK) == HAL_TIMEOUT)
  {
    return HAL_TIMEOUT;
  }
 
  /* Disable the Peripheral */
  __HAL_LPTIM_DISABLE(hlptim);
 
  if (HAL_LPTIM_GetState(hlptim) == HAL_LPTIM_STATE_TIMEOUT)
  {
    return HAL_TIMEOUT;
  }
 
  /* Enable Autoreload write complete interrupt */
  __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_ARROK);
 
  /* Enable Autoreload match interrupt */
  __HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_ARRM);
 
  /* Enable the Peripheral */
  __HAL_LPTIM_ENABLE(hlptim);
 
  /* Start timer in continuous mode */
  __HAL_LPTIM_START_CONTINUOUS(hlptim);
 
  /* Change the TIM state*/
  hlptim->State = HAL_LPTIM_STATE_READY;
 
  /* Return function status */
  return HAL_OK;
}

LPTIM1_IRQHandler is in my interrupt vector table, but it's never being called.

In stepping through HAL_LPTIM_Counter_Start_IT(), I've noticed some odd behavior in the timer's registers. Specifically, the Auto Reload Match (ARRM) and Compare Match (CMPM) flags get set in the interrupt status register (LPTIM_ISR) immediately after the timer is commanded to start in line 60, even though LPTIM_CNT hasn't yet reached the LPTIM_ARR. It doesn't seem to me like the ARRM should be set yet. I've also tried clearing it immediately with __HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARRM), but the flag won't clear from LPTIM_ISR.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

You need to enable the NVIC interrupt as well.

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

View solution in original post

2 REPLIES 2
TDK
Guru

You need to enable the NVIC interrupt as well.

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

That was the piece I was missing. Once I did that, I get my interrupts as expected. Thanks!