EmbeddedRelated.com
Forums

Interrupt from PH port

Started by Dariusz Kusinski December 23, 2004
Hi,

Problem concerns the service of interrupts from PH port.

I have 2 independents sources of events.
On the beginnig I've tested service of this events on IC (input capture) of MCU and every things have worked properly. Now I reconnect these sources of events to PH port.
I configured 2 inputs of PH port (PH0,PH1) on interrupts (on rising edge).

When events come to PH2 in different times or the same time, both are serviced properly.
______
PH0 ____| |________________
______
PH1 ____| |________________
or
______
PH0 ____| |________________
______
PH1 ______________| |_______ Problem is when one event comes during service another.
______
PH0 ____| |________________
______
PH1 _______| |_____________

Simply I lose the events. After end of service of PH0 event the MCU doesn't generete next interrupt for PH1 event.

Is it possible to service 2 independents events on PH port?
Where I make mistake?

This is fragment of my code:

__interrupt void Cpu__ivINT_PortH(void)
{
unsigned char portH_interr;

portH_interr = PIFH;

if(portH_interr & 0x01)
{
// service of PH0 event
if(PH0==1) PPSH_PPSH0 = 0; else PPSH_PPSH0 = 1; // channging of edge
// end service of PH0 event

PIFH_PIFH0 = 1;
}

portH_interr = PIFH;
if(portH_interr & 0x02)
{
// service of PH1 event
if(PH1==1) PPSH_PPSH1 = 0; else PPSH_PPSH1 = 1; // channging of edge
// end service of PH1 event

PIFH_PIFH1 = 1;
}
}
Thanks,
Darek




> Hi,
>
> Problem concerns the service of interrupts from PH port.
>
> I have 2 independents sources of events.
> On the beginnig I've tested service of this events on IC (input capture)
> of MCU and every things have worked properly. > Now I reconnect these sources of events to PH port.
> I configured 2 inputs of PH port (PH0,PH1) on interrupts (on rising edge).
>
> When events come to PH2 in different times or the same time, both are
> serviced properly.
> ______
> PH0 ____| |________________
> ______
> PH1 ____| |________________
> or
> ______
> PH0 ____| |________________
> ______
> PH1 ______________| |_______ > Problem is when one event comes during service another.
> ______
> PH0 ____| |________________
> ______
> PH1 _______| |_____________
>
> Simply I lose the events. After end of service of PH0 event the MCU
> doesn't generete next interrupt for PH1 event.
>
> Is it possible to service 2 independents events on PH port?
> Where I make mistake?
>
> This is fragment of my code:
>
> __interrupt void Cpu__ivINT_PortH(void)
> {
> unsigned char portH_interr;
>
> portH_interr = PIFH;
>
> if(portH_interr & 0x01)
> {
> // service of PH0 event
> if(PH0==1) PPSH_PPSH0 = 0; else PPSH_PPSH0 = 1; // channging of
> edge
> // end service of PH0 event
>
> PIFH_PIFH0 = 1;


What is PIFH_PIFH? Is it bitfield? Then no wonder your code won't work. You
can't use bitfields to clear KWU, ECT,TIM,MSCAN and other interrupt flags.
If PIFH_PIFH0 is member of bitfield C compiler generated code for
PIFH_PIFH0 = 1; is equivalent to PIFH = PIFH | 1;. Valid code for PIFH =
PIFH | 1 is either

LDAB PIFH
ORAB #1
STAB PIFH

or

BSET PIFH,#1

Both versions are wrong because they will reset all bits of PIFH which were
set during read from PIFH bus cycle. Use

PIFH=2; // to clear PIFH1 bit

or

PIFH &=2; // same thing but may involve BCLR instruction. BCLR PIFH,#0xFD
is valid

Did you use bitfields to clear input capture flags and code worked? Hm,
probably you didn't test code thoroughly. Marry Christmas to All
Edward
> }
>
> portH_interr = PIFH;
> if(portH_interr & 0x02)
> {
> // service of PH1 event
> if(PH1==1) PPSH_PPSH1 = 0; else PPSH_PPSH1 = 1; // channging of
> edge
> // end service of PH1 event
>
> PIFH_PIFH1 = 1;
> }
> } >
> Thanks,
> Darek


