⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashphilipslpc210x.c

📁 FlashPhilipsLPC210x读写 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 + -