ColdFire 52235: Program Flash

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

ColdFire 52235: Program Flash

6,922 Views
UDP
Contributor I
Hello
 
I am trying to program the flash (coldfire 52235).
I didn't success to burn the flash.
I am working with the EVB board with 25Mhz oscillator.
 
Can someone tell me please what's wrong with my code?
 
LCF file:
 
Code:
MEMORY{    flash   (RX)   : ORIGIN = 0x00000000, LENGTH = 0x00040000 vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400 sram (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00 ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0}C file:#define FLASH_PROGRAM_ADDR(x) \  (*(volatile unsigned long *)(void *)(&__IPSBAR[(0x04000000 + (x))]))#define ACCERR  0x10#define PVIOL  0x20#define CCIF  0x40#define CBEIF  0x80//Assume Crystal Oscillator = 25Mhzvoid InitCpuFreq(void){  MCF_CLOCK_SYNCR=0x4007;//Multiply By 12 (Divide By 5 Later),PLL Enable }void SetFlashBurnFreq(void){ MCF_CFM_CFMMCR=0;//No Lock,Interrupt Disable MCF_CFM_CFMCLKD=0x55;//Set Freq To About ~178Khz  MCF_CFM_CFMPROT=0;//No Sector Is Protect MCF_CFM_CFMSACC=0;//Flash Sectors Are Placed In Supervisor Address  MCF_CFM_CFMDACC=0;}int runInRam(char cmd, long addr, long val) { MCF_CFM_CFMUSTAT = PVIOL | ACCERR; FLASH_PROGRAM_ADDR(addr)=val; MCF_CFM_CFMCMD = cmd; MCF_CFM_CFMUSTAT = CBEIF; while (!(MCF_CFM_CFMUSTAT & (CCIF | PVIOL | ACCERR))); return MCF_CFM_CFMUSTAT & (PVIOL | ACCERR);}void runEnd(void){} // leave this immediately after runInRam  //The function to program an array of longs, for instance:  int flashProg(long *Addr, long *Value, int n) { char buf[120]; int (*ramCopy)(char,long,long) = (int(*)(char,long,long))buf; memcpy(buf, (void*)runInRam, (char*)runEnd - (char*)runInRam); while (n--)  {  if (ramCopy(0x20/*CMDPROG*/, Addr[n-1], Value[n-1])) return -1; } return 0;}void main (void){long Addr[2]=    {     0x6000,     0x6004     };    long Value[2]=     {     0xAA55AA55,     0x55AA55AA      };InitCpuFreq(); SetFlashBurnFreq();    flashProg(Addr, Value,  2);}

 
 
Thanks
 
 
 
 

Message Edited by Alban on 2006-08-07 06:38 AM

Labels (1)
0 Kudos
16 Replies

1,160 Views
UDP
Contributor I

I am burnning the flash with C commands (internal) and not by external device.

I already succeeded to program the flash.

The address should be 44000000 + wanted address and the buffer of the ram function should be bigger.

 

 

0 Kudos

1,161 Views
Ricardo_RauppV
Contributor I
Hello guys !!!
I´m happy to see how we can help each other by these storm of doubts.
Well, now its my turn..if you can help me I would apreaciate...
I´m using MCF52233 EVB for start the game, although I need to port a whole NE64 design to CF...
 
I realized you were discussing about run the flash routine program in the flash page wich is not the one is been programmed.
After got crazy with hundreds of labels , several h files and conclude there are thousands of reused pieces of code from others ColdFires devices,  wich make the learning more difficult and confused as it should be,I decided to try the simplest way to burn the flash, I mean, not use relocated segments , pragmas , const tables, et  etc in order to put the code into the ram and then rum in the mcu flash....
 
Based on the well succed attempt of Vagnoni,  I also tried it and It worked at the first time.
I copied your basic ideas and so the all (simply!!!) I did was 3 very small parts:
 
 
 
1) Invocation of burning routine by the application
 
void test_flash(void)
{
uint16 i;
 i=runInRam(0x20,0x9000,0xAABBCCDD);
}
 
2) initialization flasf parameters, called by during the mcu initialization
 
void cfm_flash_init(void)
{
 MCF_CFM_CFMCLKD=0x54;//Set Freq To About ~156Khz
 MCF_CFM_CFMPROT=0;//No Sector Is Protect
 MCF_CFM_CFMSACC=0;//Flash Sectors Are Placed In Supervisor Address
 MCF_CFM_CFMDACC=0;
 MCF_CFM_CFMMCR=0x20;
}  
 
3) The main program routine ...
 
int runInRam(UINT8 Cmd, UINT32 Addr, UINT32 Data)
{
 MCF_CFM_CFMUSTAT = (PVIOL | ACCERR);
 FLASH_PROGRAM_ADDR(Addr)=Data;
 MCF_CFM_CFMCMD = Cmd;
 MCF_CFM_CFMUSTAT = CBEIF;
 while (!(MCF_CFM_CFMUSTAT & CBEIF));//wait until buffer free
 while (!(MCF_CFM_CFMUSTAT & CCIF));//wait until execution complete
 return MCF_CFM_CFMUSTAT & (PVIOL | ACCERR);
}
 
