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.
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!
POKITTO_HW/iap.cpp
- Committer:
- Pokitto
- Date:
- 2018-06-27
- Revision:
- 50:ca94812a17b6
- Parent:
- 36:771321e70814
File content as of revision 50:ca94812a17b6:
#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, page;
bool firstpage=false, erasepage=false;
//DEBUG//
//for (int i=0;i<256;i++) data[i]=0xBB;
/* 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) {
/* 4KB addresses cover 0x000 - 0xFFF range */
firstpage = ((address & 0x0FFF) == 0);
} else {
/* 32KB addresses cover 0x0000 - 0x7FFF and 0x8000 - 0xFFFF range */
firstpage = ((address & 0x7FFF) == 0);
}
/* 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;
/* wipe pages when writing the loader */
if (address==0x39000) {
erasepage=true;
}
/* 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;
}
/* page erase for bootloader area */
if (erasepage) {
command[0] = 59; //erase page command
command[1] = 896;
command[2] = 1023;
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() {
#ifndef NOPETITFATFS
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;
#endif //NOPETITFATFS
}
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( uint16_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( uint16_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(uint16_t* index) {
uint8_t val;
readEEPROM(index,&val,1);
return val;
}
void eeprom_write_byte(uint16_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
*****************************************************************************/