Simple FLASH storage of C array (MC9S08DZ60)

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

Simple FLASH storage of C array (MC9S08DZ60)

3,246 Views
bdayberr
Contributor I
I have been lookign around on the forums trying to find a simple way of using the flash memory to store a C array in my main code. I simply need to store a long array of integers into flash, from a function in my main.c file. I need this C array to be stored in flash because it will need to access the same data after device shutdowns and reboots. Ideally, I'd like to just access it as an array like:

AverageMPGdata[index]=data;

So I want the array stored in an unused block/segment of the flash, or multiple segments if the size requires it, and be able to just treat it as an array from my C code. Is this possible? Everything I have found on using the flash is either about setting up the flash memory for the program storage or involves complex assembly code to access the flash. Could anyone help me with this? I know C well and am high on the learning curve for my device, the MC9S08DZ60 on the DEMO9S08DZ60 board from axiom. I am developing in the codewarrior IDE and using the device initialization tool to create an MCU_Init(); for all the device initialization. Any help that any one can offer is very appriciated.
Labels (1)
0 Kudos
12 Replies

768 Views
allawtterb
Contributor IV
You can't write to Flash/EEPROM that simply.  For the DZ60 you would want to write to EEPROM as the sector sizes are smaller and it can be programmed from code running in Flash memory.  The DZ60 Advanced Data Sheet shows you the steps you must take to write to EEPROM in section 4.5.  The code you will need should look something like the following:
Code:
  if (FSTAT_FACCERR)              //If EEPROM access error flag is set   FSTAT_FACCERR = 1;             //Then clear it     while(!FSTAT_FCBEF);  *address = data;                 //Set the data to be written to the address to be written to  FCMD = BYTE_PROGRAM;             //Flash/EEPROM command to program a byte (0x20)                         FSTAT_FCBEF = 1;                //Clear command buffer empty flag   if (FSTAT_FACCERR)              //If EEPROM access error flag is set   FSTAT_FACCERR = 1;             //Then clear it     if (FSTAT_FPVIOL)               //If EEPROM write error flag is set    FSTAT_FPVIOL = 1;             //Then clear it                                     while (!FSTAT_FCBEF);           //Wait for command buffer to be empty  while (!FSTAT_FCCF);            //Wait for all commands to complete

address is a pointer which points to EEPROM space and data is what you want to write and BYTE_PROGRAM is just a "#define BYTE_PROGRAM 0x20".
 
  EEPROM has limited endurance and I believe the minimum enduance for the DZ60 is around 10,000 erases.  Before you can write a byte you must erase the sector that it resides in.  I would suggest you read the section of the manual discussing the EEPROM/Flash.
 
   If you need to access this data often just keep a copy in RAM and when it is changed update a copy in EEPROM and initialize the RAM copy on startup. 
 
0 Kudos

768 Views
JimDon
Senior Contributor III
Section 4.5.1 Features
Features of the Flash and EEPROM memory include:
• Up to 100,000 program/erase cycles at typical voltage and temperature

Do you need more than the 2K of EEPROM on the device?

The trade off is EEPROM can be erased 4 bytes or 2 bytes at a time, the FLASH on this device must be erased 768 bytes at a time.
Both can be byte programmed.
Also, you must program the flash from a routine in RAM, and interrupts must be disabled while you do this.
It takes 20ms to erase a sector of flash (which could be done at start up only) and 45us to program a byte.
(There is a burst mode and a sector erase abort mode that seem faster)

Is this acceptable interrupt lock-out time for your application?
If so , I can post code to do this.
0 Kudos

768 Views
bdayberr
Contributor I
It sounds like the EEPROM is a better option, except my device could lose power at any time as it will be in a vehicle, so I would have to update the EEPROM whenever the data changes anyways and I feel that if I am updating values in EEPROM every second, the EEPROM won't last very long. I could easily be wrong but either way I have to store data somewhere non-volatile for averaging purposes, and have actually decided to just go with a struct of ints, so I really only need a little bit of memory, less than 2K, and being able to do it words at a time instead of whole sectors, along with the time constraints, make EEPROM seem to be the best choice. I only need to be able to store several some integers in EEPROM and access them from C now, would you be able to help me with that? Thank you so much for your help.
0 Kudos

768 Views
JimDon
Senior Contributor III
Well, I think what you need to do is consider that you would arrange the circuit so that you get an interrupt when the power is going down, have a big enough capacitor so that you have plenty of time to write the data to EEPROM. This chip is good from 2.7 to 5.0 volts, so this should not be  problem.
There is a Low Voltage Detect as well as a Low Voltage Warning interrupt and can be set up so that you will have plenty of time to detect this condition and update.