Derek,

The instructions:

PPSH_PIFH0 = 1
PPSH_PIFH1 = 1

are using bit fields, so the compiler will be using OR and AND
instructions, which would give you the bad result of sometimes clearing
both flags.

For example, if both PIFH0 and PIFH1 are set, since both interrupts arrived
at about the same time, the instruction "PIFH0 = 1;" is equivalent to
"PIFH_byte = PIFH_byte | 0x01 ;", writing 0x03 to PIFH and clearing both
the PIFH0 and PIFF1 bits. This will cause your PIFH1 interrupt to be lost,
while you service the PIFH0 interrupt.

In order to avoid this problem, you need to handle the PIFH register as a
byte, and use "PIFH_byte = 0x01 ;" or "PIFH_byte = 0x02 ;" to clear the
appropriate interrupt Flags, rather than trying to use bit fields for the
PPSH register.

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

At 00:15 24/12/2004 +0100, you wrote:

>Hi,
>
>Problem concerns the service of interrupts from PH port.
>
>I have 2 independents sources of events.
>On the beginnig I've tested service of this events on IC (input capture)
>of MCU and every things have worked properly. >Now I reconnect these sources of events to PH port.
>I configured 2 inputs of PH port (PH0,PH1) on interrupts (on rising edge).
>
>When events come to PH2 in different times or the same time, both are
>serviced properly.
> ______
>PH0 ____| |________________
> ______
>PH1 ____| |________________
>or
> ______
>PH0 ____| |________________
> ______
>PH1 ______________| |_______ >Problem is when one event comes during service another.
> ______
>PH0 ____| |________________
> ______
>PH1 _______| |_____________
>
>Simply I lose the events. After end of service of PH0 event the MCU
>doesn't generete next interrupt for PH1 event.
>
>Is it possible to service 2 independents events on PH port?
>Where I make mistake?
>
>This is fragment of my code:
>
>__interrupt void Cpu__ivINT_PortH(void)
>{
> unsigned char portH_interr;
>
> portH_interr = PIFH;
>
> if(portH_interr & 0x01)
> {
> // service of PH0 event
> if(PH0==1) PPSH_PPSH0 = 0; else PPSH_PPSH0 = 1; // channging of edge
> // end service of PH0 event
>
> PIFH_PIFH0 = 1;
> }
>
> portH_interr = PIFH;
> if(portH_interr & 0x02)
> {
> // service of PH1 event
> if(PH1==1) PPSH_PPSH1 = 0; else PPSH_PPSH1 = 1; // channging of edge
> // end service of PH1 event
>
> PIFH_PIFH1 = 1;
> }
>} >
>Thanks,
>Darek





--- Avoid computer viruses, Practice safe hex ---

-- Specializing in small, cost effective
embedded control systems --

