PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)
Dependents: YATTT sd_map_test cPong SnowDemo ... more
PokittoLib
Library for programming Pokitto hardware
How to Use
- Import this library to online compiler (see button "import" on the right hand side
- DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
- Change My_settings.h according to your project
- Start coding!
Diff: POKITTO_HW/iap.cpp
- Revision:
- 0:e8b8f36b4505
- Child:
- 2:968589ca3484
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/POKITTO_HW/iap.cpp Mon Sep 18 11:47:51 2017 +0000 @@ -0,0 +1,705 @@ +#include <stdio.h> +#include <stdint.h> +#include <iap.h> +#include "LPC11U6x.h" +#include "PokittoDisk.h" + +#define TICKRATE_HZ (10) /* 10 ticks per second */ +/* SystemTick Counter */ +static volatile uint32_t sysTick; + +/* LPC1347 IAP entry address */ +#define IAP_LOCATION 0x1fff1ff1 + +#define last_sector_flash 0x00038000 //0x0000F000 +#define IAP_LAST_SECTOR 28 /* Page number 896 - 1023, 0x00038000 - 0x0003FFFF */ +#define IAP_NUM_BYTES_TO_WRITE 256 +#define WRITECOUNT (IAP_NUM_BYTES_TO_WRITE / 4) /* when data array is in uint32_t */ + +#define IAP_PREWRRITE_CMD 50 /* Prepare sector for write operation command */ +#define IAP_WRISECTOR_CMD 51 +#define IAP_ERSSECTOR_CMD 52 +#define IAP_REPID_CMD 54 + +/* IAP command variables */ +static unsigned int command[5], result[4]; + +/* IAP entry function */ +typedef int (*IAP)(unsigned int[], unsigned int[]); +IAP iap_entry = (IAP) IAP_LOCATION; + +int CopyPageToFlash (uint32_t address, uint8_t* data) { + IAP iap_call = (IAP) IAP_LOCATION; + uint32_t writecount=0; + __disable_irq(); + + unsigned int sector; + bool firstpage=false; + + /* Calculate sector based on address */ + if (address < 0x18000) sector = address/0x1000; // sectors go in 4 k's + else if (address >= 0x38000) sector = 28; + else if (address >= 0x30000) sector = 27; + else if (address >= 0x28000) sector = 26; + else if (address >= 0x20000) sector = 25; + else sector = 24; + + /* Check is it the first page in the sector */ + if (sector<24) { + if (address == sector * 0x1000) firstpage = true; + } else { + if (address == (sector-24)*0x4000 + 0x18000) firstpage = true; + } + + /* Prepare the sector for writing */ + command[0] = IAP_PREWRRITE_CMD; /* Prepare to write/erase command code */ + command[1] = sector; /* Start Sector Number */ + command[2] = sector; /* End Sector Number */ + iap_call(command, result); + if (result[0]) return 1; + + /* do sector erase only when writing first page of given sector */ + if (firstpage) { + /* Erase the last sector */ + command[0] = IAP_ERSSECTOR_CMD; /* Erase command code*/ + command[1] = sector; /* Start Sector Number */ + command[2] = sector; /* End Sector Number */ + command[3] = SystemCoreClock / 1000UL; /* Core clock frequency in kHz */ + iap_call(command, result); + if (result[0]) return 1; + /* Prepare to write/erase the last sector, needs to be done again because succesful erase re-locks sectors */ + command[0] = IAP_PREWRRITE_CMD; /* Prepare to write/erase command code */ + command[1] = sector; /* Start Sector Number */ + command[2] = sector; /* Start Sector Number */ + iap_call(command, result); + if (result[0]) return 1; + } + + /* Write data to the sectors */ + command[0] = IAP_WRISECTOR_CMD; /* Write command code */ + command[1] = (uint32_t) (uint32_t*) address; /* Destination Flash Address */ + command[2] = (uint32_t) data; /* Source RAM Address */ + command[3] = 0x100; /* Number of Bytes to be written */ + command[4] = SystemCoreClock / 1000; /* System clock frequency */ + iap_call(command, result); + if (result[0]) return 1; + + /* Re-enable interrupt mode */ + __enable_irq(); + + return 0; /*succesful write*/ + +} + +__attribute__((section(".IAP_Code"))) int HelloFromIAP() { + static uint32_t array_data[WRITECOUNT]; + int i; + /* Initialize the array data to be written to FLASH */ + for (i = 0; i < WRITECOUNT; i++) { + array_data[i] = 0xB007AB1E; + } + + IAP iap_call = (IAP) IAP_LOCATION; + uint8_t teahupoo; + //readEEPROM(0,&teahupoo,1); + teahupoo++; + //writeEEPROM(0,&teahupoo,1); + + /** open file **/ + pokInitSD(); + char fn[20]; + char* now; + now = (char*)last_sector_flash; + switch (now[0]) { +case 0xAA: + fn[0]='B';fn[1]='B';fn[2]='.';fn[3]='B';fn[4]='I';fn[5]='N';fn[6]='\0';break; +case 0xBB: + fn[0]='C';fn[1]='C';fn[2]='.';fn[3]='B';fn[4]='I';fn[5]='N';fn[6]='\0';break; +default: + fn[0]='A';fn[1]='A';fn[2]='.';fn[3]='B';fn[4]='I';fn[5]='N';fn[6]='\0'; + } + if(fileOpen(fn,FILE_MODE_BINARY)) { + return 1; + } else { + for (i = 0; i < WRITECOUNT; i++) { + fileReadBytes((uint8_t*)&array_data[i],4); + } + } + + + /** write sector in flash **/ + /* Read Part Identification Number*/ + command[0] = IAP_REPID_CMD; /* Read ID command code */ + iap_call(command, result); + + __disable_irq(); + + /* Prepare to write/erase the last sector */ + command[0] = IAP_PREWRRITE_CMD; /* Prepare to write/erase command code */ + command[1] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[2] = IAP_LAST_SECTOR; /* End Sector Number */ + iap_call(command, result); + /* Erase the last sector */ + command[0] = IAP_ERSSECTOR_CMD; /* Erase command code*/ + command[1] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[2] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[3] = SystemCoreClock / 1000UL; /* Core clock frequency in kHz */ + iap_call(command, result); + /* Prepare to write/erase the last sector */ + command[0] = IAP_PREWRRITE_CMD; /* Prepare to write/erase command code */ + command[1] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[2] = IAP_LAST_SECTOR; /* Start Sector Number */ + iap_call(command, result); + /* Write to the last sector */ + command[0] = IAP_WRISECTOR_CMD; /* Write command code */ + command[1] = (uint32_t) last_sector_flash; /* Destination Flash Address */ + command[2] = (uint32_t) &array_data; /* Source RAM Address */ + command[3] = IAP_NUM_BYTES_TO_WRITE; /* Number of Bytes to be written */ + command[4] = SystemCoreClock / 1000; /* System clock frequency */ + iap_call(command, result); + + /* Re-enable interrupt mode */ + __enable_irq(); + + + SCB->AIRCR = 0x05FA0004; //issue system reset + while(1); //should never come here + return teahupoo; +} + + + + +void IAPstacksave() +{ + /*need to save 32 top bytes of RAM to RAM1*/ + #define RAM1_0 (*((volatile unsigned long *) 0x20000000)) + #define RAM1_1 (*((volatile unsigned long *) 0x20000004)) + #define RAM1_2 (*((volatile unsigned long *) 0x20000008)) + #define RAM1_3 (*((volatile unsigned long *) 0x2000000C)) + #define RAM1_4 (*((volatile unsigned long *) 0x20000010)) + #define RAM1_5 (*((volatile unsigned long *) 0x20000014)) + #define RAM1_6 (*((volatile unsigned long *) 0x20000018)) + #define RAM1_7 (*((volatile unsigned long *) 0x2000001C)) + + uint32_t *saveloc = (uint32_t*)(0x10002000-0x20); // RAM top - 32 bytes + RAM1_0 = *saveloc++; + RAM1_1 = *saveloc++; + RAM1_2 = *saveloc++; + RAM1_3 = *saveloc++; + RAM1_4 = *saveloc++; + RAM1_5 = *saveloc++; + RAM1_6 = *saveloc++; + RAM1_7 = *saveloc; +} + + +char iaptest() { + static uint32_t array_data[WRITECOUNT]; + int i; + /* Initialize the array data to be written to FLASH */ + for (i = 0; i < WRITECOUNT; i++) { + array_data[i] = 0x11223340 + i; + } + + /* Read Part Identification Number*/ + command[0] = IAP_REPID_CMD; /* Read ID command code */ + iap_entry(command, result); + + /* Reinvoke ISP mode so that reprogamming of Flash possible */ + __disable_irq(); + + command[0] = IAP_REPID_CMD; + iap_entry(command, result); + + /* Prepare to write/erase the last sector */ + command[0] = IAP_PREWRRITE_CMD; /* Prepare to write/erase command code */ + command[1] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[2] = IAP_LAST_SECTOR; /* End Sector Number */ + iap_entry(command, result); + + /* Erase the last sector */ + command[0] = IAP_ERSSECTOR_CMD; /* Erase command code*/ + command[1] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[2] = IAP_LAST_SECTOR; /* Start Sector Number */ + iap_entry(command, result); + + /* Prepare to write/erase the last sector */ + command[0] = IAP_PREWRRITE_CMD; /* Prepare to write/erase command code */ + command[1] = IAP_LAST_SECTOR; /* Start Sector Number */ + command[2] = IAP_LAST_SECTOR; /* Start Sector Number */ + iap_entry(command, result); + + /* Write to the last sector */ + command[0] = IAP_WRISECTOR_CMD; /* Write command code */ + command[1] = (uint32_t) last_sector_flash; /* Destination Flash Address */ + command[2] = (uint32_t) &array_data; /* Source RAM Address */ + command[3] = IAP_NUM_BYTES_TO_WRITE; /* Number of Bytes to be written */ + command[4] = SystemCoreClock / 1000; /* System clock frequency */ + iap_entry(command, result); + + /* Re-enable interrupt mode */ + __enable_irq(); + + //while (1) { + // __WFI(); + //} + + return 0; + +} + + +//1) EEprom Write +// +//Command code: 61 +//Param0: eeprom address (byte, half-word or word aligned) +//Param1: RAM address (byte, half-word or word aligned) +//Param2: Number of bytes to be written ( Byte, Half-words write are ok) +//Param3: System Clock Frequency (CCLK) in kHz +// +//Return Code CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED +__attribute__((section(".IAP_Code"))) void writeEEPROM( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount ) +{ + unsigned int command[5], result[4]; + + command[0] = 61; + command[1] = (uint32_t) eeAddress; + command[2] = (uint32_t) buffAddress; + command[3] = byteCount; + command[4] = SystemCoreClock/1000; + + /* Invoke IAP call...*/ +#if (EEPROM_PROFILE!=0) + LPC_CT32B0->TCR = 1; + __disable_irq(); + iap_entry(command, result); + __enable_irq(); + LPC_CT32B0->TCR = 0; +#else + __disable_irq(); + iap_entry(command, result); + __enable_irq(); +#endif + if (0 != result[0]) + { + //Trap error + while(1); + } + return; +} + +//2) EEprom Read +//Command code: 62 +//Param0: eeprom address (byte, half-word or word aligned) +//Param1: RAM address (byte, half-word or word aligned) +//Param2: Number of bytes to be read ( Byte, Half-words read are ok) +//Param3: System Clock Frequency (CCLK) in kHz +// +//Return Code CMD_SUCCESS | SRC_ADDR_NOT_MAPPED | DST_ADDR_NOT_MAPPED +__attribute__((section(".IAP_Code"))) void readEEPROM( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount ) +{ + unsigned int command[5], result[4]; + + command[0] = 62; + command[1] = (uint32_t) eeAddress; + command[2] = (uint32_t) buffAddress; + command[3] = byteCount; + command[4] = SystemCoreClock/1000; + + /* Invoke IAP call...*/ + __disable_irq(); + iap_entry( command, result); + __enable_irq(); + if (0 != result[0]) + { + //Trap error + while(1); + } + return; +} + +__attribute__((section(".IAP_Code"))) void IAPreadPartId( uint8_t* eeAddress, uint8_t* buffAddress, uint32_t byteCount ) +{ + unsigned int command[5], result[4]; + + command[0] = 62; + command[1] = (uint32_t) eeAddress; + command[2] = (uint32_t) buffAddress; + command[3] = byteCount; + command[4] = SystemCoreClock/1000; + + /* Invoke IAP call...*/ + __disable_irq(); + iap_entry( command, result); + __enable_irq(); + if (0 != result[0]) + { + //Trap error + while(1); + } + return; +} + +uint8_t eeprom_read_byte(uint8_t* index) { + uint8_t val; + readEEPROM(index,&val,1); + return val; +} + +void eeprom_write_byte(uint8_t*index , uint8_t val) { + writeEEPROM(index,&val,1); +} + +/***************************************************************************** + * $Id$ + * + * Project: NXP LPC11U6x In Application Programming + * + * Description: Provides access to In-Application Programming (IAP) routines + * contained within the bootROM sector of LPC11U6x devices. + * + * Copyright(C) 2010, NXP Semiconductor + * All rights reserved. + * + ***************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. + *****************************************************************************/ + +/* IAP Command Definitions */ +#define IAP_CMD_PREPARE_SECTORS 50 +#define IAP_CMD_COPY_RAM_TO_FLASH 51 +#define IAP_CMD_ERASE_SECTORS 52 +#define IAP_CMD_BLANK_CHECK_SECTORS 53 +#define IAP_CMD_READ_PART_ID 54 +#define IAP_CMD_READ_BOOT_ROM_VERSION 55 +#define IAP_CMD_COMPARE 56 +#define IAP_CMD_REINVOKE_ISP 57 +#define IAP_CMD_READ_UID 58 + +#define IAP_CMD_ERASE_PAGE 59 //new + +/* IAP boot ROM location and access function */ +#define IAP_ROM_LOCATION 0x1FFF1FF1UL +//#define IAP_EXECUTE_CMD(a, b) ((void (*)())(IAP_ROM_LOCATION))(a, b) + +__attribute__((section(".IAP_Code"))) void IAP_EXECUTE_CMD(uint32_t* a, uint32_t* b) { + void (*user_code_entry)(uint32_t*,uint32_t*); + uint32_t *p; + p = (uint32_t *)IAP_ROM_LOCATION; + user_code_entry = (void (*)(uint32_t*,uint32_t*))(*p); + user_code_entry(a, b); +} + + +/***************************************************************************** +** Function name: u32IAP_PrepareSectors +** +** Description: Prepares sector(s) for erasing or write operations. This +** command must be executed before executing the "Copy RAM to +** Flash" or "Erase Sector(s)" commands. +** +** Parameters: u32StartSector - Number of first sector to prepare. +** u32EndSector - Number of last sector to prepare. +** +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_PrepareSectors(uint32_t u32StartSector, uint32_t u32EndSector) +{ + uint32_t u32Status; + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + if (u32EndSector < u32StartSector) + { + u32Status = IAP_STA_INVALD_PARAM; + } + else + { + au32Command[0] = IAP_CMD_PREPARE_SECTORS; + au32Command[1] = u32StartSector; + au32Command[2] = u32EndSector; + __disable_irq(); + IAP_EXECUTE_CMD(au32Command, au32Result); + __enable_irq(); + u32Status = au32Result[0]; + } + return u32Status; +} + +/***************************************************************************** +** Function name: u32IAP_CopyRAMToFlash +** +** Description: Program the flash memory with data stored in RAM. +** +** Parameters: u32DstAddr - Destination Flash address, should be a 256 +** byte boundary. +** u32SrcAddr - Source RAM address, should be a word boundary +** u32Len - Number of 8-bit bytes to write, must be a +** multiple of 256. +* +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_CopyRAMToFlash(uint32_t u32DstAddr, uint32_t u32SrcAddr, uint32_t u32Len) +{ + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + au32Command[0] = IAP_CMD_COPY_RAM_TO_FLASH; + au32Command[1] = u32DstAddr; + au32Command[2] = u32SrcAddr; + au32Command[3] = u32Len; + au32Command[4] = SystemCoreClock / 1000UL; /* Core clock frequency in kHz */ + + IAP_EXECUTE_CMD(au32Command, au32Result); + + return au32Result[0]; +} + +/***************************************************************************** +** Function name: u32IAP_EraseSectors +** +** Description: Erase a sector or multiple sectors of on-chip Flash memory. +** +** Parameters: u32StartSector - Number of first sector to erase. +** u32EndSector - Number of last sector to erase. +* +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_EraseSectors(uint32_t u32StartSector, uint32_t u32EndSector) +{ + uint32_t u32Status; + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + if (u32EndSector < u32StartSector) + { + u32Status = IAP_STA_INVALD_PARAM; + } + else + { + au32Command[0] = IAP_CMD_ERASE_SECTORS; + au32Command[1] = u32StartSector; + au32Command[2] = u32EndSector; + au32Command[3] = SystemCoreClock / 1000UL; /* Core clock frequency in kHz */ + + IAP_EXECUTE_CMD(au32Command, au32Result); + + u32Status = au32Result[0]; + } + return u32Status; +} + +/***************************************************************************** +** Function name: u32IAP_BlankCheckSectors +** +** Description: Blank check a sector or multiple sectors of on-chip flash +** memory. +** +** Parameters: u32StartSector - Number of first sector to check. +** u32EndSector - Number of last sector to check. +** pu32Result[0] - Offset of the first non blank word location +** if the Status Code is IAP_STA_SECTOR_NOT_BLANK. +** pu32Result[1] - Contents of non blank word location. +** +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_BlankCheckSectors(uint32_t u32StartSector, uint32_t u32EndSector, uint32_t *pu32Result) +{ + uint32_t u32Status; + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + if (u32EndSector < u32StartSector) + { + u32Status = IAP_STA_INVALD_PARAM; + } + else + { + au32Command[0] = IAP_CMD_BLANK_CHECK_SECTORS; + au32Command[1] = u32StartSector; + au32Command[2] = u32EndSector; + + IAP_EXECUTE_CMD(au32Command, au32Result); + + if (au32Result[0] == IAP_STA_SECTOR_NOT_BLANK) + { + *pu32Result = au32Result[0]; + *(pu32Result + 1) = au32Result[1]; + } + u32Status = au32Result[0]; + } + return u32Status; +} + +/***************************************************************************** +** Function name: u32IAP_ReadPartID +** +** Description: Read the part identification number. +** +** Parameters: pu32PartID - Pointer to storage for part ID number. +* +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_ReadPartID(uint32_t *pu32PartID) +{ + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + au32Command[0] = IAP_CMD_READ_PART_ID; + __disable_irq(); + IAP_EXECUTE_CMD(au32Command, au32Result); + __enable_irq(); + *pu32PartID = au32Result[1]; + + return au32Result[0]; +} + +/***************************************************************************** +** Function name: u32IAP_ReadBootVersion +** +** Description: Read the boot code version number. +** +** Parameters: pu32Major - Major version number in ASCII format. +** pu32Minor - Minor version number in ASCII format. +** +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_ReadBootVersion(uint32_t *pu32Major, uint32_t *pu32Minor) +//uint32_t u32IAP_ReadBootVersion(uint32_t *pu32Major) +{ + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + au32Command[0] = IAP_CMD_READ_BOOT_ROM_VERSION; + + IAP_EXECUTE_CMD(au32Command, au32Result); + + + *pu32Major = (au32Result[1] & 0x0000FF00UL) >> 8; + *pu32Minor = au32Result[1] & 0x000000FFUL; + + return au32Result[0]; +} + +/***************************************************************************** +** Function name: u32IAP_Compare +** +** Description: Compares the memory contents at two locations. +** +** Parameters: u32Len - Number of bytes to compare, must be a multiple of 4. +** pu32Offset - Offset of the first mismatch if the Status Code is COMPARE_ERROR +** +** Returned value: Status code returned by IAP ROM function. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_Compare(uint32_t u32DstAddr, uint32_t u32SrcAddr, uint32_t u32Len, uint32_t *pu32Offset) +{ + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + au32Command[0] = IAP_CMD_COMPARE; + au32Command[1] = u32DstAddr; + au32Command[2] = u32SrcAddr; + au32Command[3] = u32Len; + + IAP_EXECUTE_CMD(au32Command, au32Result); + + if (au32Result[0] == IAP_STA_COMPARE_ERROR) + { + if (pu32Offset != 0) + { + *pu32Offset = au32Result[1]; + } + } + return au32Result[0]; +} + +/***************************************************************************** +** Function name: vIAP_ReinvokeISP +** +** Description: Invoke the bootloader in ISP mode. +** +** Parameters: None. +* +** Returned value: None. +** +******************************************************************************/ +__attribute__((section(".IAP_Code"))) void vIAP_ReinvokeISP(void) +{ + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + au32Command[0] = IAP_CMD_REINVOKE_ISP; + + IAP_EXECUTE_CMD(au32Command, au32Result); +} + +// read UID +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_ReadUID(uint32_t * pu32UID) +{ + uint32_t au32Result[5]; + uint32_t au32Command[5]; + + au32Command[0] = IAP_CMD_READ_UID; + + IAP_EXECUTE_CMD(au32Command, au32Result); +// *pu32UID++ = au32Result[1]; +// *pu32UID++ = au32Result[2]; +// *pu32UID++ = au32Result[3]; +// *pu32UID = au32Result[4]; + + *pu32UID = au32Result[1]; + *pu32UID++ = au32Result[2]; + *pu32UID++ = au32Result[3]; + *pu32UID++ = au32Result[4]; + + return au32Result[0]; + +} + +//IAP erase Page 256B 64K have 0-255 pages, page0-15 in sector 0, 32K have 0-127 pages, 128k have 0-511 pages, +__attribute__((section(".IAP_Code"))) uint32_t u32IAP_ErasePage(uint32_t u32StartPage, uint32_t u32EndPage) +{ + uint32_t u32Status; + uint32_t au32Result[3]; + uint32_t au32Command[5]; + + if (u32EndPage < u32StartPage) + { + u32Status = IAP_STA_INVALD_PARAM; + } + else + { + au32Command[0] = IAP_CMD_ERASE_PAGE; + au32Command[1] = u32StartPage; + au32Command[2] = u32EndPage; + au32Command[3] = SystemCoreClock / 1000UL; /* Core clock frequency in kHz */ + + IAP_EXECUTE_CMD(au32Command, au32Result); + + u32Status = au32Result[0]; + } + return u32Status; +} + + +/***************************************************************************** + ** End Of File + *****************************************************************************/ +