I have been working on a set to functions for saving data to EEPROM on a 9s12. My original routines worked. I then converted the routines to an interrupt driven method so that the EEPROM can be reprogrammed as a background process. The program does a mass erase, a blank verify, and then write the most of the EEPROM. I have the program break on an infinite loop and the debugger will show that the EEPROM programmed correctly and all the possible error traps would agree with this. Interrupts are turned off with an SEI instruction. Then I single step the debugger and bit 0 of some of the even bytes changes from 0 to 1. A couple of more single steps, and I see all the even bytes get bit 0 set to 1.
Does anyone have a clue what is going on here? I have included the main routines:
Thanks
////////////////////////////////////////////////////////////////////////////////
// Start the EEPROM updating process by commanding a mass erase of the EEPROM.
// The rest is handled by the EEPROM command interrupt handler.
////////////////////////////////////////////////////////////////////////////////
char UpdateEEPROM(void)
{
if ((EEintFlags & BufferInitialized) && // If EE buffer is initialized,
!(EEintFlags & EEBusy)) // and not busy...
{
EEintFlags &= ~BufferInitialized; // Clear flag.
ESTAT |= ESTAT_ACCERR_MASK | // Clear ACCERR and PVIOL flags.
ESTAT_PVIOL_MASK;
DisableInterrupts;
*(int*) EEPROM = 0; // Write to the EEPROM.
ECMD = 0x41; // Mass erase command.
ESTAT_CBEIF = 1; // Do it. CBEIF = 0 for a moment.
EnableInterrupts;
EEerrorFlags = 0; // Clear error flags.
EEintFlags |= BufferErasing | // Erasing is executing, set flag.
EEBusy; // EE is busy, set flag.
ECNFG |= ECNFG_CCIE_MASK | // Enable EEPROM command complete interrupt.
ESTAT_CBEIF_MASK;
return 0; // Return, no error.
}
else
return EENotInitialized; // Error, return not initialized.
}
////////////////////////////////////////////////////////////////////////////////
// EEPROM command interrupt handler.
////////////////////////////////////////////////////////////////////////////////
void HandleEEinterrupt()
{
byte Epage = EPAGE; // Save EPAGE;
if ((ESTAT_CBEIF) && (ESTAT_CCIF)) // If command is complete...
{
if (EEintFlags & BufferErasing) // If in erase phase...
{
if ((ESTAT_ACCERR)||(ESTAT_PVIOL)) // If these flags are set, error.
{
EEerrorFlags |= EEeraseError; // Set error during erase phase.
ECNFG = 0; // Disable EEPROM command interrupts.
return; // Return, failed.
}
EEintFlags &= ~BufferErasing; // Clear erase flag.
EEintFlags |= BufferVerifing; // Set verify flag.
DisableInterrupts;
*(int*) EEPROM = 0; // Write to the EEPROM.
ECMD = 0x05; // Verify that erase command worked.
ESTAT_CBEIF = 1; // Do it. CBEIF = 0 until erase is done.
EnableInterrupts;
return; // Return, erased EEPROM is being verified.
}
else if (EEintFlags & BufferVerifing) // If in verify phase...
{
if (!ESTAT_BLANK) // If EEPROM is not blank...
{
EEerrorFlags |= EEVerifyError; // Set error during verify phase.
ECNFG = 0; // Disable EEPROM command interrupts.
return; // Return, failed.
}
EEintFlags &= ~BufferVerifing; // Clear verify flag.
ptrEE = (char*) EEPROM; // Point to paged EEPROM base address.
ptrEEbuffer = (char*) EEBuffer; // Point to RAM buffer.
}
if ((int) ptrEE < EEPROM + EEbufferSize) // If a byte is available, write to EE...
{
if ((ESTAT_ACCERR)||(ESTAT_PVIOL)) // If these flags are set, error.
{
EEerrorFlags |= EEWriteError; // Set error during write phase.
ECNFG = 0; // Disable EEPROM command interrupts.
return; // Return, failed.
}
DisableInterrupts;
*(int*) GetEEpage(ptrEE) = *(int*) ptrEEbuffer; // Latch address and data
ECMD = 0x20; // Write command.
ESTAT_CBEIF = 1; // Do it.
EnableInterrupts;
ptrEEbuffer += 2; // Bump pointers by an int.
ptrEE += 2;
}
else
{
ECNFG = 0; // Disable EEPROM command interrupts.
EEintFlags &= ~EEBusy; // Clear busy flag, all done.
ptrEE = (char*) EEPROM; // Point to paged EEPROM base address.
ptrEEbuffer = (char*) EEBuffer; // Point to RAM buffer.
while ((int) ptrEE < EEPROM + EEbufferSize) // Loop until all checked.
{
if (*(int*) ptrEEbuffer != *(int*) GetEEpage(ptrEE)) // Equal?
{
EEerrorFlags |= EEduplicateError; // No, error.
break; // All done.
}
ptrEEbuffer += 2; // Increment int pointers.
ptrEE += 2;
}
}
}
EPAGE = Epage; // Restore EPAGE.
}
////////////////////////////////////////////////////////////////////////////////
// EEPROM command interrupt entry point.
////////////////////////////////////////////////////////////////////////////////
#pragma CODE_SEG __NEAR_SEG NON_BANKED // Vectored to unpaged flash ROM segment.
interrupt 0x22 void EECommandISR() // EEPROM command interrupt #34.
{
EnableInterrupts; // CLI, interrupts back on.
HandleEEinterrupt(); // Call far to interrupt handler.
} // RTI, return from interrupt.
#pragma CODE_SEG DEFAULT