RT1176-EVAL: Clock drift when using Periodic Interrupt Timer (PIT)

cancel
Showing results for 
Search instead for 
Did you mean: 

RT1176-EVAL: Clock drift when using Periodic Interrupt Timer (PIT)

87 Views
raddeh
Contributor I

I've been trying to build a real-time-clock using the PIT. But comparing the resulting msec-clock with my systems epoch time, I've been seeing a clock drift on the board. That shift is not constant, it's around 1 to 2 msec per minute. I'm asking myself: is this expected behaviour? Can I somehow improve the accuracy of this clock? Am I initialising it incorrectly? I've been using the PIT example in the SDK as a baseline. As SDK I'm using MCUXpresso Software Development Kit (SDK) in Version 2.9.1.

The following is my code handling this msec-clock. Note that the actual implementation is variable (e.g. a different period than 1msec could be set or other PIT channels could be used), to allow the usage of other PIT-timers as well. But for now I only use it for the msec-timer, and have set the variables to its constant values.

Initialisation of the PIT:

{
    PIT_Type * pit_base = PIT1;
    pit_config_t pitConfig;
    uint8_t pit_channel = 0;
    uint32_t usec = 1000;

    PIT_GetDefaultConfig(&pitConfig);
    PIT_Init(pit_base, &pitConfig);


    PIT_SetTimerPeriod(pit_base, pit_channel, USEC_TO_COUNT(usec, CLOCK_GetRootClockFreq(kCLOCK_Root_Bus))); //PIT always uses "Peripheral Bus Clock". Has no selectable clock source
    PIT_EnableInterrupts(pit_base, pit_channel, kPIT_TimerInterruptEnable);
    EnableIRQ(PIT1_IRQn);
    PIT_StartTimer(pit_base, pit_channel);
}

 

Handling PIT-IRQ:

void PIT1_IRQHandler(void)
{
    //which channel of PIT1? Clear irq flag, call callback-fct
    if(PIT_GetStatusFlags(PIT1, kPIT_Chnl_0) & kPIT_TimerFlag)
    {
        PIT_ClearStatusFlags(PIT1, kPIT_Chnl_0, kPIT_TimerFlag);
        update_clock(); ///< function increases a int64_t counter by 1
    }
    {...}

    /* Added for, and affects, all PIT handlers. For CPU clock which is much larger than the IP bus clock,
     * CPU can run out of the interrupt handler before the interrupt flag being cleared, resulting in the
     * CPU's entering the handler again and again. Adding DSB can prevent the issue from happening.
     */
    __DSB();
}

 

Initialisation of the `kCLOCK_Root_Bus`:

void BOARD_BootClockRUN(void)
{
    clock_root_config_t rootCfg = {0};

    [...]

    /* Configure BUS using SYS_PLL3_CLK */
#if __CORTEX_M == 7
    rootCfg.mux = kCLOCK_BUS_ClockRoot_MuxSysPll3Out;
    rootCfg.div = 2;
    CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg);
#endif

    [...]
}

 

Could it be, that the PIT counter isn't running during the handling of the interrupt? Or is the clock-source just not that stable on the EVAL-board? Would I be better of using the GPT for such high-precision timers? 

0 Kudos
1 Reply

63 Views
Omar_Anguiano
NXP TechSupport
NXP TechSupport

Hello

Hope you are well.  I will gladly help you with this.

I don´t think that the interrupt is causing this drift but I suggest you reserve the IRQ_Handler only for setting or clearing flags. You can create a callback that uses the function update_clock() each time the interruption is executed.

The precision of the timer is determined by the root clock, using the GPT will not make a considerable difference since they can be fed by the same clock.
The 24Mhz that feds the PLL3 has a good precision of +-20ppm so it is a good result.
I also suggest you use the latest version of the SDK(2.10.1)

You can also check the RTC functionality of the SNVS module, there is one example at the SDK of your board.

If you have more questions do not hesitate to ask me.
Best regards,
Omar

0 Kudos