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

📄 rack_iap.c

📁 关于远程升级
💻 C
字号:
/* 移值IAP演示程序  刘国兵 2006-7-4 */
/*
在IAP程序中,应注意以下问题
    1. IAP服务代码是Thumb指令,所以调用时要进行处理器状态切换或使用BX指令调用,若使用C程序直接调用,请设置编译参数-apcs /interwork
    2. IAP占用片内RAM的最高端的32字节空间,如果用户要使用IAP功能,那么请保留这部分RAM 
      (此项目中我已修改"Startup.s"文件 " MSR     CPSR_c, #0xdf  
                                          LDR     SP, =StackUsr-32")"
    3. 调用IAP功能前,要关闭PLL、MAM部件及所有中断
*/

#include  "Rack_PrjHead.h"


/* 定义函数指针 */
//void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);

uint32  paramin[8];                         // IAP入口参数缓冲区
uint32  paramout[8];                        // IAP出口参数缓冲区

    
//    IAP_Entry = (void(*)())IAP_ENTER_ADR;           // 初始化函数指针IAP_Entry
    
/*
*********************************************************************************************************
** 函数名称:SelSector()
** 函数功能:IAP操作扇区选择,命令代码50。
** 入口参数:sec1        起始扇区
**           sec2        终止扇区
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  SelSector(uint8 sec1, uint8 sec2)
{  
    paramin[0] = IAP_SELECTOR;               // 设置命令字
    paramin[1] = sec1;                       // 设置参数
    paramin[2] = sec2;
    iap_entry(paramin, paramout);         	// 调用IAP服务程序
   
    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:RamToFlash()
** 函数功能:复制RAM的数据到FLASH,命令代码51。
** 入口参数:dst        目标地址,即FLASH起始地址。以512字节为分界
**           src        源地址,即RAM地址。地址必须字对齐
**           no         复制字节个数,为512/1024/4096/8192
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  RamToFlash(uint32 dst, uint32 src, uint32 no)
{  
    paramin[0] = IAP_RAMTOFLASH;             // 设置命令字
    paramin[1] = dst;                        // 设置参数
    paramin[2] = src;
    paramin[3] = no;
    paramin[4] = IAP_FCCLK;
    iap_entry(paramin, paramout);         	// 调用IAP服务程序
    
    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:EraseSector()
** 函数功能:扇区擦除,命令代码52。
** 入口参数:sec1       起始扇区
**           sec2       终止扇区
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  EraseSector(uint8 sec1, uint8 sec2)
{  
    paramin[0] = IAP_ERASESECTOR;            // 设置命令字
    paramin[1] = sec1;                       // 设置参数
    paramin[2] = sec2;
    paramin[3] = IAP_FCCLK;
    iap_entry(paramin, paramout);         	// 调用IAP服务程序
   
    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:BlankCHK()
** 函数功能:扇区查空,命令代码53。
** 入口参数:sec1       起始扇区
**           sec2       终止扇区
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  BlankCHK(uint8 sec1, uint8 sec2)
{  
    paramin[0] = IAP_BLANKCHK;               // 设置命令字
    paramin[1] = sec1;                       // 设置参数
    paramin[2] = sec2;
    iap_entry(paramin, paramout);         	// 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:ReadParID()
** 函数功能:扇区查空,命令代码53。
** 入口参数:无
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  ReadParID(void)
{  
    paramin[0] = IAP_READPARTID;             // 设置命令字
    iap_entry(paramin, paramout);         	// 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:BootCodeID()
** 函数功能:读取boot代码版本号,命令代码55。
** 入口参数:无
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  BootCodeID(void)
{  
    paramin[0] = IAP_BOOTCODEID;             // 设置命令字
    iap_entry(paramin, paramout);         	// 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:Compare()
** 函数功能:校验数据,命令代码56。
** 入口参数:dst        目标地址,即RAM/FLASH起始地址。地址必须字对齐
**           src        源地址,即FLASH/RAM地址。地址必须字对齐
**           no         复制字节个数,必须能被4整除
** 出口参数:IAP操作状态码
**           IAP返回值(paramout缓冲区)
*******************************************************************************************************
*/
uint32  Compare(uint32 dst, uint32 src, uint32 no)
{  
    paramin[0] = IAP_COMPARE;                // 设置命令字
    paramin[1] = dst;                        // 设置参数
    paramin[2] = src;
    paramin[3] = no;
    iap_entry(paramin, paramout);         	// 调用IAP服务程序

    return(paramout[0]);                     // 返回状态码
}

