AnsweredAssumed Answered

MK20 LPTMR clocked from ERCLK32K

Question asked by Simon Haines on Mar 28, 2019
Latest reply on Mar 31, 2019 by Simon Haines

I am trying to clock the low power timer on a MK20FX512 from a 32.768kHz crystal attached to XTAL32/EXTAL32, but the timer does not work from that clock source.

 

Here is what I have tried:

  • Clocking the LPTMR from the 1kHz LPO works as expected.
  • Clocking the LPTMR from the OSC0ERCLK works as expected (this is a 16MHz clock).
  • The RTC derived from XTAL32/EXTAL32 works as expected and is accurate.

 

The documentation states that setting LPTMR0_PSR[PCS] to 0b10 uses 'ERCLK32K — secondary external reference clock' as the clock source, however the timer does not operate from that clock source.

 

Here is some code that demonstrates how I am setting up the peripherals.

// Enable real-time clock
SIM->SCGC6 |= SIM_SCGC6_RTC_MASK;
// Disable time counter for setup
RTC->CR = 0;
RTC->SR = 0;
// RTC oscillator (EXTAL32/XTAL32) is 12.5pF +/-10ppm, enable oscillator and enable output
RTC->CR = RTC_CR_SC8P_MASK | RTC_CR_SC4P_MASK | RTC_CR_CLKO_MASK | RTC_CR_OSCE_MASK;
RTC->TSR = 0x01;  // Reset the seconds count, clearing the 'time invalid' flag
RTC->SR = RTC_SR_TCE_MASK;  // Enable time counter
// Select RTC oscillator as source for ERCLK32K
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL_MASK;

// Enable LPTIMER trigger interrupt at 10Hz
SIM->SCGC5 |= SIM_SCGC5_LPTIMER_MASK;
LPTMR0->CSR = 0;  // Disable timer for setup

LPTMR0->PSR = LPTMR_PSR_PCS(0b10) | LPTMR_PSR_PRESCALE(0b0110);  // Select RTC 32.768kHz clock /32768 = 1kHz
LPTMR0->CMR = 100;  // Set compare value: 1kHz / 100 = 10Hz

// Enable interrupts
NVIC_SetPriority(LPTimer_IRQn, 0x02);
NVIC_EnableIRQ(LPTimer_IRQn);

// Enable timer and interrupt
LPTMR0->CSR = LPTMR_CSR_TIE_MASK | LPTMR_CSR_TEN_MASK;

volatile int rtc, status;
while (true) {
     rtc = RTC->TSR;    // This increments as expected
     status = RTC->SR;  // This is 0b10000 = 'time counter enabled'
}

 

The timer interrupt simply toggles a pin that can monitor timer operation.

 

void LPTimer_IRQHandler() {
     // Clear timer compare flag
     LPTMR0->CSR |= LPTMR_CSR_TCF_MASK;

     // Toggle a status pin SPARE1 (PTC12)
     PTC->PTOR |= (1 << 12);
}

 

When setting LPTMR0_PSR[PCS] to either 0b01 (LPO) or 0b11 (OSC0ERCLK), the interrupt triggers as expected. When the clock source is set to 0b10 (ERCLK32K), the interrupt is never triggered.

 

Am I missing something in my setup?

Outcomes