Hi,
Device is MK22FN256VLL12, the LPTMR is currently using the LPO (1 kHz) with prescaler bypassed, running in time counter mode. What I am experiencing is about 2 ms overhead regardless of CMR value, e.g. until TCF is set. I check the LPO on PTE0 using the following setup:
SIM->SOPT1 |= SIM_SOPT1_OSC32KSEL(3) | SIM_SOPT1_OSC32KOUT(1);
The waveform looks as follows:
So about 1% slower, which is well within acceptable.
In the following, the clock output on PTE0 is disabled, it just works as a normal GPIO, configured as output
My LPTMR setups is as follows:
void LPTMR_init(void)
{
SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK;
LPTMR0->CSR = 0;
LPTMR0->PSR = LPTMR_PSR_PCS(1) | LPTMR_PSR_PBYP_MASK;
}
The LPTMR delay function looks like this:
void LPTMR_delay(uint16_t uValue)
{
LPTMR0->CMR = LPTMR_CMR_COMPARE(uValue);
LPTMR0->CSR |= LPTMR_CSR_TEN_MASK;
while(!(LPTMR0->CSR & LPTMR_CSR_TCF_MASK));
LPTMR0->CSR &= ~LPTMR_CSR_TEN_MASK;
GPIOE->PTOR = GPIO_PIN(0);
}
The function calling the LPTMR_delay is as follows:
do
{
LPTMR_delay(10);
}
while(1);
This is just called from main. The ONLY other ISR running at 20 ms intervals is the SysTick ISR, which just increases a counter and nothing else. The results when monitoring PTE0 using a scope, is as follows:
So what ought to be 10 ms toggle intervals is now approximately 12 ms intervals.
Any suggestions why I have an overhead of 2 ms and what I've misunderstood about the LPTMR?
Thanks a lot.
According to my understanding: When 1kHz LPO is used, LPTMR0->CMR=0x09 will lead 10ms timeout.
Additionally: When the LPTMR is enabled, the first increment will take an additional one or two prescaler clock cycles due to synchronization logic.
Best Regards,
Robin
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
In addition to this I tested with the 4 MHz fast IRC as clock for the LPTMR, downscaled to 1 MHz by the MCG, doing the following:
// Disable fast IRC (4 MHz) when FRDRIV is changed
MCG->C2 &= ~MCG_C2_IRCS_MASK;
// Divide by 4 to bring clock speed to 1 MHz.
// Make sure to clear any previous setting (reset default is 2!).
MCG->SC &= ~MCG_SC_FCRDIV_MASK;
MCG->SC |= MCG_SC_FCRDIV(2);
// Enable fast IRC again.
MCG->C2 |= MCG_C2_IRCS_MASK;
// Enable active IRC as MCGIRCLK for use with LPTMR.
MCG->C1 |= MCG_C1_IRCLKEN_MASK;
Then I configured PSR as follows:
LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PBYP_MASK;
Otherwise, the code is unchanged. The overhead with this configuration is about 2 us, not 2 ms, so quite acceptable!