123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- #include <REGtenxTM52F1386.H>
- #include "CRC.h"
- #include "iap.h"
- //以下两个指针必须是xdata类型
- unsigned char xdata *p_info_addr; //指向信息存储器区域 - 读写
- unsigned char xdata *p_write_app_addr; //指向app区域 - 写
- unsigned char code *p_read_app_addr; //指向app区域 - 读
- static bit iap_flag=0; //0:正常 1:异常
- unsigned char CheckBuf[20]={0}; //读取升级标记的数组
- /******************************************************************************************
- ** 函数名称: erasure_INFO_page
- ** 函数描述: 擦除信息存储器区域的一页数据
- ** 输入参数: 地址
- ** 输出参数: 状态:0 正常, 1 异常
- *******************************************************************************************/
- static bit erasure_INFO_page(unsigned int addr)
- {
- unsigned char temp_ea;
-
- if(addr < 0x800) //INFO区 5~8,用户可写
- {
- return 1; //返回异常值
- }
-
- iap_flag = 0; //iap_flag标志清零
-
- temp_ea = EA;
- EA = 0;
-
- LVRCON = LVRCON|0x10; //关闭LVR
-
- p_info_addr = (unsigned char *)addr;
-
- AUX2 = AUX2&0xF9|0x06; //设置IAP超时时间
-
- //写入0XA1和0xBA, 开启 INFO 区域擦除
- IAPWE_SFR=0XA1;
- IAPWE_SFR=0XBA;
-
- //INFO区域不需要设置 SWCMD 寄存器
-
- *p_info_addr = 0; //触发页擦除
-
- if(IAPWE_SFR & IAPTO) //置位表示超时
- {
- iap_flag = 1; //iap_flag标志置位
- }
-
- AUX2 = AUX2&0xF9; //关闭IAP看门狗
- IAPWE_SFR = 0x00; //禁止IAP擦除
- SWCMD = 0x00; //关闭IAP权限
-
- LVRCON = LVRCON&~0x10; //开启LVR
-
- EA = temp_ea;
-
- return iap_flag;
- }
- /******************************************************************************************
- ** 函数名称: read_INFO_byte
- ** 函数描述: 读取信息存储器区域的数据
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 无
- *******************************************************************************************/
- static void read_INFO_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- unsigned int i;
-
- p_info_addr =(unsigned char*)addr;
-
- for(i = 0; i<len; i++)
- {
- buf[i] = *p_info_addr;
- p_info_addr++;
- }
- }
- /******************************************************************************************
- ** 函数名称: write_INFO_byte
- ** 函数描述: 写入信息存储器区域的数据
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 状态:0 正常, 1 异常
- *******************************************************************************************/
- static bit write_INFO_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- unsigned char temp_ea;
- unsigned int i;
-
- iap_flag = 0; //iap_flag标志清零
-
- temp_ea = EA;
- EA = 0;
-
- LVRCON = LVRCON|0x10; //关闭LVR
-
- p_info_addr = (unsigned char *)addr;
-
- AUX2 = AUX2&0xF9|0x06; //设置IAP超时时间
-
- //写入0XA1和0X4C, 开启 INFO 区域擦除
- IAPWE_SFR=0XA1;
- IAPWE_SFR=0X4C;
-
- //INFO区域不需要设置 SWCMD 寄存器
- for(i = 0; i<len; i++)
- {
- *p_info_addr = buf[i];//触发写
- p_info_addr++;
- }
-
- if(IAPWE_SFR & IAPTO) //置位表示超时
- {
- iap_flag = 1; //iap_flag标志置位
- }
-
- AUX2 = AUX2&0xF9; //关闭IAP看门狗
- IAPWE_SFR = 0x00; //禁止IAP擦除
- SWCMD = 0x00; //关闭IAP权限
-
- LVRCON = LVRCON&~0x10; //开启LVR
-
- EA = temp_ea;
-
- return iap_flag;
- }
- /******************************************************************************************
- ** 函数名称: user_write_INFO_byte
- ** 函数描述: 存储INFO数据的函数,供用户使用
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 状态:0 正常, 1 异常
- *******************************************************************************************/
- bit user_write_INFO_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- bit flag=0;
- unsigned int crc_write=0,crc_read=0;
-
- //页首地址才会执行页擦除,一页512byte
- if(addr==0 || ((addr%0x200)==0))
- {
- flag = erasure_INFO_page(addr);
- if(flag) return flag; //异常就返回
- }
-
- //先擦除页,再写入数据
- flag = write_INFO_byte(addr,buf,len);
- if(flag) return flag; //异常就返回
- crc_write = crc_calcu(buf,len); //计算写之前的CRC值
-
- //读出比较CRC值
- read_INFO_byte(addr,buf,len);
- crc_read = crc_calcu(buf,len); //从flash里读出数据,在计算CRC值
-
- if(crc_write != crc_read) //判断读写的数据是否一致
- {
- flag = 1;
- }
-
- return flag;
- }
- /******************************************************************************************
- ** 函数名称: user_read_INFO_byte
- ** 函数描述: 读INFO数据的函数,供用户使用
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 无
- *******************************************************************************************/
- void user_read_INFO_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- read_INFO_byte(addr, buf,len);
- }
- /******************************************************************************************
- ** 函数名称: erasure_APP_page
- ** 函数描述: 擦除信app区域的一页数据
- ** 输入参数: 地址
- ** 输出参数: 状态:0 正常, 1 异常
- *******************************************************************************************/
- static bit erasure_APP_page(unsigned int addr)
- {
- unsigned char temp_ea;
-
- iap_flag = 0; //iap_flag标志清零
-
- temp_ea = EA;
- EA = 0;
-
- LVRCON = LVRCON|0x10; //关闭LVR
-
- p_write_app_addr = (unsigned char *)addr;
-
- AUX2 = AUX2&0xF9|0x06; //设置IAP超时时间
-
- //写入0xE2和0xBA, 开启APP 区域擦除
- IAPWE_SFR=0XE2;
- IAPWE_SFR=0XBA;
-
- //写入0x65和0xA7,开启APP区域擦除和写入权限
- SWCMD=0x65;
- SWCMD=0xA7;
-
- *p_write_app_addr = 0; //触发页擦除
-
- if(IAPWE_SFR & IAPTO) //置位表示超时
- {
- iap_flag = 1; //iap_flag标志置位
- }
-
- AUX2 = AUX2&0xF9; //关闭IAP看门狗
- IAPWE_SFR = 0x00; //禁止IAP擦除
- SWCMD = 0x00; //关闭IAP权限
-
- LVRCON = LVRCON&~0x10; //开启LVR
-
- EA = temp_ea;
-
- return iap_flag;
- }
- /******************************************************************************************
- ** 函数名称: read_APP_byte
- ** 函数描述: 读取APP区域的数据
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 无
- *******************************************************************************************/
- static void read_APP_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- unsigned int i;
-
- p_read_app_addr =(unsigned char*)addr;
-
- for(i = 0; i<len; i++)
- {
- buf[i] = *p_read_app_addr;
- p_read_app_addr++;
- }
- }
- /******************************************************************************************
- ** 函数名称: write_APP_byte
- ** 函数描述: 写入APP的数据
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 状态:0 正常, 1 异常
- *******************************************************************************************/
- static bit write_APP_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- unsigned char temp_ea;
- unsigned int i;
-
- iap_flag = 0; //iap_flag标志清零
-
- temp_ea = EA;
- EA = 0;
-
- LVRCON = LVRCON|0x10; //关闭LVR
-
- p_write_app_addr = (unsigned char *)addr;
-
- AUX2 = AUX2&0xF9|0x06; //设置IAP超时时间
-
- //写入0xE2和0X4C, 开启APP 区域擦除
- IAPWE_SFR=0XE2;
- IAPWE_SFR=0X4C;
-
- //写入0x65和0xA7,开启APP区域擦除和写入权限
- SWCMD=0x65;
- SWCMD=0xA7;
-
- for(i = 0; i<len; i++)
- {
- *p_write_app_addr = buf[i]; //触发写
- p_write_app_addr++;
- }
-
- if(IAPWE_SFR & IAPTO) //置位表示超时
- {
- iap_flag = 1; //iap_flag标志置位
- }
-
- AUX2 = AUX2&0xF9; //关闭IAP看门狗
- IAPWE_SFR = 0x00; //禁止IAP擦除
- SWCMD = 0x00; //关闭IAP权限
-
- LVRCON = LVRCON&~0x10; //开启LVR
-
- EA = temp_ea;
-
- return iap_flag;
- }
- /******************************************************************************************
- ** 函数名称: user_write_APP_byte
- ** 函数描述: 存储APP数据的函数,供用户使用
- ** 输入参数: 地址 数组的首地址、长度
- ** 输出参数: 状态:0 正常, 1 异常
- *******************************************************************************************/
- bit user_write_APP_byte(unsigned int addr, unsigned char *buf, unsigned int len)
- {
- bit flag=0;
- unsigned int crc_write=0,crc_read=0;
-
- //页首地址才会执行页擦除
- if(addr==0 || ((addr%0x200)==0))
- {
- flag = erasure_APP_page(addr);
- if(flag) return flag; //异常就返回
- }
-
- //先擦除页,再写入数据
- flag = write_APP_byte(addr,buf,len);
- if(flag) return flag; //异常就返回
- crc_write = crc_calcu(buf,len); //计算写之前的CRC值
-
- //读出比较CRC值
- read_APP_byte(addr,buf,len);
- crc_read = crc_calcu(buf,len); //从flash里读出数据,在计算CRC值
-
- if(crc_write != crc_read)
- {
- flag = 1;
- }
-
- return flag;
- }
|