http://www.smithmachineworks.com/embedprod.html Robert L. (Bob) Smith
Smith Machine Works, Inc.
9900 Lumlay Road
Richmond, VA 23236 804/745-2608
----- Original Message -----
From: "Doron Fael" <>
To: <>
Sent: Friday, December 24, 2004 3:10 AM
Subject: Re: [68HC12] Interrupt from PH port > Derek,
>
> The instructions:
>
> PPSH_PIFH0 = 1
> PPSH_PIFH1 = 1
>
> are using bit fields, so the compiler will be using OR and AND
> instructions, which would give you the bad result of sometimes clearing
> both flags.
>
> For example, if both PIFH0 and PIFH1 are set, since both interrupts
arrived
> at about the same time, the instruction "PIFH0 = 1;" is equivalent to
> "PIFH_byte = PIFH_byte | 0x01 ;", writing 0x03 to PIFH and clearing both
> the PIFH0 and PIFF1 bits. This will cause your PIFH1 interrupt to be lost,
> while you service the PIFH0 interrupt.
>
> In order to avoid this problem, you need to handle the PIFH register as a
> byte, and use "PIFH_byte = 0x01 ;" or "PIFH_byte = 0x02 ;" to clear the
> appropriate interrupt Flags, rather than trying to use bit fields for the
> PPSH register.
>
> Hope this helps,
> Doron
> Nohau Corporation
> HC12 In-Circuit Emulators
> www.nohau.com/emul12pc.html
>
> At 00:15 24/12/2004 +0100, you wrote:
>
> >Hi,
> >
> >Problem concerns the service of interrupts from PH port.
> >
> >I have 2 independents sources of events.
> >On the beginnig I've tested service of this events on IC (input capture)
> >of MCU and every things have worked properly.
> >
> >
> >Now I reconnect these sources of events to PH port.
> >I configured 2 inputs of PH port (PH0,PH1) on interrupts (on rising
edge).
> >
> >When events come to PH2 in different times or the same time, both are
> >serviced properly.
> > ______
> >PH0 ____| |________________
> > ______
> >PH1 ____| |________________
> >or
> > ______
> >PH0 ____| |________________
> > ______
> >PH1 ______________| |_______
> >
> >
> >Problem is when one event comes during service another.
> > ______
> >PH0 ____| |________________
> > ______
> >PH1 _______| |_____________
> >
> >Simply I lose the events. After end of service of PH0 event the MCU
> >doesn't generete next interrupt for PH1 event.
> >
> >Is it possible to service 2 independents events on PH port?
> >Where I make mistake?
> >
> >This is fragment of my code:
> >
> >__interrupt void Cpu__ivINT_PortH(void)
> >{
> > unsigned char portH_interr;
> >
> > portH_interr = PIFH;
> >
> > if(portH_interr & 0x01)
> > {
> > // service of PH0 event
> > if(PH0==1) PPSH_PPSH0 = 0; else PPSH_PPSH0 = 1; // channging of
edge
> > // end service of PH0 event
> >
> > PIFH_PIFH0 = 1;
> > }
> >
> > portH_interr = PIFH;
> > if(portH_interr & 0x02)
> > {
> > // service of PH1 event
> > if(PH1==1) PPSH_PPSH1 = 0; else PPSH_PPSH1 = 1; // channging of
edge
> > // end service of PH1 event
> >
> > PIFH_PIFH1 = 1;
> > }
> >}
> >
> >
> >
> >Thanks,
> >Darek > Yahoo! Groups Sponsor
>
> Get unlimited calls to
>
> U.S./Canada >
>
> --
------
> Yahoo! Groups Links
>
> a.. To


Sorry for the empty reply a few minutes ago. Just old fumble fingers here Doron has explained this 'problem' well. I just have a couple of side notes
to add.

It is amusing, in an amazing (not funny), sort of way how certain quirks of
the Moto MCUs persist from family-to-family. This "interrupt flag clearing"
problem has been around since the 68HC11, has propagated to the 'HC12 and
the 'HC08s' and I'm willing to bet one cold beer that if I took my 'HC16
evaluation kit down off of the shelf, I could find it there also.

For further, and excellent, reading on this topic I recommend that you refer
to the M68HC11 Reference Manual, affectionately known as the "Pink Book"
(M68HC11RM/AD, Rev. 3) which has been replaced in recent years by the "White
Book" (M68HC11RM/D, Rev. 6, 4/2002).

In the Pink Book (Rev. 3) see Section 10.2.4 "Tips for Clearing Timer
Flags". There you will find a discussion of what _does_not_ work,
especially BSET as Doron has described and a discussion of 7 different
instruction sequences that _do_ work along with their pros and cons.

The equivalent section in the White Book; (Rev 6) is Section 10.4.4 "Tips
for Clearing Timer Flags". This will be the version that you will surely
find at the Freescale web site. Those who don't have an 'HC11 reference
manual at hand can view the .PDF copy at the web site and download and print
only those pages of interest.

Ho, ho, ho, and best wishes

Bob Smith --- Avoid computer viruses, Practice safe hex ---

