lpcware

IAP for flash on LPC1778

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by ivon on Thu Apr 23 00:24:28 MST 2015
Hi,
I'm using LPC1778
I want to replace the flash code in the internal flash.
The start address is 0x0000, and the end address is 0x4FFF
The IAP function as follows is located in ROM at a fixed address (0xC000) in order to avoid overwriting.
I am sure that the value in Flash ROM is rewritten correctly by using the watch memory on debug mode in uVision5.
When I reset the MCU, it still couldn’t work. I think it can’t execute “SystemInit” and “main” loop.

IAP.c

#include "LPC177x_8x.h"

void jp_RFP(uint8_t *indata)
{
uint32_t  str_Flashaddr,romsize;
  uint8_t   result;
    *(indata+0)=cmd_RRF;
Delay_ms(2000);
LCMClrAll();
Delay_ms(2000);
  str_Flashaddr=0;
  romsize   =0x5000;
  result=LPC_IAP_Load(str_Flashaddr,romsize);//start_addr,Rom_size
  *(indata+1)=result;
}
uint8_t LPC_IAP_Load(uint32_t addr,uint32_t size)
{
uint8_t Start_Sec,End_Sec,iap_status=0;
uint32_t result=0,i,loop,loop_max,SecSel=0x00;
int32_t sur_size;
__disable_irq(); //disable irq
if(addr<0x00010000)
{
Start_Sec=addr/4096;
sur_size=size;
for(i=Start_Sec;i<=15;i++)
{
End_Sec=i;
sur_size-=4096;
if(sur_size<=0) sur_size=0;
if(sur_size==0) break;
}

if(sur_size!=0)
{
for(i=End_Sec;i<=29;i++)
{
End_Sec=i+1;
sur_size-=32768;
if(sur_size<=0) sur_size=0;
if(sur_size==0) break;
}
}

}
else
{
Start_Sec=(addr-0x00010000)/32768 +16;
End_Sec=Start_Sec+(size/32768);
}

for(SecSel=Start_Sec; SecSel<=End_Sec; SecSel++)
{
LPC_IAP_SelSector(SecSel,SecSel);
LPC_IAP_EraseSector(SecSel,SecSel);
      iap_status=LPC_IAP_BlankCHK(SecSel,SecSel);
if(iap_status != 0x00)
{
result = 0x01;
return  result;
}

}
SPIaddr=0x80000;
FlashAddr=addr;
loop_max=size/256;
for(loop=0;loop<loop_max;loop++)
{
result=LPC_IAP_Loop();
}
__enable_irq();   //enable irq
return  result;   //result=0 -> pass, result=1 -> blank fail, result=2 -> verify fail
}

