📄 flashphilipslpc210x.c
字号:
/**************************************************
* Copyright 2004-2005 IAR Systems. All rights reserved.
*
* $Revision: 1.9 $
**************************************************/
// Flash loader driver for the Philips LPC21xx and LPC22xx series microcontrollers.
#include <stdio.h>
#include <stdlib.h>
#include "FlashPhilipsLPC210x.h"
#include "Interface.h" // The flash loader framework API declarations.
typedef struct SLayout {
int sectors;
int size;
} Layout;
static IAP iap_entry = (IAP)kIAPentry; // MCU flash firmware interface function.
static unsigned long sectorbuf[WRITE_SIZE/4]; // The sector buffer must be word aligned.
// The CPU clock speed (CCLK), the default value is used if no clock option is found.
static int clock = CCLK;
//==============================================
// 128k flash, 1'st generation
// LPC2104 (16k RAM)
// LPC2105 (32k RAM)
// LPC2106 (64k RAM)
// LPC2114 (16k RAM)
// LPC2212 (16k RAM)
// LPC2119 (16k RAM)
//==============================================
#ifdef FLASH_128K
#include <iolpc210x.h>
#define FLASH_SIZE 0x1e000
const Layout flashLayout[] =
{
{15, 8192},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
512,
1024,
4096,
8192,
0
};
#endif
//==============================================
// 256k flash, 1'st generation
// LPC2124 (16k RAM)
// LPC2129 (16k RAM)
// LPC2194 (16k RAM)
// LPC2214 (16k RAM)
// LPC2292 (16k RAM)
// LPC2294 (16k RAM)
//==============================================
#ifdef FLASH_256K
#include <iolpc2129.h>
#define FLASH_SIZE 0x3e000
const Layout flashLayout[] =
{
{ 8, 8192},
{ 2, 65536},
{ 7, 8192},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
512,
1024,
4096,
8192,
0
};
#endif
//==============================================
// 32k flash, 2'nd generation
// LPC2131 (8k RAM)
//==============================================
#ifdef FLASH_32K
#include <iolpc2132.h>
#define FLASH_SIZE 0x08000
const Layout flashLayout[] =
{
{ 8, 4096},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
256,
512,
1024,
4096,
0
};
#endif
//==============================================
// 64k flash, 2'nd generation
// LPC2132 (16k RAM)
// LPC2142 (16k RAM)
//==============================================
#ifdef FLASH_64K
#include <iolpc2132.h>
#define FLASH_SIZE 0x10000
const Layout flashLayout[] =
{
{ 8, 4096},
{ 1, 32768},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
256,
512,
1024,
4096,
0
};
#endif
//==============================================
// 128k flash, 2'nd generation
// LPC2134 (16k RAM)
//==============================================
#ifdef FLASH_128K2
#include <iolpc2134.h>
#define FLASH_SIZE 0x20000
const Layout flashLayout[] =
{
{ 8, 4096},
{ 3, 32768},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
256,
512,
1024,
4096,
0
};
#endif
//==============================================
// 256k flash, 2'nd generation
// LPC2136 (16k RAM)
//==============================================
#ifdef FLASH_256K2
#include <iolpc2136.h>
#define FLASH_SIZE 0x40000
const Layout flashLayout[] =
{
{ 8, 4096},
{ 7, 32768},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
256,
512,
1024,
4096,
0
};
#endif
//==============================================
// 512k (500k) flash, 2'nd generation
// LPC2138 (32k RAM)
// LPC2148 (32k RAM)
//==============================================
#ifdef FLASH_512K
#include <iolpc2138.h>
#define FLASH_SIZE 0x7d000
const Layout flashLayout[] =
{
{ 8, 4096},
{14, 32768},
{ 5, 4096},
{ 0, 0}
};
const int allowedWriteSizes[] =
{
256,
512,
1024,
4096,
0
};
#endif
// Returns the flash sector number for a given flash address.
// Returns -1 if the address is outside the flash.
static int CalculateSector(unsigned long addr, int *erase_sector)
{
int i;
int j;
int sector = 0;
unsigned long current = 0;
*erase_sector = 0;
for (i = 0; flashLayout[i].sectors; i++)
{
for (j = 0; j < flashLayout[i].sectors; j++)
{
if (addr < current + flashLayout[i].size)
{
if (addr < current + WRITE_SIZE)
{
*erase_sector = 1;
}
return sector;
}
sector++;
current += flashLayout[i].size;
}
}
return -1;
}
// Execute a flash firmware command.
static int ExecuteCommand(unsigned long* cmd, unsigned long* status)
{
int ret;
for (;;)
{
iap_entry(cmd, status);
ret = status[0];
if (ret != STATUS_BUSY)
{
return ret;
}
// Try again if busy.
}
}
// Program a sector. The device allows fractions of a sector to be written.
// dst - the flash address to start writing at.
// src - the address of the data buffer to be written.
// size - the number of bytes in the data buffer to write.
static void ProgramFlash(unsigned long dst, unsigned long* src, int size)
{
int i;
int ret;
int sector;
int erase_sector;
unsigned long sum;
unsigned long cmd[6];
unsigned long status[3];
// User Flash Mode. Interrupt vectors are not re-mapped and reside in Flash.
MEMMAP = 1;
// Round up size to nearest allowable write size.
for (i = 0; allowedWriteSizes[i]; i++)
{
if (size <= allowedWriteSizes[i])
{
size = allowedWriteSizes[i];
break;
}
}
sector = CalculateSector(dst, &erase_sector);
if (dst + size > FLASH_SIZE || sector == -1)
{
FlMessageBox("Data outside flash.");
FlErrorExit();
}
// Check for first part of sector 0 and that a reset vector is present,
// note that the buffer is initialized to all 1's.
if (sector == 0 && erase_sector && src[0] != 0xffffffff)
{
// Calculate exception vector 0x14 if the sector is zero and a reset address is present.
sum = src[0] + src[1] + src[2] + src[3] +
src[4] + src[6] + src[7];
src[5] = -sum; // Vector 0x14.
}
// Prepare sector for erase.
cmd[0] = CMD_PREPARE_SECTORS;
cmd[1] = sector;
cmd[2] = sector;
ret = ExecuteCommand(cmd, status);
if (ret != STATUS_CMD_SUCCESS)
{
FlMessageBox("CMD_PREPARE_SECTORS failed.");
FlErrorExit();
}
if (erase_sector)
{
// Erase sector.
cmd[0] = CMD_ERASE_SECTORS;
cmd[1] = sector;
cmd[2] = sector;
cmd[3] = clock;
ret = ExecuteCommand(cmd, status);
if (ret != STATUS_CMD_SUCCESS)
{
FlMessageBox("CMD_ERASE_SECTORS failed.");
FlErrorExit();
}
}
// Prepare sector for write.
cmd[0] = CMD_PREPARE_SECTORS;
cmd[1] = sector;
cmd[2] = sector;
ret = ExecuteCommand(cmd, status);
if (ret != STATUS_CMD_SUCCESS)
{
FlMessageBox("CMD_PREPARE_SECTORS failed.");
FlErrorExit();
}
// Program sector.
cmd[0] = CMD_COPY_RAM_TO_FLASH;
cmd[1] = dst;
cmd[2] = (unsigned long)src;
cmd[3] = size;
cmd[4] = clock;
ret = ExecuteCommand(cmd, status);
if (ret != STATUS_CMD_SUCCESS)
{
FlMessageBox("CMD_COPY_RAM_TO_FLASH failed.");
FlErrorExit();
}
}
// Write one byte to flash at addr.
// The bytes are buffered in sectorbuf. The sectorbuf is written to
// the flash when it overflows.
// If byte == -1 the flash loader framework signals a flush operation
// at the end of the input file.
static void FlashWriteByte(unsigned long addr, int byte)
{
int i;
int offset; // Current offset into sector buffer.
static int bytes = 0; // Number of bytes in the sector buffer (including gaps).
static int base_addr; // Pysical address of the start of the sector.
restart:
if (bytes == 0) // First byte of a new sector.
{
bytes = addr % WRITE_SIZE;
base_addr = addr - bytes; // Calculate physical start address of this sector.
// Intialize sector buffer with 0xff (flash erase pattern).
for (i = 0; i < WRITE_SIZE/4; i++)
sectorbuf[i] = 0xffffffff;
}
// Write sector buffer to the flash memory if a flush is requested or the
// new byte address is beyond the sector buffer.
if (byte == -1 || addr - base_addr >= WRITE_SIZE)
{
ProgramFlash(base_addr, sectorbuf, bytes);
if (byte == -1)
{
return; // This was a flush operation, all data is written.
}
bytes = 0;
// Previous sector buffer is written to flash.
// Continue with a new empty sector buffer.
goto restart;
}
// Store byte in sector buffer.
offset = addr - base_addr;
((unsigned char*)sectorbuf)[offset] = byte;
bytes = offset + 1;
}
void FlashDriverInitialize(int argc, char const* argv[])
{
const char* str;
// Register the flash write function.
FlRegisterWriteFunction(FlashWriteByte);
// See if user has passed a clock speed option.
// If not, the default CCLK value is used.
str = FlFindOption("--clock", 1, argc, argv);
if (str)
{
clock = strtoul(str, 0, 0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -