You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
7.4 KiB
223 lines
7.4 KiB
4 years ago
|
////////////////////////////////////////////////////////////////////////////
|
||
|
///@copyright Copyright (c) 2018, 传控科技 All rights reserved.
|
||
|
///-------------------------------------------------------------------------
|
||
|
/// @file msp_eeprom.c
|
||
|
/// @brief msp @ driver config
|
||
|
///-------------------------------------------------------------------------
|
||
|
/// @version 1.0
|
||
|
/// @author CC
|
||
|
/// @date 20190106
|
||
|
/// @note cc_AS_stc02 由stc-isp v6.0860
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
#include "eeprom.h"
|
||
|
#include "../bsp/bsp_config.h"
|
||
|
|
||
|
struct eeprom_block_t eep_block;
|
||
|
|
||
|
#if(TYPE_MCU == TYPE_MCU_STC_8A || TYPE_MCU == TYPE_MCU_STC_8F)
|
||
|
#define WT_30M 0x80
|
||
|
#define WT_24M 0x81
|
||
|
#define WT_20M 0x82
|
||
|
#define WT_12M 0x83
|
||
|
#define WT_6M 0x84
|
||
|
#define WT_3M 0x85
|
||
|
#define WT_2M 0x86
|
||
|
#define WT_1M 0x87
|
||
|
|
||
|
|
||
|
void L0_Iap_Idle()
|
||
|
{
|
||
|
IAP_CONTR = 0; //关闭IAP功能
|
||
|
IAP_CMD = 0; //清除命令寄存器
|
||
|
IAP_TRIG = 0; //清除触发寄存器
|
||
|
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
|
||
|
IAP_ADDRL = 0;
|
||
|
}
|
||
|
|
||
|
char L0_Iap_Read(vU16 addr)
|
||
|
{
|
||
|
char dat;
|
||
|
|
||
|
IAP_CONTR = WT_12M; //使能IAP
|
||
|
IAP_CMD = 1; //设置IAP读命令
|
||
|
IAP_ADDRL = addr; //设置IAP低地址
|
||
|
IAP_ADDRH = addr >> 8; //设置IAP高地址
|
||
|
IAP_TRIG = 0x5a; //写触发命令(0x5a)
|
||
|
IAP_TRIG = 0xa5; //写触发命令(0xa5)
|
||
|
_nop_();
|
||
|
dat = IAP_DATA; //读IAP数据
|
||
|
L0_Iap_Idle(); //关闭IAP功能
|
||
|
|
||
|
return dat;
|
||
|
}
|
||
|
|
||
|
void L0_Iap_Program(vU16 addr, char dat)
|
||
|
{
|
||
|
IAP_CONTR = WT_12M; //使能IAP
|
||
|
IAP_CMD = 2; //设置IAP写命令
|
||
|
IAP_ADDRL = addr; //设置IAP低地址
|
||
|
IAP_ADDRH = addr >> 8; //设置IAP高地址
|
||
|
IAP_DATA = dat; //写IAP数据
|
||
|
IAP_TRIG = 0x5a; //写触发命令(0x5a)
|
||
|
IAP_TRIG = 0xa5; //写触发命令(0xa5)
|
||
|
_nop_();
|
||
|
L0_Iap_Idle(); //关闭IAP功能
|
||
|
}
|
||
|
|
||
|
///每个扇区512字节
|
||
|
///指定地址可以为当前扇区内的任意地址,都会完整擦除当前扇区
|
||
|
void L0_Iap_Erase(vU16 addr)
|
||
|
{
|
||
|
IAP_CONTR = WT_12M; //使能IAP
|
||
|
IAP_CMD = 3; //设置IAP擦除命令
|
||
|
IAP_ADDRL = addr; //设置IAP低地址
|
||
|
IAP_ADDRH = addr >> 8; //设置IAP高地址
|
||
|
IAP_TRIG = 0x5a; //写触发命令(0x5a)
|
||
|
IAP_TRIG = 0xa5; //写触发命令(0xa5)
|
||
|
_nop_(); //
|
||
|
L0_Iap_Idle(); //关闭IAP功能
|
||
|
}
|
||
|
|
||
|
#elif (TYPE_MCU == TYPE_MCU_STC_8G || TYPE_MCU == TYPE_MCU_STC_8H)
|
||
|
void L0_Iap_Idle()
|
||
|
{
|
||
|
IAP_CONTR = 0; //关闭IAP功能
|
||
|
IAP_CMD = 0; //清除命令寄存器
|
||
|
IAP_TRIG = 0; //清除触发寄存器
|
||
|
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
|
||
|
IAP_ADDRL = 0;
|
||
|
}
|
||
|
|
||
|
char L0_Iap_Read(vU16 addr)
|
||
|
{
|
||
|
char dat;
|
||
|
|
||
|
IAP_CONTR = 0x80; //使能IAP
|
||
|
IAP_TPS = 12;
|
||
|
IAP_CMD = 1; //设置IAP读命令
|
||
|
IAP_ADDRL = addr; //设置IAP低地址
|
||
|
IAP_ADDRH = addr >> 8; //设置IAP高地址
|
||
|
IAP_TRIG = 0x5a; //写触发命令(0x5a)
|
||
|
IAP_TRIG = 0xa5; //写触发命令(0xa5)
|
||
|
_nop_();
|
||
|
dat = IAP_DATA; //读IAP数据
|
||
|
L0_Iap_Idle(); //关闭IAP功能
|
||
|
|
||
|
return dat;
|
||
|
}
|
||
|
|
||
|
void L0_Iap_Program(vU16 addr, char dat)
|
||
|
{
|
||
|
IAP_CONTR = 0x80; //使能IAP
|
||
|
IAP_TPS = 12; //设置擦除等待参数 12MHz
|
||
|
IAP_CMD = 2; //设置IAP写命令
|
||
|
IAP_ADDRL = addr; //设置IAP低地址
|
||
|
IAP_ADDRH = addr >> 8; //设置IAP高地址
|
||
|
IAP_DATA = dat; //写IAP数据
|
||
|
IAP_TRIG = 0x5a; //写触发命令(0x5a)
|
||
|
IAP_TRIG = 0xa5; //写触发命令(0xa5)
|
||
|
_nop_();
|
||
|
L0_Iap_Idle(); //关闭IAP功能
|
||
|
}
|
||
|
|
||
|
///每个扇区512字节
|
||
|
///指定地址可以为当前扇区内的任意地址,都会完整擦除当前扇区
|
||
|
void L0_Iap_Erase(vU16 addr)
|
||
|
{
|
||
|
IAP_CONTR = 0x80; //使能IAP
|
||
|
IAP_TPS = 12; //设置擦除等待参数 12MHz
|
||
|
IAP_CMD = 3; //设置IAP擦除命令
|
||
|
IAP_ADDRL = addr; //设置IAP低地址
|
||
|
IAP_ADDRH = addr >> 8; //设置IAP高地址
|
||
|
IAP_TRIG = 0x5a; //写触发命令(0x5a)
|
||
|
IAP_TRIG = 0xa5; //写触发命令(0xa5)
|
||
|
_nop_(); //
|
||
|
L0_Iap_Idle(); //关闭IAP功能
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
void L0_Iap_Program_array(vU16 addr,U8 *buf,U8 len)
|
||
|
{
|
||
|
U8 i = 0;
|
||
|
for(i=0;i<len;i++)
|
||
|
{
|
||
|
L0_Iap_Program(addr + i,buf[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void L0_Iap_Read_array(vU16 addr,U8 *buf,U8 len)
|
||
|
{
|
||
|
U8 i = 0;
|
||
|
for(i=0;i<len;i++)
|
||
|
{
|
||
|
buf[i] = L0_Iap_Read(addr + i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//处于节省空间考虑,eeprom读取的数据直接存放到了用户提供的buf中,
|
||
|
//如果buf长度过小,可能引起内存错误
|
||
|
U8 L1_eep_read_block(U8 sector, U8 block, U16 blocksize, U8 *buf, U16 *plen)
|
||
|
{
|
||
|
U16 i,addr = D_EEP_SECTOR_SIZE * sector + blocksize * block;
|
||
|
//读取整块
|
||
|
L0_Iap_Read_array(addr, (U8*)&eep_block, sizeof(eep_block));
|
||
|
if(eep_block.filter[0] == D_EEP_BLOCK_FILTER0 && eep_block.filter[1] == D_EEP_BLOCK_FILTER1)
|
||
|
{
|
||
|
U8 crc[2] = {0,0};
|
||
|
crc16(crc, eep_block.filter, 2 + 2 + D_EEP_SECTOR_BLOCK_BUF_SIZE);
|
||
|
if(eep_block.crc[0] == crc[0] && eep_block.crc[1] == crc[1])
|
||
|
{
|
||
|
U16 len = (U16)eep_block.len[0] << 8 | eep_block.len[1];
|
||
|
for(i=0;i<len;i++)
|
||
|
{
|
||
|
buf[i] = eep_block.buf[i];
|
||
|
}
|
||
|
if(plen != NULL)
|
||
|
{
|
||
|
*plen = len;
|
||
|
}
|
||
|
L0_uart0_uc('#');
|
||
|
return 0; //ok
|
||
|
}
|
||
|
}
|
||
|
return 1; //error
|
||
|
}
|
||
|
|
||
|
U8 L1_eep_write_block(U8 sector, U8 block, U16 blocksize, const U8 *buf, U16 len, U8 sectorEraseFlag)
|
||
|
{
|
||
|
U16 i, addr = D_EEP_SECTOR_SIZE * sector + blocksize * block;
|
||
|
if(len > D_EEP_SECTOR_BLOCK_BUF_SIZE)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
Lc_memset((U8*)&eep_block,0,sizeof(eep_block));
|
||
|
eep_block.filter[0] = D_EEP_BLOCK_FILTER0;
|
||
|
eep_block.filter[1] = D_EEP_BLOCK_FILTER1;
|
||
|
eep_block.len[0] = len >> 8 & 0xFF;
|
||
|
eep_block.len[1] = len >> 0 & 0xFF;
|
||
|
for(i=0;i<len;i++)
|
||
|
{
|
||
|
eep_block.buf[i] = buf[i];
|
||
|
}
|
||
|
crc16(eep_block.crc, eep_block.filter, 2 + 2 + D_EEP_SECTOR_BLOCK_BUF_SIZE);
|
||
|
if(sectorEraseFlag == 1)
|
||
|
{
|
||
|
L0_Iap_Erase(addr);
|
||
|
}
|
||
|
//写入整块
|
||
|
L0_Iap_Program_array(addr, (U8*)&eep_block, sizeof(eep_block));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
U8 L1_eep_erase_sector(U8 sector)
|
||
|
{
|
||
|
U16 addr = D_EEP_SECTOR_SIZE * sector;
|
||
|
L0_Iap_Erase(addr);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|