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

📄 iap.c

📁 最新的LPC214X IAP驱动程序
💻 C
字号:
////  $Id: iap.c 188 2008-10-19 14:36:39Z jcw $//  $Revision: 188 $//  $Author: jcw $//  $Date: 2008-10-19 10:36:39 -0400 (Sun, 19 Oct 2008) $//  $HeadURL: http://tinymicros.com/svn_public/arm/lpc2148_demo/trunk/iap/iap.c $//#include "FreeRTOS.h"#include <string.h>#include "../cpu/cpu.h"#include "iap.h"//////#define CPUCLK_IN_KHZ 48000#define IRQ_MASK  0x00000080#define FIQ_MASK  0x00000040#define INTs_MASK (IRQ_MASK | FIQ_MASK)//////typedef struct flashSectorToAddress_s{  unsigned long address;  int sizeInBytes;}flashSectorToAddress_t;static flashSectorToAddress_t flashSectorToAddress [] = {  { 0x00000000, 4096 },   // 0  { 0x00001000, 4096 },   // 1  { 0x00002000, 4096 },   // 2  { 0x00003000, 4096 },   // 3  { 0x00004000, 4096 },   // 4  { 0x00005000, 4096 },   // 5  { 0x00006000, 4096 },   // 6  { 0x00007000, 4096 },   // 7  { 0x00008000, 32768 },  // 8  { 0x00010000, 32768 },  // 9  { 0x00018000, 32768 },  // 10  { 0x00020000, 32768 },  // 11  { 0x00028000, 32768 },  // 12  { 0x00030000, 32768 },  // 13  { 0x00038000, 32768 },  // 14  { 0x00040000, 32768 },  // 15  { 0x00048000, 32768 },  // 16  { 0x00050000, 32768 },  // 17  { 0x00058000, 32768 },  // 18  { 0x00060000, 32768 },  // 19  { 0x00068000, 32768 },  // 20  { 0x00070000, 32768 },  // 21  { 0x00078000, 4096 },   // 22  { 0x00079000, 4096 },   // 23  { 0x0007a000, 4096 },   // 24  { 0x0007b000, 4096 },   // 25  { 0x0007c000, 4096 },   // 26};typedef struct iapErrnoStr_s{  int errno;  const char *text;}iapErrnoStr_t;static iapErrnoStr_t iapErrnoStr [] ={  { IAP_RESULT_CMD_SUCCESS,         "success" },  { IAP_RESULT_INVALID_COMMAND,     "invalid command" },  { IAP_RESULT_SRC_ADDR_ERROR,      "source address error" },  { IAP_RESULT_DST_ADDR_ERROR,      "destination address error" },  { IAP_RESULT_SRC_ADDR_NOT_MAPPED, "source address not mapped" },  { IAP_RESULT_DST_ADDR_NOT_MAPPED, "destination address not mapped" },  { IAP_RESULT_COUNT_ERROR,         "count error" },  { IAP_RESULT_INVALID_SECTOR,      "invalid sector" },  { IAP_RESULT_SECTOR_NOT_BLANK,    "sector not blank" },  { IAP_RESULT_SECTOR_NOT_PREPARED, "sector not prepared" },  { IAP_RESULT_COMPARE_ERROR,       "compare error" },  { IAP_RESULT_BUSY,                "busy" },  { IAP_RESULT_PARAM_ERROR,         "parameter error" },  { IAP_RESULT_ADDR_ERROR,          "address error" },  { IAP_RESULT_ADDR_NOT_MAPPED,     "address not mapped" },  { IAP_RESULT_CMD_LOCKED,          "command locked" },  { IAP_RESULT_INVALID_CODE,        "invalid code" },  { IAP_RESULT_INVALID_BAUD_RATE,   "invalid baud rate" },  { IAP_RESULT_ANVALID_STOP_BIT,    "invalid stop bit" },  { IAP_RESULT_CRP_ENABLED,         "CRP enabled" },  { IAP_RESULT_X_NOTSAFEREGION,     "sector or address not in safe region" },  { IAP_RESULT_X_NOSAFEREGIONAVAIL, "no safe sectors available (all of memory used?)" },};//////static unsigned int iapCommands [5];static unsigned int iapResults [2];static int iapErrno = 0;extern unsigned long __end_of_text__;static unsigned int end_of_text = (unsigned int) &__end_of_text__;//////void iapInit (void){}//////int iapSectorToAddress (int sectorNumber, unsigned long *address, int *sectorSize){  if (sectorNumber >= (int) arrsizeof (flashSectorToAddress))    return -1;  if (address)    *address = flashSectorToAddress [sectorNumber].address;  if (sectorSize)    *sectorSize = flashSectorToAddress [sectorNumber].sizeInBytes;  return 0;}////  Convert address to sector, or -1 if address not in flash area//int iapAddressToSector (unsigned long address){  int i;  for (i = 0; i < (int) arrsizeof (flashSectorToAddress); i++)    if (address < (flashSectorToAddress [i].address + flashSectorToAddress [i].sizeInBytes))      return i;  iapErrno = IAP_RESULT_INVALID_SECTOR;  return -1;}////  1 == address in safe region, 0 if not//int iapIsSafeAddress (unsigned long address){  int eotSector;  int addressSector;  if ((eotSector = iapAddressToSector (end_of_text)) == -1)    return 0;  if ((addressSector = iapAddressToSector (address)) == -1)    return 0;  if (addressSector <= eotSector)  {    iapErrno = IAP_RESULT_X_NOTSAFEREGION;    return 0;  }  return 1;}////  0 == not safe sector, 1 == safe (not in a code sector)//int iapIsSafeSector (int sector){  int eotSector;  if ((eotSector = iapAddressToSector (end_of_text)) == -1)    return 0;  if (sector <= eotSector)  {    iapErrno = IAP_RESULT_X_NOTSAFEREGION;    return 0;  }  return 1;}////  Returns a safe sector number or -1 if none available//int iapFindSafeSector (void){  unsigned int i;  for (i = 0; i < arrsizeof (flashSectorToAddress); i++)    if (iapIsSafeSector (i))      return i;  iapErrno = IAP_RESULT_X_NOSAFEREGIONAVAIL;  return -1;}////  1 == sector is safe, 0 == not safe//int iapIsValidSector (int sector){  if ((sector < 0) || (sector >= (int) arrsizeof (flashSectorToAddress)))  {    iapErrno = IAP_RESULT_INVALID_SECTOR;    return 0;  }  return 1;}//////int iapGetErrno (void){  return iapErrno;}const char *iapStrerror (int err){  unsigned int i;  for (i = 0; i < arrsizeof (iapErrnoStr); i++)    if (iapErrnoStr [i].errno == err)      return iapErrnoStr [i].text;  return NULL;}//////static void iapCall (void) __attribute ((naked));static void iapCall (void){  register void *pFP0 asm("r0") = iapCommands;  register void *pFP1 asm("r1") = iapResults;  asm volatile(" bx  %[iapLocation]"               :               : "r" (pFP0), "r" (pFP1), [iapLocation] "r" (IAP_LOCATION) );}//////static inline unsigned __get_cpsr (void){  unsigned long retval;  asm volatile (" mrs  %0, cpsr" : "=r" (retval) : /* no inputs */  );  return retval;}static inline void __set_cpsr (unsigned val){  asm volatile (" msr  cpsr, %0" : /* no outputs */ : "r" (val)  );}static unsigned disableInts (void){  unsigned _cpsr;  _cpsr = __get_cpsr ();  do    __set_cpsr (_cpsr | INTs_MASK);  while ((__get_cpsr () ^ INTs_MASK) & INTs_MASK);  return _cpsr;}static unsigned restoreInts (unsigned oldCPSR){  unsigned _cpsr;  _cpsr = __get_cpsr();  do    __set_cpsr ((_cpsr & ~INTs_MASK) | (oldCPSR & INTs_MASK));  while ((__get_cpsr () ^ oldCPSR) & INTs_MASK);  return _cpsr;}//////int iapPrepareSectors (int startingSector, int endingSector){  unsigned int cpsr;  if (!iapIsSafeSector (startingSector) || !iapIsSafeSector (endingSector))    return -1;  iapCommands [0] = IAP_CMD_PREPARE;  iapCommands [1] = startingSector;  iapCommands [2] = endingSector;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  return ((iapErrno = iapResults [0]) == IAP_RESULT_CMD_SUCCESS) ? 0 : -1;}////  IAP_CMD_COPYRAMTOFLASH can span multiple sectors (2, at any rate, since bufferLen//  must be 256, 512, 1024 or 4096, and the smallest sectors are 4096 bytes).  Although//  more than 2 sectors can be prepared for writing, it's useless to do so, since//  after each IAP_CMD_COPYRAMTOFLASH, the sectors are re-locked.//int iapWriteSectors (unsigned int address, unsigned char *buffer, int bufferLen){  unsigned int cpsr;  iapCommands [0] = IAP_CMD_COPYRAMTOFLASH;  iapCommands [1] = address;  iapCommands [2] = (int) buffer;  iapCommands [3] = bufferLen;  iapCommands [4] = CPUCLK_IN_KHZ;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  if ((iapErrno = iapResults [0]) != IAP_RESULT_CMD_SUCCESS)    return -1;  return 0;}int iapFillSectors (int startingSector, int endingSector, int byte){  int sector;  unsigned char buffer [256];  if (!iapIsSafeSector (startingSector) || !iapIsSafeSector (endingSector))    return -1;  memset (buffer, byte, sizeof (buffer));  for (sector = startingSector; sector <= endingSector; sector++)  {    int i;    unsigned long address;    int sectorSize;    if (iapSectorToAddress (sector, &address, &sectorSize))      return -1;    for (i = 0; i < sectorSize; i += sizeof (buffer))    {      if (iapPrepareSectors (sector, sector) == -1)        return -1;      if (iapWriteSectors (address + i, buffer, sizeof (buffer)) == -1)        return -1;      if (iapCompare (address + i, buffer, sizeof (buffer)) == -1)        return -1;    }  }  return 0;}int iapEraseSectors (int startingSector, int endingSector){  unsigned int cpsr;  if (!iapIsSafeSector (startingSector) || !iapIsSafeSector (endingSector))    return -1;  if (iapPrepareSectors (startingSector, endingSector) == -1)    return -1;  iapCommands [0] = IAP_CMD_ERASE;  iapCommands [1] = startingSector;  iapCommands [2] = endingSector;  iapCommands [3] = CPUCLK_IN_KHZ;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  return ((iapErrno = iapResults [0]) == IAP_RESULT_CMD_SUCCESS) ? 0 : -1;}//// -1 = error (iapErrno set)//  0 = sector blank//  1 = sector not blank//int iapBlankCheckSectors (int startingSector, int endingSector){  unsigned int cpsr;  if (!iapIsValidSector (startingSector) || !iapIsValidSector (endingSector))    return -1;  iapCommands [0] = IAP_CMD_BLANKCHECK;  iapCommands [1] = startingSector;  iapCommands [2] = endingSector;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  if ((iapErrno = iapResults [0]) == IAP_RESULT_CMD_SUCCESS)    return 0;  if (iapResults [0] == IAP_RESULT_SECTOR_NOT_BLANK)    return 1;  return -1;}//////unsigned int iapReadPartID (void){  unsigned int cpsr;  iapCommands [0] = IAP_CMD_READPARTID;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  return iapResults [1];}//////unsigned int iapReadBootCodeVersion (void){  unsigned int cpsr;  iapCommands [0] = IAP_CMD_READBOOTCODEVER;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  return iapResults [1];}//////int iapCompare (unsigned int address, unsigned char *buffer, int bufferLen){  unsigned int cpsr;  iapCommands [0] = IAP_CMD_COMPARE;  iapCommands [1] = address;  iapCommands [2] = (int) buffer;  iapCommands [3] = bufferLen;  cpsr = disableInts ();  iapCall ();  restoreInts (cpsr);  return ((iapErrno = iapResults [0]) == IAP_RESULT_CMD_SUCCESS) ? 0 : -1;}//////void iapISP (void){  int i;  REG32 *p;  portDISABLE_INTERRUPTS ();  VIC_IntEnClr = VIC_IntEnClr_MASK;  SCB_PLLCON = 0;  SCB_PLLCFG = 0;  SCB_PLLFEED = SCB_PLLFEED_FEED1;  SCB_PLLFEED = SCB_PLLFEED_FEED2;  USB_PLLCON = 0;   USB_PLLCFG = 0;   USB_PLLFEED = USB_PLLFEED_FEED1;  USB_PLLFEED = USB_PLLFEED_FEED2;  for (p = (REG32 *) T1_BASE_ADDR, i = 0; i< 0x74 / 4; i++)    *p++ = 0;  T1_IR = 0xff;  SCB_PCONP = SCB_PCONP_ATRESET;  UART0_IER = 0x00;   UART0_LCR = 0x80;   UART0_DLL = 0x01;   UART0_DLM = 0x00;  UART0_LCR = 0x00;   UART0_FCR = 0x06;   UART0_FDR = 0x10;  SCB_MEMMAP = 0;  SCB_VPBDIV = 0;  PCB_PINSEL0 = PCB_PINSEL0_ALL_GPIO;  PCB_PINSEL1 = PCB_PINSEL1_ALL_GPIO;    GPIO0_FIODIR = 0x00004000;  GPIO0_FIOCLR = 0x00004000;  WD_TC = 0x0ffffff;   WD_MOD = 0;  WD_FEED = WD_FEED_FEED1;  WD_FEED = WD_FEED_FEED2;  iapCommands [0] = IAP_CMD_REINVOKEISP;  // disableInts ();  // cpuPLLDisable ();  // cpuT1Disable ();  iapCall ();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -