interrupt problem MC9S08DZ60

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

interrupt problem MC9S08DZ60

880 Views
Bert2
Contributor II

Hello guys,

maybe I'm missing something but I ran into the following problem with port-interrupts:

A: WORKING FINE:

PTASC_PTAIE=0; //disable int by clearing PTxIE
PTASC_PTAMOD=0; //port detects edges only
PTAES_PTAES6=1; //rising edge
PTAPS_PTAPS6=1; //Enable interrupt pin
PTASC_PTAACK=1; //Clear the interrupt flag
PTASC_PTAIE=1; //Enable interrupts


B: WORKING FINE:

PTASC_PTAIE=0; //disable int by clearing PTxIE
PTASC_PTAMOD=0; //port detects edges only
PTAES_PTAES7=1; //rising edge
PTAPS_PTAPS7=1; //Enable interrupt pin
PTASC_PTAACK=1; //Clear the interrupt flag
PTASC_PTAIE=1; //Enable interrupts


C: NOT WORKING! -> only PTA7 gets triggered!?

PTASC_PTAIE=0; //disable int by clearing PTxIE
PTASC_PTAMOD=0; //port detects edges only
PTAES_PTAES6=1; //rising edge
PTAES_PTAES7=1; //rising edge
PTAPS_PTAPS6=1; //Enable interrupt pin
PTAPS_PTAPS7=1; //Enable interrupt pin
PTASC_PTAACK=1; //Clear the interrupt flag
PTASC_PTAIE=1; //Enable interrupts

Does anybody know why in version C: the PTA6 does not trigger the interrupt anymore like it did in version A: ?

Thanks in advance for any hint or help!
Greets,
Sundiver

6 Replies

586 Views
mfugere
Contributor III

Offhand, I would say "check the generated assembly language"  intermediate file.  What compiler/toolchain are you using?

Each of those PTASC  or PTAES or PTAPS lines generates a read-modify-write sequence.  The compiler may be optimizing (erroneously) the intermediate  instruction/ out on PTA6 because it is immediately updating the value again on the next line.  Try changing the order of instructions and see if it changes the result (e.g. write PTAES7 first, then 6..... or try the PTAES6/PTAPS6 writes sequentially, then the PTAES7/PTAPS7 writes.... or just combine the things into a single write to set both PTA6 and PTA7 bits simultaneously and reduce the number of instructions).   I suspect trying one or more of these will change the outcome and indicate that the compiler is optimizing out the intermediate step that you are reliant upon in the version "C" example you provide.

This is not anything new with many of these 8-bit compilers.   I have had similar problems with Cosmic Compiler HCS08 tools doing similar things to what I describe above.  An old standby of using an intermediate variable with case to "volatile unsigned char" to read the register value and modify it  and then use it to update the subsequent register update is another possibility, but is ugly/clunky and so 1990s...

0 Kudos

586 Views
Bert2
Contributor II

Hi Michael,

thanks for your quick answer. That's what I was thinking, too. I normally set those registers just by using portx=0xC0; or similar. I pulled it apart and used the macros, re-ordered them without luck.
I'll check the assembly to see what's happening. I'm using CodeWarrior 10.6 eclipse - I think it is using a GNU toolchain?

Maybe I also try inline assembler...don't know if the optimizer touches it.

Thanks again for the hint, greets,

Sun

0 Kudos

586 Views
kef2
Senior Contributor IV

Michael, read-modify-write issue doesn't apply to S08 port interrupt. RMW problem applies only to registers, which include several interrupt flags, not the single. No matter, is flag clearable writing '0' or '1' to flag, RMW is bad when single register contains more than one such flags. Example:

Both flag bits are set. Now you write one just to bit 1, and "preserve" one in bit 2. As a result you clear both flags instead of one, because you made CPU writing ones to both flags. It doesn't matter, is it BSET instruction or sequence of LDA OR STA, in both cases you get wrong results. You need to code it so that one is written only to flag you want to clear.

Since PTASC has single flag bit, it is fine to use RMW.

Bert, you didn't say what exactly isn't working, but PORT interrupt has single latch for all unmasked PTAPSx bits! See 6.3 Pin interrupts.    It means that you need to provide that you service A6 edge (get to interrupt and clear interrupt flag) before A7 edge, and vice versa, else you will loose interrupt events. Isn't it your issue?

586 Views
mfugere
Contributor III

Edward,

You misunderstand me.   I did not say it was not permissible to use RMW with PTASC register - I said that it might be possible that the COMPILER was (erronesouly) optimizing some of the intermediate instructions out of the generated code stream.   This, has been a problem which I have encountered before with other (not GNU) compilers in certain cases in the past, and I suggested that Bert look to see if this was occuring, particularly with respect to PTAPS or PTAES registers.

I had assumed from his description "only PTA7 [interrupt] is triggered" in his example C above, that it could be the PTA6 bit setting instructions were being optimized out of the generated code because the following lines set the PTA7 bit in the PTAPS, PTAES same registers. And his description said only PTA7 was working, so I assumed that he had tested several cases for his interrupt being generated.  He did not say "whichever interrupt I trigger first works, but the following/next one is missed" - but I concede that could be what was meant.

We will have to see if Bert replies to let us know iwhat he found or to provide clarification on the manner of testing.

0 Kudos

586 Views
kef2
Senior Contributor IV

Michael, I think I understood you well. I heard zillion of blames to innocent RMW instructions and compilers using them. Always it was improper coding done by human, no matter C or ASM. Perhaps CW08 compiler isn't bug free, but why then you mentioned RMW? And what it has to do with GNU?

Regards,

Edward

0 Kudos

586 Views
mfugere
Contributor III

Let us wait and see what Bert reports.

I mentioned GNU, because Bert speculated the Eclipse based version of the tools he has might be using the GNU compiler in his earlier post.   I do not know for certain if this is true or not, but I have not encountered a problem with too-aggressive compiler optimizations with any GNU based compiler tools I have used, only with proprietary ones.  

Further speculation is pointless without more data/feedback

0 Kudos