uint8_t LPC_IAP_Loop(void)
{
uint32_t SecNum=0x00,iap_status=0;
uint8_t  SPIddrH,SPIddrM,SPIddrL,result=0;

  
if(FlashAddr <= 0x00000FFF) SecNum = 0x00;
else if(FlashAddr <= 0x00001FFF) SecNum = 0x01;
else if(FlashAddr <= 0x00002FFF) SecNum = 0x02;
else if(FlashAddr <= 0x00003FFF) SecNum = 0x03;
else if(FlashAddr <= 0x00004FFF) SecNum = 0x04;
else if(FlashAddr <= 0x00005FFF) SecNum = 0x05;
else if(FlashAddr <= 0x00006FFF) SecNum = 0x06;
else if(FlashAddr <= 0x00007FFF) SecNum = 0x07;
else if(FlashAddr <= 0x00008FFF) SecNum = 0x08;
else if(FlashAddr <= 0x00009FFF) SecNum = 0x09;
else if(FlashAddr <= 0x0000AFFF) SecNum = 0x0a;
else if(FlashAddr <= 0x0000BFFF) SecNum = 0x0b;
else if(FlashAddr <= 0x0000CFFF) SecNum = 0x0c;
else if(FlashAddr <= 0x0000DFFF) SecNum = 0x0d;
else if(FlashAddr <= 0x0000EFFF) SecNum = 0x0e;
else if(FlashAddr <= 0x0000FFFF) SecNum = 0x0f;
else if(FlashAddr <= 0x00017FFF) SecNum = 0x10;
else if(FlashAddr <= 0x0001FFFF) SecNum = 0x11;
else if(FlashAddr <= 0x00027FFF) SecNum = 0x12;
else if(FlashAddr <= 0x0002FFFF) SecNum = 0x13;
else if(FlashAddr <= 0x00037FFF) SecNum = 0x14;
else if(FlashAddr <= 0x0003FFFF) SecNum = 0x15;
else if(FlashAddr <= 0x00047FFF) SecNum = 0x16;
else if(FlashAddr <= 0x0004FFFF) SecNum = 0x17;
else if(FlashAddr <= 0x00057FFF) SecNum = 0x18;
else if(FlashAddr <= 0x0005FFFF) SecNum = 0x19;
else if(FlashAddr <= 0x00067FFF) SecNum = 0x1a;
else if(FlashAddr <= 0x0006FFFF) SecNum = 0x1b;
else if(FlashAddr <= 0x00077FFF) SecNum = 0x1c;
else if(FlashAddr <= 0x0007FFFF) SecNum = 0x1d;


LPC_IAP_SelSector(SecNum,SecNum);

SPIddrH=(uint8_t)((SPIaddr&0xFF0000)>>16);
SPIddrM=(uint8_t)((SPIaddr&0x00FF00)>>8);
SPIddrL=(uint8_t)(SPIaddr&0x0000FF);
SPIflash_read_nByte_withAddr(SPIddrH,SPIddrM,SPIddrL,&ToFlashBuff[0],256);

iap_status=LPC_IAP_RamToFlash(FlashAddr, (uint32_t)ToFlashBuff, 256);

//if(iap_status != 0x00) result = 0x01;

iap_status=LPC_IAP_Compare(FlashAddr, (uint32_t)ToFlashBuff, 256);  

if(iap_status != 0x00) result = 0x02;


SPIaddr+=256;
FlashAddr +=256;




return  result;

}
int LPC_IAP_SelSector(uint32_t sector_start, uint32_t sector_end)
{
uint32_tparamin[8];
  uint32_tparamout[8];
typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_SELSECTOR;
paramin[1] = sector_start;
paramin[2] = sector_end;
LPC_IAP_entry(paramin, paramout);
return  paramout[0];
}

int LPC_IAP_RamToFlash(uint32_t flash_address, uint32_t ram_address, uint32_t no)
{
uint32_tparamin[8];
  uint32_tparamout[8];
  typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
  LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_RAMTOFLASH;
paramin[1] = (uint32_t)flash_address;
paramin[2] = (uint32_t)ram_address;
paramin[3] = no;
paramin[4] = 100000;
LPC_IAP_entry(paramin, paramout);
return  paramout[0];
}


int LPC_IAP_EraseSector(uint32_t sector_start, uint32_t sector_end)
{
uint32_tparamin[8];
  uint32_tparamout[8];
typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
  LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_ERASESECTOR;
paramin[1] = sector_start;
paramin[2] = sector_end;
paramin[3] = 100000;
LPC_IAP_entry(paramin, paramout);
  return  paramout[0];
}

int LPC_IAP_BlankCHK(uint8_t sec1, uint8_t sec2)
{
uint32_tparamin[8];
  uint32_tparamout[8];
typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
  LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_BLANKCHK;
paramin[1] = sec1;
paramin[2] = sec2;
LPC_IAP_entry(paramin, paramout);
  return  paramout[0];
}

int LPC_IAP_ReadParID(void)
{
uint32_tparamin[8];
  uint32_tparamout[8];
typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
  LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_READPARTID;
LPC_IAP_entry(paramin, paramout);
  return  paramout[0];
}

int LPC_IAP_BootCodeID(void)
{
uint32_tparamin[8];
  uint32_tparamout[8];
typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
  LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_BOOTCODEID;
LPC_IAP_entry(paramin, paramout);
  return  paramout[0];
}

int LPC_IAP_Compare(uint32_t dst, uint32_t src, uint32_t no)
{
uint32_tparamin[8];
  uint32_tparamout[8];
typedef void(*LPC_IAP)(uint32_t[], uint32_t []);
LPC_IAP LPC_IAP_entry;
  LPC_IAP_entry=(LPC_IAP) LPC_IAP_LOCATION;
paramin[0] = LPC_IAP_COMPARE;
paramin[1] = dst;
paramin[2] = src;
paramin[3] = no;
LPC_IAP_entry(paramin, paramout);
return  paramout[0];
}

scatter file is as follows

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x00000000 0x00080000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00080000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  ER_IAP 0x0000C000 FIXED
{
nwtr_iap.o(+RO)
}
  RW_IRAM1 0x10000000 0x00010000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

Do you have any idea for that? I will be pleasure if you can give any advice to me, thank you.

Outcomes