Hi Jeff
Yes, thankfully.
You mustn't write to the FLASH directly but to the CFM FLASH (this is sort of a copy of FLASH at ISPBASE + 0x4000000). EG: If you want to program the address 0x10000 in FLASH (FLASHBAR set up to start at 0x00000000) then you write the value to 4410000 (ISPBASE + CFM FLASH + FLASH offset). Then it works.
Therefore the FLASH itself is protected against writes (it generates an access error). The FLASHBAR seems to default to 0x00000100 and not 0 as in all documents and this bit can not be cleared, which is OK since it is not necessary to write to it.
There seems to be other protections against writing to the CFM FLASH and I couldn't get the sequence working by writing manually via the BDM (presumably this is possible if the access rights are set up correctly but I didn't experiment very long). The core itself has access rights by default and the code sequence works fine when the processor is running.
I put my project online - see the following post:
http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=274
I luckily found the tip in a BDM manufacturer's documentation about the CFM FLASH. I still don't see where it is described in the Coldfire datasheet!! Once you know it is obvious, but I lost 2 days looking and experimenting.
If you don't like too far away you can buy me a beer for the tip!!
Don't forget to check out the uTasker (also in other post) which now includes a read-to-run Coldfire project with FLASH file system.
Regards
Mark
www.mjbc.ch
Mark,
That did it!. Thank you so much for your help.
You did leave off one zero, the write location for 0x00010000 would be
0x44010000.
If you are ever in the middle of the United States, I'll buy you that beer.
Jeff
Hi Jeff
Sorry about the zero (I do get a bit dizzy looking a these long numbers!!).
Glad it helped. Send me an air ticket from Zurich, Switzerland and I'll be over - just keep the beer cold until then.....
Cheers
Mark
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}
Message Edited by Alban on 2006-09-11 12:47 PM
programmed, or verified. Flash logical blocks are divided into multiple logical pages that can be erased
separately. "
So it seems that you can work on a logical block different from the code block. I think that is not clear because in the manual there are more terms as Logical block, sector, page.
As I wrote in the manual indicates every block as 8Kbyte large: you can protect this sector by the CFMPROT register and i suppose (it is not indicate) that 8Kbyte is the smallest part of Flash that I can delete (you wrote me that is 2 Kbyte, where do you read it?).
So if I understand (I hope!!!) in 52235 we have:
256 Kbytes (x 32 bit) of FLASH divided into 32 logical sector (the smallest part of memory that I can protect);
Every sector is divided into logical page of 2Kb (as you wrote the smallest part of memory that I can erase).
what do you think?
I can't help with the flash issue, but I have had some experience with dbug.
The "mm" (memory read/modify) and "md" (memory display) use a "." convention to specify the size you desire:
mm.b = byte, mm.w = word, mm.l = long. mm with no dot defaults to word (I think, I've since changed this on my dbug so that it defualts to byte).
cheers,
Joe