Incircuit FLASH programming - M5223X

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Incircuit FLASH programming - M5223X

10,578 Views
mjbcswitzerland
Specialist V
Hi
 
I am having a bad time trying to program the FLASH on the M52235EVB from the application!!!!!!!

I am moving from the MC9S12NE64 which is almost identical and so I expected the code to work with a few small modifications.
 
Before letting the code run, I walked through with the BDM and tried the command manually. This is the sequence (which is indeed very simple and works fine on the NE64 using BDM - register names are the only modification).
1. Set CFMCLKD to 0x4f - it reads back 0xcf showing that it has been written to.
2. Write a long word to a FLASH location - say 0x20000
3. Write the command in CFMCMD - say 20 to program a long word
4. Write 0x80 to CFMUSTAT (to start the command - writing the '1' resets CBEIF).
I read back immediatly 0xc0 - indicating ready for command and no errors.
 
The problem is that it doesn't program, erase or do anything (with various commands attempted). Also when I intentionally do comething incorrectly, or cancel by writing 0x00 to CFMUSTAT there are never error error bits set as would be expected.
 
My only explanation is that there is some additional initialisation required which I have not yet found as my impression is that the commands are presently being totally ignored.
The result is the same whether I step through code performing this sequence or when I write the bytes manually using the BDM.
 
I then tried with the dBUG in the EVB. Using the inbuilt flash commands I managed to erase a block so the device is fine. I wanted to see how it had left the registers but this was not possible since I couldn't get a memory read of the registers to work - the reason being that reads default to half word reads, which cause a bus error in this peripheral area. When I tried a byte read (md b 401d0002, according to the documentation) it just gave me a memory dump from address 0 (like a serial upload because it never stopped and I had to reset the board), suggesting also a problem with the dBUG on the new EVB.
 
So I have a few questions:
- When setting CFMCLKD is the value correct for a 25MHz quarz and 60MHz PLL operation. I am not sure which clock is actually used for the calculation and so am using the faster to avoid destroying something if wrong - I would have loved to see what the dBUG programs but I just can't read the register - it is very frustrating....
- Does anyone know what is missing in the above sequence which is causing it not to work?

- After studying the data sheet I was convinced that the granuality of the FLASH is 8k (the smallest block which can be individually erased) but dBUG told me it is 2k and it really is so from the test results. I think that this point is missing in the data sheet.
By the way, I saw previous FLASH programming questions and looked at the dBUG code for the 5213 but the programing routine is defined as an array of constant data (I assume assembler code to be copied to RAM) so I didn't learn much there. 
 
I would be very grateful if someone could help since this is a very annoying problem, especially as I never had any trouble programming the HCS FLASH, which seems to be basically identical....
 
Regards
 
Mark Butcher
www.mjbc.ch
 
Labels (1)
0 Kudos
23 Replies

1,039 Views
JeffB
Contributor I
Mark,
 
Did you get your problem resolved?
 
I have run into the same brick wall.  I have sent an e-mail to the Freescale application engineer but have not yet received a reply.
 
Thanks.
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V

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

0 Kudos

1,037 Views
EdW
Contributor I
Very good post. Would not have guessed this from the MCF5282 user manual CFM section. However, the point should be mentioned that in your case, FLASHBAR sets the CFM starting address to 0x00000000. This may not be the case for everyone, therefore the FLASH address being represented in SRAM as (IPSBASE + CFM_BASE + FLASH_OFFSET) should also indicate that FLASH_OFFSET = desired FLASH addr & 0x0007FFFF for the CFM size in the MCF5282 (may be another mask for a different FLASH size). This at least worked for me and where my CFM starting address is 0xF0000000.
 
 
0 Kudos

1,039 Views
JeffB
Contributor I

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

0 Kudos

1,039 Views
alexod
Contributor I
Guys - my heroes.

I've spent 4-5 hours trawling the web, and the MCF5213RM for this answer.  They say to write the address and data, but they don't make a big fuss about using the offset to the CFM  image of the flash.

I just want to drive back to the office now and try it out.

Thanks.

Alex
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V
Alex

I have also programmed the 5213 with the same code - FLASH is the same - so you should find it works.

One small tip about interrupts. As you probably know, the FLASH can not be accessed to run code when it is being programmed. Therefore the code runs out of RAM during this period. Assuming that all interrupts are not also operating  in RAM it is necessary to disable interrupts to avoid them trying to access FLASH and causing an exception.

