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

Dependents:   Sensitive

Fork of PokittoLib by Jonne Valola

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