|
Для лпс2214
/* Коды команд IAP */
#define IAP_CMD_PREPARE 50
#define IAP_CMD_WRITE 51
#define IAP_CMD_ERASE 52
#define IAP_CMD_CHECK 53
#define IAP_CMD_PART 54
#define IAP_CMD_VERSION 55
#define IAP_CMD_COMPARE 56
/* Коды статуса */
#define CMD_SUCCESS 0
#define INVALID_COMMAND 1
#define SRC_ADDR_ERROR 2
#define DST_ADDR_ERROR 3
#define SRC_ADDR_NOT_MAPPED 4
#define DST_ADDR_NOT_MAPPED 5
#define COUNT_ERROR 6
#define INVALID_SECTOR 7
#define SECTOR_NOT_BLANK 8
#define SECTOR_NOT_PREPARED 9
#define COMPARE_ERROR 10
#define BUSY 11
/* Точка входа в IAP */
#define IAP_LOCATION 0x7FFFFFF1
typedef void (*IAP)(PUINT32, PUINT32);
UINT32 command[5];
UINT32 result[2];
/******************************************************************************
; Функция записи данных в сектор.
;******************************************************************************/
void flash_write(UINT32 Buf[], UINT32 BufSize)
{
PUINT32 prom;
UINT32 i;
IAP iap_entry = (IAP)(IAP_LOCATION);
prom =(PUINT32)(0x30000);
// Отключение прерываний.
os_interrupt_disable ();
// Отключение PLL.
lpc_PLL_setup (0x00, 0x00);
PLLCON = 0x00;
// Производим сравнение RAM и Flash.
for (i = 0; i != BufSize; i++)
{
if (Buf[i] != *prom)
{
i = 0x00;
break;
}
prom++;
}
if (i != 0) {goto flash_write_exit;}
// Подготовка сектора к стиранию.
while (1)
{
command[0] = IAP_CMD_PREPARE;
command[1] = 0x0A;
command[2] = 0x0A;
command[3] = 0x00;
command[4] = 0x00;
iap_entry (command, result);
if (result[0] == CMD_SUCCESS){break;}
if (result[0] == BUSY){continue;}
goto flash_write_exit;
}
// Стирание сектора.
while (1)
{
command[0] = IAP_CMD_ERASE;
command[1] = 0x0A;
command[2] = 0x0A;
command[3] = 10000;
iap_entry (command, result);
if (result[0] == CMD_SUCCESS){break;}
if (result[0] == BUSY){continue;}
goto flash_write_exit;
}
// Подготовка сектора к записи.
while (1)
{
command[0] = IAP_CMD_PREPARE;
command[1] = 0x0A;
command[2] = 0x0A;
command[3] = 0x00;
command[4] = 0x00;
iap_entry (command, result);
if (result[0] == CMD_SUCCESS){break;}
if (result[0] == BUSY){continue;}
goto flash_write_exit;
}
// Запись сектора.
while (1)
{
command[0] = IAP_CMD_WRITE;
command[1] = 0x30000;
command[2] = (UINT32)(Buf);
command[3] = 512;
command[4] = 10000;
iap_entry (command, result);
if (result[0] == CMD_SUCCESS){break;}
if (result[0] == BUSY){continue;}
goto flash_write_exit;
}
flash_write_exit:
// Настройка модуля PLL
lpc_PLL_setup (0x05, 0x01);
// Включение прерываний.
os_interrupt_enable ();
}
/******************************************************************************/