Hi
I'm using this on my LPC2148 and it works fine so far:
I'm flashing in chunks of 512bytes. Don't forget to turn off IRQs!
clock = 60Mhz
static char flashdata[512];
static unsigned long flashdatapointer=0;
static unsigned long flashsectorpointer=0;
static unsigned long flashaddrpointer=0;
//+++++++++++++++++++++++++IAP++++++++++++++++++++++++++++++++++++
#define PREPARE_SECTOR_FOR_WRITE_OPERATION 50 // IAP command
#define COPY_RAM_TO_FLASH 51
#define ERASE_SECTOR 52
#define BLANK_CHECK_SECTOR 53
#define READ_PART_ID 54
#define READ_BOOT_CODE_VERSION 55
#define COMPARE 56 // codes
static unsigned long iap_cmd[5]; // IAP command table
static unsigned long iap_res[3]; // result table
static long iap(long code, long p1, long p2, long p3, long p4)
{
iap_cmd[0] = code; // set command code
iap_cmd[1] = p1; // 1st param
iap_cmd[2] = p2; // 2nd param
iap_cmd[3] = p3; // 3rd param
iap_cmd[4] = p4; // 4th param
((void (*)())0x7ffffff1)(iap_cmd, iap_res); // IAP entry point
return *iap_res; // return status
}
static void part_id(void)
{
if (iap(READ_PART_ID, 0, 0, 0, 0)) {
DBG("Error reading part ID\n");
return;
}
DBG("Part ID: %u\n", iap_res[1]);
}
static void bootcodeversion(void)
{
if (iap(READ_BOOT_CODE_VERSION, 0, 0, 0, 0)) {
DBG("Reading boot code version\n");
return;
}
DBG("Boot code version: %d.%d\n",(unsigned char)(iap_res[1]>>8),
(unsigned char)iap_res[1]);
}
unsigned long adress_to_sector(unsigned long address)
{
if (address<0x8000)
return (address>>12);
if (address<0x78000)
return ((address>>15)+7);
if (address<0x7D000)
return ((address>>12)-98);
return 26;
}
static void s_write(unsigned long address)
{
unsigned long SECT = 0;
SECTress_to_sector(address);
if (iap(PREPARE_SECTOR_FOR_WRITE_OPERATION, SECT, SECT, 0, 0)
|| iap(COPY_RAM_TO_FLASH, address, (long)flashdata, 512, 60000)
|| iap(COMPARE, address, (long)flashdata, 512, 0)) {
DBG("Error Writing sector");
return;
}
DBG("Data successfully written.");
}
static void s_erase(unsigned long address)
{
unsigned long SECT = 0;
SECTress_to_sector(address);
if (!iap(BLANK_CHECK_SECTOR, SECT, SECT, 0, 0)) {
DBG("Sector already blank!\n");
return;
}
if (iap(PREPARE_SECTOR_FOR_WRITE_OPERATION, SECT, SECT, 0, 0)
|| iap(ERASE_SECTOR, SECT, SECT, 60000, 0)
|| iap(BLANK_CHECK_SECTOR, SECT, SECT, 0, 0)) {
DBG("Error Erasing sector\n");
return;
}
DBG("Sector successfully erased.\n");
}
void InApplicationProgramming(void)
{
disableIRQ();
if (flashsectorpointer
{
s_erase(flashaddrpointer);
flashsectorpointerress_to_sector(flashaddrpointer);
}
s_write(flashaddrpointer);
enableIRQ();
}