Hi,
At the moment I'm not doing anything with the USART interrupt - it's never been fired during these tests. But I'll need to use it for the "front end" later on - if I get there - and the is to stuff data into a buffer and signal the main program when a LF or CR arrives.

Just so we're all on the same page, here are the current interupts:
INT2_INT - High priority ISR in ASM
IC2QEIF_INT - High priority ISR in PBP but "declared" as ASM in the INT_LIST macro
TMR2_INT - Low priroity ISR in PBP
RX_INT - Low priotity ISR in PBP


I originally had the TMR2 interrupt as high priority but then I didn't get more than a few kHz before it started to miss pulses. The DoServo routine that is run as the TMR2 ISR is quite "heavy" since it does all the math including the PID routine:
Code:
DoServo:                                    'Interrupt handler starts here.
PortB.5 = 1                                 'Used for timing purposes
GetPosition:
'Since the position counter isn't double buffered we can get to situations
'where the lowbyte overflows between readings of the high and low byte. This
'is prevented by reading the high byte two times and compare the two readings.
'If they are the same then we're fine, if not re-read the registers.
  
    PosHigh = POSCNTH                       'Get high byte of counter
    PosLow = POSCNTL                        'Get low byte of counter
    PosTemp = POSCNTH                       'Get high byte again
    
    If PosHigh - PosTemp = 0 then Goto Done 'Compare, if equal we're done.
    
    PosHigh = POSCNTH                       'If not, get values again.
    PosLow = POSCNTL

Done:  
'The high word of the Position variable is handled by the RollOver ISR that gets
'tripped by IC2QEIF when POSCNT = MAXCNT.
    
    Position.Word0 = POSHIGH * 256 + PosLow 'Put high and lowbyte together.
    Speed = Position - oldPosition          'Calculate current motor speed.

    INTCON3.4 = 0                           'Temporarily disable INT2 interrupt
    TempStepBuffer = StepBuffer
    StepBuffer = 0
    INTCON3.4 = 1                           'Re-enable INT2 interrupt.

    If TempStepBuffer.7 = 1 then            'Step buffer is negative
     Setpoint = Setpoint - ABS (TempStepBuffer)
    Else
     SetPoint = Setpoint + TempStepBuffer
    Endif
    pid_Error = Setpoint - Position          'Calculate error....
    
'Now we have our error-signal in the variable that the PID-routine expects
'so we call the PID-filter with a GOSUB. The filter will respond with the
'output in variable pid_out.

    Gosub PID                               'and send to PID filter
' (PID filter execution time measured to ~190uS worst case @20Mhz)
 
    If pid_out.15 = 0 then                  'If the output from the pid-filter
       Direction = 1                        'is positive we want to drive the
       Duty = pid_Out                       'motor forward.
    Else
       Direction = 0                        'If it's negative we want to drive
       Duty = ABS (pid_Out)                 'it backwards.
    Endif

    CCP1CON.5 = Duty.1                      'Set the two LSB's of the dutycycle-
    CCP1CON.4 = Duty.0                      'register. Then shift them out and
    CCPR1L = Duty >> 2                      'set the remainig 8 bits.
    
    oldPosition = Position                  'Store position for next interrupt.

ISRCount = ISRCount + 1
PortB.5 = 0

@  INT_RETURN                               ;ISR is complete, return from here.
The actual PID code isn't shown here, I've measured the execution time of the complete DoServo ISR and it seems to vary alot, from 160uS all the way up to 400uS.

So, I guess I'll need to stick with DT-Ints since re-writing the DoServo routine including the PID code in ASM would take me years. Question is what else, if anything, can be improved to increase the speed. The thing is that I was hoping to add more code to the DoServo routine but I guess that may not be a good idea.

Thanks alot guys!

/Henrik.