Hi, im almost there...Im finishing my project...
I have to storage some numbers in the non-volatile memory (Flash). I have a few questions about it, and these are:
1. The code that i wrote in C (Codewarrior 6.2) where is it going to be in the flash memory? the base memory address in flash?
2. How do i read the information that i already storage?
Thanks for your help!
I was trying to program the flash but the Reference Manual isnt clear enough...
Im using C language, and i dont know how to specify the flash address where i want to storage my precious data...How do i do this?
Thanks! please take a look to the image in this message to understand the problem...
I was trying to make some assembler code asm{xxxxx} but i didnt make it...The data that i want to storage is word type (Unsigned short - 16 bits...
Thanks! please help me!
Hi,
To specify the address and data for a word program operation in C is as simple as:
*(uint32 *)address = data;
If it helps, I have some working flash access routines for the 51QE128 (and about a dozen other MCUs -- you'll want to follow the MCF51QE128 #if's) in sources/flash.c in skeleton.zip downloadable from the bottom of this page:
http://www.cpustick.com/downloads.htm
You'll want to pick the page you use to store your precious data so it does not overlap any of your code, possibly using your linker command file to ensure this.
Then you might also want to store two copies of the data, so you can survive if you lose power or crash during an update, since the update is not atomic. I describe an algorithm you can use to do this here:
If you need any clarification, just let me know... I'll be leaving for a week on Wednesday, however.
-- Rich
Ok, thanks...
Im going to take a look of that...
Maybe in the afternoon i will write to you...
Thanks Again! Rich T...you know a lot...
I have one question, that maybe i will not solve by myself...
1) My C code that i have written where is going to be in the flash memory? I ask you this because i have to storage some data in the flash memory, and i dont know the location of my C code, i dont know where is going to be storage in the flash memory...
Im taking a look to your website...
Thanks...
Please, HELP!
I tried the program of the flash memory but i didn´t make it...I dont know what Im doing wrong...Can you please give me some example of how to use your functions (Skeleton; flash.c). I included that file in my project but then it requires the main.h...
Please, can you give me some examples? can i only add the flash.c file to my project? does it configure the flash clock to a secure freq.?
I just want to save a data in the flash memory..only one number...it is16 bits long (word). Well, as i write the memory later iwould like to read it...
Please, help me with this...is the only thing that i havent do in my project...but i tried, and tried that i dont know what else to do..
Thanks Again Rich T...
Hi,
You definitely don't want to pull in entire files for this...
You only need the following routines (from the MCF51QE128 #if's):
flash_command_ram()
flash_command()
flash_erase_pages()
flash_write_words()
flash_initialize()
You can then extract the bare minimum header information (like assert, FLASH_PAGE_SIZE, etc.) that you need to compile -- just pull in one line at a time as you encounter compile errors.
You'll have to also set variables for things like:
uint32 bus_frequency;
Then, during your initialization, call:
flash_initialize();
Then, to erase a flash page (say, at 0x10000), you can do something like:
flash_erase_pages((uint32 *)0x10000, 1);
And to program a word in it, you can do:
uint32 word;
word = 0x12345678;
flash_write_words((uint32 *)0x10000, &word, 1);
-- Rich
I dont know much about preprocessor directives, I dont know quite well what to copy in the flash.c file. Im going to put here, what i did, and i put this in my main.c file as a functions...
uint32 bus_frequency=24000000;
oscillator_frequency=?????? is it the same that bus freq
// The type of data uint32 is the same that word data(unsigned short)?
static
void
flash_command_ram(uint8 cmd, uint32 *addr, uint32 data)
{
// N.B. this code generates no relocations so we can run it from RAM!!!
// write the flash thru the frontdoor address
#if MC9S08QE128
*(byte *)addr = data;
#elif MC9S12DT256 || MC9S12DP512
*(uint16 *)addr = data;
#else
*addr = data;
#endif
// write the command
MCF_CFM_CFMCMD = cmd;
// launch the command (N.B. this clears CBEIF!)
MCF_CFM_CFMUSTAT = MCF_CFM_CFMUSTAT_CBEIF;
// busy wait for flash command complete
while (! (MCF_CFM_CFMUSTAT & MCF_CFM_CFMUSTAT_CCIF)) {
// assert no errors
assert_ram(! (MCF_CFM_CFMUSTAT & (MCF_CFM_CFMUSTAT_PVIOL|MCF_CFM_CFMUSTAT_ACCERR)));
// NULL
}
// assert no errors
assert_ram(! (MCF_CFM_CFMUSTAT & (MCF_CFM_CFMUSTAT_PVIOL|MCF_CFM_CFMUSTAT_ACCERR)));
}
static
void
flash_command(uint8 cmd, uint32 *addr, uint32 data)
{
void *fn;
// assert we're initialized
assert(MCF_CFM_CFMCLKD & MCF_CFM_CFMCLKD_DIVLD);
// assert we're ready
assert(MCF_CFM_CFMUSTAT & MCF_CFM_CFMUSTAT_CBEIF);
// assert no errors
MCF_CFM_CFMUSTAT |= MCF_CFM_CFMUSTAT_PVIOL|MCF_CFM_CFMUSTAT_ACCERR;
assert(! (MCF_CFM_CFMUSTAT & (MCF_CFM_CFMUSTAT_PVIOL|MCF_CFM_CFMUSTAT_ACCERR)));
fn = (void *)(((uint32)big_buffer+3)&~3);
memcpy(fn, flash_command_ram, (uint32)flash_command-(uint32)flash_command_ram);
((void (* near)(uint8, uint32 *, uint32))fn)(cmd, addr, data);
}
void
flash_erase_pages(uint32 *addr_in, uint32 npages_in)
{
#if DEBUG
int i;
#endif
int x;
uint32 *addr;
uint32 npages;
addr = addr_in;
npages = npages_in;
x = splx(7);
// while there are more pages to erase...
while (npages) {
flash_command(MCF_CFM_CFMCMD_PAGE_ERASE, addr, 0);
npages--;
addr += FLASH_PAGE_SIZE/sizeof(uint32);
}
(void)splx(x);
#if DEBUG
for (i = 0; i < npages_in*FLASH_PAGE_SIZE/sizeof(uint32); i++) {
assert(addr_in[i] == -1);
}
#endif
}
void
flash_write_words(uint32 *addr_in, uint32 *data_in, uint32 nwords_in)
{
#if DEBUG
int i;
#endif
#if MC9S08QE128
int x;
byte *addr;
byte *data;
uint32 nbytes;
addr = (byte *)addr_in;
data = (byte *)data_in;
nbytes = nwords_in*sizeof(uint32);
x = splx(7);
// while there are more bytes to program...
while (nbytes) {
flash_command(MCF_CFM_CFMCMD_WORD_PROGRAM, (uint32 *)addr, (uint32)*data);
nbytes--;
addr++;
data++;
}
(void)splx(x);
#elif MC9S12DT256 || MC9S12DP512
int x;
uint16 *addr;
uint16 *data;
uint32 nshorts;
addr = (uint16 *)addr_in;
data = (uint16 *)data_in;
nshorts = nwords_in*sizeof(uint16);
x = splx(7);
// while there are more shorts to program...
while (nshorts) {
flash_command(MCF_CFM_CFMCMD_WORD_PROGRAM, (uint32 *)addr, (uint32)*data);
nshorts--;
addr++;
data++;
}
(void)splx(x);
#else
int x;
uint32 *addr;
uint32 *data;
uint32 nwords;
addr = addr_in;
data = data_in;
nwords = nwords_in;
x = splx(7);
// while there are more words to program...
while (nwords) {
flash_command(MCF_CFM_CFMCMD_WORD_PROGRAM, addr, *data);
nwords--;
addr++;
data++;
}
(void)splx(x);
#endif
#if DEBUG
for (i = 0; i < nwords_in; i++) {
assert(addr_in[i] == data_in[i]);
}
#endif
}
void
flash_initialize(void)
{
#if MCF52221 || MCF52233 || MCF52259 || MCF5211 || MCF51JM128 || MCF51QE128 || MC9S08QE128 || MC9S12DT256 || MC9S12DP512
assert((int)flash_upgrade_ram_end - (int)flash_upgrade_ram_begin <= sizeof(big_buffer));
#if MC9S12DT256 || MC9S12DP512
if (oscillator_frequency > 12800000) {
MCF_CFM_CFMCLKD = MCF_CFM_CFMCLKD_PRDIV8|MCF_CFM_CFMCLKD_DIV((oscillator_frequency/8-1)/200000);
} else {
MCF_CFM_CFMCLKD = MCF_CFM_CFMCLKD_DIV((oscillator_frequency-1)/200000);
}
#define setReg8(RegName, val) (RegName = (byte)(val))
/* FCNFG: CBEIE=0,CCIE=0,KEYACC=0,??=0,??=0,??=0,BKSEL1=0,BKSEL0=1 */
setReg8(FCNFG, 1); /* Select the flash block #1 */
/* FSTAT: CBEIF=0,CCIF=0,PVIOL=1,ACCERR=1,??=0,BLANK=0,??=0,??=0 */
setReg8(FSTAT, 48); /* Clear error flags PVIOL and ACCERR */
/* FPROT: FPOPEN=1,NV6=1,FPHDIS=1,FPHS1=1,FPHS0=1,FPLDIS=1,FPLS1=1,FPLS0=1 */
setReg8(FPROT, 255); /* Set protection of flash block #1 */
/* FCNFG: CBEIE=0,CCIE=0,KEYACC=0,??=0,??=0,??=0,BKSEL1=1,BKSEL0=0 */
setReg8(FCNFG, 2); /* Select the flash block #2 */
/* FSTAT: CBEIF=0,CCIF=0,PVIOL=1,ACCERR=1,??=0,BLANK=0,??=0,??=0 */
setReg8(FSTAT, 48); /* Clear error flags PVIOL and ACCERR */
/* FPROT: FPOPEN=1,NV6=1,FPHDIS=1,FPHS1=1,FPHS0=1,FPLDIS=1,FPLS1=1,FPLS0=1 */
setReg8(FPROT, 255); /* Set protection of flash block #2 */
/* FCNFG: CBEIE=0,CCIE=0,KEYACC=0,??=0,??=0,??=0,BKSEL1=1,BKSEL0=1 */
setReg8(FCNFG, 3); /* Select the flash block #3 */
/* FSTAT: CBEIF=0,CCIF=0,PVIOL=1,ACCERR=1,??=0,BLANK=0,??=0,??=0 */
setReg8(FSTAT, 48); /* Clear error flags PVIOL and ACCERR */
/* FPROT: FPOPEN=1,NV6=1,FPHDIS=1,FPHS1=1,FPHS0=1,FPLDIS=1,FPLS1=1,FPLS0=1 */
setReg8(FPROT, 255); /* Set protection of flash block #3 */
/* FCNFG: CBEIE=0,CCIE=0,KEYACC=0,??=0,??=0,??=0,BKSEL1=0,BKSEL0=0 */
setReg8(FCNFG, 0); /* Select the flash block #0 */
/* FSTAT: CBEIF=0,CCIF=0,PVIOL=1,ACCERR=1,??=0,BLANK=0,??=0,??=0 */
setReg8(FSTAT, 48); /* Clear error flags PVIOL and ACCERR */
/* FPROT: FPOPEN=1,NV6=1,FPHDIS=1,FPHS1=1,FPHS0=1,FPLDIS=1,FPLS1=1,FPLS0=1 */
setReg8(FPROT, 255); /* Set protection of flash block #0 */
#else
if (bus_frequency > 12800000) {
MCF_CFM_CFMCLKD = MCF_CFM_CFMCLKD_PRDIV8|MCF_CFM_CFMCLKD_DIV((bus_frequency/8-1)/200000);
} else {
MCF_CFM_CFMCLKD = MCF_CFM_CFMCLKD_DIV((bus_frequency-1)/200000);
}
#endif
#if MCF52221 || MCF52233 || MCF52259 || MCF5211
MCF_CFM_CFMPROT = 0;
MCF_CFM_CFMSACC = 0;
MCF_CFM_CFMDACC = 0;
MCF_CFM_CFMMCR = 0;
#endif
#endif
}
//Please help, im a lot confused...
Thanks again Rich...
Try this -- I don't think I can make it any simpler.
-- Rich