G071 LPTIM encoder mode creeps around
I'm using LPTIM1 in encoder mode and have noticed that, if there's jitter on one of the encoder signals the count will gradually creep up which should not be possible in encoder mode.
This is on a decent encoder that's got an RC network (per the Bourns data sheet / appnote) in front of it too so this isn't nasty HF noise, it's good solid pulses of 50-100ms or more on one channel but the counter seems to creep up.
Identical encoders wired to TIM2 / TIM3 behave normally, and my colleague has seen the same issue in another project using the same setup - LPTIM has a problem where TIMx does not.
Init code for LPTIM1:
/* LPTIM1 init function */
void MX_LPTIM1_Init(void)
{
/* USER CODE BEGIN LPTIM1_Init 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_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
/**LPTIM1 GPIO Configuration
PB5 ------> LPTIM1_IN1
PB7 ------> LPTIM1_IN2
*/
GPIO_InitStruct.Pin = ENC1_As_Pin;
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_5;
LL_GPIO_Init(ENC1_As_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = ENC1_Bs_Pin;
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_5;
LL_GPIO_Init(ENC1_Bs_GPIO_Port, &GPIO_InitStruct);
/* 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_NONE, LL_LPTIM_CLK_POLARITY_RISING);
LL_LPTIM_TrigSw(LPTIM1);
LL_LPTIM_SetInput1Src(LPTIM1, LL_LPTIM_INPUT1_SRC_GPIO);
LL_LPTIM_SetInput2Src(LPTIM1, LL_LPTIM_INPUT2_SRC_GPIO);
/* USER CODE BEGIN LPTIM1_Init 2 */
/*
* To activate the Encoder mode the ENC bit has to be set to ‘1’. The LPTIM must first be
* configured in Continuous mode.
* When Encoder mode is active, the LPTIM counter is modified automatically following the
* speed and the direction of the incremental encoder.
*/
LL_LPTIM_StartCounter(LPTIM1,LL_LPTIM_OPERATING_MODE_CONTINUOUS);
// This function must be called when the LPTIM instance is disabled.
LL_LPTIM_SetEncoderMode(LPTIM1, LL_LPTIM_ENCODER_MODE_RISING/*_FALLING*/);
/*
* This function must be called when the LPTIM instance is disabled.
* In this mode the LPTIM instance must be clocked by an internal clock
* source. Also, the prescaler division ratio must be equal to 1.
* LPTIM instance must be configured in continuous mode prior enabling
* the encoder mode.
*/
LL_LPTIM_EnableEncoderMode(LPTIM1);
LL_LPTIM_Enable(LPTIM1);
/*
* The counter just counts continuously between 0 and the
* auto-reload value programmed into the LPTIM_ARR register
* (0 up to ARR or ARR down to 0 depending on the direction).
* Therefore LPTIM_ARR must be configured before starting
*/
LL_LPTIM_SetAutoReload(LPTIM1, ENCODER_RELOAD);
//LPTIM instance must be enabled before starting the counter.
LL_LPTIM_StartCounter(LPTIM1,LL_LPTIM_OPERATING_MODE_CONTINUOUS);
/* USER CODE END LPTIM1_Init 2 */
}