-- Specializing in small, cost effective
embedded control systems --

http://www.smithmachineworks.com/embedprod.html Robert L. (Bob) Smith
Smith Machine Works, Inc.
9900 Lumlay Road
Richmond, VA 23236 804/745-2608
----- Original Message -----
From: "Doron Fael" <>
To: <>
Sent: Friday, December 24, 2004 3:10 AM
Subject: Re: [68HC12] Interrupt from PH port > Derek,
>
> The instructions:
>
> PPSH_PIFH0 = 1
> PPSH_PIFH1 = 1
>
> are using bit fields, so the compiler will be using OR and AND
> instructions, which would give you the bad result of sometimes clearing
> both flags.
>
> For example, if both PIFH0 and PIFH1 are set, since both interrupts
arrived
> at about the same time, the instruction "PIFH0 = 1;" is equivalent to
> "PIFH_byte = PIFH_byte | 0x01 ;", writing 0x03 to PIFH and clearing both
> the PIFH0 and PIFF1 bits. This will cause your PIFH1 interrupt to be lost,
> while you service the PIFH0 interrupt.
>
> In order to avoid this problem, you need to handle the PIFH register as a
> byte, and use "PIFH_byte = 0x01 ;" or "PIFH_byte = 0x02 ;" to clear the
> appropriate interrupt Flags, rather than trying to use bit fields for the
> PPSH register.
>
> Hope this helps,
> Doron
> Nohau Corporation
> HC12 In-Circuit Emulators
> www.nohau.com/emul12pc.html
>
> At 00:15 24/12/2004 +0100, you wrote:
>
> >Hi,
> >
> >Problem concerns the service of interrupts from PH port.
> >
> >I have 2 independents sources of events.
> >On the beginnig I've tested service of this events on IC (input capture)
> >of MCU and every things have worked properly.
> >
> >
> >Now I reconnect these sources of events to PH port.
> >I configured 2 inputs of PH port (PH0,PH1) on interrupts (on rising
edge).
> >
> >When events come to PH2 in different times or the same time, both are
> >serviced properly.
> > ______
> >PH0 ____| |________________
> > ______
> >PH1 ____| |________________
> >or
> > ______
> >PH0 ____| |________________
> > ______
> >PH1 ______________| |_______
> >
> >
> >Problem is when one event comes during service another.
> > ______
> >PH0 ____| |________________
> > ______
> >PH1 _______| |_____________
> >
> >Simply I lose the events. After end of service of PH0 event the MCU
> >doesn't generete next interrupt for PH1 event.
> >
> >Is it possible to service 2 independents events on PH port?
> >Where I make mistake?
> >
> >This is fragment of my code:
> >
> >__interrupt void Cpu__ivINT_PortH(void)
> >{
> > unsigned char portH_interr;
> >
> > portH_interr = PIFH;
> >
> > if(portH_interr & 0x01)
> > {
> > // service of PH0 event
> > if(PH0==1) PPSH_PPSH0 = 0; else PPSH_PPSH0 = 1; // channging of
edge
> > // end service of PH0 event
> >
> > PIFH_PIFH0 = 1;
> > }
> >
> > portH_interr = PIFH;
> > if(portH_interr & 0x02)
> > {
> > // service of PH1 event
> > if(PH1==1) PPSH_PPSH1 = 0; else PPSH_PPSH1 = 1; // channging of
edge
> > // end service of PH1 event
> >
> > PIFH_PIFH1 = 1;
> > }
> >}
> >
> >
> >
> >Thanks,
> >Darek > Yahoo! Groups Sponsor
>
> Get unlimited calls to
>
> U.S./Canada >
>
> --
------
> Yahoo! Groups Links
>
> a.. To



"Bob Smith" <> wrote:

[...]

> It is amusing, in an amazing (not funny), sort of way how certain quirks of
> the Moto MCUs persist from family-to-family. This "interrupt flag clearing"

that's IMO no quirk but an efficient solution: a simple write access
is faster than read-modify-write.

Oliver
--
Oliver Betz, Muenchen