Forcing RESET in code - 68HC711K4

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Forcing RESET in code - 68HC711K4

跳至解决方案
1,581 次查看
rjgardner
Contributor II

I am in the process of going back through some 10-15 year old code to diagnosis a problem we are having on a product that is 68HC711K4 based.   The issue I have having is forcing a reset of the microcontroller when ever an Illegal Opcode interrupt occurs.  Periodically, we get reports of the units failing in this mode (LCD displays error code indicating the illegal opcode) - and I would like the microcontroller to automatically reset in the ISR for the Illegal Opcode, especially since I believe that EMI may be intermittently corrupting the data/addr lines going to the external Flash we use for the firmware.  

 

I believe I am correct in stating, that, unlike the HC08, the Illegal Opcode interrupt does not force a full reset.  So, I am trying to force a clock monitor reset instead, from inside the Illegal Opcode ISR.  Here is the ISR:

 

*********************************   

__mod2__ void IllegalInst(void)

{

    asm("\tsei");                                                    /* Disable all interrupts */
    DisplayError(ILLEGAL_INST);                                    /* Display the error */
    SetSolenoidPWM(A, 0, 0, 0);                                   /* Deactivate the solenoids */

    SetSolenoidPWM(B, 0, 0, 0);
    Register.PORTH.BIT.PW2 = 0;                                 
    Register.PORTH.BIT.PW4 = 0;
    asm("\tldaa\t#$00");                                             /* \t(instruction)\t(operand) */  

    asm("\ttap");                                                       /* clear bit 7 of CCR - enable STOP */
    Register.OPTION.BIT.FCME = 1;                              /* 1.02 - enable Clock Monitor */
    asm("\tstop");                                                     /* 1.02 - Stop system clocks and since Clock Monitor enabled, system will reset */

}

*********************************

 

I thought that this would force the program to go to the Clock Monitor interrupt vector since the STOP instruction stops the clocks, but it doesn't appear to going to that vector.  

 

Sorry for the long-winded description, but I haven't really used an HC11 since college and it's tough remember all the caveats sometimes.  Any insight is greatly appreciated.

标签 (1)
0 项奖励
1 解答
532 次查看
rjgardner
Contributor II
Got it working, thanks for the great help.  I added the NOP but I don't think that was an issue at all.  I stupidly did indeed have the clock monitor fail vector pointing to another ISR where they put the processor in an infinite loop waiting for a manual reset.   I of course pointed it to the reset vector and all is well.

在原帖中查看解决方案

0 项奖励
8 回复数
532 次查看
tonyp
Senior Contributor II

Besides getting the reset to work, your ILLOP handler should also reset the stack pointer so that the various functions can be called successfully.  When the ILLOP handler is run, there are no guarantees for any register (including the SP) having correct values.

 

The following code will force a reset, provided the XIRQ line is not pulled low continuously.

 

         sei

         tap

         anda     #$7F

         tap


         ldx       #REGS
         bset      OPTION,x,#CME.

Stop stop
        bra       Stop

 

0 项奖励
532 次查看
rjgardner
Contributor II

Thanks for the help, I will try out this morning. 

 

I should have known to reset the SP, the illegal opcode interrupt pushes the addr of the first byte of the illegal opcode onto the stack so it can be analyzed and possibly corrected in the interrupt handler.  Otherwise, I am probably just in a stack overflow situation.

0 项奖励
532 次查看
tonyp
Senior Contributor II

To correct myself:

 

The following code will force a reset, provided the XIRQ line (or edge-level IRQ) is not pulled low continuously.

 

         sei

         tpa

         anda     #$7F

         tap


         ldx       #REGS
         bset      OPTION,x,#CME.

Stop stop
        bra       Stop

 

0 项奖励
532 次查看
rjgardner
Contributor II

Well, no luck on this.  I followed tonyp's instructions and can't get the darn thing to reset from the illegal opcode handler.  Here is my modified code:

 

*****************************************

__mod2__ void IllegalInst(void)
{
    asm("\tsei");                                                       /* Disable all interrupts */
    asm("\tlds\t#$037F");                                          /* Reset the stack pointer */
    DisplayError(ILLEGAL_INST);                                   /* Display the error */
    SetSolenoidPWM(A, 0, 0, 0);
    SetSolenoidPWM(B, 0, 0, 0);
    Register.PORTH.BIT.PW2 = 0;
    Register.PORTH.BIT.PW4 = 0;                   
    Reset();                                                              /* 1.02 */
}

 

void Reset(void)

{

    asm("\ttpa");
    asm("\tanda\t#$7F");
    asm("\ttap");

    Register.OPTION.BIT.CME = 1;       /* equivalent to ldx #REGS, bset OPTION,x,#CME */
    while(1)
    {
        asm("\tstop");
    }

}

*****************************************

 

Sorry if the inline assembly seems unreadable, the compiler I'm using is CC11 DOS command line based and is ancient.  

0 项奖励
532 次查看
tonyp
Senior Contributor II

Well, this code works for me (and has been, for years).

 

Check if the remaining conditions are also met (XIRQ and IRQ staying high long enough).  If any of these are pulled low (e.g.., due to noise) before the CMF is detected, you repeatedly exit STOP mode.

 

Does your CMF vector point to the same place as the reset vector?

 

Also, just in case one the functions you call re-enable interrupts,  put another SEI instruction right before the TPA inside Reset().

 

Have you tried calling Reset() directly to test it?

 

I don't know how your compiler works, but some C compilers expect hex values (even for embedded assembly code) using C syntax (0x instead of dollar sign) -- for LDS and ANDA instructions in this case.  Can you check the actual produced assembly code for correctness?

 

That's all I can think of for now.

Message Edited by tonyp on 2010-01-16 10:37 AM
0 项奖励
532 次查看
tonyp
Senior Contributor II

One more think I just remembered.  Some 68HC11 masksets had an error which required a NOP right before the STOP instruction to work properly.  Just add that in there, just in case.


0 项奖励
533 次查看
rjgardner
Contributor II
Got it working, thanks for the great help.  I added the NOP but I don't think that was an issue at all.  I stupidly did indeed have the clock monitor fail vector pointing to another ISR where they put the processor in an infinite loop waiting for a manual reset.   I of course pointed it to the reset vector and all is well.
0 项奖励
532 次查看
kef
Specialist I

I think you should set OPTION.CME bit, not FCME.

 

OPTION.FCME bit seems to be writeable only in first 64 cycles after reset and if I understand it properly, it forces clock monitor enabled disregarding the state of OPTION.CME bit.

 

0 项奖励