...and I could see through CodeWarrior memory watch window (option:see memory as...)
0x9000  AABBCCDD   0xFFFFFFFF ....    0xFFFFFFFF 
0x901C 0xFFFFFFFF  0xFFFFFFFF ....    0xFFFFFFFF
 
and 0x0000 was returned from the runInRam routine ....
 
usually we ask for someone discover a bug, but here I ask you if you agree with the approach I used above ...
What your opinion guys ?
 
Thanks everybody !!!!
 
 
 
 
 
 
 
0 Kudos

1,161 Views
p_vagnoni
Contributor III
Hi,
 
I am working with a 52235 micro and I would to use a part of FLASH as an EEPROM (in my old prject I have all external devices and I would to mantain the same logical architecture).
 
I have not understand why the FLASH erase/write routine must run in RAM. Is possible to have the routines in a sector (protect sector) and working on other sector (the one that I will use as EEPROM) ? (only Page erase function and write word function).
 
Could you help me?
 
Thanks
0 Kudos

1,161 Views
UDP
Contributor I
Hello
 
You can not program/erase the flash while the program software running in it.
The Coldfire does not support it. In order to program/erase the flash or part of it you should run the
code that actually make the earse or program from the ram.
Please look at the example code at the top of the page.
You should increase buf to about 200 bytes instead of 120.
You can calculate it by substruct the pointers.
If you will not success please let me know.
 
 
 
0 Kudos

1,161 Views
p_vagnoni
Contributor III
Hi,
 
Great news about the flash: I test the erase page and program words with the same routines but running in flash and it runs.
 
As I suppose the limitation regards only the same Page (2KB): the routines can't work on the same page of the code that manage the FLASH, so for my project I can use a part of FLASH as EEPROM and the other as code.
 
Bye
0 Kudos

1,161 Views
UDP
Contributor I
Hi
 
According to freescale support it's not possible to program/erase the flash while running in it(the section place does not matter).
Are you saying that you succeed to program/erase the flash without running the commands in the ram?
According to what i read in the PDF in't not forbidden.
Any way you can emulate what you did when run the flash command also in the ram.
I suggest you to ask freescale if it's OK mybe this can cause problem even if it's works(prog/erase flash when running in the flash).
 
 
 
0 Kudos

1,161 Views
p_vagnoni
Contributor III
Hi,
 
I try your code and it run, but I found a little bug:
 
in the while instruction you decrease the n variable (the number of word you want to program) and after use the index n-1 for the array of address, in this manner if you use n= 2 the program copies only 1 word (n-1 word).
 
I move the decrease of n in the while cycle, after the ramCopy execution.
 
Bye.
0 Kudos

1,161 Views
UDP
Contributor I
Hi
 
You right.
 
Anyway this loop was just for debug and not for the real program.
 
 
bye
 
0 Kudos

1,161 Views
p_vagnoni
Contributor III
Hi,
 
I try to expand the array to test the functionality and I found that it run for n = 1, 2 or 3 but if I set 4 it doesn't program the FLASH.
 
 Any idea?
0 Kudos

1,161 Views
UDP
Contributor I
Please add your code to the message so i can see.
 
 
0 Kudos

