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.
Petr hi,
Thank you for your suggestions, I couldn't check the time by scope yet but with the debugger I checked the CVAL and LDVAL values are changing as you can see below, values jump from ~4.000 to ~40.000 level at 782. call of doSlotBasedTaskScheduling() function. Do you have a forecast for that effect?
#define TASK_TIMER_NEW_LOAD_VALUE PIT.RTI.LDVAL.R
#define TASK_TIMER_CURRENT_LOAD_VALUE PIT.RTI.CVAL.R
GLOBAL void doSlotBasedTaskScheduling(void)
{
/* This function will be called for every 1 ms from the INTC module */
TASK_TIMER_INTERRUPT_FLAG = 0x00000001;
if (counterX < 2000)
{
array_period_rti_ldval[counterX] = TASK_TIMER_NEW_LOAD_VALUE;
array_period_rti_cval[counterX] = TASK_TIMER_CURRENT_LOAD_VALUE;
counterX++;
}
}
Regards,
Hi Petr,
LDVAL is only set in the initialization function as PIT.RTI.LDVAL.R = 39.999.
Regards,
Dear Petr,
I determined to use PIT instead of RTI timer. Therefore you can close the issue. Thank you very much for your help and support.
Regards,