# Interrupts

Started by May 8, 2008
Hi guys,

So I have two output compare interrupts setup such that the handlers
look up in a circulating table (one for each handler) the state a port
should be in and when the next interrupt should occur, then sets the
port and loads the next interrupt into TC#. This table is dynamic
based on user input. Anyway everything seems to work as I planned
when interrupts are not occurring at a high speed rate and or close
together. However, my needs are for a very close, sometimes the same
time, interrupts. The issue (confusion) I'm experiencing is when I
need two interrupts to occur at the same time and then the two same
interrupts to occur again .1 mS later. So I know I'm limited by the
length of my interrupt handler, however here's the weird thing. I
would expect in this scenario to see:
OC_0 Interrupt occur at T(0mS)
0C_1 Interrupt occur at T(0mS+cycle time of OC_0_HANDLER)
OC_0 Interrupt occur at T(.1mS, assuming cycle time <.1ms)
0C_1 Interrupt occur at T(.1mS+cycle time of 0C_0_Handler)

However what I see is this:
OC_0 Interrupt occur at T(0mS)
OC_0 Interrupt occur at T(.1mS)
0C_1 Interrupt occur at T(.1mS+some arbitrary time)
0C_1 Interrupt occur at T(.1mS+some arbitrary time+.1uS)

So I haven't been a good engineer and calculated exactly the cycle
time of the handlers, but I'm assuming since, even though in the wrong
order, I see 0C_0 occur twice within the distance they're programmed
to occur at, my cycle time is less than .1mS, which will suffice for
my tolerance.

Any ideas to why I might be seeing this?
Thanks,
Matt
Matt wrote:

> Hi guys,
>
> So I have two output compare interrupts setup such that the handlers
> look up in a circulating table (one for each handler) the state a port
> should be in and when the next interrupt should occur, then sets the
> port and loads the next interrupt into TC#. This table is dynamic
> based on user input. Anyway everything seems to work as I planned
> when interrupts are not occurring at a high speed rate and or close
> together. However, my needs are for a very close, sometimes the same
> time, interrupts. The issue (confusion) I'm experiencing is when I
> need two interrupts to occur at the same time and then the two same
> interrupts to occur again .1 mS later. So I know I'm limited by the
100uS is a lot even for 8MHz busclock. Your circulating table etc should
work.

> length of my interrupt handler, however here's the weird thing. I
> would expect in this scenario to see:
> OC_0 Interrupt occur at T(0mS)
> 0C_1 Interrupt occur at T(0mS+cycle time of OC_0_HANDLER)
> OC_0 Interrupt occur at T(.1mS, assuming cycle time <.1ms)
> 0C_1 Interrupt occur at T(.1mS+cycle time of 0C_0_Handler)
>

I see nothing wrong above.

> However what I see is this:
> OC_0 Interrupt occur at T(0mS)
> OC_0 Interrupt occur at T(.1mS)
> 0C_1 Interrupt occur at T(.1mS+some arbitrary time)
> 0C_1 Interrupt occur at T(.1mS+some arbitrary time+.1uS)
>

Let me guess, is this some arbitrary time close to 2^16 * timer_tick? I
think it's just a well known wrong flag-clear sequence. Show us your code,
at least show how are you clearing timer flags.

Edward
> So I haven't been a good engineer and calculated exactly the cycle
> time of the handlers, but I'm assuming since, even though in the wrong
> order, I see 0C_0 occur twice within the distance they're programmed
> to occur at, my cycle time is less than .1mS, which will suffice for
> my tolerance.
>
> Any ideas to why I might be seeing this?
> Thanks,
> Matt
>
Edward,
I'm not 100 % sure what the arbitrary time is. One thing is I'm on a 2MHZ
Bus clk, I would like to jump up to 16, but not sure if I can just do that
right away. I'm on a dev board and use their software to write to the chip,
and think they have timing characteristics built into their code based on
the clk speed they sent the board operating on.

