struggle to use LPTIM with LSE clock, timer frequency different by factor of 10 to 32,768 kHz
Hello,
I struggle to use the LSE clock as a source for timer LPTIMER1. My MC is a STM32L051R8Tx and I am using Keil MDK-Lite. ARM Compiler default 5.
For debugging purpose I am using the following settings: PSC = 1; ARR = 3275; Interrupt: Auto-reload match. In the IRQ handler I toggle a LED to measure the frequency by use of a manual stop-watch.
I cant measure the 32,768 kHz. Instead I measure the following:
| with printf() statement in loop | with debugger | Lowest drive | ~3,276kHz |
| with printf() statement in loop | without debugger | Lowest drive | ~3,276kHz |
| without printf() | with debugger | Lowest drive | ~150Hz |
| without printf() | without debugger | Lowest drive | ~50Hz |
The frequency is approx. factor 10 less and will dramatically go down when I remove the printf statement inside the while(1) loop. Can someone please give me some hints where I need to have a look on?
bool low_power_timer_init(void)
{
RCC->APB1ENR |= RCC_APB1ENR_PWREN; // 1: Power interface clock enabled
RCC->APB1ENR |= RCC_APB1ENR_LPTIM1EN; // 1: Low-power timer clock enabled
RCC->CCIPR |= RCC_CCIPR_LPTIM1SEL_0; // 11: LSE clock selected as LP Timer cloc
RCC->CCIPR |= RCC_CCIPR_LPTIM1SEL_1; // 11: LSE clock selected as LP Timer cloc
PWR->CR |= PWR_CR_DBP; // 1: Access to RTC, RTC Backup and RCC CSR registers enabled
PWR->CR; // Dummy read, needed due to timings?
LPTIM1->CR = 0; // CFGR must only be modified when the LPTIM is disabled
LPTIM1->CFGR &= ~LPTIM_CFGR_CKSEL; // 0: LPTIM is clocked by internal clock source (APB clock or any of the embedded oscillators)
LPTIM1->CFGR &= ~LPTIM_CFGR_COUNTMODE; // 0: the counter is incremented following each internal clock pulse
RCC->CSR |= RCC_CSR_LSEON; // Enable LPTIM -> LSE (32.768 kHz) clock
// Wait until the LSE oscillator is stable
WaitForConditionToTrue(((RCC->CSR) & RCC_CSR_LSERDY) == RCC_CSR_LSERDY,
I2C_POLL_TIME, return false);
//RCC->CSR |= RCC_CSR_LSEDRV_1; // 11: Highest drive
//RCC->CSR |= RCC_CSR_LSEDRV_0;
RCC->CSR &= ~RCC_CSR_LSEDRV_1; // 00: Lowest drive
RCC->CSR &= ~RCC_CSR_LSEDRV_0;
PWR->CR &= ~PWR_CR_DBP; // Lock Access to CSR register
// If any bit in the LPTIM_IER register (Interrupt Enable Register) is set after that its
// corresponding flag in the LPTIM_ISR register (Status Register) is set, the interrupt is not
// asserted.
LPTIM1->ICR |= LPTIM_ICR_ARRMCF; // Writing 1 to this bit clears the ARRM flag in the LPTIM_ISR register
LPTIM1->IER |= LPTIM_IER_ARRMIE; // 1: ARRM interrupt enabled
//The LPTIM_CFGR register must only be modified when the LPTIM is disabled (ENABLE bit reset to ‘0’).
//LPTIM1->CFGR |= LPTIM_CFGR_PRELOAD; // Registers are updated at the end of the current LPTIM period
LPTIM1->CFGR &= ~LPTIM_CFGR_PRELOAD; // 0: Registers are updated after each APB bus write access
LPTIM1->CFGR &= ~LPTIM_CFGR_TRIGEN_0; // 00: software trigger (counting start is initiated by software)
LPTIM1->CFGR &= ~LPTIM_CFGR_TRIGEN_1; // 00: software trigger (counting start is initiated by software)
LPTIM1->CFGR &= ~LPTIM_CFGR_PRESC_0; // 000: /1
LPTIM1->CFGR &= ~LPTIM_CFGR_PRESC_1;
LPTIM1->CFGR &= ~LPTIM_CFGR_PRESC_2;
return true;
}
void low_power_timer_enable(void)
{
LPTIM1->CNT = 0; // Reset counter value
LPTIM1->CR |= LPTIM_CR_ENABLE; // 1:LPTIM is enabled
LPTIM1->CR |= LPTIM_CR_CNTSTRT; // Setting this bit starts the timer in Continuous mode
// This bit can be set only when the LPTIM is enabled.
LPTIM1->CMP = 0; // CMP is the compare value used by the LPTIM.
// This bit can be set only when the LPTIM is enabled.
LPTIM1->ARR = 3276-1; // This value must be strictly greater than the CMP[15:0] value
// This bit can be set only when the LPTIM is enabled.
}
main()
low_power_timer_enable();
while(1)
{
//printf("\r");
}