PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)
Fork of PokittoLib by
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
Generated on Tue Jul 12 2022 18:08:12 by 1.7.2