Basically for my handlers, I have time_stamps of when I need to change
state. So I always store the current time stamp and use that and the next
time stamp to calculate the # of ticks until the next interrupt. Wording
may be a bit confusing down below. Logic in beginning of handler is to
decide if end of index has arrived and need to start at beginning. State
and Time Stamp arrays are out of phase by one index.

So I also calculated the number of cycles the program should take and in the
worst case shouldn't be more than 140 cycles. which should be under 100uS
with my bus speed. What's the lapse time between when the interrupt occurs,
and the handler starts executing? large, or something like exiting the
interrupt (10 cycles)? When I set and clear a port bit on entry and exit of
interrupt and measure that on a scope I get something like 120uS, approx
representation of handler cycle time.

;********************************************************************
;OC_INIT -- Initialization of the Interuptfor OC0
;Going to set up a periodic interupt on OC0-2 (Output Compare 0-2)
;Prescale is set to 3
;********************************************************************
OC_INIT:
sei ;disable interrupts
bset DDRP, #\$FF ;make port P output
bset DDRT, #\$FF ;make port T output
bset DDRM, #\$FF ;make port M output
clr PTP ;make port P outputs all zero
clr PTT ;make port T outputs all zero
clr PTM ;make port M outputs all zero
bset TIOS, #\$07 ;set interrupt on OC0-2
movb #\$90, TSCR1 ;set TEN (Timer Enable) & fast clear
movb #\$03, TSCR2 ;set Prescaler to make counter ticks operate at
;250kHz instead of E-clk of 8MHz
bset TIE, #\$07 ;Arm C[0-2]F,
movb #\$07, TFLG1 ;clear C[0-2]F (OC[0-2] Flag)
OC_RE_INIT:
ldd TCNT ;load current clock tick in d
addd #\$4E20 ;offset the clock tick by 80 ms for first interrupt
std TC0 ;store the next interrupt time in Timer Capture
Channel 0
std TC1 ;store the next interrupt time in Timer Capture
Channel 1
std TC2 ;store the next interrupt time in Timer Capture
Channel 2
clr OXYGEN_INDEX1
clr FUEL_INDEX1
clr SPARK_INDEX1
clr OXYGEN_PREV_DELAY
clr FUEL_PREV_DELAY
clr SPARK_PREV_DELAY
ldaa #\$02
staa OXYGEN_INDEX2
staa FUEL_INDEX2
staa SPARK_INDEX2
;cli ;initialize interrupts
rts ;return from subroutine
;********************************************************************
;OC0_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
;Test state of PORTP and apply the opposite to it
; Incrementing loop is working. checked output of both indexes !
;********************************************************************
OC0_HANDLER:
;bset TFLG1, #\$01 ;Acknowledge interupt and clear flag
ldaa OXYGEN_NUM_STATES
deca
cmpa OXYGEN_INDEX1
bne COMP2_OK0
bclr OXYGEN_INDEX2, #\$FF

COMP2_OK0:
ldaa OXYGEN_INDEX1 ;Check Current Index
cmpa OXYGEN_NUM_STATES
bne INDEX_OK0 ;Index is less than 6
bclr OXYGEN_INDEX1, #\$FF ;reset ENG1_INDEX1 to zero
ldd #\$0000
std OXYGEN_PREV_DELAY

INDEX_OK0:
ldy #OXYGEN_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa OXYGEN_INDEX2 ;retrieve current index
ldd a,y ;index the array
subd OXYGEN_PREV_DELAY
addd TC0 ;Calc next State Change
std TC0 ;Load next State Change.
ldy #OXYGEN_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa OXYGEN_INDEX2 ;retrieve current index
ldd a,y ;index the array
std OXYGEN_PREV_DELAY
ldy #OXYGEN_STATES ; put base address of STATE Array in X
ldaa OXYGEN_INDEX1 ;retrieve current index
ldab a,y ;index the array
eorb PTP ;
stab PTP ;make state change on PORT P
inc OXYGEN_INDEX1 ;retrieve current index
ldaa OXYGEN_INDEX2 ;retrieve previous index for delay array
adda #\$02 ;increment by 2 (16-bit)
staa OXYGEN_INDEX2 ;store next index value
rti ;return from subroutine
;********************************************************************
;OC1_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
;Test state of PORTP and apply the opposite to it
; Incrementing loop is working. checked output of both indexes !
;********************************************************************
OC1_HANDLER:
;bset TFLG1, #\$02 ;Acknowledge interupt and clear flag
ldaa FUEL_NUM_STATES
deca
cmpa FUEL_INDEX1
bne COMP2_OK1
bclr FUEL_INDEX2, #\$FF

