Reply by Doron Fael July 27, 20052005-07-27
Stefan,

See answers below:

Hope this helps,
Doron
Nohau
HC12 In-Circuit Emulators
www.nohau.com/emul12pc.html

At 12:42 23/07/2005 +0000, you wrote:
>Hi Stephen
>
>Thx for your answer. I was busy and couldnt reply earlier
>
>Two more questions:
>
>a) About those assembler commands:
>_asm ("sei"); // disable interrupts
>_asm ("cli"); // enable interrupts
>
>Does the "sei" call block the jump into the individual isr, keeping
>the interrupts in a kind of buffer alive if they occur, or are
>interrupts between the call of "sei" and "cli" completly off and lost
>(not recorded)

The individual pending interrupts are "remembered" in the individual flag
bit. Thus, as long as the individual flag for the specific interrupt has
not been cleared, the interrupt is only temporarily disabled when the CCR I
bit is set, and once the I bit becomes cleared again, it can be processed.
(In other words, it is not lost).

You should also note that the interrupt processing mechanism automatically
sets the CCR I bit when an interrupt service routine is started, and
automatically pulls the old CCR register including the I bit value from the
stack to the CCR register when the interrupt service routine is completed.
This mechanism is in order to temporarily disable new interrupts while
already servicing another interrupt, and when one interrupt processing is
completed (when the RTI instruction is met), allow again processing more
interrupts if there are any.

If there is a need to process other interrupts while already servicing one
interrupt, the specific interrupt service routine can include the assembler
"cli" instruction to enable processing other pending interrupts. The "sei"
instruction should be included only after clearing the individual flag that
caused the specific interrupt, in order to avoid starting many interrupt
service routine for only one interrupt. >b)
>Is the same principle to clear an interrupt flag of a timer valid for
>a port interrupt?
>
>For example:
>@interrupt void PIrq(void)
>{
>if (PIFP & 0x01)
>{
> PIFP |= 0x01;
> P1Handler();
>}
>if (PIFP & 0x01)
>{
> PIFP |= 0x02;
> P2Handler();
>}
>}
>
>if PIFP is set with 0x03, will the reset of 0x01 clear both flags
>this way, too, and thus no jump into p2handler ?

In this described method you may actually loose interrupts completely.
The way to clear the individual interrupt flag is using:

PIFP = 0x02;
PIFP = 0x01;

and not:

PIFP |= 0x02;
PIFP |= 0x01; >Best regards
>Stefan >
>--- In 68HC12@68HC..., "Stephen Trier" <sct@p...> wrote:
> > Stefan,
> >
> > The assignment operations are almost right. TFLG1 is write-1-to-
>clear, so
> > you must do the following:
> >
> > TFLG1 = 0x01; /* To clear C0F (channel 0 flag) */
> > TFLG1 = 0x02; /* To clear C1F (channel 1 flag) */
> > TFLG1 = 0x04; /* To clear C2F (channel 2 flag) */
> > /* etc... */
> >
> > Using the |= operator will cause lost interrupts. Imagine, for
>example,
> > that both the channel 0 and channel 1 flags are set when the
>channel 0
> > handler is entered. Then TFLG1 will be 0x03. The operation "TFLG1
>|=
> > 0x01" would set TFLG1 to (0x03 | 0x01), which is 0x03. Writing
>that 0x03
> > will then reset *both* timer flags. The channel 1 interrupt
>handler will
> > never get called, because its flag is already cleared! Thus, the |=
> > operator is incorrect. The correct way to clear the flag is a
>simple
> > assignment of the correct bit, not an |= operation.
> >
> > Stephen
> >
> > --
> > Stephen Trier
> > Technical Development Lab
> > Cleveland FES Center
> > sct@p... >
>Yahoo! Groups Links >
>




Reply by Stefan Loos July 23, 20052005-07-23
Hi Stephen

Thx for your answer. I was busy and couldnt reply earlier

Two more questions:

a) About those assembler commands:
_asm ("sei"); // disable interrupts
_asm ("cli"); // enable interrupts

Does the "sei" call block the jump into the individual isr, keeping
the interrupts in a kind of buffer alive if they occur, or are
interrupts between the call of "sei" and "cli" completly off and lost
(not recorded)

b)
Is the same principle to clear an interrupt flag of a timer valid for
a port interrupt?

For example:
@interrupt void PIrq(void)
{
if (PIFP & 0x01)
{
PIFP |= 0x01;
P1Handler();
}
if (PIFP & 0x01)
{
PIFP |= 0x02;
P2Handler();
}
}

if PIFP is set with 0x03, will the reset of 0x01 clear both flags
this way, too, and thus no jump into p2handler ?

Best regards
Stefan
--- In 68HC12@68HC..., "Stephen Trier" <sct@p...> wrote:
> Stefan,
>
> The assignment operations are almost right. TFLG1 is write-1-to-
clear, so
> you must do the following:
>
> TFLG1 = 0x01; /* To clear C0F (channel 0 flag) */
> TFLG1 = 0x02; /* To clear C1F (channel 1 flag) */
> TFLG1 = 0x04; /* To clear C2F (channel 2 flag) */
> /* etc... */
>
> Using the |= operator will cause lost interrupts. Imagine, for
example,
> that both the channel 0 and channel 1 flags are set when the
channel 0
> handler is entered. Then TFLG1 will be 0x03. The operation "TFLG1
|=
> 0x01" would set TFLG1 to (0x03 | 0x01), which is 0x03. Writing
that 0x03
> will then reset *both* timer flags. The channel 1 interrupt
handler will
> never get called, because its flag is already cleared! Thus, the |=
> operator is incorrect. The correct way to clear the flag is a
simple
> assignment of the correct bit, not an |= operation.
>
> Stephen
>
> --
> Stephen Trier
> Technical Development Lab
> Cleveland FES Center
> sct@p...



Reply by Stephen Trier July 18, 20052005-07-18
Stefan,

The assignment operations are almost right. TFLG1 is write-1-to-clear, so
you must do the following:

TFLG1 = 0x01; /* To clear C0F (channel 0 flag) */
TFLG1 = 0x02; /* To clear C1F (channel 1 flag) */
TFLG1 = 0x04; /* To clear C2F (channel 2 flag) */
/* etc... */

Using the |= operator will cause lost interrupts. Imagine, for example,
that both the channel 0 and channel 1 flags are set when the channel 0
handler is entered. Then TFLG1 will be 0x03. The operation "TFLG1 |=
0x01" would set TFLG1 to (0x03 | 0x01), which is 0x03. Writing that 0x03
will then reset *both* timer flags. The channel 1 interrupt handler will
never get called, because its flag is already cleared! Thus, the |=
operator is incorrect. The correct way to clear the flag is a simple
assignment of the correct bit, not an |= operation.

Stephen

--
Stephen Trier
Technical Development Lab
Cleveland FES Center
sct@sct@...



Reply by Stefan Loos July 18, 20052005-07-18
Hi

Can u tell me how to clear timer interrupt flags if you have two
timers running ?

Do you have to wrtie

TFLG1 = 0x01
or
TFLG1 |= 0x01
to clear Timer1 flag

and

TFLG1 = 0x02
or
TFLG1 |= 0x02
to clear Timer2 flag

in the isr ???

Thx for help
Stefan