cancel
Showing results for 
Search instead for 
Did you mean: 

LPTIM encoder mode counting issue with LL Drivers on STM32L476RG Nucleo

BHuls.1
Associate II

I am currently working on a project using a sensor that sends quadrature encoded data. I have it wired so that the data is connected to comp1 and comp2 which in turn is read by the LPTIM1. LPTIM1 is set to encoder mode, but for some reason I for the life of me can't figure out why it won't count. If I use HAL drives instead everything works fine as I would expect. HAL_LPTIM_Encoder_Start_IT() is the function that seems to make all the difference and I cannot replicate what its doing with the LL drivers.

Mx Setup

0693W00000FDDmxQAH.png 

Below is the working code for HAL drivers with what the registers look like for comparison.

LPTIM_HandleTypeDef hlptim1;
 
/* LPTIM1 init function */
void MX_LPTIM1_Init(void)
{
 
  /* USER CODE BEGIN LPTIM1_Init 0 */
//	uint32_t count = 0;
 
  /* USER CODE END LPTIM1_Init 0 */
 
  /* USER CODE BEGIN LPTIM1_Init 1 */
 
  /* USER CODE END LPTIM1_Init 1 */
  hlptim1.Instance = LPTIM1;
  hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
  hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
  hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING_FALLING;
  hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_4TRANSITIONS;
  hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
  hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
  hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
  hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_EXTERNAL;
  hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_COMP1;
  hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_COMP2;
  if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPTIM1_Init 2 */
 
  /* Reset all interrupt flags for start up */
  hlptim1.Instance->ICR = 0x7F;
 
  HAL_LPTIM_Encoder_Start_IT(&hlptim1, 0x50);
  hlptim1.Instance->IER &= ~(LPTIM_IT_UP | LPTIM_IT_DOWN);
 
  /* USER CODE END LPTIM1_Init 2 */
 
}

0693W00000FDDmdQAH.pngLL Code and Register compare:

void MX_LPTIM1_Init(void)
{
 
  /* USER CODE BEGIN LPTIM1_Init 0 */
//	uint32_t count = 0;
 
  /* USER CODE END LPTIM1_Init 0 */
 
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_PCLK1);
 
  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
 
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
  /**LPTIM1 GPIO Configuration
  PC1   ------> LPTIM1_OUT
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
  /* LPTIM1 interrupt Init */
  NVIC_SetPriority(LPTIM1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(LPTIM1_IRQn);
 
  /* USER CODE BEGIN LPTIM1_Init 1 */
 
  /* USER CODE END LPTIM1_Init 1 */
  LL_LPTIM_SetClockSource(LPTIM1, LL_LPTIM_CLK_SOURCE_INTERNAL);
  LL_LPTIM_SetPrescaler(LPTIM1, LL_LPTIM_PRESCALER_DIV1);
  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_EXTERNAL);
  LL_LPTIM_ConfigClock(LPTIM1, LL_LPTIM_CLK_FILTER_4, LL_LPTIM_CLK_POLARITY_RISING_FALLING);
  LL_LPTIM_TrigSw(LPTIM1);
  LL_LPTIM_SetInput1Src(LPTIM1, LL_LPTIM_INPUT1_SRC_COMP1);
  LL_LPTIM_SetInput2Src(LPTIM1, LL_LPTIM_INPUT2_SRC_COMP2);
  /* USER CODE BEGIN LPTIM1_Init 2 */
 
  /* Reset all interrupt flags for start up */
//  hlptim1.Instance->ICR = 0x7F;
 
//  HAL_LPTIM_Encoder_Start_IT(&hlptim1, 0x50);
//  hlptim1.Instance->IER &= ~(LPTIM_IT_UP | LPTIM_IT_DOWN);
 
  LL_LPTIM_EnableIT_ARRM(LPTIM1);
  LL_LPTIM_Enable(LPTIM1);
 
  LL_LPTIM_SetAutoReload(LPTIM1, 32768UL);
  LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
  LL_LPTIM_EnableEncoderMode(LPTIM1);
 
  /* USER CODE END LPTIM1_Init 2 */
 
}

0693W00000FDDo0QAH.png 

The interesting thing is, I was able to get it to count in LL if using only Rising edge or only Falling edge but it was very inaccurate.

4 REPLIES 4

Read out LPTIM and relevant GPIO registers content and compare to working case.

JW

Yea that was one of the things I attempted to no avail. As far as I could tell the gpios, comps, and the LPTIM registers all looked the same. This is what lead me to believe that it might have to deal with the order in which setup/initialization was done in. Although, that doesn't really explain why on LL I can get the counter to work when I only do rising or falling edge but not both for clock polarity.

What is the input frequency of the signal?

And what's the LPTIM clock, i.e. how is RCC_CCIPR.LPTIM1SEL set, in both cases?

JW

The clock in the above code was set to the PCLK1 which is scaled down from the HSI to 8MHz. We plan on using the LSE for it which is a 32kHz crystal for low energy modes. The sensor that it is reading can go up to around 320Hz. I have tested with the LSE and it has the same issue in that with HAL it will count but LL it won't.