COMP2_OK1:
ldaa FUEL_INDEX1 ;Check Current Index
cmpa FUEL_NUM_STATES
bne INDEX_OK1 ;Index is less than 6
bclr FUEL_INDEX1, #\$FF ;reset ENG1_INDEX1 to zero
ldd #\$0000
std FUEL_PREV_DELAY

INDEX_OK1:
ldy #FUEL_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa FUEL_INDEX2 ;retrieve current index
ldd a,y ;index the array
subd FUEL_PREV_DELAY
addd TC1 ;Calc next State Change
std TC1 ;Load next State Change.
ldy #FUEL_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa FUEL_INDEX2 ;retrieve current index
ldd a,y ;index the array
std FUEL_PREV_DELAY
ldy #FUEL_STATES ; put base address of STATE Array in X
ldaa FUEL_INDEX1 ;retrieve current index
ldab a,y ;index the array
eorb PTT ;
stab PTT ;make state change on PORT P
inc FUEL_INDEX1 ;retrieve current index
ldaa FUEL_INDEX2 ;retrieve previous index for delay array
adda #\$02 ;increment by 2 (16-bit)
staa FUEL_INDEX2 ;store next index value
rti ;return from subroutine

;********************************************************************
;OC2_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
;Test state of PORTP and apply the opposite to it
; Incrementing loop is working. checked output of both indexes !
;********************************************************************
OC2_HANDLER:
;bset TFLG1, #\$04 ;Acknowledge interupt and clear flag
ldaa SPARK_NUM_STATES
deca
cmpa SPARK_INDEX1
bne COMP2_OK2
bclr SPARK_INDEX2, #\$FF

COMP2_OK2:
ldaa SPARK_INDEX1 ;Check Current Index
cmpa SPARK_NUM_STATES
bne INDEX_OK2 ;Index is less than 6
bclr SPARK_INDEX1, #\$FF ;reset ENG1_INDEX1 to zero
ldd #\$0000
std SPARK_PREV_DELAY

INDEX_OK2:
ldy #SPARK_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa SPARK_INDEX2 ;retrieve current index
ldd a,y ;index the array
subd SPARK_PREV_DELAY
addd TC2 ;Calc next State Change
std TC2 ;Load next State Change.
ldy #SPARK_TIMESTAMP ;put base address of TIMESTAMP Array in Y
ldaa SPARK_INDEX2 ;retrieve current index
ldd a,y ;index the array
std SPARK_PREV_DELAY
ldy #SPARK_STATES ; put base address of STATE Array in X
ldaa SPARK_INDEX1 ;retrieve current index
ldab a,y ;index the array
eorb PTM ;
stab PTM ;make state change on PORT P
inc SPARK_INDEX1 ;retrieve current index
ldaa SPARK_INDEX2 ;retrieve previous index for delay array
adda #\$02 ;increment by 2 (16-bit)
staa SPARK_INDEX2 ;store next index value
rti ;return from subroutine
Lots of Thanks,
Matt

On Fri, May 9, 2008 at 12:06 AM, Edward Karpicz wrote:

