PIT ISR prioity Timing
Posted: Tue May 25, 2010 7:14 am
Here's a timing issue I'm trying to figure out. I have PIT timer1 running at a 0.01 sec interval triggering an ISR. The ISR increments two variables, one forever, the other from 0 to 99. When the 2nd variable is 99, I reset it to 0, and post a semaphore to a pending task called the ControlTask (which therefore runs 1X/sec). When ControlTask runs, it sets an output hi, does a OSTimeDly(1) to generate a 50mSec delay, then sets the output low. TICKS_PER_SECOND is set at the default of 20. As expected, I get a pulse every second, however, the pulsewidth varies a lot: from several microsecs at the shortest, to something less than the expected 50mSec. Have I mis-configured the prios for the PIT1 ISR? I'd like to ensure that ticks used in the ControlTask for variety of future purposes are not skewed somehow... Should I change the SR mask in the INTERRUPT macro (2200), or the IRQ level (2) or the IRQ priority (3) in the SetIntc() function? My understanding is that the SR mask digit "X" 2X00 must be the same as the IRQ "level" in SetIntc( IRQController, ISRFuctionAddr, vector, level, priority).
I've fooled with both the level (2, 3, or 4) and prio ( 3 or 7) variables, but don't seem to get much improvement. I also changed the OSTimeDly(1) in the Controltask to OSTimeDly(2). This produced time delays that were between 50 and 100 mSec, biut not the expected 100mSec. Looks like the last tick gets chopped off short?
Here's how the PIT1 is set up:
I've fooled with both the level (2, 3, or 4) and prio ( 3 or 7) variables, but don't seem to get much improvement. I also changed the OSTimeDly(1) in the Controltask to OSTimeDly(2). This produced time delays that were between 50 and 100 mSec, biut not the expected 100mSec. Looks like the last tick gets chopped off short?
Here's how the PIT1 is set up:
Code: Select all
//////VARIABLES: ===============================================================
//The following variables are incremented by the PIT and used to sequence
// when the tasks run.
volatile DWORD PIT_CountsSincePwrOn = 0; //++ every 10 msec = 1/100 sec).
volatile unsigned int PIT_TicksSinceControlTaskRan = 0;
//////OS SEMAPHORES, MAILBOXES, Qs, or FIFOs ===================================
OS_SEM ControlTaskSemaphore;
INTERRUPT( IRQ2TimeslicePIT_ISR, 0x2200) //SR mask= x2?00 where, here, ? = 2.
WORD tmp = sim.pit[1].pcsr; // Get PIT1 Control & Status Register
// data
// Clear PIT1 - Refer to table 23-3 for more information on what
// bits are being cleared and set
tmp &= 0xFF0F; // Bits 4-7 cleared
tmp |= 0x0F; // Bits 0-3 set
sim.pit[1].pcsr = tmp;
PIT_CountsSincePwrOn++; // Increment when an interrupt occurs
PIT_TicksSinceControlTaskRan++;
// Now see if it's time to post the semaphores to trigger other tasks...
if ( PIT_TicksSinceControlTaskRan >= (PIT_TICKS_IN_CONTROL_LOOP - 1) ) {
PIT_TicksSinceControlTaskRan = 0 ;
if ( PIT_ControlTaskEnabled ) {
ControlTaskSemPostRetVal = OSSemPost( &ControlTaskSemaphore) ;
}
}
}
///////////////////////////////////////////////////////////////////////
// SetUpPITR - PIT setup function. See chapter 23 of the 5235 reference
// manual for details
//
void SetUpPITR( int pitr_ch, WORD clock_interval, BYTE pcsr_pre /* See
table 23-3 in the reference manual for bits 8-11 */ )
{
WORD tmp;
if ( ( pitr_ch < 1 ) || ( pitr_ch > 3 ) ) {
iprintf( "*** ERROR - PIT channel out of range ***\r\n" );
return;
}
SetIntc( 0, // Interrupt controller 0
( long) &IRQ2TimeslicePIT_ISR, // Addr of function to install in
// the IRQ vector table
36 + pitr_ch, // The IRQ vector number
2, // The IRQ level ( Must be >= to
// the ? in SRmask or the
// INTERRUPT macro above.
3 ); // The IRQ priority
//
// Configure the PIT for the specified time values
//
sim.pit[pitr_ch].pmr = clock_interval; // Set PIT modulus value
tmp = pcsr_pre;
tmp = ( tmp << 8 ) | 0x0F;
sim.pit[pitr_ch].pcsr = tmp; // Set system clock divisor to 16 &
// set bits [3:0] in PCSR
}
void ControlTask (void *pdata) {
iprintf(" Starting ControlTask...\r\n");
while (1) {
OSSemPend ( &ControlTaskSemaphore, WaitForever ); //Pend on PIT
iprintf("Control\r\n");
ControlTaskActiveHiOutputPin = 1; // Task active: pin hi.
OSTimeDly(1);
ControlTaskActiveHiOutputPin = 0; //Task not active: pin lo.
}
}