Здравствуйте. Есть программа для LPC2103, в которой используется сохранение данных во встроенную Flash-память. Ведет себя она довольно странно: при вызове из одного места программы она работает как положено, а из другого, похожего - в 90% случаев не работает, но закономерность появления этого сбоя я не нашел. Выражается сбой так: после попытки стирания или записи в память, память не стирается и не записывается, а остается с теми же данными, а result[0] = 0.
Вот набор процедур IAP выдранный из серийного проекта для LPC2368.
# /******************************************************************************
# *
# * Copyright:
# * © 2005 Embedded Artists AB
# *
# * File:
# * iap.c
# *
# * Description:
# * Code that implements the iap interface.
# *
# *****************************************************************************/
/******************************************************************************
* Defines and typedefs
*****************************************************************************/
//#define CRYSTAL_FREQUENCY FOSC
#define m_IAP_ENTRY(a,

((void (*)(unsigned int[], unsigned int[]))(0x7ffffff1))(a,
/*****************************************************************************
* Local function prototypes
****************************************************************************/
static void iapCommand(unsigned int *pCommand, unsigned int *pResult);
/*****************************************************************************
# * Implementation of local functions
# ****************************************************************************/
#
# /*****************************************************************************
# *
# * Description:
# * Performs the actual IAP command, based on input command stored in
# * 'pCommand'. The PLL, MAM, and VIC are disabled during the command
# * and restored afterwards.
# * This code must run in THUMB mode, since the IAP interface assumes this!
# *
# * Params:
# * [in] pCommand - pointer to command vector (up to five unsigned int words)
# * [inout] pResult - pointer to where the result can be stored
# *
# ****************************************************************************/
static void iapCommand(unsigned int *pCommand, unsigned int *pResult)
{
//perform IAP command
m_IAP_ENTRY(pCommand, pResult);
}
/*****************************************************************************
# * Implementation of public functions
# ****************************************************************************/
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Select Sector, which prepares the sectors for
# * write operations.
# *
# * Params:
# * [in] sector1 - start sector
# * [in] sector2 - end sector (must be equal or larger to sector1)
# *
# * Returns:
# * IAP status code (see list in iap.h)
# *
# ****************************************************************************/
unsigned int iapSelectSector(unsigned int sector1, unsigned int sector2)
{
unsigned int parameter[3];
unsigned int result[1];
parameter[0] = IAP_SELSECTOR;
parameter[1] = sector1;
parameter[2] = sector2;
iapCommand(parameter, result);
return result[0];
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Copy RAM to FLASH
# *
# * Params:
# * [in] destAddress - desitnation address within the FLASH memory
# * Must be on 256 byte boundary.
# * [in] srcAddress - address to RAM data block (word boundary needed).
# * [in] length - length of data block (256, 512, 1024 or 4096)
# *
# * Returns:
# * IAP status code (see list in iap.h)
# *
# ****************************************************************************/
unsigned int iapRamToFlash(unsigned int destAddress, unsigned int srcAddress, unsigned int length)
{
unsigned int parameter[5];
unsigned int result[1];
parameter[0] = IAP_RAMTOFLASH;
parameter[1] = destAddress;
parameter[2] = srcAddress;
parameter[3] = length;
parameter[4] = Fcclk / 1000;
iapCommand(parameter, result);
return result[0];
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Erase Sector
# *
# * Params:
# * [in] sector1 - start sector
# * [in] sector2 - end sector (must be equal or larger to sector1)
# *
# * Returns:
# * IAP status code (see list in iap.h)
# *
# ****************************************************************************/
unsigned int iapEraseSector(unsigned int sector1, unsigned int sector2)
{
unsigned int parameter[4];
unsigned int result[1];
parameter[0] = IAP_ERASESECTOR;
parameter[1] = sector1;
parameter[2] = sector2;
parameter[3] = Fcclk / 1000;
iapCommand(parameter, result);
return result[0];
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Blank Check Sectors
# *
# * Params:
# * [in] sector1 - start sector
# * [in] sector2 - end sector (must be equal or larger to sector1)
# *
# * Returns:
# * IAP status code (see list in iap.h)
# *
# ****************************************************************************/
unsigned int iapBlankCheck(unsigned int sector1, unsigned int sector2)
{
unsigned int parameter[3];
unsigned int result[1];
parameter[0] = IAP_BLANKCHK;
parameter[1] = sector1;
parameter[2] = sector2;
iapCommand(parameter, result);
return result[0];
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Read Part ID
# *
# * Returns:
# * The Part ID, or 0 (if command failed)
# *
# ****************************************************************************/
unsigned int iapReadPartID(void)
{
unsigned int parameter[1];
unsigned int result[2];
parameter[0] = IAP_READPARTID;
iapCommand(parameter, result);
if (result[0] == IAP_CMD_SUCCESS)
return result[1];
else
return 0;
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Read Boot Version
# *
# * Returns:
# * The boot code version, or 0 (if command failed)
# *
# ****************************************************************************/
unsigned int iapReadBootVer(void)
{
unsigned int parameter[1];
unsigned int result[2];
parameter[0] = IAP_BOOTCODEID;
iapCommand(parameter, result);
if (result[0] == IAP_CMD_SUCCESS)
return result[1];
else
return 0;
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Compare
# *
# * Params:
# * [in] destAddress - desitnation address within the FLASH memory
# * Must be on word boundary.
# * [in] srcAddress - address to RAM data block (word boundary needed).
# * [in] length - length of data block (must be a multiple of 4)
# *
# * Returns:
# * IAP status code (see list in iap.h)
# *
# ****************************************************************************/
unsigned int iapCompare(unsigned int destAddress, unsigned int srcAddress, unsigned int length)
{
unsigned int parameter[4];
unsigned int result[1];
parameter[0] = IAP_COMPARE;
parameter[1] = destAddress;
parameter[2] = srcAddress;
parameter[3] = length;
iapCommand(parameter, result);
return result[0];
}
/*****************************************************************************
# *
# * Description:
# * Performs the IAP command: Reinvoke ISP
# *
# ****************************************************************************/
void iapReinvokeIsp(void)
{
unsigned int parameter[1];
unsigned int result[1];
parameter[0] = IAP_REINVOKE_ISP;
iapCommand(parameter, result);
}
А вот как производится запись сектора.