Hi,
ME is not ISR (interrupt service routine), it's MER (machine exception routine), which as was told can't return normally, no return address is stored on the stack.
Here's how I do it, in production quite a long:
return from MER requires either code disassembly at address pointed by MMCPC register or something else. We need to get instruction length, which is pointed by MMCPC. S12Z instruction can be anything from 1 to 11 bytes. Knowing instruction length you could skip past it and return, so that machine exception doesn't fire again and again on the same CPU instruction.
Instead of disassembly or calculating instruction length I do it simpler, I just put enough NOPs past the EEPROM access C line and return from MER to anywhere between those NOPs.
EEPROM read function looks like this
void ReadEepromByte(void *src, char *dst)
{
*dst = *(char*)(src); // read data
asm {
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
}
fixecc(src, sizeof(char));
}
char EeepromECCUncorrectable;
static void fixecc(void *addr, int size)
{
if(EeepromECCUncorrectable)
{
// get EEPROM sector aligned address
unsigned long strtaddr = (long)addr & ~(4-1);
unsigned long endaddr = (long)addr + size;
// erase first sector
EEpromErasesect( (void*)strtaddr );
// in my case size is up to 8, sizeof(long long)
// check if size crosses sector boundary and erase 2nd sector
if((endaddr - strtaddr) > 4)
EEpromErasesect( (void*)(strtaddr+4) );
EeepromECCUncorrectable = 0;
}
}
MER handler:
#pragma NO_ENTRY
#pragma NO_EXIT
static void MachineException(void)
{
asm{
// create RTI stack frame
LEA S, (-3,S)
PSH ALL
// check MMCRCH.TGT
LSL.B D0, MMCECH, #4
CMP D0, #3 << 4
BNE L1
// ME fault was caused by EEPROM ECC
ST D0, EeepromECCUncorrectable
LD X, MMCPC
LEA X, (11,X) // longest S12Z instruction is 11 bytes long. please fill location
// after EEPROM read access with enough NOPs
ST X, (26, S) // store RTI return address
RTI // return to
L1:
}
// for everything else go loop forever or until COP timeout
for(;;)
{
int a;
a++;
if(!a)
DEBUGPIN25_PORT ^= DEBUGPIN25_PIN;
}
}
Edward