We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I am implementing a functionality of IAP in LPC2214, for start up I have written a simple code in which I am able to ease Sector 0 & other Sectors as Well, but when I try to write any data on sector 0 then it is not written it shows all 0xFF 0xFF ............. But in all the sectors data has been written succesfully only if I comment the sector 0 ERASE & WRITE function...
I have selected the ARM Mode in keil.
Can any one let me know what is the reason why I am not able to write on sector 0 ? what are the parameters that has to be taken care while writing on sector 0 ?
#include "FlashOS.H" #define M8(adr) (*((volatile unsigned char *) (adr))) void IAP_download(void); volatile int ret; unsigned char TempBuf[1024] = " CMS CMS CMS "; static unsigned char TempBuf2[1024]; unsigned int Cnt; void IAP_download (void ) { unsigned long n; unsigned short Cnt; ret = Init(0, 48000000, 1); // Erase Sector 0 ret |= EraseSector(0x00000000); for (Cnt = 0; Cnt < 1024; Cnt++) { TempBuf2[Cnt] = '*'; } ret |=ProgramPage(0x00000000,1024,(unsigned char*) TempBuf2 );
/* main Function */ int main(void) { IODIR0 = 0xFFFFFFFF; IODIR1 = 0xFFFFFFFF; // #pragma ARM VICIntEnClr = 0xFFFFFFFF; IAP_download( ); // #pragma thumb while (1); }
/* FalshPrg.c*/ #define STACK_SIZE 64 // Stack Size #define SET_VALID_CODE 1 // Set Valid User Code Signature unsigned long CCLK; // CCLK in kHz struct sIAP { // IAP Structure unsigned long cmd; // Command unsigned long par[4]; // Parameters unsigned long stat; // Status } IAP; void IAP_Execute (struct sIAP *pIAP); unsigned long GetSecNum (unsigned long adr) { unsigned long n; n = (adr >> 13) & 0x1F; if (n >= 24) { n -= 14; } else if (n >= 8) { n = 8 + (n >> 4); } return (n); } int Init (unsigned long adr, unsigned long clk, unsigned long fnc) { unsigned int Cntr; CCLK = (1049*(clk >> 10)) >>10; MEMMAP = 0x01; for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); return (0); } int UnInit (unsigned long fnc) { return (0); } int EraseChip (void) { IAP.cmd = 50; IAP.par[0] = 0; IAP.par[1] = 16; IAP_Execute (&IAP); if (IAP.stat) return (1); IAP.cmd = 52; IAP.par[0] = 0; IAP.par[1] = 16; IAP.par[2] = CCLK; IAP_Execute (&IAP); if (IAP.stat) return (1); return (0); } int EraseSector (unsigned long adr) { unsigned long n; unsigned int Cntr; n = GetSecNum(adr); IAP.cmd = 50; IAP.par[0] = n; IAP.par[1] = n; IAP_Execute (&IAP); if (IAP.stat) return (1); for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); IAP.cmd = 52; IAP.par[0] = n; IAP.par[1] = n; IAP.par[2] = CCLK; IAP_Execute (&IAP); if (IAP.stat) return (1); for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); return (0); } int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) { unsigned long n; unsigned int Cntr; #if SET_VALID_CODE != 0 if (adr == 0) { n = *((unsigned long *)(buf + 0x00)) + *((unsigned long *)(buf + 0x04)) + *((unsigned long *)(buf + 0x08)) + *((unsigned long *)(buf + 0x0C)) + *((unsigned long *)(buf + 0x10)) + *((unsigned long *)(buf + 0x18)) + *((unsigned long *)(buf + 0x1C)); *((unsigned long *)(buf + 0x14)) = 0 - n; } #endif n = GetSecNum(adr); IAP.cmd = 50; IAP.par[0] = n; IAP.par[1] = n; IAP_Execute (&IAP); if (IAP.stat) return (1); for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); IAP.cmd = 51; IAP.par[0] = adr; IAP.par[1] = (unsigned long)buf; IAP.par[2] = 1024; IAP.par[3] = CCLK; IAP_Execute (&IAP); if (IAP.stat) return (1); for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); return (0); }
I don't know you processor, but maybe your program is running from sector 0? did you try to place your programming code in RAM?
Thanks Tamir,
I have checked by placeing my programming code in RAM. As you can see I have setted MEMMAP = 0x02;
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) { unsigned int Cntr; CCLK = (1049*(clk >> 10)) >> 10; // PLLCON = 0x00; // PLLFEED = 0xAA; // PLLFEED = 0x55; MEMMAP = 0x02; for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); return (0); }
Still I am not able to write on Sector 0 ?
first of all, settting MEMMAP where you did has no effect. it is best to use following macroes in the ASM tab preprocessor textbox: RAM_INTVEC REMAP RAM_MODE second, you need to place the code that write the flash in RAM, not only the interrupt service routines! right click on your C file, use options to select a RAM region - or use your scatter file.
I have done following modification in my code & checked again but the condition is same ? not able to write on sector 0 ?
; Memory Mapping (when Interrupt Vectors are in RAM) MEMMAP EQU 0xE01FC040 ; Memory Mapping Control IF :DEF:REMAP LDR R0, =MEMMAP ; IF :DEF:EXTMEM_MODE ; MOV R1, #3 ; ELIF :DEF:RAM_MODE IF :DEF:RAM_MODE MOV R1, #2 ELSE MOV R1, #1 ENDIF STR R1, [R0] ENDIF
Hi Mustafa,
You told us that, you can erase sector 0, but can not write to sector 0. Then, you should check the Return Code of IAP Copy RAM to flash command.
It means, what is the value of your IAP.stat after you execute the IAP Copy RAM to flash command?
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) { unsigned long n; unsigned int Cntr; #if SET_VALID_CODE != 0 if (adr == 0) { n = *((unsigned long *)(buf + 0x00)) + *((unsigned long *)(buf + 0x04)) + *((unsigned long *)(buf + 0x08)) + *((unsigned long *)(buf + 0x0C)) + *((unsigned long *)(buf + 0x10)) + *((unsigned long *)(buf + 0x18)) + *((unsigned long *)(buf + 0x1C)); *((unsigned long *)(buf + 0x14)) = 0 - n; } #endif n = GetSecNum(adr); IAP.cmd = 50; IAP.par[0] = n; IAP.par[1] = n; IAP_Execute (&IAP); if (IAP.stat) return (1); /* IAP.stat provides all the information about why you can not write to sector 0. */ for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); IAP.cmd = 51; IAP.par[0] = adr; IAP.par[1] = (unsigned long)buf; IAP.par[2] = 1024; IAP.par[3] = CCLK; IAP_Execute (&IAP); if (IAP.stat) return (1); for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); return (0); }
Sorry, let me try again.
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) { unsigned long n; unsigned int Cntr; #if SET_VALID_CODE != 0 if (adr == 0) { n = *((unsigned long *)(buf + 0x00)) + *((unsigned long *)(buf + 0x04)) + *((unsigned long *)(buf + 0x08)) + *((unsigned long *)(buf + 0x0C)) + *((unsigned long *)(buf + 0x10)) + *((unsigned long *)(buf + 0x18)) + *((unsigned long *)(buf + 0x1C)); *((unsigned long *)(buf + 0x14)) = 0 - n; } #endif n = GetSecNum(adr); IAP.cmd = 50; IAP.par[0] = n; IAP.par[1] = n; IAP_Execute (&IAP); if (IAP.stat) return (1); /* IAP.stat provides all the information about why you can not write to sector 0. */ for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); IAP.cmd = 51; IAP.par[0] = adr; IAP.par[1] = (unsigned long)buf; IAP.par[2] = 1024; IAP.par[3] = CCLK; IAP_Execute (&IAP); if (IAP.stat) return (1); /* IAP.stat provides all the information about why you can not write to sector 0. */ for(Cntr=0; Cntr<50000; Cntr++); for(Cntr=0; Cntr<50000; Cntr++); return (0); }
I have tired to erase sector 0, but It does not return from the IAP_Execute (&IAP); function i.e the code in the RED ?
int EraseSector (unsigned long adr) { unsigned long n; unsigned long int Cntr; n = GetSecNum(adr); IAP.cmd = 50; IAP.par[0] = n; IAP.par[1] = n; IAP_Execute (&IAP); // call LED Blink function LEDBlink(ON); // Add Delay for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); LEDBlink(OFF); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); if (IAP.stat) { // call LED Blink function LEDBlink(ON); // Add Delay for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); LEDBlink(OFF); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); return (1); } IAP.cmd = 52; IAP.par[0] = n; IAP.par[1] = n; IAP.par[2] = CCLK; LEDBlink(ON); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); LEDBlink(OFF); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); IAP_Execute (&IAP); /* It does not execute below function if we try to erase sector 0 */ LEDBlink(ON); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); LEDBlink(OFF); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); if (IAP.stat) { // call LED Blink function LEDBlink(ON); // Add Delay for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); LEDBlink(OFF); for(Cntr=0; Cntr<5000000; Cntr++); for(Cntr=0; Cntr<5000000; Cntr++); return (1); } return (0); }
question remains: have you followed my advise? even if it does not immediately fix the problem, at least you'll have that out of th way. you really need to UNDERSTAND what you are doing - changing here and there is not going to bring you anywhere.
=> I have tired to erase sector 0, but It does not return from the IAP_Execute (&IAP); <=
Do you mean that, actually, you have never erased sector 0 successfully?
It does not return, then, do you know where is it? What is the value of your Program Counter?
Thanks Tamir & John .........
I am very happy by the advice suggested by you ....... really .... Just changing the code here and there had not help me .... I have gone through the whole code with conceptually and through understanding .......
Finally I was able to write the full IAP routine successfully ..... .i.e able to erase all the sectors & programmed it......
I am making mistake in placing the code in ROM region, after your advice place the code in IRAM region that write the flash in RAM, right click on your C file, use options to select a RAM region -
groovy!