/*
*******************************************************************************************************
** 函数名称:main()
** 函数功能:IAP函数调用,演示程序
** 因LPC22xx与LPC2132扇区不同,其程序中 IAP_MARK1 与 IAP_MARK2处做适当修改
** 注:LPC2132 flash扇区分布
**      共8个扇区,每扇区4KB
**      如:
**          扇区号 0  0x0000 0000 -> 0x0000 0fff
**          扇区号 7  0x0000 7000 -> 0x0000 7fff
**     LPC22xx每扇区8KB(注:当 flash size >= 256KB 时,扇区大小不一至)
*******************************************************************************************************
*/
uint8 Rack_IAP_Ready(void)
{  
    uint8 err;
    //uint32 i;
    
    MAMCR = 0;         // 关闭MAM
    PLLCON = 0;        // 关闭PLL
    PLLFEED = 0xaa;
    PLLFEED = 0x55;
   
    SelSector(IAP_Sector_Start,IAP_Sector_End);                                 // 选择扇区
    EraseSector(IAP_Sector_Start,IAP_Sector_End);                               // 擦除扇区
    BlankCHK(IAP_Sector_Start,IAP_Sector_End) ;                                 // 查空扇区
   
    SelSector(IAP_Sector_Start,IAP_Sector_End);                                 // 选择扇区
    
//IAP_MARK1 用此句代替下一句可实现用现有开发板实验
    //RamToFlash(0x00002000, 0x40001000, 512);        // 写数据到扇区1 (LPC2214)
    RamToFlash(IAP_RAM_Start, IAP_Flash_Start, IAP_Number);          // 写数据到扇区1 (LPC2132)

//IAP_MARK2 用此句代替下一句可实现用现有开发板实验
    //err = Compare(0x00002000, 0x40001000, 512);     // 比较数据      (LPC2214)
    err = Compare(IAP_RAM_Start, IAP_Flash_Start, IAP_Number);       // 比较数据      (LPC2132)
    
//    if(err == CMD_SUCCESS)
//    {	/* 成功,蜂鸣一声 */
//        IO0CLR = BEEP;
//        for (i=0; i<0x3FFFFF; i++);
//        IO0SET = BEEP;
//    }
//    else
//    {	/* 失败,一直蜂鸣 */
//        IO0CLR = BEEP;
//    }
   
    while(1);
    return(0);
}


/*
*******************************************************************************************************
** 函数名称:IAP_Write_SADDR()
** 函数功能:IAP函数调用,对flash进行program。
** 因LPC22xx与LPC2132扇区不同,其程序中 IAP_MARK1 与 IAP_MARK2处做适当修改
** 注:LPC2103 flash扇区分布
**      共8个扇区,每扇区4KB
**      如:
**          扇区号 0  0x0000 0000 -> 0x0000 0fff
**          扇区号 7  0x0000 7000 -> 0x0000 7fff
**     LPC22xx每扇区8KB(注:当 flash size >= 256KB 时,扇区大小不一至)
*******************************************************************************************************
*/
uint8 IAP_Write_SADDR(void)
{
	uint8 err;
	uint32 VICIntEnable_bak;
	
	VICIntEnable_bak = VICIntEnable;		//屏蔽所有中断
	VICIntEnClr = 0xffff;
	
    MAMCR = 0;         // 关闭MAM
    PLLCON = 0;        // 关闭PLL
    PLLFEED = 0xaa;
    PLLFEED = 0x55;
	
    SelSector(IAP_Sector_Start,IAP_Sector_End);                                 // 选择扇区
    EraseSector(IAP_Sector_Start,IAP_Sector_End);                               // 擦除扇区
    BlankCHK(IAP_Sector_Start,IAP_Sector_End) ;                                 // 查空扇区
   
    SelSector(IAP_Sector_Start,IAP_Sector_End);                                 // 选择扇区
    
//IAP_MARK1 用此句代替下一句可实现用现有开发板实验
    //RamToFlash(0x00002000, 0x40001000, 512);        // 写数据到扇区1 (LPC2214)
    RamToFlash(IAP_Flash_Start, IAP_RAM_Start, IAP_Number);          // 写数据到扇区 (LPC2132)

//IAP_MARK2 用此句代替下一句可实现用现有开发板实验
    //err = Compare(0x00002000, 0x40001000, 512);     // 比较数据      (LPC2214)
    err = Compare(IAP_Flash_Start, IAP_RAM_Start, IAP_Number);       // 比较数据      (LPC2132)
    
    //重新开启MAM and PLL
    // 设置系统各部分时钟 
	// Set system timers for each component 
	    PLLCON = 1;
	#if (Fpclk / (Fcclk / 4)) == 1
	    VPBDIV = 0;
	#endif
	#if (Fpclk / (Fcclk / 4)) == 2
	    VPBDIV = 2;
	#endif
	#if (Fpclk / (Fcclk / 4)) == 4
	    VPBDIV = 1;
	#endif

	#if (Fcco / Fcclk) == 2	
	    PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);
	#endif
	#if (Fcco / Fcclk) == 4
	    PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);
	#endif
	#if (Fcco / Fcclk) == 8
	    PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);
	#endif
	#if (Fcco / Fcclk) == 16
	    PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);
	#endif
	    PLLFEED = 0xaa;
	    PLLFEED = 0x55;
	    while((PLLSTAT & (1 << 10)) == 0);
	    PLLCON = 3;
	    PLLFEED = 0xaa;
	    PLLFEED = 0x55;
	    
	    /* 设置存储器加速模块 */
	    /* Set memory accelerater module*/
	    MAMCR = 0;
	#if Fcclk < 20000000
	    MAMTIM = 1;
	#else
	#if Fcclk < 40000000
	    MAMTIM = 2;
	#else
	    MAMTIM = 3;
	#endif
	#endif
	    MAMCR = 2; 
	    
	VICIntEnable = VICIntEnable_bak;
	    
	return(err);
}

⌨️ 快捷键说明

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