I am currently using an MC9S12E128 processor and I have a troublesome problem. If I enable the COP and then move to a loop where I don't reset the COP, I am not vectoring to the
address placed in the "COP monitor fail reset vector" (0xFFFA). Currently the location 0xFFFA has 0xC00C as the address. At that address I sit in an endless loop flashing an LED if I don't reset the COP.
I am using CodeWarrior 5.9.0 and when I am debugging the code the debugger stops at address 0x4A4D. If I disconnect the debugger and do a power reset I never see the software locking up at the endless flashing LED loop, so it's not a debugger issue.
At this point I can't get the COP to pull a reset. What could possibly be going wrong???
; code section
ORG $C000
Entry: ldx #$0500 ;Reset stack pointer
txs
ldaa #$47 ;Enable COP
staa COPCTL
;Endless loop
_Startup:
nop ;Don't reset COP
bra _Startup
;**************************************************************
;* COP TRAP *
;**************************************************************
;COP vector address!!
COPRes equ *
ldaa #$41 ;LED ON
staa PTM
staa DDRM
ldx #$FFFF
Decxs: dex
bne Decxs
ldaa #$40 ;LED OFF
staa PTM
ldx #$FFFF
Decys: dex
bne Decys
bra COPRes ;Endless branch!!!
Hi,
Do you use your custom made board? Or is it a Freescale one?
The reset line shouldn’t contain any capacitor (or just very small value like 10nF). Otherwise the COP reset can be recognized as a normal external reset and the vector 0xFFFE will be fetched.
The reason is following:
If the watchdog expires the reset line is forced to zero for 128 cycles and released then. The state of reset pin is checked after next 64 cycles. If the pin is in high state, then the source of reset is recognized as a COP. If the pin is still in low state, then it means that the pin is driven low externally – recognized as an external reset.
If the capacitor is connected then the rising edge is too slow and after 64 cycles the state of reset line can be recognized as a low level. This also says that the external reset signal has to be longer than 192 cycles.
The COP reset behavior is the same as POR reset – the stack pointer is not defined, all registers are in default states. So, the initialization has to be done again. The best way is to take care about critical events in the interrupt and then jump to the _startup routine and run the code like after POR reset.
But, looking in your code, there seems to be problem with the branch instruction i.e. bra _Startup.
In most cases, the jump assmbler instruction is used instead :
asm jmp _Startup;
The thing is that BRA instruction has offset of 256 (-128,127), so if the code is executed somewhere at 0xC000, there is no chance to branch to reset vector (0xFFFE).
Operation of BRA:
(PC) + $0002 + Rel ⇒ PC
Rel is a relative offset stored as a two’s complement number in the second byte of the branch instruction.
Regards,
iggi
Quote from manual, which explains the issue:
start-up state. It also acts as an open-drain output to indicate that an internal failure has been detected in
either the clock monitor or COP watchdog circuit. External circuitry connected to the RESET pin should
not include a large capacitance that would interfere with the ability of this signal to rise to a valid logic one
within 32 ECLK cycles after the low drive is released. Upon detection of any reset, an internal circuit
drives the RESET pin low and a clocked reset sequence controls when the MCU can begin normal
processing.