I'm using an 'HC908JK3 in a noisy automotive ignition environment. Have several variations on a theme over half a dozen different boards, the relevant code being virtually identical except for I/O differences to help board layout. One board in particular has a habit of acting up for some customers although I have not been able to reproduce it on the bench. My recent post regarding what to do with unbonded input pins was a big help in getting on top of this problem, so thanks to all that helped.
Anyway, my code uses no interrupts so I want to put a trap in the vector area so if a spurious interrupt does occur it can recover gracefully. What is the best way of doing this? I have all interrupts disabled but I want to go both belt and braces.
ORG $FFDE
RTI
ORG $FFE0
RTI
etc,
OR
ORG $FFDE
FDB START
ORG $FFE0
FDB START
etc
"START" is the very top of the listing, the reset vector.
Regards,
Graham
Hello Monica,
Unfortunately, no, it has not fixed my problem yet. My code is certainly more airtight now though. We are going to make a fairly comprehensive test setup in the next few weeks hopefully so we can reproduce the problem and then try a few different approaches. Till then I just have to wait.
Regards,
Graham.
Hello Graham,
Exiting a spurious interrupt as quickly as possible is probably the best approach, unless the noise burst that caused the interrupt has additionally corrupted registers, etc. In this instance you may wish to force a reset, perhaps by purposely generating an illegal operation ILOP error reset. You will need to judge which would be the least disruptive to normal operation.
Placing a RTI instruction at each vector location will not work - the interrupt is entered by fetching the address present at the vector location. So the following approach would be needed. You may also wish to consider placing additional diagnostic code within the ISR, so that the number of spurious interrupts that occur may be interrogated in some manner.
ILOP equ $3E
DUMMY_ISR2: ; Causes illegal operation reset
ILOP
DUMMY_ISR1: ; Exit interrupt
rti
...
; Vector table:
org $FFDE
fdb DUMMY_ISR1 ; ADC conversion
fdb DUMMY_ISR1 ; Keyboard
org $FFF2
fdb DUMMY_ISR1 ; TIM overflow
fdb DUMMY_ISR1 ; TIM channel 1
fdb DUMMY_ISR1 ; TIM channel 0
fdb $FFFF ; Not used
fdb DUMMY_ISR1 ; IRQ
fdb DUMMY_ISR1 ; SWI instruction
fdb START ; Reset
It may also be possible that the noise burst is corrupting the I/O setup. In particular the data direction and pull-up enable registers may be critical to operation. Traditionally, these registers are initialised following a reset, and are then expected to remain uncorrupted for an indefinite period, maybe days, weeks or months in some instances. You may therefore find that it be desireable to re-initialise the data direction and pull-up enable registers on each circuit of the main loop.
Regards,
Mac
The problem with the "DUMMY_ISR1" approach is that it does not clear the source of the interrupt request. For example, if the source of the interupt was TIM Channel 0 then you will need to clear the timer interrupt flag before issuing the RTI instruction - i.e., TSC0[CH0F]. If you don't clear this flag the interrupt is still pending and you will simply thrash back and forth into and out of the DUMMY_ISR1 routine forever - or until the watchdog resets you.
Since you're not using interrupts, you could enhance the DUMMY_ISR1 routine such that it clears all interrupt request flags from all peripherals:
DUMMY_ISR1:
bset ACK,INTSCR ; clear IRQ pin request
bclr TOF,TSC ; clear TIM overflow request
bclr CH0F,TSC0 ; clear TIM Channel 0 request
bclr CH1F,TSC1 ; clear TIM Channel 1 request
bset ACKK,KBSCR ; clear Keyboard request
rti
I would also suggest assigning all interrupt vector locations (i.e., from $FFDE to $FFFD), whether they are used or not.
Best Regards,
Derrick