Hi Paolo
First a few things to know about the FLASH in the M5223X:
1. It must be written as long words.
2. It must first be deleted (to 0xffffffff) before programming. It is necessary to delete it as sector.
3. A sector is 2kb in size in the M5223X (this is not that obvious from the data sheet), meaning that it is the smallest block of memory that can be deleted at a time. I think that it is often refered to as the GRANULARITY.
4. It IS possible to cumulatively program the bits in a long word to '0', which make it easier to use that FLASH which doesn't support this (eg. the HCS12 FLASH).
5. When deleting or writing, the whole of the FLASH no longer accessible. This means that the code must run from RAM during this time and interrupts best disabled (if their service routines are not also in RAM).
6. When actually writing to the FLASH one doesn't write to the FLASH address but to CFM_FLASH (this is a sort of copy of the FLASH buffer at a certain offset from the FLASH address range). This is not described very well in the data sheet and many people (including myself) do get rather stuck until somehow working it out or finding the tip somewhere (eg. in this thread).
So here comes some code, which works well (it is from the uTasker project, where it is used as FLASH interface for the file system and parameter routines). I haven't included any code which controls higher level stuff but it is all available in the uTasker project for the M5223X - see the following posting for more info, linsk and on-line demos:
http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=274and the uTasker web site. (
www.uTasker.com) It is free for educational and non-commerical work, including email support, and there is an application form on the web site if you would like to evaluate the complete code including a unique M5223X simulator).
The parameter management controls a dual-parameter buffer allowing temporary parameter changes and old parameter rescue. Its size can be configured (min. 4k in the M5223X since it works with at least 2 FLASH sectors).
Unfortunately Rome is a bit far but I will be in Milano on Sunday and will certainly be tasting some good Italian wine while there.
Send an application for the uTasker since you are (as are others) more than welcome to join the uTasker user's community. We can catch up on the drink later once you have got your complete project up and running!!
Regards
Mark
www.mjbc.ch /
www.uTasker.com============================================================
Code:static void fnConfigFlash(void){CFMUSTAT = (ACCERR | PVIOL); // clear error flagsif (CFMCLKD & DIVLD) return; // already configured// before erasing or writing FLASH, the clock must be configured correctly// we want to be in the 150kHz..200kHz range but as fast as possible// This works for oscillator clocks greater than 12.8MhzCFMCLKD = (PRDIV8 | (unsigned char)((OSCCLK/200000/8))); // warning - If in doubt, best check that it is in range before using - errors can destroy FLASH!!!}// This runs from RAM (on the stack) and should normally be protected against interrupts//static void fnFlashRoutine(void){CFMUSTAT = CBEIF; // launch commandwhile (!(CFMUSTAT & CBEIF)) {} // wait until buffer freewhile (!(CFMUSTAT & CCIF)) {} // wait until execution complete}static int fnFlashNow(unsigned char ucCommand, unsigned long *ptrWord, unsigned long ulWord){unsigned char ucProgSpace[PROG_SIZE];unsigned char *ptrProg = (unsigned char*)fnFlashRoutine;void (*fnRAM_code)(void) = (void(*)(void))ucProgSpace;int i = 0;while (i PROG_SIZE) { // copy program to stackucProgSpace[i++] = *ptrProg++;}uDisable_Interrupt(); // protect this region from interruptsptrWord += (CFM_FLASH/sizeof(unsigned long)); // position the write into CFM FLASH (a copy of real FLASH for commands)*ptrWord = ulWord; // value not important for deletesCFMCMD = ucCommand; // The commandfnRAM_code(); // execute from RAM [stack]__enable_interrupt(); // safe to accept interrupts againreturn (CFMUSTAT & (ACCERR | PVIOL)); // if there was an error this will be non-zero}// The address must be on a word boundary or it will fail//static int fnWriteLongWordFlash(unsigned long *ptrAdd, unsigned long ulValue){fnConfigFlash();if (!(CFMUSTAT & CBEIF)) return 1; // the command buffers are full - we can not program yetreturn (fnFlashNow(CMD_PROGRAMM_WORD, ptrAdd, ulValue));}// Erase a FLASH sector. The pointer can be anywhere in the sector to be erased//int fnEraseFlash(unsigned char *ptrSector){fnConfigFlash(); // ensure that the FLASH is configuredif (!(CFMUSTAT & CBEIF)) return 1; // the command buffers are full - we can not proceedreturn (fnFlashNow(CMD_SECTOR_ERASE, (unsigned long *)((unsigned long)ptrSector & ~0x3), (unsigned long)0)); // ensure long word address} (Alban formatted code + links)Message Edited by Alban on 2006-09-11 12:47 PM