Question about using FLASH on MCF52210

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

Question about using FLASH on MCF52210

2,976 Views
junkers13
Contributor I
Hi, this may be a stupid question but is there any way to store a variable in flash?  Say I receive a value only once and store it to a variable.  I want to retain the value of that variable even if the power to the board is shut off. 
 
Thanks for any help
Labels (1)
0 Kudos
12 Replies

954 Views
RichTestardi
Senior Contributor II
Hi Joey,
 
I do this all the time on an MCF52221, which I believe will be very similar.
 
You can see the routines I use in this post:
 
 
Cmag got them to work for him as well in a subsequent thread.
 
I'm happy to mail you the source files, as well, if that helps.
 
One thing you'll want to consider, though, is storing two copies of your data in case you lose power during an update.  I describe what I do here:
 
 
Good luck.
 
-- Rich
0 Kudos

954 Views
junkers13
Contributor I
Geesh I have no idea how I didnt find that thread, thats exactly what I need. Thanks for the info, I'm sure I'll be back if something goes wrong.
0 Kudos

954 Views
junkers13
Contributor I
Everything compiles correctly and runs fine but I dont know how to pull that value from flash.  I see in the other thread that I should use memcpy() but I dont have memcpy and have no idea how to create the function.  Also I dont even know if the value made it into flash or not.
 
Thanks,
0 Kudos

954 Views
RichTestardi
Senior Contributor II
To look in flash in the debugger, you can just view memory and look at the flash address you wrote.
 
To do it in C, if the flash address was, for example, 0xf800 (the last page of your flash), you could just do:
 
  uint32 *address;
  uint32 data_written;
  uint32 data_read;
 
  address = (uint32 *)0xf800;
  flash_erase_pages(address, 1);
  data_written = 0x12345678;
  flash_write_words(address, &data_written, 1);
  data_read = *address;
 
You have half the flash I have, so hopefully it will work.
 
I just ran that on a 52221 and data_read was equal to data_written when it was done.
 
-- Rich
0 Kudos

954 Views
mjbcswitzerland
Specialist V
Hi

Just a side note.

The 52210 has also the potential to hold values in battery backed-up RAM (VSTBY power intput) which can be an interesting alternative to storing to FLASH (as long as a suitable battery is connected).

Regards

Mark

www.uTasker.com

0 Kudos

954 Views
junkers13
Contributor I
Hmm I can definantly read from flash now but it doesnt seem to be writting.  I look through the debugger and it doesnt write anything to the address.  I know I'm retreving the value at the memory address correctly becuase its value is being set to FFFFFFFFFF which is the value @ 0xf800.  On a side note using your code here:  http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=4262#M4262
 
under flash command function, for me it doesnt like when i declare backdoor_adr inside the function, I'm not sure what thats about, it says "invalid address" in the debugger, but if I make the variable global, it uses a different memory location and is able to get a valid address.
 
Thanks for the help
0 Kudos

954 Views
junkers13
Contributor I
The only code of yours I changed was the:
 
 // write the flash thru the backdoor address
    backdoor_addr = (uint32 *)(__IPSBAR+0x04000000+(int)addr);
    *backdoor_addr = data;
 
to
 
 // write the flash thru the backdoor address
    backdoor_addr = (uint32 *)(int)addr);
    *backdoor_addr = data;
 
the address of *backdoor_addr is correct (0x0000F800) but the value is not changing to data, could the cmds be wrong?
 
my cmds have different names but the values should be the same:
MCF_CFM_CFMCMD_WORD_PROGRAM = (0x20) right?
and
MCF_CFM_CFMCMD_PAGE_ERASE = (0x40)
 
The registers are getting the right values though.... hmm im stumped
 


Message Edited by joey c on 2008-07-31 05:03 PM

Message Edited by joey c on 2008-07-31 05:08 PM
0 Kudos

954 Views
RichTestardi
Senior Contributor II
Hi Joey,
 
> The only code of yours I changed was the:
>    backdoor_addr = (uint32 *)(__IPSBAR+0x04000000+(int)addr);
> to
>    backdoor_addr = (uint32 *)(int)addr);
 
I would not expect the code to work if you did not use the backdoor address -- that's critical for writing the flash.
 
The MCF52211 Reference Manual in 18.3.2 seems to indicate the 52210 behaves identically to the 52221 (that I am using) in this regard:
 

NOTE
Flash accesses (reads/writes) by a bus master other than the core, DMA
controller, or writes to flash by the core during programming must use the
backdoor flash address of IPSBAR plus an offset of 0x0400_0000. For
example, for a DMA transfer from the first location of flash when IPSBAR
is at its default location of 0x4000_0000, the source register would be
loaded with 0x4400_0000. Backdoor access to flash for reads can be made
by the bus master, but it takes two cycles longer than a direct read of the
flash if using its FLASHBAR address.

So I think you want to leave that unchanged.

 

Did you try it unchanged?

 

-- Rich

0 Kudos

954 Views
RichTestardi
Senior Contributor II
Oh, and one more thing...
 
The *debugger* likely cannot read the backdoor address...  That's why in the code snippet I posted, I set "address" to 0xf800.  Then only when you go into the flash functions does the CPU compute (and then discard) backdoor_addr -- you should not ask the debugger to dereference the backdoor address, only the normal (front door :-) address.  And when you are reading flash, you should use the normal address, as well.
 
-- Rich
0 Kudos

954 Views
junkers13
Contributor I
Yea that worked, I just couldn't put all the pieces together, thanks alot for the help man.
0 Kudos

954 Views
RichTestardi
Senior Contributor II
Glad to hear it!!!  You're welcome.
 
0 Kudos

954 Views
RichTestardi
Senior Contributor II
One more thing, sorry...
 
If you're using the debugger and you want to look at local variables, I'd suggest changing your project settings as follows:
 
1. under Code Generation -> ColdFire Processor, *uncheck* Register Coloring
2. under Code Generation -> Global Optimizations, set Level 1
 
Otherwise the debugger will have problems displaying local variables for you.
 
Note that once you do this, your code will be bigger and slower, so you might not want to ship that way.
 
-- Rich
 
0 Kudos