1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Reset Occurs After Keyboard Interrupt on Motorola HC08

Discussion in 'Embedded' started by Aria, Aug 11, 2005.

  1. Aria

    Aria Guest

    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;
    }
    }
     
    Aria, Aug 11, 2005
    #1
    1. Advertisements

  2. Aria

    Aria Guest

    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;
     
    Aria, Aug 11, 2005
    #2
    1. Advertisements

  3. 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
     
    Steve at fivetrees, Aug 12, 2005
    #3
  4. Aria

    Ian Bell Guest

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

    Ian
     
    Ian Bell, Aug 12, 2005
    #4
  5. Aria

    rTrenado Guest

    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!
     
    rTrenado, Aug 12, 2005
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.