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,
it looks the LDVAL is changed during runtime. Could this be the case in your code?
BR, Petr
Hi Petr,
LDVAL is only set in the initialization function as PIT.RTI.LDVAL.R = 39.999.
Regards,
Hi,
if a debugger has an option to put breakpoint on register write, use it for LDVAL.
BR, Petr
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,
Hi,
try to check RTI.CVAL and RTI.LDVAL values within debugger and also measure generated interval by scope (toggle some pin). Do you see expected results?
BR, Petr