DEMO9S12XDT512 EEPROM problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DEMO9S12XDT512 EEPROM problem

2,153 Views
TSCeric
Contributor I
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
Labels (1)
0 Kudos
4 Replies

449 Views
kef
Specialist I
Sounds like too short programming time, caused by wrong ECLKDIV setting. Please check this
 
0 Kudos

449 Views
TSCeric
Contributor I
The demo board comes with a 4MHz crystal oscillator.  I am using PRDIV8 = 0 and EDIV = 19.  This should be a 4MHz / 1 / 20 = 200kHz.  This worked before I converted the routines to an interrupt driven method.
 
0 Kudos

449 Views
TSCeric
Contributor I
I have removed the instruction to restore EPAGE at the end of the interrupt service routine.  The EEPROM write looks good now.  Does this make sense to anyone?  Is it possible that changing the EPAGE value during an EEPROM write cycle can mess things up?
 
0 Kudos

449 Views
TSCeric
Contributor I
Please ignore previous EPAGE restore comment.  It does not work.  This is strange.
0 Kudos