cancel
Showing results for 
Search instead for 
Did you mean: 

LPTIM PWM and Interrupt Issues

Daniel L
Associate III

I am having problems running LPTIM1 off the LSE. When I set up and interrupt it is firing ever clock cycle and does not seem to be clearing. RCC_BDCR_LSERDY bit is active before selecting the LPTIM1 clock source. I have also tried disabling the interrupt and just enabling a PWM output. This results in a toggle every clock cycle on the output pin instead of the expected duty cycle and period.

Is this related to the issue mentioned in this errata (2.7.2)?

static void LPTIM_Init(void)
{
	/* Disable LPTIM1 */
	RCC->APB1ENR1 &= ~RCC_APB1ENR1_LPTIM1EN;
 
	/* Change Clock Source */
	RCC->CCIPR &= ~RCC_CCIPR_LPTIM1SEL;
	RCC->CCIPR |= RCC_CCIPR_LPTIM1SEL_0 | RCC_CCIPR_LPTIM1SEL_1; // Select LSE as source
 
	/* Reset LPTIM1 */
	RCC->APB1RSTR1 |= RCC_APB1RSTR1_LPTIM1RST;
	RCC->APB1RSTR1 &= ~RCC_APB1RSTR1_LPTIM1RST;
 
	/* Enable During Sleep */
	RCC->APB1SMENR1 |= RCC_APB1SMENR1_LPTIM1SMEN; //Enable During Sleep
	RCC->C2APB1SMENR1 |= RCC_C2APB1SMENR1_LPTIM1SMEN; //Enable During CPU2 CSleep mode 
 
 
	/* Enable LPTIM1 */
	RCC->APB1ENR1 |= RCC_APB1ENR1_LPTIM1EN;
 
	RCC->BDCR |= RCC_BDCR_LSCOSEL; // Select LSE for LSCO
	RCC->BDCR |= RCC_BDCR_LSCOEN; // Enable LSCO
 
	LPTIM1->CFGR = 0;
	LPTIM1->CMP = 49;
	LPTIM1->ARR = 199;
	LPTIM1->IER = LPTIM_IER_ARRMIE;
 
	/* System interrupt init*/
	HAL_NVIC_SetPriority(LPTIM1_IRQn, 7, 0);
	HAL_NVIC_EnableIRQ(LPTIM1_IRQn);
 
	LPTIM1->CR |= LPTIM_CR_ENABLE;
	LPTIM1->CR |= LPTIM_CR_CNTSTRT;
}
 
void LPTIM1_IRQHandler(void)
{
	if(isr & LPTIM_IT_ARRM)
	{
		LPTIM1->ICR = LPTIM_ICR_ARRMCF;
		Toggle_Pin();
	}
}

Thanks,

Daniel

1 ACCEPTED SOLUTION

Accepted Solutions
Daniel L
Associate III

Just found out that LPTIM works differently to normal Timers as the CMP and ARR Registers need to be set after the Enable.

	LPTIM1->CR |= LPTIM_CR_ENABLE;
 
	LPTIM1->CMP = 49;
	LPTIM1->ARR = 199;
 
	LPTIM1->CR |= LPTIM_CR_CNTSTRT;

View solution in original post

2 REPLIES 2
Daniel L
Associate III

Just found out that LPTIM works differently to normal Timers as the CMP and ARR Registers need to be set after the Enable.

	LPTIM1->CR |= LPTIM_CR_ENABLE;
 
	LPTIM1->CMP = 49;
	LPTIM1->ARR = 199;
 
	LPTIM1->CR |= LPTIM_CR_CNTSTRT;

Le Corre Pierre
Associate III

Dear @Daniel L​ ,

You can check inside the STM32Cube_FW_WB_V1.2.0, there is an example demonstrating the PWM generation from LPTIM clocked from LSE:

  • It demonstrate how to configure and use, through the HAL LPTIM API, the LPTIM peripheral using LSE as counter clock, to generate a PWM signal, in a low-power mode.
  • It is available, inside the zip under: Projects\P-NUCLEO-WB55.Nucleo\Examples\LPTIM\LPTIM_PWM_LSE

This example seems the best fit for your problem.

You can also checks:

  • LPTIM_PWMExternalClock: How to configure and use, through the HAL LPTIM API, the LPTIM peripheral using an external counter clock, to generate a PWM signal at the lowest power consumption.
  • LPTIM_PulseCounter: How to configure and use, through the LPTIM HAL API, the LPTIM peripheral to count pulses.
  • LPTIM_Timeout: How to implement, through the HAL LPTIM API, a timeout with the LPTIMER peripheral, to wake up the system from a low-power mode.

If you prefer low level driver, you can also refer to:

  • LPTIM_PulseCounter: This one demonstrate how to use the LPTIM peripheral in counter mode to generate a PWM output signal and update its duty cycle. This example is based on the STM32WBxx LPTIM LL API. The peripheral is initialized with LL unitary service functions to optimize for performance and size.
  • Available under: Projects\P-NUCLEO-WB55.Nucleo\Examples_LL\LPTIM\LPTIM_PulseCounter

Pierre.