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() */