Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Tue Jul 12 2022 21:03:50 by
1.7.2