Flash Program - MCF51QE128 (Codewarrior 6.2)

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

Flash Program - MCF51QE128 (Codewarrior 6.2)

3,258 Views
jreyes085
Contributor I

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!

Labels (1)
0 Kudos
9 Replies

716 Views
jreyes085
Contributor I

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!

0 Kudos

716 Views
RichTestardi
Senior Contributor II

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:

 

  http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=4348&query.id=25059#M...

 

If you need any clarification, just let me know...  I'll be leaving for a week on Wednesday, however.

 

-- Rich

 

0 Kudos

716 Views
jreyes085
Contributor I

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...

0 Kudos

716 Views
jreyes085
Contributor I

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...

0 Kudos

716 Views
RichTestardi
Senior Contributor II
You can see where the compiler has allocated flash for your C code and constants in the .xMAP file in your build directory -- that's a text file that tells you where everything is laid out.  You can also control the general layout by editing your linker command file (.lcf), such as to declare the space where you store your parameters as "off limits" to the compiler.  The lcf file format is documented in "ColdFire® V1 Build Tools Reference Manual for Microcontrollers" in your CodeWarrior Help/PDF directory.
0 Kudos

716 Views
jreyes085
Contributor I

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...

0 Kudos

716 Views
RichTestardi
Senior Contributor II

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

 

0 Kudos

716 Views
jreyes085
Contributor I

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...

 

0 Kudos

716 Views
RichTestardi
Senior Contributor II

Try this -- I don't think I can make it any simpler.

 

-- Rich

0 Kudos