What do you think?
 AN2400 Gives "C" code and an explanation for the EEPROM. I don't have a board that has 08 EEPROM, so you will have to test it out.


Message Edited by JimDon on 2008-02-20 10:12 PM
0 Kudos

768 Views
bdayberr
Contributor I
Thank you Jim and Mac you have been of such monumental help. I have read through the AN2400 document and the EEPROM information for the chip I am using and I think I can give some test code a shot tomorrow in the lab. My only question about the C code mentioned in the AN2400 is the EEPROM address. is it just a hex value representing 0-2k? In my final PCB design (I am using the DEMO board currently), I will take into consideration the power issues and using the LVD and LVW interrupts with large input caps to be able to write to EEPROM before the voltage drops too significantly. If I go with using LVW interrupt to store the data to EEPROM before power loss, it gives the benefit of being able to just fetch the data out of EEPROM at startup, maintain it in the program memory, and store it back to EEPROM when an LVW interrupt occurs. I will keep the thread updated with progress and thanks again for the help.
0 Kudos

768 Views
peg
Senior Contributor IV
Hi,

I think that when you start talking about modifying the power supply etc in order to support using the internal memory for this kind of storage, that it is time to step back and take another look.
Adding say a SPI FRAM can avoid all of these issues in one fell swoop.
NO write endurance issues.
NO erase times

0 Kudos

768 Views
JimDon
Senior Contributor III
Well the changes to the power supply are pretty minimal.
However FRAM is not a bad option. A 2k part is pretty reasonable.

0 Kudos

768 Views
bdayberr
Contributor I
As a follow up to this entire thread, I ended up using EEPROM and the LVW interrupt. I have tested this on the device and it works great, and I can post the code for it if anyone needs it.
0 Kudos

768 Views
JimDon
Senior Contributor III
Yes, you absolute should.
If it is long, post a link to a file. If you can prune it down to the basic code, post it inline
Did you have to jack up the power supply?
Did you ever figure about how much time you have after the Low Voltage Interrupt?

0 Kudos

768 Views
bigmac
Specialist III
Hello,
 
Keep in mind that the erase time of 20ms per sector applies whether it be a 4 byte EEPROM sector or a 768 byte flash sector.  If you need more than one EEPROM sector to store the data, this would increase the total erase time.  This might be a problem if erasure must occur after loss of input power is detected.
 
A possible solution, to minimize the update time required, could be to maintain two separate blocks for the non-volatile data, with one of the blocks being pre-erased, ready to be programmed on the next power loss detection.  The other block that contained the previous data would need to be identified as the older data, just in case there were to be programming problems.
 
Since the LV detect function operates at a comparatively low voltage, the amount of time before MCU operation becomes problematic may be quite small, using this method.  Or a substantially larger hold-up capacitor may be necessary.  A more reliable method is to sense the source voltage at the input of the regulator, preferably on the anode side of the reverse polarity diode.  This should give much earlier brown-out or power loss detection, and give substantially more time to complete the shut-down procedure.
 
Regards,
Mac
 
0 Kudos

768 Views
JimDon
Senior Contributor III
The LDV and LVW levels are programmable on this chip.
4.6V on a 5V supply, or 2.9 V for 3.3V supply for LVW. If you are using a 3.3V supply, it could be a bit tight.
If you are using a 5V supply, the chip will run down to 2.7V, so you will have a good margin.

The important design point is to arrange the circuit so that the CPU has it's own branch, and the loads it is driving are on a different branch with a separate filter cap.If done right, you can get a good amount of time with a minimum of capacitance (or, like mac said use a large cap). If the CPU is sinking the loads, it will work best, as the "other" cap will be suppling the current.

Since a sector is only 8 bytes on EEPROM, you will want to do a suggested and pre-erase the next block. However, since you do not need to lock out interrupts for EEPROM, you can do this in the foreground and not affect performance.




0 Kudos

768 Views
bigmac
Specialist III
Hello,


JimDon wrote:
The important design point is to arrange the circuit so that the CPU has it's own branch, and the loads it is driving are on a different branch with a separate filter cap.
 

This would seem to imply the use of separate regulators for the MCU and the external peripheral devices, to provide isolation between the loads.  This may introduce additional "power cycling" issues, including input injection current considerations, at the interface between the MCU and the peripherals.  Further isolation measures at the interface might be necessary.
 
Rather than two regulators, if isolation is to be achieved, using a series diode from the regulator output to the MCU Vdd, this may create further issues with the accuracy of ATD operation.  Any power cycling issues would probably still remain.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-02-21 04:51 PM
0 Kudos