Reset Occurs After Keyboard Interrupt on Motorola HC08

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi,

I'm kind of new to programming MCUs but this must be something I missed
when I was reading about them. I am programming a MC68HC098QY4 motorola
processor with CodeWarrior and in C Language. Everything was going fine
until I discovered that after my software sets off a keyboard
interrupt, the chip resets itself. WHYYY??? Here's what I'm doing.

from the start of the main function:
-configure registars
-go into stop mode and wait for keyboard interrupt
-when interrupt comes in, blink a LED a few times then acknoledge
interrupt and clear interrupt masks (asm CLI).

now turns out, the program restarts when it comes out of the interrupt!
is this supposed to happen? how can i prevent it? I even tried finding
out what's setting offf the reset using the SRSR register but no lock!
I've enclosed my code for your review. any help would be greatly
appreciated.

thanks in advance,
Aria

**********
CODE:
**********


#include <hidef.h> /* for EnableInterrupts macro */
#include <MC68HC908QY4.h> /* include peripheral declarations */
#include <stdio.h>


#define EVER (;;)

void lightOn(int num);
void lightOff(int num);
void blink(int num);


int i;
byte cyc;
int adrval;
int zeroadr;

void main(void) {
  //EnableInterrupts; /* enable interrupts. Same as CLI command */
  /* include your code here */

  //setting CONFIG1 and CONFIG2
  CONFIG1 = 0x2B; //00101011
  CONFIG2 = 0x01; //00000001

  //setting ADSCR
  ADSCR = 0x23; //00100011 Continous ADC on AD3

  //setting ADC clock
  ADICLK = 0x80; //busclock / 16

  //enabling keyboard inputs
  KBSCR_IMASKK = 1;
  KBIER = 0x13; //00010011
  KBSCR_MODEK = 1;
  KBSCR_ACKK = 1;
  KBSCR_IMASKK = 0;

  //setting up port B
  PTB = 0x00; //initializing

  DDRB = 0xFF; //all pins on port B configured as outputs

  PTB_PTB0 = 0;

  //zeroadr = ADR; //ADR value at "zero" load.

  blink(3);
  lightOn(0);
  for (i=0;i<32000;i++) {

  }
  for (i=0;i<32000;i++) {

  }
  lightOff(0);

  //finding reset cause
  if (SRSR_LVI == 1){
    blink(1);
  }else if (SRSR_MODRST == 1){
    blink(2);
  }else if (SRSR_ILAD == 1){
    blink(3);
  }else if (SRSR_ILOP == 1){
    blink(4);
  }else if (SRSR_COP == 1){
    blink(5);
  }else if (SRSR_PIN == 1){
    blink(6);
  }else if (SRSR_POR == 1){
    blink(7);
  }else{
    lightOn(0);
    for (i=0;i<32000;i++) {

  }
  for (i=0;i<32000;i++) {

  }
  for (i=0;i<32000;i++) {

  }
  lightOff(0);
  }

  //asm WAIT;


}

interrupt 15 void KBI_ISR(void){

  asm SEI;

  if (PTA_PTA0 == 0) {
    blink(5);
  }else if (PTA_PTA1 == 0){
    blink(10);
  }else if (PTA_PTA4 == 0){
    //adrval = ADR; //clearing flag to make sure we get up-to-date
reading
    //while (!ADSCR_COCO){
      //do nothing and wait
    //}
    adrval = ADR;
    if (adrval == 155) {
      for (cyc=0;cyc<5;cyc++) {
        for (i=0;i<32000;i++) {
          lightOn(0);
        }
      }
      lightOff(0);
    }else{
      if (adrval > 150){
        blink(adrval % 150);
      }else{
        blink(1);
      }
      //blink(2);
    }
  }

  KBSCR_ACKK = 1; //acknowledging interrupt

  asm CLI;
  //asm STOP;

}

interrupt 1 void SWI_ISR(void){
  //for testing

  //asm RTI;
  asm CLI;
  asm NOP;
}

void lightOn(int num){
  switch (num){
    case 0:
      PTB_PTB0 = 1;
      break;
    case 1:
      PTB_PTB1 = 1;
      break;
    case 2:
      PTB_PTB2 = 1;
      break;
  }
}

void lightOff(int num){
  switch (num){
    case 0:
      PTB_PTB0 = 0;
      break;
    case 1:
      PTB_PTB1 = 0;
      break;
    case 2:
      PTB_PTB2 = 0;
      break;
  }
}

void blink(int num) {
  int count;
  for (count=0;count<(num*2);count++) {
    for (i=0;i<32000;i++) {
     //delay
    }
    PTB_PTB0 = ~PTB_PTB0;
  }
}


Re: Reset Occurs After Keyboard Interrupt on Motorola HC08
sorry, the last line in the main() function is not supposed to be
commented out:

It should read:

asm WAIT;

AND NOT read:

//asm WAIT.


Correction: asm WAIT;   not  //asm WAIT;


Re: Reset Occurs After Keyboard Interrupt on Motorola HC08

Quoted text here. Click to load it

Trouble is as soon as you exit the interrupt routine, main tries to carry on
and simply returns. Main should never return.

Ian

Re: Reset Occurs After Keyboard Interrupt on Motorola HC08
If you want your app to just wait for interrupts in one of the
low-power modes do the following arround the "asm WAIT" statement.

for (;;)
{
    asm WAIT
}


This will make your app to go to WAIT everytime the keyboard interrupt
returns.

Also, just to let you know, on your interrupt handlers the CPU
automatically disables global interrupts for you as soon as the
interrupt is serviced, it then re-enables them as soon as it executes
the RTI instruction (return in C).
So your asm CLI and asm SEI seem at little bit redundant.

By the way, for a beginner in C and MCU programming, you are doing very
well!

Ian Bell wrote:
Quoted text here. Click to load it


Re: Reset Occurs After Keyboard Interrupt on Motorola HC08
Quoted text here. Click to load it
  <snip>
Quoted text here. Click to load it

Hmm. I don't know your particular setup well enough to debug it for you, but
I would make some general comments about your code:

  - Don't enable interrupts until you've completed your initialisation.
Consider what would happen if an interrupt occurred at startup.

  - Ensure you have a valid stack before enabling interrupts (or calling any
functions). (Presumably a function of your compiler & linker script.)

  - Do as little as possible within the interrupt. Manipulating I/O is
dangerous (without some safeguards). Delay loops generally don't belong in
interrupts. Where possible consider instead communicating the fact that the
interrupt occurred (and any data provided uniquely by the ISR) to the
top-level routine, and dealing with the event at the higher level.

  - You might find it convenient to break your code down into smaller
chunks - for instance (once the stack is valid) putting all the
initialisation into a function (or functions).

  - Consider putting your debug statements inside a conditional compilation
clause. (This would make it easier for you and I to read the code and
understand which bits are which.)

  - Avoid magic numbers (i.e. literal constants such as "1", "33" etc) in
code. Use e.g. a #define to define them, or where appropriate, a typedef
enum (for instance for your interrupt vector idents).

  - Consider using macros to enable/disable interrupts. The compiler may
already provide a suitable set of macros. (They're just clearer than
embedded assembler.)

If you rewrite your code bearing all these points in mind, there's a good
chance the flaw will become obvious (if it is indeed in the code - but even
if it isn't, then your confidence in the code will rise). The clearer the
code, the more likely it is to be correct.

Hope this helps.

Steve
http://www.fivetrees.com



Site Timeline