Alex Levy

erasing MC9S08QE128 flash in C

Discussion created by Alex Levy on May 25, 2010
Latest reply on May 26, 2010 by Alex Levy

Hi all-

 

I have an application that's being ported over from the MC9S08GB60 to the MS9S08QE128.  I'm using the Cosmic compiler version 4.6.3, and I'm trying to figure out how to modify the bootloader to work with the paged memory structure.  The function I've pasted below is passed a page 0-7, and an address 0x8000-0xBFFF.  It is supposed to erase the page, and then verify it has been erased successfully.  After the verification, I have some debug information printed out the serial port which is saying I've failed to erase.  I see this each time I call the function, regardless of which page I call it with (I haven't tried page 0, which is where my bootloader is stored).  I've also tried ignoring the messages and programming anyway, which obviously failed.

 

Some things I've considered, or seen pointed out on other threads:

  • The address range is incorrect:  I'm printing the addresses out the serial port with the RAMDebugString function, and the values I'm seeing are valid.
  • Flash clock speed is off: I've set the flash clock according to table 4-12 in MC9S08QE128RM Rev. 2, and verified that FDIVLD is set before calling this function
  • Not running from RAM: I'm using a Cosmic-provided function to copy the code from flash to RAM
  • I noticed on https://community.freescale.com/message/56096#56096that there was a delay needed between writing FSTAT = FCBEF and checking FSTAT to see if FCCF is set.  I've inserted the four "nop" cycles, and the code still does not work.

Obviously I'm doing something wrong, but I can't see it.  I've tried to follow figures 4-19 (erase) and 4-16 (erase verify) from the reference manual as closely as possible.  Any help would be greatly appreciated.

 

 

static unsigned char ucRAMEraseFlashPage(unsigned char ucPage, unsigned char * pucAddr)
{

#if DEBUG_MODE
    unsigned int uiaDebug[2];

    uiaDebug[0] = (unsigned int) ucPage;
    uiaDebug[1] = pucAddr;
    RAMDebugString("% %\r", uiaDebug);
#endif

    while((FSTAT & FCBEF) != FCBEF) {
    /* Wait until flash command buffer is empty */
    }

    /* Check for a flash access error */
    if(FSTAT & FACCERR || FSTAT & FPVIOL) {

        /* Clear flash access error */
        FSTAT |= FACCERR | FPVIOL;

#if DEBUG_MODE
        RAMWriteString("Acc err or prot viol cleared prior to erase\r", 2);
#endif

    } // if(FSTAT & FACCERR || FSTAT & FPVIOL)

    // Write any data to a 512 byte page
    PPAGE = ucPage;
    *pucAddr = DEFAULT_ERASE_DATA;

    // Issue the erase command
    FCMD = PAGE_ERASE;

    // Start command
    FSTAT = FCBEF;

    /* Undocumented wait needed.  See
       https://community.freescale.com/message/56096#56096
       for details. */
    _asm("nop\nnop\nnop\nnop\n");
  
    // Wait until all flash commands are completed
    while((FSTAT & FCCF) != FCCF) {
    }

    // Begin to verify that we've erased properly.
    while(FSTAT & FCBEF != FCBEF) {
    }

    // Make sure we didn't break any rules.
    if(FSTAT & FPVIOL || FSTAT & FACCERR) {
        FSTAT = FPVIOL | FACCERR;
#if DEBUG_MODE
        RAMWriteString("2 - viol or acc err after erase\r", 2);
#endif
    }

    // Again set up where we're writing
    PPAGE = ucPage;
    *pucAddr = DEFAULT_ERASE_DATA;

    // Issue the command
    FCMD = ERASE_VERIFY;

    // And away we go.
    FSTAT = FCBEF;

    // Undocumented wait needed.
    _asm("nop\nnop\nnop\nnop\n");
    while(FSTAT & FCCF != FCCF) {
        /* Wait until all flash commands are completed */
    }

    if(FSTAT & FBLANK) {

#if DEBUG_MODE
        RAMWriteString("Successful erase\r", 2);
#endif

        return FLASH_ERASE_OK;
    } else {

#if DEBUG_MODE
        RAMWriteString("Failed to erase\r", 2);
#endif

        return FLASH_ERASE_NOT_BLANK;
    } // if(FSTAT & FBLANK)... else...

} /* ucRAMEraseFlashPage() */

Outcomes