> Matt wrote:
>
> > Hi guys,
> >
> > So I have two output compare interrupts setup such that the handlers
> > look up in a circulating table (one for each handler) the state a port
> > should be in and when the next interrupt should occur, then sets the
> > port and loads the next interrupt into TC#. This table is dynamic
> > based on user input. Anyway everything seems to work as I planned
> > when interrupts are not occurring at a high speed rate and or close
> > together. However, my needs are for a very close, sometimes the same
> > time, interrupts. The issue (confusion) I'm experiencing is when I
> > need two interrupts to occur at the same time and then the two same
> > interrupts to occur again .1 mS later. So I know I'm limited by the
>
> 100uS is a lot even for 8MHz busclock. Your circulating table etc should
> work.
>
> > length of my interrupt handler, however here's the weird thing. I
> > would expect in this scenario to see:
> > OC_0 Interrupt occur at T(0mS)
> > 0C_1 Interrupt occur at T(0mS+cycle time of OC_0_HANDLER)
> > OC_0 Interrupt occur at T(.1mS, assuming cycle time <.1ms)
> > 0C_1 Interrupt occur at T(.1mS+cycle time of 0C_0_Handler)
> > I see nothing wrong above.
>
> > However what I see is this:
> > OC_0 Interrupt occur at T(0mS)
> > OC_0 Interrupt occur at T(.1mS)
> > 0C_1 Interrupt occur at T(.1mS+some arbitrary time)
> > 0C_1 Interrupt occur at T(.1mS+some arbitrary time+.1uS)
> > Let me guess, is this some arbitrary time close to 2^16 * timer_tick? I
> think it's just a well known wrong flag-clear sequence. Show us your code,
> at least show how are you clearing timer flags.
>
> Edward
>
> > So I haven't been a good engineer and calculated exactly the cycle
> > time of the handlers, but I'm assuming since, even though in the wrong
> > order, I see 0C_0 occur twice within the distance they're programmed
> > to occur at, my cycle time is less than .1mS, which will suffice for
> > my tolerance.
> >
> > Any ideas to why I might be seeing this?
> > Thanks,
> > Matt
> >
> >
> >
> >
> >
sorry for delay

Matt Gauthier wrote:

> Edward,
> I'm not 100 % sure what the arbitrary time is. One thing is I'm on a 2MHZ
> Bus clk, I would like to jump up to 16, but not sure if I can just do that
> right away. I'm on a dev board and use their software to write to the
> chip,
> and think they have timing characteristics built into their code based on
> the clk speed they sent the board operating on.
>

Your code sets timer fot fast flag clear (FFC). I wrongly assumed you are
using normal flag clear sequence. And regarding normal flag clear I only
found commented out lines like this one

> ;bset TFLG1, #\$01 ;Acknowledge interupt and clear flag

Bset'ing TFLG1 would be wrong as it would clear not only bit0 (\$01 mask),
but also all other TFLG1 flags. So if TC0 and TC1 were close to each other,
TC0 handler would clear TC1 flag and delay TC1 handler for about 2^16 timer
ticks. Normal flag clear can be done two ways. Either you write bitmask to
flags register, like somewhere in your code:

> movb #\$07, TFLG1 ;clear C[0-2]F (OC[0-2] Flag)

, or bclear TFLG1 with inverse bitmask. For example, to clear TC0 flag you
do

bclr TFLG1,#\$FE
bset ORs register/memory byte with pattern you specify. That's the problem
for flags that are clearable by writing ones to them. If you had TC1 and TC0
flags set, then bsetting TFLG1 with #1 would write 3 back to TFLG1 and clear
both TC0 and TC1 flags. Now you may figure yourself why bclr TFLG1,#\$FE may
be used and bset can't.

But your code uses FFC and my guess was wrong. I never used FFC (I found it
suspicious ant not really fast many years ago), but I don't see anything
wrong in how you are clearing timer flags. More shots:

1) are you accessing TCx registers somewhere not from your TCx handlers?
That could clear timer flags (due FFC) and lead to effects you described
previously.
2) is there somewhere bset TFLG1 not in your TC0-TC2 handlers? That could
clear all timer flags and lead to something odd.
2) are you using BDM debugger with memory window pointed at TCx
registers? -"-
> Basically for my handlers, I have time_stamps of when I need to change
> state. So I always store the current time stamp and use that and the next
> time stamp to calculate the # of ticks until the next interrupt. Wording
> may be a bit confusing down below. Logic in beginning of handler is to
> decide if end of index has arrived and need to start at beginning. State
> and Time Stamp arrays are out of phase by one index.
>

