AnsweredAssumed Answered

PIT & RTI Load Values in MPC5644A

Question asked by Turgay Kale on Apr 3, 2020
Latest reply on Apr 15, 2020 by Turgay Kale

Hi,

I have been facing wrong PIT and RTI load register values in MPC5644A microcontroller. My board has a crystal oscillator that drives at 40 MHz and microcontroller system frequency is at 150 MHz. I want to use RTI timer for generating an interrupt for every 1 ms and want to use PIT0 for measuring the time triggered from RTI timer.

 

freq_rti = 40 MHz thus period for a single RTI pulse is 1 / 40.000.000 = 25 ns

freq_pit0 = 150 MHz thus period for a single PIT pulse is 1 / 150.000.000 = 6,667 ns

 

***************************************************************************************************************

#define RTI_READ_LOAD_VALUE             PIT.RTI.CVAL.R

#define RTI_INTERRUPT_FLAG                 PIT.RTI.TFLG.R

#define PIT0_READ_LOAD_VALUE           PIT.TIMER[0].CVAL.R 

 

static void RTI_init (void)
{
   PIT.PITMCR.B.MDIS_RTI = 0;     // clear MDIS_RTI; enable clock for RTI
   PIT.PITMCR.B.FRZ = 1;              // Timers are stopped in debug mode
   PIT.RTI.LDVAL.R = 40.000.000 / 1000 - 1;     // RTI load register value for generating interrupt for every 1 ms
   PIT.RTI.TCTRL.B.TIE = 1;                              // let RTI generate interrupts
   PIT.RTI.TCTRL.B.TEN = 1;                            // start RTI

 

   // assign interrupt function for RTI ISR vector number
   INTC_InstallINTCInterruptHandler(doSlotBasedTaskScheduling, 305, 1);       // RTI vector: 305
}

 

static void PIT0_init (void)

{

   /* 30: MDIS = 0 to enable clock for PITs. */
   /* 31: FRZ = 1 for Timers stopped in debug mode */
   PIT.PITMCR.R = 0x00000001;
   PIT.TIMER[0].LDVAL.R = (150.000.000 / 1000) * 10 - 1; // PIT0 load value to measure 10 ms time range

 

   /* clear the TIF flag */
   PIT.TIMER[0].TFLG.R = 0x00000001;

 

   /* 30: TIE = 0 for interrupt request disabled */
   /* 31: TEN = 1 for timer active */
   PIT.TIMER[0].TCTRL.R = 0x00000001;

}

 

GLOBAL void doSlotBasedTaskScheduling (void)
{
   /* This function will be called for every 1 ms from the INTC module */

 

  RTI_INTERRUPT_FLAG = 0x00000001;     // clear RTI timer interrupt flag

 

   if (counterX < 2000)
   {
      array_period_rti[counterX] = RTI_READ_LOAD_VALUE;
      array_period_pit0[counterX] = PIT0_READ_LOAD_VALUE;

      counterX++;
   }

}

 

***************************************************************************************************************

P.M. RTI timer is sourced from the external crystal oscilator thus there may be a bunch of delayed cycles for reading RTI values.

 

I expect to read approximately 40.000 - 1 - delay_rti = ~39.999 cycles (1 ms) from the RTI load register value but I read 3977. And I couldn't understand why.

 

 

And similarly, I expect to read approximately 150.000 - 1 = ~ 149.999 cycles (1 ms) between two ordered PIT0 load register value readings but I read approximately 15.000 cycles (ex.119.966-104.976 = ~14.990) between two ordered PIT0 readings. 

 

 

Would you pls help me to fix the problem?

Thank you.

Outcomes