Be ware that any interrupts set with priority level 7 are equivalent to NMIs and so will not be blocked. Therefore ensure than no interrupts in the system have a priority of greater than 6 (except maybe for the watchdog interrupt) otherwise they may lead to an unexpected crash.

Regards

Mark

0 Kudos

1,037 Views
alexod
Contributor I
I had seen references to not being able to execute from flash while programming it.  It mentions you cannot execute from one logical block while erasing, programming, or verifying.  I was going to partition my memory so that my config data was in a couple of 2K blocks (erase page size) at the far end of flash.  Would that not give me the protection I need.

You also answered another question.  While programming, if I have to poll a status bit for done (CBEIF), can't I get on with system tasks, and come back on a ticker or a done interrupt?  If I have to be careful where I execute from, then I'll just have to sit in the programmer.  Should be okay for me, and my systems notions of real time.

Just arrived in the office now, so I 'll spend a few hours playing with your suggestions.

Again, thanks

Alex
0 Kudos

1,037 Views
mjbcswitzerland
Specialist V
Hi Alex

It is correct that the 'logical' block can not be used while being programmed.

However the sector size of 2k has nothing to do with the logical block size. There is just one 'logical block' in the device, so when programming or deleting an individual 2k sector, the whole of the FLASH is non-available for other work.

If there were more than one logical block - some devices have more than one FLASH bank or there may be an also external FLASH bank (if there is an external bus) then a different strategy is possible.
You will find that erasure and programming times of the "Super-FLASH" are quite fast and I have found that for web server/FTP applications where files are being copied, deletd and modified you don't 'notice' any delays due to the system having to wait.

There are some devices (not the Coldfire) where a sector erase will take almost 1s (word writes still in the order of about 8us) and this can be a bit 'distrurbing'. There are obviously applications where blocking interrupts for more than a few ms could result in big problems and these will have to be designed to really allows FLASH programming/deletion to take place in parallel either using devices with parallel logical FLASH banks or techniques out of RAM.
For most 'normal' application work the Coldfire FLASH is a very good solution...

Regards

Mark
0 Kudos

1,037 Views
alexod
Contributor I
I guess I was expecting logical device to be at least as big as a protect sector (8k).  I've been away from Motorola stuff for 7 years, I last had a 68K with 128K of offchip NVRAM.  I've been using various offchip flash technologies, and they all had the concept of a page being as big as it's internal RAM buffer, a block being many pages, and the smallest erase size, and then many blocks to give me my FLASH.  I guess that paradigm does not translate.

So my final analysis

1) Buffer data from 2k block in RAM
2) Allow user edits.
3) on SAVE load flash programmer to RAM
4) disable interrupts (no task switching, no interrupts)
5) branch to RAM based programmer code
6) erase/program/verify target flash (may be alternate location from previous)
7) return to FLASH based code
8) release buffers (data and code)
9) re-enable interrupts

Little more work than I wanted to do, but not unreasonable.

Thanks
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V

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

0 Kudos

1,039 Views
p_vagnoni
Contributor III
Hello Mark,
 
I read your mail about the flash program and it will help me because I am not able to program the flash on the CFM52235. I would use a part of them (maybe only one block of 8 Kb) as EEPROM to record parameters. I try to make a simple program that make it but when I try to write in the CFM register I have no results. Can you help me in this way?
 
Thank you,
 
Paolo
 
PS: If you come in Rome you will have a lot of beer, or if you prefer we have a good wine! :smileyhappy:
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V
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=274
and 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

0 Kudos

1,039 Views
p_vagnoni
Contributor III
ooops I forget this:
 
in your code part maybe you forgot the "<" sign in the while instruction:
 
...
while(i < PROG_SIZE) { // copy program to stack
ucProgSpace[i++] = *ptrProg++;
}
...
 
and PROG_SIZE is the size of fnFlashRoutine if I understand, correct?
 
Best Regards
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V
Paolo

Yes

#define PROG_SIZE 80

It is the size of the routine to be run from RAM. It is also possible to calculate the size from the address of the routine and the address of the following routine. But I simply made it large and looked at the assembler size in the debugger - it is also generous in case a different compiler were to be a little less efficient...

Regards

Mark
0 Kudos

1,039 Views
p_vagnoni
Contributor III
Hi Mark,
 
About the memory I read on the Reference Manual of 52235 (overview of chapter 17)
 
"It is not possible to read from any Flash logical block while the same logical block is being erased,

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?