Yes, it's something smart and confusing. Can't TCx be used as old timestamp
on ISR entry?

> So I also calculated the number of cycles the program should take and in
> the
> worst case shouldn't be more than 140 cycles. which should be under 100uS
> with my bus speed. What's the lapse time between when the interrupt
> occurs,
> and the handler starts executing? large, or something like exiting the
> interrupt (10 cycles)? When I set and clear a port bit on entry and exit
> of
> interrupt and measure that on a scope I get something like 120uS, approx
> representation of handler cycle time.
>

Yes, looks like your ISR's should something about ~140cycles. At 2MHz bus
clock that's ~70us, OK. But you have 3 such interrupts that can happen at
the same time? Suppose the worst case scenario, all 3 interrupts should
happen at 0us, then all 3 at 100us, 200us etc..

1111111______________1111111
_______2222222______________2222222
______________3333333______________3333333

^123456789^123456789^

You can't run so long ISR's at so high rate.

Edward
> ;********************************************************************
> ;OC_INIT -- Initialization of the Interuptfor OC0
> ;Going to set up a periodic interupt on OC0-2 (Output Compare 0-2)
> ;Prescale is set to 3
> ;********************************************************************
> OC_INIT:
> sei ;disable interrupts
> bset DDRP, #\$FF ;make port P output
> bset DDRT, #\$FF ;make port T output
> bset DDRM, #\$FF ;make port M output
> clr PTP ;make port P outputs all zero
> clr PTT ;make port T outputs all zero
> clr PTM ;make port M outputs all zero
> bset TIOS, #\$07 ;set interrupt on OC0-2
> movb #\$90, TSCR1 ;set TEN (Timer Enable) & fast clear
> movb #\$03, TSCR2 ;set Prescaler to make counter ticks operate at
> ;250kHz instead of E-clk of 8MHz
> bset TIE, #\$07 ;Arm C[0-2]F,
> movb #\$07, TFLG1 ;clear C[0-2]F (OC[0-2] Flag)
> OC_RE_INIT:
> ldd TCNT ;load current clock tick in d
> addd #\$4E20 ;offset the clock tick by 80 ms for first interrupt
> std TC0 ;store the next interrupt time in Timer Capture
> Channel 0
> std TC1 ;store the next interrupt time in Timer Capture
> Channel 1
> std TC2 ;store the next interrupt time in Timer Capture
> Channel 2
> clr OXYGEN_INDEX1
> clr FUEL_INDEX1
> clr SPARK_INDEX1
> clr OXYGEN_PREV_DELAY
> clr FUEL_PREV_DELAY
> clr SPARK_PREV_DELAY
> ldaa #\$02
> staa OXYGEN_INDEX2
> staa FUEL_INDEX2
> staa SPARK_INDEX2
> ;cli ;initialize interrupts
> rts ;return from subroutine
> ;********************************************************************
> ;OC0_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
> ;Test state of PORTP and apply the opposite to it
> ; Incrementing loop is working. checked output of both indexes !
> ;********************************************************************
> OC0_HANDLER:
> ;bset TFLG1, #\$01 ;Acknowledge interupt and clear flag
> ldaa OXYGEN_NUM_STATES
> deca
> cmpa OXYGEN_INDEX1
> bne COMP2_OK0
> bclr OXYGEN_INDEX2, #\$FF
>
> COMP2_OK0:
> ldaa OXYGEN_INDEX1 ;Check Current Index
> cmpa OXYGEN_NUM_STATES
> bne INDEX_OK0 ;Index is less than 6
> bclr OXYGEN_INDEX1, #\$FF ;reset ENG1_INDEX1 to zero
> ldd #\$0000
> std OXYGEN_PREV_DELAY
>
> INDEX_OK0:
> ldy #OXYGEN_TIMESTAMP ;put base address of TIMESTAMP Array in Y
> ldaa OXYGEN_INDEX2 ;retrieve current index
> ldd a,y ;index the array
> subd OXYGEN_PREV_DELAY
> addd TC0 ;Calc next State Change
> std TC0 ;Load next State Change.
> ldy #OXYGEN_TIMESTAMP ;put base address of TIMESTAMP Array in Y
> ldaa OXYGEN_INDEX2 ;retrieve current index
> ldd a,y ;index the array
> std OXYGEN_PREV_DELAY
> ldy #OXYGEN_STATES ; put base address of STATE Array in X
> ldaa OXYGEN_INDEX1 ;retrieve current index
> ldab a,y ;index the array
> eorb PTP ;
> stab PTP ;make state change on PORT P
> inc OXYGEN_INDEX1 ;retrieve current index
> ldaa OXYGEN_INDEX2 ;retrieve previous index for delay array
> adda #\$02 ;increment by 2 (16-bit)
> staa OXYGEN_INDEX2 ;store next index value
> rti ;return from subroutine
> ;********************************************************************
> ;OC1_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
> ;Test state of PORTP and apply the opposite to it
> ; Incrementing loop is working. checked output of both indexes !
> ;********************************************************************
> OC1_HANDLER:
> ;bset TFLG1, #\$02 ;Acknowledge interupt and clear flag
> ldaa FUEL_NUM_STATES
> deca
> cmpa FUEL_INDEX1
> bne COMP2_OK1
> bclr FUEL_INDEX2, #\$FF
>
> COMP2_OK1:
> ldaa FUEL_INDEX1 ;Check Current Index
> cmpa FUEL_NUM_STATES
> bne INDEX_OK1 ;Index is less than 6
> bclr FUEL_INDEX1, #\$FF ;reset ENG1_INDEX1 to zero
> ldd #\$0000
> std FUEL_PREV_DELAY
>
> INDEX_OK1:
> ldy #FUEL_TIMESTAMP ;put base address of TIMESTAMP Array in Y
> ldaa FUEL_INDEX2 ;retrieve current index
> ldd a,y ;index the array
> subd FUEL_PREV_DELAY
> addd TC1 ;Calc next State Change
> std TC1 ;Load next State Change.
> ldy #FUEL_TIMESTAMP ;put base address of TIMESTAMP Array in Y
> ldaa FUEL_INDEX2 ;retrieve current index
> ldd a,y ;index the array
> std FUEL_PREV_DELAY
> ldy #FUEL_STATES ; put base address of STATE Array in X
> ldaa FUEL_INDEX1 ;retrieve current index
> ldab a,y ;index the array
> eorb PTT ;
> stab PTT ;make state change on PORT P
> inc FUEL_INDEX1 ;retrieve current index
> ldaa FUEL_INDEX2 ;retrieve previous index for delay array
> adda #\$02 ;increment by 2 (16-bit)
> staa FUEL_INDEX2 ;store next index value
> rti ;return from subroutine
>
> ;********************************************************************
> ;OC2_HANDLER -- Toggles the ouptut to PORTP(0-2) on interrupt
> ;Test state of PORTP and apply the opposite to it
> ; Incrementing loop is working. checked output of both indexes !
> ;********************************************************************
> OC2_HANDLER:
> ;bset TFLG1, #\$04 ;Acknowledge interupt and clear flag
> ldaa SPARK_NUM_STATES
> deca
> cmpa SPARK_INDEX1
> bne COMP2_OK2
> bclr SPARK_INDEX2, #\$FF
>
> COMP2_OK2:
> ldaa SPARK_INDEX1 ;Check Current Index
> cmpa SPARK_NUM_STATES
> bne INDEX_OK2 ;Index is less than 6
> bclr SPARK_INDEX1, #\$FF ;reset ENG1_INDEX1 to zero
> ldd #\$0000
> std SPARK_PREV_DELAY
>
> INDEX_OK2:
> ldy #SPARK_TIMESTAMP ;put base address of TIMESTAMP Array in Y
> ldaa SPARK_INDEX2 ;retrieve current index
> ldd a,y ;index the array
> subd SPARK_PREV_DELAY
> addd TC2 ;Calc next State Change
> std TC2 ;Load next State Change.
> ldy #SPARK_TIMESTAMP ;put base address of TIMESTAMP Array in Y
> ldaa SPARK_INDEX2 ;retrieve current index
> ldd a,y ;index the array
> std SPARK_PREV_DELAY
> ldy #SPARK_STATES ; put base address of STATE Array in X
> ldaa SPARK_INDEX1 ;retrieve current index
> ldab a,y ;index the array
> eorb PTM ;
> stab PTM ;make state change on PORT P
> inc SPARK_INDEX1 ;retrieve current index
> ldaa SPARK_INDEX2 ;retrieve previous index for delay array
> adda #\$02 ;increment by 2 (16-bit)
> staa SPARK_INDEX2 ;store next index value
> rti ;return from subroutine
> Lots of Thanks,
> Matt
>
> On Fri, May 9, 2008 at 12:06 AM, Edward Karpicz wrote:
>
>> Matt wrote:
>>
>> > Hi guys,
>> >
>> > So I have two output compare interrupts setup such that the handlers
>> > look up in a circulating table (one for each handler) the state a port
>> > should be in and when the next interrupt should occur, then sets the
>> > port and loads the next interrupt into TC#. This table is dynamic
>> > based on user input. Anyway everything seems to work as I planned
>> > when interrupts are not occurring at a high speed rate and or close
>> > together. However, my needs are for a very close, sometimes the same
>> > time, interrupts. The issue (confusion) I'm experiencing is when I
>> > need two interrupts to occur at the same time and then the two same
>> > interrupts to occur again .1 mS later. So I know I'm limited by the
>>
>> 100uS is a lot even for 8MHz busclock. Your circulating table etc should
>> work.
>>
>> > length of my interrupt handler, however here's the weird thing. I
>> > would expect in this scenario to see:
>> > OC_0 Interrupt occur at T(0mS)
>> > 0C_1 Interrupt occur at T(0mS+cycle time of OC_0_HANDLER)
>> > OC_0 Interrupt occur at T(.1mS, assuming cycle time <.1ms)
>> > 0C_1 Interrupt occur at T(.1mS+cycle time of 0C_0_Handler)
>> >
>>
>> I see nothing wrong above.
>>
>> > However what I see is this:
>> > OC_0 Interrupt occur at T(0mS)
>> > OC_0 Interrupt occur at T(.1mS)
>> > 0C_1 Interrupt occur at T(.1mS+some arbitrary time)
>> > 0C_1 Interrupt occur at T(.1mS+some arbitrary time+.1uS)
>> >
>>
>> Let me guess, is this some arbitrary time close to 2^16 * timer_tick? I
>> think it's just a well known wrong flag-clear sequence. Show us your
>> code,
>> at least show how are you clearing timer flags.
>>
>> Edward
>>
>> > So I haven't been a good engineer and calculated exactly the cycle
>> > time of the handlers, but I'm assuming since, even though in the wrong
>> > order, I see 0C_0 occur twice within the distance they're programmed
>> > to occur at, my cycle time is less than .1mS, which will suffice for
>> > my tolerance.
>> >
>> > Any ideas to why I might be seeing this?
>> > Thanks,
>> > Matt
>> >
>> >
>> >
>> >
>> >
Edward,
Thanks for the info, definitely some useful information in there that I
would have never known! Long story short, I rewrote my code to only use one
interrupt to eliminate my error. Up until now I've used the BDM debugger, I
guess. Not that I was actually using it, but I guess it was running in the
background. Now I've rearranged my development board and prorammed to
non-volatile flash such that I am completely stand alone with no debugger.
Now my Interrupt handler executes in the time frame that was expected,
approx 50uS. Which is good, because my precision only needs to be 100 uS,
between two consecutive interrupts.

thanks a lot for your help, you definitely have a lot of knowledge and a
great way of conveying it!
hope all is well,
Matt