PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iap.cpp Source File

iap.cpp

00001 #include <stdio.h>
00002 #include <stdint.h>
00003 #include <iap.h>
00004 #include "LPC11U6x.h"
00005 #include "PokittoDisk.h "
00006 
00007 #define TICKRATE_HZ (10)    /* 10 ticks per second */
00008 /* SystemTick Counter */
00009 static volatile uint32_t sysTick;
00010 
00011 /* LPC1347 IAP entry address */
00012 #define IAP_LOCATION 0x1fff1ff1
00013 
00014 #define last_sector_flash  0x00038000  //0x0000F000
00015 #define IAP_LAST_SECTOR 28 /* Page number 896 - 1023, 0x00038000 - 0x0003FFFF */
00016 #define IAP_NUM_BYTES_TO_WRITE 256
00017 #define WRITECOUNT (IAP_NUM_BYTES_TO_WRITE / 4) /* when data array is in uint32_t */
00018 
00019 #define IAP_PREWRRITE_CMD 50 /* Prepare sector for write operation command */
00020 #define IAP_WRISECTOR_CMD 51
00021 #define IAP_ERSSECTOR_CMD 52
00022 #define IAP_REPID_CMD 54
00023 
00024 /* IAP command variables */
00025 static unsigned int command[5], result[4];
00026 
00027 /* IAP entry function */
00028 typedef int (*IAP)(unsigned int[], unsigned int[]);
00029 IAP iap_entry = (IAP) IAP_LOCATION;
00030 
00031 int CopyPageToFlash (uint32_t address, uint8_t* data) {
00032     IAP iap_call = (IAP) IAP_LOCATION;
00033     //uint32_t writecount=0;
00034     __disable_irq();
00035 
00036     unsigned int sector;//, page;
00037     bool firstpage=false, erasepage=false;
00038 
00039     //DEBUG//
00040     //for (int i=0;i<256;i++) data[i]=0xBB;
00041 
00042     /* Calculate sector based on address */
00043     if (address < 0x18000) sector = address/0x1000; // sectors go in 4 k's
00044     else if (address >= 0x38000) sector = 28;
00045     else if (address >= 0x30000) sector = 27;
00046     else if (address >= 0x28000) sector = 26;
00047     else if (address >= 0x20000) sector = 25;
00048     else sector = 24;
00049 
00050     /* Check is it the first page in the sector */
00051     if (sector < 24) {
00052         /* 4KB addresses cover 0x000 - 0xFFF range */
00053         firstpage = ((address & 0x0FFF) == 0);
00054     } else {
00055         /* 32KB addresses cover 0x0000 - 0x7FFF and 0x8000 - 0xFFFF range */
00056         firstpage = ((address & 0x7FFF) == 0);
00057     }
00058 
00059     /* Prepare the sector for writing */
00060     command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00061     command[1] = sector;                                    /* Start Sector Number */
00062     command[2] = sector;                                    /* End Sector Number */
00063     iap_call(command, result);
00064     if (result[0]) return 1;
00065 
00066     /* wipe pages when writing the loader */
00067     if (address==0x39000) {
00068             erasepage=true;
00069     }
00070 
00071     /* do sector erase only when writing first page of given sector */
00072     if (firstpage) {
00073         /* Erase the last sector */
00074         command[0] = IAP_ERSSECTOR_CMD;                     /* Erase command code*/
00075         command[1] = sector;                                    /* Start Sector Number */
00076         command[2] = sector;                                    /* End Sector Number */
00077         command[3] = SystemCoreClock / 1000UL;  /* Core clock frequency in kHz */
00078         iap_call(command, result);
00079         if (result[0]) return 1;
00080         /* Prepare to write/erase the last sector, needs to be done again because succesful erase re-locks sectors */
00081         command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00082         command[1] = sector;                                        /* Start Sector Number */
00083         command[2] = sector;                                    /* Start Sector Number */
00084         iap_call(command, result);
00085         if (result[0]) return 1;
00086     }
00087 
00088     /* page erase for bootloader area */
00089     if (erasepage) {
00090         command[0] = 59; //erase page command
00091         command[1] = 896;
00092         command[2] = 1023;
00093         command[3] = SystemCoreClock / 1000UL;  /* Core clock frequency in kHz */
00094         iap_call(command, result);
00095         if (result[0]) return 1;
00096         /* Prepare to write/erase the last sector, needs to be done again because succesful erase re-locks sectors */
00097         command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00098         command[1] = sector;                                        /* Start Sector Number */
00099         command[2] = sector;                                    /* Start Sector Number */
00100         iap_call(command, result);
00101         if (result[0]) return 1;
00102     }
00103 
00104     /* Write data to the sectors */
00105     command[0] = IAP_WRISECTOR_CMD;                     /* Write command code */
00106     command[1] = (uint32_t) (uint32_t*) address;                        /* Destination Flash Address */
00107     command[2] = (uint32_t) data;                       /* Source RAM Address */
00108     command[3] = 0x100;                                 /* Number of Bytes to be written */
00109     command[4] = SystemCoreClock / 1000;                /* System clock frequency */
00110     iap_call(command, result);
00111     if (result[0]) return 1;
00112 
00113     /* Re-enable interrupt mode */
00114     __enable_irq();
00115 
00116     return 0; /*succesful write*/
00117 
00118 }
00119 
00120 __attribute__((section(".IAP_Code"))) int HelloFromIAP() {
00121     static uint32_t array_data[WRITECOUNT];
00122     int i;
00123     /* Initialize the array data to be written to FLASH */
00124     for (i = 0; i < WRITECOUNT; i++) {
00125         array_data[i] = 0xB007AB1E;
00126     }
00127 
00128     IAP iap_call = (IAP) IAP_LOCATION;
00129     uint8_t teahupoo;
00130     //readEEPROM(0,&teahupoo,1);
00131     teahupoo++;
00132     //writeEEPROM(0,&teahupoo,1);
00133 
00134     /** open file **/
00135     pokInitSD();
00136     char fn[20];
00137     char* now;
00138     now = (char*)last_sector_flash;
00139     switch (now[0]) {
00140 case 0xAA:
00141     fn[0]='B';fn[1]='B';fn[2]='.';fn[3]='B';fn[4]='I';fn[5]='N';fn[6]='\0';break;
00142 case 0xBB:
00143     fn[0]='C';fn[1]='C';fn[2]='.';fn[3]='B';fn[4]='I';fn[5]='N';fn[6]='\0';break;
00144 default:
00145     fn[0]='A';fn[1]='A';fn[2]='.';fn[3]='B';fn[4]='I';fn[5]='N';fn[6]='\0';
00146     }
00147     if(fileOpen(fn,FILE_MODE_BINARY)) {
00148             return 1;
00149     } else {
00150      for (i = 0; i < WRITECOUNT; i++) {
00151         fileReadBytes((uint8_t*)&array_data[i],4);
00152      }
00153     }
00154 
00155 
00156     /** write sector in flash **/
00157     /* Read Part Identification Number*/
00158     command[0] = IAP_REPID_CMD;                             /* Read ID command code */
00159     iap_call(command, result);
00160 
00161     __disable_irq();
00162 
00163     /* Prepare to write/erase the last sector */
00164     command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00165     command[1] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00166     command[2] = IAP_LAST_SECTOR;                           /* End Sector Number */
00167     iap_call(command, result);
00168     /* Erase the last sector */
00169     command[0] = IAP_ERSSECTOR_CMD;                     /* Erase command code*/
00170     command[1] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00171     command[2] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00172     command[3] = SystemCoreClock / 1000UL;  /* Core clock frequency in kHz */
00173     iap_call(command, result);
00174     /* Prepare to write/erase the last sector */
00175     command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00176     command[1] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00177     command[2] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00178     iap_call(command, result);
00179     /* Write to the last sector */
00180     command[0] = IAP_WRISECTOR_CMD;                             /* Write command code */
00181     command[1] = (uint32_t) last_sector_flash;              /* Destination Flash Address */
00182     command[2] = (uint32_t) &array_data;                    /* Source RAM Address */
00183     command[3] = IAP_NUM_BYTES_TO_WRITE;                    /* Number of Bytes to be written */
00184     command[4] = SystemCoreClock / 1000;                    /* System clock frequency */
00185     iap_call(command, result);
00186 
00187     /* Re-enable interrupt mode */
00188     __enable_irq();
00189 
00190 
00191     SCB->AIRCR = 0x05FA0004; //issue system reset
00192     while(1); //should never come here
00193     //return teahupoo;
00194 }
00195 
00196 
00197 
00198 
00199 void IAPstacksave()
00200 {
00201   /*need to save 32 top bytes of RAM to RAM1*/
00202   #define RAM1_0 (*((volatile unsigned long *) 0x20000000))
00203   #define RAM1_1 (*((volatile unsigned long *) 0x20000004))
00204   #define RAM1_2 (*((volatile unsigned long *) 0x20000008))
00205   #define RAM1_3 (*((volatile unsigned long *) 0x2000000C))
00206   #define RAM1_4 (*((volatile unsigned long *) 0x20000010))
00207   #define RAM1_5 (*((volatile unsigned long *) 0x20000014))
00208   #define RAM1_6 (*((volatile unsigned long *) 0x20000018))
00209   #define RAM1_7 (*((volatile unsigned long *) 0x2000001C))
00210 
00211   uint32_t *saveloc = (uint32_t*)(0x10002000-0x20); // RAM top - 32 bytes
00212   RAM1_0 = *saveloc++;
00213   RAM1_1 = *saveloc++;
00214   RAM1_2 = *saveloc++;
00215   RAM1_3 = *saveloc++;
00216   RAM1_4 = *saveloc++;
00217   RAM1_5 = *saveloc++;
00218   RAM1_6 = *saveloc++;
00219   RAM1_7 = *saveloc;
00220 }
00221 
00222 
00223 char iaptest() {
00224     static uint32_t array_data[WRITECOUNT];
00225     int i;
00226     /* Initialize the array data to be written to FLASH */
00227     for (i = 0; i < WRITECOUNT; i++) {
00228         array_data[i] = 0x11223340 + i;
00229     }
00230 
00231     /* Read Part Identification Number*/
00232     command[0] = IAP_REPID_CMD;                             /* Read ID command code */
00233     iap_entry(command, result);
00234 
00235     /* Reinvoke ISP mode so that reprogamming of Flash possible */
00236     __disable_irq();
00237 
00238     command[0] = IAP_REPID_CMD;
00239     iap_entry(command, result);
00240 
00241     /* Prepare to write/erase the last sector */
00242     command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00243     command[1] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00244     command[2] = IAP_LAST_SECTOR;                           /* End Sector Number */
00245     iap_entry(command, result);
00246 
00247     /* Erase the last sector */
00248     command[0] = IAP_ERSSECTOR_CMD;                     /* Erase command code*/
00249     command[1] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00250     command[2] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00251     iap_entry(command, result);
00252 
00253     /* Prepare to write/erase the last sector */
00254     command[0] = IAP_PREWRRITE_CMD;                     /* Prepare to write/erase command code */
00255     command[1] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00256     command[2] = IAP_LAST_SECTOR;                           /* Start Sector Number */
00257     iap_entry(command, result);
00258 
00259     /* Write to the last sector */
00260     command[0] = IAP_WRISECTOR_CMD;                             /* Write command code */
00261     command[1] = (uint32_t) last_sector_flash;      /* Destination Flash Address */
00262     command[2] = (uint32_t) &array_data;                    /* Source RAM Address */
00263     command[3] = IAP_NUM_BYTES_TO_WRITE;                    /* Number of Bytes to be written */
00264     command[4] = SystemCoreClock / 1000;                    /* System clock frequency */
00265     iap_entry(command, result);
00266 
00267     /* Re-enable interrupt mode */
00268     __enable_irq();
00269 
00270     //while (1) {
00271     //  __WFI();
00272     //}
00273 
00274     return 0;
00275 
00276 }
00277 
00278 
00279 //1) EEprom Write
00280 //
00281 //Command code: 61
00282 //Param0: eeprom address (byte, half-word or word aligned)
00283 //Param1: RAM address (byte, half-word or word aligned)
00284 //Param2: Number of bytes to be written ( Byte, Half-words write are ok)
00285 //Param3: System Clock Frequency (CCLK) in kHz
00286 //
00287 //Return Code CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED
00288 __attribute__((section(".IAP_Code"))) void writeEEPROM( uint16_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount )
00289 {
00290     unsigned int command[5], result[4];
00291 
00292     command[0] = 61;
00293     command[1] = (uint32_t) eeAddress;
00294     command[2] = (uint32_t) buffAddress;
00295     command[3] = byteCount;
00296     command[4] = SystemCoreClock/1000;
00297 
00298     /* Invoke IAP call...*/
00299 #if (EEPROM_PROFILE!=0)
00300     LPC_CT32B0->TCR = 1;
00301     __disable_irq();
00302     iap_entry(command, result);
00303     __enable_irq();
00304     LPC_CT32B0->TCR = 0;
00305 #else
00306     __disable_irq();
00307     iap_entry(command, result);
00308     __enable_irq();
00309 #endif
00310     if (0 != result[0])
00311     {
00312         //Trap error
00313         while(1);
00314     }
00315     return;
00316 }
00317 
00318 //2) EEprom Read
00319 //Command code: 62
00320 //Param0: eeprom address (byte, half-word or word aligned)
00321 //Param1: RAM address (byte, half-word or word aligned)
00322 //Param2: Number of bytes to be read ( Byte, Half-words read are ok)
00323 //Param3: System Clock Frequency (CCLK) in kHz
00324 //
00325 //Return Code CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED
00326 __attribute__((section(".IAP_Code"))) void readEEPROM( uint16_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount )
00327 {
00328     unsigned int command[5], result[4];
00329 
00330     command[0] = 62;
00331     command[1] = (uint32_t) eeAddress;
00332     command[2] = (uint32_t) buffAddress;
00333     command[3] = byteCount;
00334     command[4] = SystemCoreClock/1000;
00335 
00336     /* Invoke IAP call...*/
00337     __disable_irq();
00338     iap_entry( command, result);
00339     __enable_irq();
00340     if (0 != result[0])
00341     {
00342         //Trap error
00343         while(1);
00344     }
00345     return;
00346 }
00347 
00348 __attribute__((section(".IAP_Code"))) void IAPreadPartId( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount )
00349 {
00350     unsigned int command[5], result[4];
00351 
00352     command[0] = 62;
00353     command[1] = (uint32_t) eeAddress;
00354     command[2] = (uint32_t) buffAddress;
00355     command[3] = byteCount;
00356     command[4] = SystemCoreClock/1000;
00357 
00358     /* Invoke IAP call...*/
00359     __disable_irq();
00360     iap_entry( command, result);
00361     __enable_irq();
00362     if (0 != result[0])
00363     {
00364         //Trap error
00365         while(1);
00366     }
00367     return;
00368 }
00369 
00370 uint8_t eeprom_read_byte(uint16_t* index) {
00371     uint8_t val;
00372     readEEPROM(index,&val,1);
00373     return val;
00374 }
00375 
00376 void eeprom_write_byte(uint16_t* index , uint8_t val) {
00377     writeEEPROM(index,&val,1);
00378 }
00379 
00380 /*****************************************************************************
00381  * $Id$
00382  *
00383  * Project:     NXP LPC11U6x In Application Programming
00384  *
00385  * Description: Provides access to In-Application Programming (IAP) routines
00386  *              contained within the bootROM sector of LPC11U6x devices.
00387  *
00388  * Copyright(C) 2010, NXP Semiconductor
00389  * All rights reserved.
00390  *
00391  *****************************************************************************
00392  * Software that is described herein is for illustrative purposes only
00393  * which provides customers with programming information regarding the
00394  * products. This software is supplied "AS IS" without any warranties.
00395  * NXP Semiconductors assumes no responsibility or liability for the
00396  * use of the software, conveys no license or title under any patent,
00397  * copyright, or mask work right to the product. NXP Semiconductors
00398  * reserves the right to make changes in the software without
00399  * notification. NXP Semiconductors also make no representation or
00400  * warranty that such application will be suitable for the specified
00401  * use without further testing or modification.
00402  *****************************************************************************/
00403 
00404 /* IAP Command Definitions */
00405 #define IAP_CMD_PREPARE_SECTORS           50
00406 #define IAP_CMD_COPY_RAM_TO_FLASH         51
00407 #define IAP_CMD_ERASE_SECTORS               52
00408 #define IAP_CMD_BLANK_CHECK_SECTORS     53
00409 #define IAP_CMD_READ_PART_ID                54
00410 #define IAP_CMD_READ_BOOT_ROM_VERSION   55
00411 #define IAP_CMD_COMPARE                       56
00412 #define IAP_CMD_REINVOKE_ISP                57
00413 #define IAP_CMD_READ_UID              58
00414 
00415 #define IAP_CMD_ERASE_PAGE            59    //new
00416 
00417 /* IAP boot ROM location and access function */
00418 #define IAP_ROM_LOCATION                0x1FFF1FF1UL
00419 //#define IAP_EXECUTE_CMD(a, b)         ((void (*)())(IAP_ROM_LOCATION))(a, b)
00420 
00421 __attribute__((section(".IAP_Code"))) void IAP_EXECUTE_CMD(uint32_t* a, uint32_t* b) {
00422     void (*user_code_entry)(uint32_t*,uint32_t*);
00423     uint32_t *p;
00424     p = (uint32_t *)IAP_ROM_LOCATION;
00425     user_code_entry = (void (*)(uint32_t*,uint32_t*))(*p);
00426     user_code_entry(a, b);
00427 }
00428 
00429 
00430 /*****************************************************************************
00431 ** Function name:   u32IAP_PrepareSectors
00432 **
00433 ** Description:     Prepares sector(s) for erasing or write operations. This
00434 **                              command must be executed before executing the "Copy RAM to
00435 **                              Flash" or "Erase Sector(s)" commands.
00436 **
00437 ** Parameters:      u32StartSector - Number of first sector to prepare.
00438 **                              u32EndSector - Number of last sector to prepare.
00439 **
00440 ** Returned value:  Status code returned by IAP ROM function.
00441 **
00442 ******************************************************************************/
00443 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_PrepareSectors(uint32_t u32StartSector, uint32_t u32EndSector)
00444 {
00445     uint32_t u32Status;
00446     uint32_t au32Result[3];
00447     uint32_t au32Command[5];
00448 
00449     if (u32EndSector < u32StartSector)
00450     {
00451         u32Status = IAP_STA_INVALD_PARAM;
00452     }
00453     else
00454     {
00455         au32Command[0] = IAP_CMD_PREPARE_SECTORS;
00456         au32Command[1] = u32StartSector;
00457         au32Command[2] = u32EndSector;
00458         __disable_irq();
00459         IAP_EXECUTE_CMD(au32Command, au32Result);
00460         __enable_irq();
00461         u32Status = au32Result[0];
00462     }
00463     return u32Status;
00464 }
00465 
00466 /*****************************************************************************
00467 ** Function name:   u32IAP_CopyRAMToFlash
00468 **
00469 ** Description:     Program the flash memory with data stored in RAM.
00470 **
00471 ** Parameters:      u32DstAddr - Destination Flash address, should be a 256
00472 **                               byte boundary.
00473 **                  u32SrcAddr - Source RAM address, should be a word boundary
00474 **                  u32Len     - Number of 8-bit bytes to write, must be a
00475 **                               multiple of 256.
00476 *
00477 ** Returned value:  Status code returned by IAP ROM function.
00478 **
00479 ******************************************************************************/
00480 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_CopyRAMToFlash(uint32_t u32DstAddr, uint32_t u32SrcAddr, uint32_t u32Len)
00481 {
00482     uint32_t au32Result[3];
00483     uint32_t au32Command[5];
00484 
00485     au32Command[0] = IAP_CMD_COPY_RAM_TO_FLASH;
00486     au32Command[1] = u32DstAddr;
00487     au32Command[2] = u32SrcAddr;
00488     au32Command[3] = u32Len;
00489     au32Command[4] = SystemCoreClock / 1000UL;  /* Core clock frequency in kHz */
00490 
00491     IAP_EXECUTE_CMD(au32Command, au32Result);
00492 
00493     return au32Result[0];
00494 }
00495 
00496 /*****************************************************************************
00497 ** Function name:   u32IAP_EraseSectors
00498 **
00499 ** Description:     Erase a sector or multiple sectors of on-chip Flash memory.
00500 **
00501 ** Parameters:      u32StartSector - Number of first sector to erase.
00502 **                  u32EndSector - Number of last sector to erase.
00503 *
00504 ** Returned value:  Status code returned by IAP ROM function.
00505 **
00506 ******************************************************************************/
00507 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_EraseSectors(uint32_t u32StartSector, uint32_t u32EndSector)
00508 {
00509     uint32_t u32Status;
00510     uint32_t au32Result[3];
00511     uint32_t au32Command[5];
00512 
00513     if (u32EndSector < u32StartSector)
00514     {
00515         u32Status = IAP_STA_INVALD_PARAM;
00516     }
00517     else
00518     {
00519         au32Command[0] = IAP_CMD_ERASE_SECTORS;
00520         au32Command[1] = u32StartSector;
00521         au32Command[2] = u32EndSector;
00522         au32Command[3] = SystemCoreClock / 1000UL;  /* Core clock frequency in kHz */
00523 
00524         IAP_EXECUTE_CMD(au32Command, au32Result);
00525 
00526         u32Status = au32Result[0];
00527     }
00528     return u32Status;
00529 }
00530 
00531 /*****************************************************************************
00532 ** Function name:   u32IAP_BlankCheckSectors
00533 **
00534 ** Description:     Blank check a sector or multiple sectors of on-chip flash
00535 **                  memory.
00536 **
00537 ** Parameters:      u32StartSector - Number of first sector to check.
00538 **                  u32EndSector - Number of last sector to check.
00539 **                  pu32Result[0] - Offset of the first non blank word location
00540 **                  if the Status Code is IAP_STA_SECTOR_NOT_BLANK.
00541 **                  pu32Result[1] - Contents of non blank word location.
00542 **
00543 ** Returned value:  Status code returned by IAP ROM function.
00544 **
00545 ******************************************************************************/
00546 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_BlankCheckSectors(uint32_t u32StartSector, uint32_t u32EndSector, uint32_t *pu32Result)
00547 {
00548     uint32_t u32Status;
00549     uint32_t au32Result[3];
00550     uint32_t au32Command[5];
00551 
00552     if (u32EndSector < u32StartSector)
00553     {
00554         u32Status = IAP_STA_INVALD_PARAM;
00555     }
00556     else
00557     {
00558         au32Command[0] = IAP_CMD_BLANK_CHECK_SECTORS;
00559         au32Command[1] = u32StartSector;
00560         au32Command[2] = u32EndSector;
00561 
00562         IAP_EXECUTE_CMD(au32Command, au32Result);
00563 
00564         if (au32Result[0] == IAP_STA_SECTOR_NOT_BLANK)
00565         {
00566             *pu32Result       = au32Result[0];
00567             *(pu32Result + 1) = au32Result[1];
00568         }
00569         u32Status = au32Result[0];
00570     }
00571     return u32Status;
00572 }
00573 
00574 /*****************************************************************************
00575 ** Function name:   u32IAP_ReadPartID
00576 **
00577 ** Description:     Read the part identification number.
00578 **
00579 ** Parameters:      pu32PartID - Pointer to storage for part ID number.
00580 *
00581 ** Returned value:  Status code returned by IAP ROM function.
00582 **
00583 ******************************************************************************/
00584 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_ReadPartID(uint32_t *pu32PartID)
00585 {
00586     uint32_t au32Result[3];
00587     uint32_t au32Command[5];
00588 
00589     au32Command[0] = IAP_CMD_READ_PART_ID;
00590     __disable_irq();
00591     IAP_EXECUTE_CMD(au32Command, au32Result);
00592     __enable_irq();
00593     *pu32PartID = au32Result[1];
00594 
00595     return au32Result[0];
00596 }
00597 
00598 /*****************************************************************************
00599 ** Function name:   u32IAP_ReadBootVersion
00600 **
00601 ** Description:     Read the boot code version number.
00602 **
00603 ** Parameters:      pu32Major - Major version number in ASCII format.
00604 **                  pu32Minor - Minor version number in ASCII format.
00605 **
00606 ** Returned value:  Status code returned by IAP ROM function.
00607 **
00608 ******************************************************************************/
00609 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_ReadBootVersion(uint32_t *pu32Major, uint32_t *pu32Minor)
00610 //uint32_t u32IAP_ReadBootVersion(uint32_t *pu32Major)
00611 {
00612     uint32_t au32Result[3];
00613     uint32_t au32Command[5];
00614 
00615     au32Command[0] = IAP_CMD_READ_BOOT_ROM_VERSION;
00616 
00617     IAP_EXECUTE_CMD(au32Command, au32Result);
00618 
00619 
00620     *pu32Major = (au32Result[1] & 0x0000FF00UL) >> 8;
00621     *pu32Minor = au32Result[1] & 0x000000FFUL;
00622 
00623     return au32Result[0];
00624 }
00625 
00626 /*****************************************************************************
00627 ** Function name:   u32IAP_Compare
00628 **
00629 ** Description:     Compares the memory contents at two locations.
00630 **
00631 ** Parameters:      u32Len - Number of bytes to compare, must be a multiple of 4.
00632 **                  pu32Offset - Offset of the first mismatch if the Status Code is COMPARE_ERROR
00633 **
00634 ** Returned value:  Status code returned by IAP ROM function.
00635 **
00636 ******************************************************************************/
00637 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_Compare(uint32_t u32DstAddr, uint32_t u32SrcAddr, uint32_t u32Len, uint32_t *pu32Offset)
00638 {
00639     uint32_t au32Result[3];
00640     uint32_t au32Command[5];
00641 
00642     au32Command[0] = IAP_CMD_COMPARE;
00643     au32Command[1] = u32DstAddr;
00644     au32Command[2] = u32SrcAddr;
00645     au32Command[3] = u32Len;
00646 
00647     IAP_EXECUTE_CMD(au32Command, au32Result);
00648 
00649     if (au32Result[0] == IAP_STA_COMPARE_ERROR)
00650     {
00651         if (pu32Offset != 0)
00652         {
00653             *pu32Offset = au32Result[1];
00654         }
00655     }
00656     return au32Result[0];
00657 }
00658 
00659 /*****************************************************************************
00660 ** Function name:   vIAP_ReinvokeISP
00661 **
00662 ** Description:     Invoke the bootloader in ISP mode.
00663 **
00664 ** Parameters:      None.
00665 *
00666 ** Returned value:  None.
00667 **
00668 ******************************************************************************/
00669 __attribute__((section(".IAP_Code"))) void vIAP_ReinvokeISP(void)
00670 {
00671     uint32_t au32Result[3];
00672     uint32_t au32Command[5];
00673 
00674     au32Command[0] = IAP_CMD_REINVOKE_ISP;
00675 
00676     IAP_EXECUTE_CMD(au32Command, au32Result);
00677 }
00678 
00679 // read UID
00680 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_ReadUID(uint32_t * pu32UID)
00681 {
00682     uint32_t au32Result[5];
00683     uint32_t au32Command[5];
00684 
00685     au32Command[0] = IAP_CMD_READ_UID;
00686 
00687     IAP_EXECUTE_CMD(au32Command, au32Result);
00688 //  *pu32UID++ =  au32Result[1];
00689 //  *pu32UID++ =  au32Result[2];
00690 //  *pu32UID++ =  au32Result[3];
00691 //  *pu32UID =  au32Result[4];
00692 
00693     *pu32UID =  au32Result[1];
00694     *pu32UID++ =  au32Result[2];
00695     *pu32UID++ =  au32Result[3];
00696     *pu32UID++ =  au32Result[4];
00697 
00698     return au32Result[0];
00699 
00700 }
00701 
00702 //IAP erase Page  256B   64K have 0-255 pages, page0-15 in sector 0,    32K have 0-127 pages, 128k have 0-511 pages,
00703 __attribute__((section(".IAP_Code"))) uint32_t u32IAP_ErasePage(uint32_t u32StartPage, uint32_t u32EndPage)
00704 {
00705     uint32_t u32Status;
00706     uint32_t au32Result[3];
00707     uint32_t au32Command[5];
00708 
00709     if (u32EndPage < u32StartPage)
00710     {
00711         u32Status = IAP_STA_INVALD_PARAM;
00712     }
00713     else
00714     {
00715         au32Command[0] = IAP_CMD_ERASE_PAGE;
00716         au32Command[1] = u32StartPage;
00717         au32Command[2] = u32EndPage;
00718         au32Command[3] = SystemCoreClock / 1000UL;  /* Core clock frequency in kHz */
00719 
00720         IAP_EXECUTE_CMD(au32Command, au32Result);
00721 
00722         u32Status = au32Result[0];
00723     }
00724     return u32Status;
00725 }
00726 
00727 
00728 /*****************************************************************************
00729  **                            End Of File
00730  *****************************************************************************/
00731