1,161 Views
p_vagnoni
Contributor III
Code:
#define FLASH_PROGRAM_ADDR(x) \  (*(volatile unsigned long *)(void *)(&__IPSBAR[(0x04000000 + (x))]))#define ACCERR MCF_CFM_CFMUSTAT_ACCERR#define PVIOL MCF_CFM_CFMUSTAT_PVIOL#define CCIF MCF_CFM_CFMUSTAT_CCIF#define CBEIF MCF_CFM_CFMUSTAT_CBEIFvoid InitCpuFreq(void){  MCF_CLOCK_SYNCR=0x4007;//Multiply By 12 (Divide By 5 Later),PLL Enable }void SetFlashBurnFreq(void){ MCF_CFM_CFMMCR=0;//No Lock,Interrupt Disable MCF_CFM_CFMCLKD=0x55;//Set Freq To About ~178Khz  MCF_CFM_CFMPROT=0;//No Sector Is Protect MCF_CFM_CFMSACC=0;//Flash Sectors Are Placed In Supervisor Address  MCF_CFM_CFMDACC=0;}int runInRam(char cmd, long addr, long val) { MCF_CFM_CFMUSTAT = PVIOL | ACCERR; FLASH_PROGRAM_ADDR(addr)=val; MCF_CFM_CFMCMD = cmd; MCF_CFM_CFMUSTAT = CBEIF; while (!(MCF_CFM_CFMUSTAT & (CCIF | PVIOL | ACCERR))); return (MCF_CFM_CFMUSTAT & (PVIOL | ACCERR));}void runEnd(void){} // leave this immediately after runInRam  //The function to program an array of longs, for instance:  int flashProg(long *Addr, long *Value, int n)  { char buf[200]; int (*ramCopy)(char,long,long) = (int(*)(char,long,long))buf; memcpy(buf, (void*)runInRam, (char*)runEnd - (char*)runInRam);   if(n!=0)  { /* PROGRAM WORD */  while (n--)   {   if (ramCopy(MCF_CFM_CFMCMD_PGM, Addr[n], Value[n])) return (-1);   }  } else /* PAGE ERASE */  {  if (ramCopy(MCF_CFM_CFMCMD_PGERS, Addr[0], Value[0])) return (-1);  }  return (0); }void main() { int local, num_word; long Addr[8]=     {     0x00006000,     0x00006004,     0x00006008,     0x0000600B,     0x00006010,     0x00006014,     0x00006018,     0x0000601B       };    long Value[8]=     {     0xAA55AA55,     0x01234567,     0x55AA55A0,     0x89ABCDEF,     0x00112211,     0x0ABCCD00,     0x44444444,     0x76543210      }; InitCpuFreq(); SetFlashBurnFreq();  num_word = 0;  while(1)  {  local = flashProg(Addr, Value,  num_word);    if(num_word == 8)   {   num_word = 0;   }  else   {   num_word++;   }  local = flashProg(Addr, Value,  num_word);  } }

 
The main cycle write a number of word variable and after reset the flash for the sequent write-test.
I check that if I when n is equal to 4 in the flashprog routine, the ramcopy return an error (PVIOL or ACCESS).
 
I am waiting for your result.
 
 
0 Kudos

1,161 Views
UDP
Contributor I
Hi
 
First of all you are writing to the same addresses over and over.
You can't write to un erase address (0xFFFFFFFF).
If you wrote data once before you can write it again (to the same place ) you must erase all the sector.
 
Second i made a little diffrent in my code since this message:
 
void SetFlashBurnFreq(void)
{
 MCF_CFM_CFMCLKD=0x54;//Set Freq To About ~156Khz
 MCF_CFM_CFMPROT=0;//No Sector Is Protect
 MCF_CFM_CFMSACC=0;//Flash Sectors Are Placed In Supervisor Address 
 MCF_CFM_CFMDACC=0;
 MCF_CFM_CFMMCR=0x20;
}  
 
int runInRam(UINT8 Cmd, UINT32 Addr, UINT32 Data)
{
 MCF_CFM_CFMUSTAT = (PVIOL | ACCERR);
 FLASH_PROGRAM_ADDR(Addr)=Data;
 MCF_CFM_CFMCMD = Cmd;
 MCF_CFM_CFMUSTAT = CBEIF;
 while (!(MCF_CFM_CFMUSTAT & CBEIF));//wait until buffer free
    while (!(MCF_CFM_CFMUSTAT & CCIF));//wait until execution complete
 return MCF_CFM_CFMUSTAT & (PVIOL | ACCERR);
}
 
Hope it helps
 
 
0 Kudos

1,161 Views
Cortez
Contributor I
Hi UDP.

First of all, I have a doubt concerning the resulting clock after setting the MDF in CPU clk configuration and the prescaler and divider in the MCF module. Is the clock that feeds the CFM module half of the system clock resulting after the PLL (*12) and the default system prescaler (/5) ??? I just couldnt find an explanation to the fact that I was getting a 60MHz feeding CFM.

Second, I need some help in the flash program procedure.
I'm trying to write in the flash, following your steps, but my code is a bit different. (Function interface to be more clear). I use the 52235EVB.

I've configured the CFM as you did, but when running the debugger (program debugged in RAM) I've got a Cpu interrupt in which all that is done is asm(HALT). I traced what was causing that just to find out that the line (taken from your program) FLASH_PROGRAM_ADDR(Addr)=Data; is the problem.

Interrupts were cleared as you did.
Expecting some help ....
0 Kudos

1,161 Views
p_vagnoni
Contributor III

Hi,

I find the problem: it was on the address array!!!

I used 0x600B instead of 0x600C and

0x601B instead of 0x601C

now it runs!

Thanks

0 Kudos

1,161 Views
p_vagnoni
Contributor III
Hi,
 
about the WRITE repeat on the same location I test it and is not request the erase of lacation for writing in: if you only change bits from 1 to 0 you can rewrite the new word on the same location without erase the page. It is necessary when you have to change bits from 0 to 1.
 
Now I am testing the buffer command because I read on the manual (17.4.2.3 Reference manual) that is possible to "load" up to 2 instruction before start the command (to have time optimization).
 
Bye
 
0 Kudos

1,161 Views
fire
Contributor I

hi,

how you are burning( are you using flash programmer?).

have you changed the jumper settings before programing the flash.

reply with details.

0 Kudos