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:
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() */
Erase verify command checks if all flash bytes are erased or not. To make FBLANK set you need to erase everything. Erase verify is used by BDM flash burners. Executing this command is required step after mass erase to unsecure secured chip.
Thank you, kef. I was confused by the first line of section 4.6.3.2.1, where it says that "the erase verify operation will verify that a flash block is erased" (emphasis added). I'd assumed that this referred to the 512 byte page, not the whole flash array. When I re-read the section more carefully, what you said made sense.