0 Kudos

1,039 Views
mjbcswitzerland
Specialist V
Paolo

The manual says that there are 32 x 8k logical sectors for PROTECTION. I haven't actually used protection but assume that this is correct.

I also ORIGINALLY understood that the smallest block which could be deleted would be this and I don't think that there is any more detail in the manual to suggest different.

If you use the CF Flasher you will see that it allows 16 sectors to be erased - this would suggest 16k size. But if you try using the FLASH programmer in the CodeWarrior you will find that the delete command allows you to really specify individual sectors to be deleted, of 0x800 (2k).

I can't remember how, but sometime I did realise that the size is really 2k. So trust me - it does work like that.

Regards

Mark
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V
Paolo

In the data sheet it states:
"It is not possible to read from any FLASH logical block is being erased, programmed, or verified.
FLASH logical blocks are divided into multiple logical pages that can be erased separately."
If you study figure 17-1 you will see that a logical blocks can also be even block arrays and odd block arrays.

My understanding is that the whole FLASH in the chip has to be considered a logical block, divided into logical pages (sectors), which can be deleted separately.

Therefore which ever logical page is being writen, erased or verified, it is in the same unique logical block. This means that it is not possible to write in one sector and still run code from another - all sectors are in the same logical block.

I have also never seen any code trying to do this. It is also a normal stated restriction that code can not run when writing so I am quite sure that it must be perfomred this way.

The missing (small than sign) is due to the code giving invalid HTML and was deleted when copying the code to the forum. Good you saw it - I did get a message that something had been modified but didn't see what. [Perhaps a moderator can edit the post to put it back in?]

Good luck.

Regards

Mark
0 Kudos

1,039 Views
p_vagnoni
Contributor III
Hi Mark,
 
Thanks for reply. I have only something that is no clear:
 
you say that when I write in FLASH the routine must run from RAM because the FLASH is no longer accessible, but in the manual it seems that only the sector that i delete/write is no accessible, so if my FLASH routines are in a sector X I can rewrite anyone sector different from X (and so without disable the interrupts as I need).
 
It is another error on the manual or depends only to make the routine abvle to rewrite all sector of FLASH?
 
Thanks a lot! 
0 Kudos

1,039 Views
mjbcswitzerland
Specialist V
Hi. Is there any one out there???
 
I'm in big trouble with the FLASH programming and today made no progress. There must be a very simple answer but I haven't been able to find it as of yet.
 
1. I loaded an assember routine to the EVB so that I could get dBUG to dump me the contents of the CFM after I had commanded it to erase a page of memory:
All registers were all 0x0 apart from
CFMCLKD = 0xcf (the same value as I was setting)
CFMUSTAT = 0xc0 (infoming ready and no errors)
CFMCMD = 0x40 (the last page erase command)
 
So no help here since the contents are the same I have.

2. I studied the data sheet in great detail. The following point is really confusing me since it represents a simple test of life which is not reacting as expected.
In the section 17.4.2.3.5 there is a list of actions which result in an error, which sets the ACCERR flag.
The simplest test of such an error is point 1 "Writing to the FLASH memory before initializing CFMCLKD".
After a reset CFMCLKD is 0x00 since it has not been initialised so all one has to do is write a long word to an address in memory and the error has taken place and the bit will be set.
When I write to FLASH there is no reaction...
 
3. I then concluded that the write to FLASH must be failing otherwise it would surely cause the described error. I believe this now to be the case because it seems as though when the write is attempted there is immediately an interrupt (handled by the default handler and almost invisible) - I assume due to illegal access. The write probably never actually takes place and so the FLASH command sequence never actually begins. So my hunt turns to the FLASH access itself. Using the CodeWarrior and P&E Coldfire Multiling BDM I could evaluate that the Write protect bit is always set in FLASHBAR and I don't find a way of removing it - I can program it as I like but the bit stays at '1', which is possibly the root cause of the problem.
 
I find no explanation of the FLASHBAR register being nitialised with writes protected (a reset value of 0000_0000 is given in the data sheet) which doesn't tie up with the value I see with the debugger.
 
Status:
I believe that the FLASH programming is not working because the FLASH is protected against write instructions but I can not explain whether the protection is normal or not in my system and how to remove it. How can the dBUG erase FLASH?
 
Basically a bad day. Please, please someone put me out of my missery......
 
Regards
 
Mark
 
0 Kudos

1,039 Views
nanoGeek
Contributor I

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

0 Kudos