PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)
Embed:
(wiki syntax)
Show/hide line numbers
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