Цитата(Тоша @ Jul 2 2014, 06:11)

Поробую с частотой процессора поиграть.
Угу. "Фигли думать, трясти надо". Что с ней играться, ее надо указать такой, как требует описание. И все. IAP уже давно используется во всех процессорах NXP и работает точно в соответствии с описанием. Надо искать причину. Делать это не видя вашего кода - невозможно (телепаты в отпуске). Ну выложу я вам свой код, он 100% рабочий. Подозреваю, что он точно так же не пойдет у вас - ведь этот код всего лишь обертка над вызовами IAP.
Вам писали о резервировании ОЗУ - а стек у вас случайно не на конец ОЗУ устанавливается?
CODE
#ifndef IAP_H__
#define IAP_H__
#include <stdint.h>
class iap
{
public:
// (NXP IAP) Status Codes
enum status_t
{
CMD_SUCCESS,
INVALID_CMD,
SRC_ADDR_ERROR,
DST_ADDR_ERROR,
SRC_ADDR_NOT_MAPPED,
DST_ADDR_NOT_MAPPED,
COUNT_ERROR,
INVALID_SECTOR,
SECTOR_NOT_BLANK,
SECTOR_NOT_PREPARED,
COMPARE_ERROR,
BUSY,
PARAM_ERROR,
ADDR_ERROR,
ADDR_NOT_MAPPED,
CMD_LOCKED,
INVALID_CODE,
INVALID_BAUD_RATE,
INVALID_STOP_BIT,
CODE_READ_PROT_ENABLED,
MAX_ERROR
};
enum cmd_code_t
{
PREPARE = 50,
COPY,
ERASE,
BLANK_CHECK,
GET_PART_ID,
GET_BOOT_VER,
COMPARE,
REINVOKE_ISP,
READ_UID,
SIZE_ALIGN = 0xFFFFFFFF
};
static uint_fast32_t const SECTOR_SIZE = 32 * 1024;
static uint_fast32_t const MAX_SECTOR = 29;
static uint_fast32_t const BLOCK_SIZE = 4096;
static status_t check_blank(uint_fast8_t start_sector, uint_fast8_t end_sector);
static status_t erase (uint_fast8_t start_sector, uint_fast8_t end_sector);
static status_t erase (uint_fast8_t sector) { return erase (sector, sector); }
static status_t write_block(uint32_t const *pDst, void const * pSrc);
private:
struct command_t
{
cmd_code_t Code;
uint32_t Param[4];
};
struct result_t
{
status_t Status;
uint32_t Result[4];
};
static void (* const IAP)(command_t *params, result_t *result);
} static Flash __attribute__((unused));
#endif // IAP_H__
#include "iap.h"
#include "../hardware.h"
#include <macros.h>
#include <scmRTOS.h>
void (* const iap::IAP)(command_t *params, result_t *result) = (void(*)(command_t *params, result_t *result))0x1fff1ff1;
iap::status_t iap::check_blank(uint_fast8_t start_sector, uint_fast8_t end_sector)
{
iap::command_t Command;
iap::result_t Result;
Command.Code = BLANK_CHECK;
Command.Param[0] = start_sector;
Command.Param[1] = end_sector;
TCritSect cs;
IAP(&Command, &Result);
return Result.Status;
}
iap::status_t iap::erase (uint_fast8_t start_sector, uint_fast8_t end_sector)
{
if(check_blank(start_sector, end_sector) == CMD_SUCCESS)
return CMD_SUCCESS;
iap::command_t Command;
iap::result_t Result;
Command.Code = PREPARE;
Command.Param[0] = start_sector;
Command.Param[1] = end_sector;
TCritSect cs;
IAP(&Command, &Result);
if (Result.Status == CMD_SUCCESS)
{
Command.Code = ERASE;
Command.Param[0] = start_sector;
Command.Param[1] = end_sector;
Command.Param[2] = CCLK_FREQ / 1000;
IAP(&Command, &Result);
if (Result.Status == CMD_SUCCESS)
{
Command.Code = BLANK_CHECK;
Command.Param[0] = start_sector;
Command.Param[1] = end_sector;
IAP(&Command, &Result);
}
}
return Result.Status;
}
#include <string.h>
iap::status_t iap::write_block(uint32_t const *pDst, void const * pSrc)
{
uint32_t Buffer[BLOCK_SIZE / sizeof(uint32_t)];
memcpy(Buffer, pSrc, sizeof(Buffer));
iap::command_t Command;
iap::result_t Result;
Command.Code = PREPARE;
Command.Param[0] = 1; // do not overwrite bootloader
Command.Param[1] = MAX_SECTOR;
TCritSect cs;
IAP(&Command, &Result);
if (Result.Status != CMD_SUCCESS)
return Result.Status;
Command.Code = COPY;
Command.Param[0] = (uint32_t) pDst;
Command.Param[1] = (uint32_t) Buffer;
Command.Param[2] = BLOCK_SIZE;
Command.Param[3] = CCLK_FREQ / 1000;
IAP(&Command, &Result);
return Result.Status;
}