📄 iap.c
字号:
#include "config.h"
#define IAP_ENTER_ADDR 0x7FFFFFF1 /* IAP入口地址定义 */
/* 定义IAP命令字 */
#define IAP_SELSECTOR 50
#define IAP_RAMTOFLASH 51
#define IAP_ERASESECTOR 52
#define IAP_BLANKCHK 53
#define IAP_READPARTID 54
#define IAP_BOOTCODEID 55
#define IAP_COMPARE 56
/* 定义IAP返回状态字 */
#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_FOR_WRITE_OPERATION 9
#define COMPARE_ERROR 10
#define BUSY 11
#define PARAM_ERROR 12 /* Insufficient number of parameters */
#define ADDR_ERROR 13 /* Address not on word boundary */
#define ADDR_NOT_MAPPED 14
#define CMD_LOCKED 15 /* Command is locked */
#define INVALID_CODE 16 /* Unlock code is invalid */
#define INVALID_BAUD_RATE 17
#define INVALID_STOP_BIT 18
/* 定义CCLK值大小,单位为KHz */
#define IAP_FCCLK (Fcclk / 1000)
/* 定义函数指针 */
typedef (*IAP) (UDWORD param_tab[], UDWORD result_tab[]);
IAP IAP_Entry;
UDWORD IAP_ParaIn[IAP_PARA_LEN]; // IAP入口参数缓冲区
UDWORD IAP_ParaOut[IAP_PARA_LEN]; // IAP出口参数缓冲区
/****************************************************************************
* 名称:SelSector()
* 功能:IAP操作扇区选择,命令代码50。
* 入口参数:sec1 起始扇区
* sec2 终止扇区
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_SelSector(UCHAR sec1, UCHAR sec2)
{
IAP_ParaIn[0] = IAP_SELSECTOR; // 设置命令字
IAP_ParaIn[1] = sec1; // 设置参数
IAP_ParaIn[2] = sec2;
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_SelSector(UCHAR sec1, UCHAR sec2)
/****************************************************************************
* 名称:RamToFlash()
* 功能:复制RAM的数据到FLASH,命令代码51。
* 入口参数:dst 目标地址,即FLASH起始地址。以512字节为分界
* src 源地址,即RAM地址。地址必须字对齐
* no 复制字节个数,为512/1024/4096/8192
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_RamToFlash(UDWORD dst, UDWORD src, UDWORD no)
{
IAP_ParaIn[0] = IAP_RAMTOFLASH; // 设置命令字
IAP_ParaIn[1] = dst; // 设置参数
IAP_ParaIn[2] = src;
IAP_ParaIn[3] = no;
IAP_ParaIn[4] = IAP_FCCLK;
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_RamToFlash(UDWORD dst, UDWORD src, UDWORD no)
/****************************************************************************
* 名称:EraseSector()
* 功能:扇区擦除,命令代码52。
* 入口参数:sec1 起始扇区
* sec2 终止扇区
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_EraseSector(UCHAR sec1, UCHAR sec2)
{
IAP_ParaIn[0] = IAP_ERASESECTOR; // 设置命令字
IAP_ParaIn[1] = sec1; // 设置参数
IAP_ParaIn[2] = sec2;
IAP_ParaIn[3] = IAP_FCCLK;
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_EraseSector(UCHAR sec1, UCHAR sec2)
/****************************************************************************
* 名称:BlankCHK()
* 功能:扇区查空,命令代码53。
* 入口参数:sec1 起始扇区
* sec2 终止扇区
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_BlankCHK(UCHAR sec1, UCHAR sec2)
{
IAP_ParaIn[0] = IAP_BLANKCHK; // 设置命令字
IAP_ParaIn[1] = sec1; // 设置参数
IAP_ParaIn[2] = sec2;
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_BlankCHK(UCHAR sec1, UCHAR sec2)
/****************************************************************************
* 名称:ReadParID()
* 功能:扇区查空,命令代码53。
* 入口参数:无
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_ReadPartID(void)
{
IAP_ParaIn[0] = IAP_READPARTID; // 设置命令字
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_ReadPartID(void)
/****************************************************************************
* 名称:BootCodeID()
* 功能:读取boot代码版本号,命令代码55。
* 入口参数:无
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_BootCodeID(void)
{
IAP_ParaIn[0] = IAP_BOOTCODEID; // 设置命令字
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_BootCodeID(void)
/****************************************************************************
* 名称:IAP_Compare()
* 功能:校验数据,命令代码56。
* 入口参数:dst 目标地址,即RAM/FLASH起始地址。地址必须字对齐
* src 源地址,即FLASH/RAM地址。地址必须字对齐
* no 复制字节个数,必须能被4整除
* 出口参数:IAP返回值(paramout缓冲区)
****************************************************************************/
void IAP_Compare(UDWORD dst, UDWORD src, UDWORD no)
{
IAP_ParaIn[0] = IAP_COMPARE; // 设置命令字
IAP_ParaIn[1] = dst; // 设置参数
IAP_ParaIn[2] = src;
IAP_ParaIn[3] = no;
IAP_Entry(IAP_ParaIn, IAP_ParaOut); // 调用IAP服务程序
}//void IAP_Compare(UDWORD dst, UDWORD src, UDWORD no)
void IAP_Init(void)
{
IAP_Entry = (IAP)IAP_ENTER_ADDR;
}//void IAP_Init(void)
void IAP_ReadFlash(UDWORD FlashAddr,UDWORD RamAddr,UDWORD len)
{
int i;
for(i = 0; i < len; i++) *(UCHAR *)(RamAddr + i)= *(UCHAR *)(IAP_FLASH_BASE_ADDR + FlashAddr + i);
}//void IAP_ReadFlash(UDWORD RamAddr,UDWORD RamAddr,UDWORD len)
UCHAR IAP_WriteFlash(UDWORD FlashAddr,UDWORD RamAddr,UDWORD len)//22644384
{
int i;
if(FlashAddr + len > IAP_BUFF_LEN) return 1;
for(i = len - 1; i >= 0; i--) *(UCHAR *)(RamAddr + FlashAddr + i) = *(UCHAR *)(RamAddr + i);
IAP_ReadFlash(0,RamAddr,FlashAddr);
IAP_ReadFlash(FlashAddr + len,RamAddr + FlashAddr + len,IAP_BUFF_LEN - len - FlashAddr);
Uart0_SendByte(1);
IAP_SelSector(IAP_FLASH_SECTOR,IAP_FLASH_SECTOR);
if(IAP_ParaOut[0] != CMD_SUCCESS) return 2;
Uart0_SendByte(2);
IAP_EraseSector(IAP_FLASH_SECTOR,IAP_FLASH_SECTOR);
if(IAP_ParaOut[0] != CMD_SUCCESS) return 3;
Uart0_SendByte(3);
IAP_BlankCHK(IAP_FLASH_SECTOR,IAP_FLASH_SECTOR);
if(IAP_ParaOut[0] != CMD_SUCCESS) return 4;
Uart0_SendByte(4);
IAP_SelSector(IAP_FLASH_SECTOR,IAP_FLASH_SECTOR);
if(IAP_ParaOut[0] != CMD_SUCCESS) return 5;
Uart0_SendByte(5);
IAP_RamToFlash(IAP_FLASH_BASE_ADDR,RamAddr,IAP_BUFF_LEN);
if(IAP_ParaOut[0] != CMD_SUCCESS) return 6;
Uart0_SendByte(6);
IAP_Compare(IAP_FLASH_BASE_ADDR,RamAddr,IAP_BUFF_LEN);
if(IAP_ParaOut[0] != CMD_SUCCESS) return 7;
Uart0_SendByte(7);
return 0;
}//UCHAR IAP_WriteFlash(UDWORD FlashAddr,UDWORD RamAddr,UDWORD len)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -