📄 eeprom.c
字号:
#include "global.h"
#define WREN 6 // 0000 x110,write enable
#define WRDI 4 // 0000 x100,write disable
#define RDSR 5 // 0000 x101,read status register
#define WRSR 1 // 0000 x001,write status register
#define READ 3 // 0000 x011,read sequence
#define WRITE 2 // 0000 x010,write sequence
//extern unsigned char xdata combuf[32];
unsigned char code defdata[32]={0xaa,
0x55,
0x20, //基站号
0x00, //cmd
0x00,0x00,0x02,0x01, //id
0x00,0x00,0x00,0x03,0x02,0x01,//tag
0x00,0x03,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//选型
0x00,0x00,0x00,0x00,0x00, //none
0xdb,0x6b //crc
}; //默认参数表
/***************************************************************************************
**函数功能:AT25128
**入参: 无
**返回值: 无
**作者: jerkoh
**日期: 2009-07-02
**说明: SPI eeprom
***************************************************************************************/
/*-------------------------------------------------------
SPI_WriteByte()
Function: Send a byte of data to the device using
SPI interface.
Input: the data(one byte) want to send.
Output: None.
NOTE: Using SPI Mode 3/0
--------------------------------------------------------*/
void SPI_WriteByte(uchar spi_write_data)
{
uchar temp=0;
uchar i=0;
temp=spi_write_data;
for(i=0;i<8;i++) //send 8 bits
{
X_SCK=0;
if(temp & 0x80)//MSB first
X_SI=1;
else
X_SI=0;
temp=temp<<1;
X_SCK=1;
}
}
/*-------------------------------------------------------
SPI_ReadByte()
Function: Read a byte of data from the device using
SPI interface.
Input: None.
Output: The data(one byte) been read,as a return value.
NOTE: Using SPI Mode 3/0
--------------------------------------------------------*/
uchar SPI_ReadByte(void)
{
uchar temp=0;
uchar i=0;
bit bit_in;
temp=0x00;//initialize the data output
for(i=0;i<8;i++)
{
X_SCK=1;//Data is output on the SO line by the falling edge of SCK.
temp=temp << 1;
X_SCK=0;
bit_in=X_SO;
if(bit_in) temp=temp | 0x01;
}
return (temp);
}
/*---------------------------------------------------------
AT25_GetStatusReg()
Function: Read the Status Register of the AT25XXXA
Input: None.
Output: Content of the status register,as a return value.
-----------------------------------------------------------*/
uchar AT25_GetStatusReg(void)
{
uchar temp;
X_CS=0;
SPI_WriteByte(RDSR);
temp=SPI_ReadByte();
X_CS=1;
return temp;
}
/*---------------------------------------------------------
AT25_IsReady()
Function: Return 0 if AT25XXXA is busy and 1 if ready.
-----------------------------------------------------------*/
bit AT25_IsReady(void)
{
if(0x01 & AT25_GetStatusReg()) return 0;
else return 1;
}
/*---------------------------------------------------------
AT25_SetStatusReg()
Function: Set the Status Register of the AT25XXXA
Input: The Byte of the status register. NOTE: Only
bit7(WPEN),bit3(BP1) and bit2(BP0) can be changed,
so this byte should in the form of: x000 xx00
Output: None.
-----------------------------------------------------------*/
void AT25_SetStatusReg(uchar status_data)
{
uint j;
/* wait when device is busy */
//while(!AT25_IsReady()); //jerkoh
for(j=0;j<60000;j++)
{
if(AT25_IsReady()==1)
{
break;
}
}
if(j==60000)
{
return;
}
/* make sure that the device is write enabled */
X_CS=0;
_nop_();
SPI_WriteByte(WREN);
X_CS=1;
_nop_();
_nop_();
X_CS=0;
_nop_();
SPI_WriteByte(WRSR);
SPI_WriteByte(status_data & 0x8C);
X_CS=1;
}
/*---------------------------------------------------------
AT25_ReadArray()
Function: Read data streams from AT25XXXA.
Input: address,num_of_byte,destination
Output: No return value.
NOTE: The function do not report error if the parameters
are wrong(eg.address>0x3000),it modify the parameters.
So be careful.
-----------------------------------------------------------*/
void AT25_ReadArray(uint address, //from this address;
uint num_of_byte, //the number of bytes to read;
uchar* destination //store the result.
)
{
uint i=0;
uint j=0;
/* Filter the parameters */
if(num_of_byte>32) num_of_byte=1;
if(address>0x3fff) address=0;
/* wait when device is busy */
//while(!AT25_IsReady()); //jerkoh
for(j=0;j<60000;j++)
{
if(AT25_IsReady()==1)
{
break;
}
}
if(j==60000)
{
return;
}
X_CS=0;//Enable the AT25XXXA.
_nop_();
SPI_WriteByte(READ);//op_code
SPI_WriteByte((uchar)((address & 0x0F00)>>8)); //write address A11~A0
SPI_WriteByte((uchar)(address & 0x00FF));
for(i=0;i<num_of_byte;i++)
{
*destination=SPI_ReadByte();
destination++;
}
X_CS=1;//Disable the AT25XXXA.
}
/*---------------------------------------------------------
AT25_ReadByte()
Function: Read only one byte from the AT25XXXA,as a return
value.
-----------------------------------------------------------*/
/*
uchar AT25_ReadByte(uint address)
{
uchar temp[1];
AT25_ReadArray(address,1,&temp);
return temp[0];
}
*/
/*---------------------------------------------------------
AT25_WritePage()
Function: Write data(<=32 bytes) to the AT25XXXA.
Input: address,num_of_byte,source
Output: No return value.
NOTE: The function do not report error if the parameters
are wrong(eg.address>0x3fff),it modify the parameters.
So be careful.
-----------------------------------------------------------*/
void AT25_WritePage(uint address, //from this address;
uchar num_of_byte, //the number(<32) of bytes to write;
uchar* source //data to write.
)
{
uchar i=0;
uint j=0;
/* Filter the parameters */
if(num_of_byte>32) num_of_byte=32;
if(address>0x3fff) address=0;
/* make sure that the device is ready */
/* NOTE:No time out strategy here. */
//while(!AT25_IsReady()); //jerkoh
for(j=0;j<60000;j++)
{
if(AT25_IsReady()==1)
{
break;
}
}
if(j==60000)
{
return;
}
/* make sure that the device is write enabled */
X_CS=0;
_nop_();
SPI_WriteByte(WREN);
X_CS=1;
_nop_();
_nop_();
/* write op_code,address and data into the device */
X_CS=0;
_nop_();
SPI_WriteByte(WRITE);//op_code
SPI_WriteByte((uchar)((address & 0x0F00)>>8)); //write address A11~A0
SPI_WriteByte((uchar)(address & 0x00FF));
for(i=0;i<num_of_byte;i++)
{
SPI_WriteByte(*source);
source++;
}
X_CS=1;
}
/*---------------------------------------------------------
Init_AT25XXX()
Function: Initialize the AT25XXXA.
Input: None.
Output: None.
NOTE: This function initialize the AT25XXXA with no
data protected and #WP disable.
-----------------------------------------------------------*/
void Init_AT25XXX(uchar SetSR)
{
AT25_SetStatusReg(SetSR);
}
/***************************************************************************************
**函数功能:flash_c8051f310
**入参: addr
**返回值: 无
**作者: jerkoh
**日期: 2009-03-16
**说明: c8051f310擦读写
***************************************************************************************/
#ifdef CFSL
void FLASH_PageErase (UINT addr)
{
bit EA_SAVE = EA; // preserve EA
UCHAR xdata * data pwrite; // FLASH write pointer
EA = 0; // disable interrupts
// change clock speed to slow, then restore later
VDM0CN = 0x80; // enable VDD monitor
RSTSRC = 0x02; // enable VDD monitor as a reset source
pwrite = (UCHAR xdata *) addr;
FLKEY = 0xA5; // Key Sequence 1
FLKEY = 0xF1; // Key Sequence 2
PSCTL |= 0x03; // PSWE = 1; PSEE = 1
VDM0CN = 0x80; // enable VDD monitor
RSTSRC = 0x02; // enable VDD monitor as a reset source
*pwrite = 0; // initiate page erase
PSCTL &= ~0x03; // PSWE = 0; PSEE = 0
EA = EA_SAVE; // restore interrupts
}
#endif
#ifdef CFSL
void FLASH_ByteWrite (UINT addr, UCHAR byte)
{
bit EA_SAVE = EA; // preserve EA
UCHAR xdata * data pwrite; // FLASH write pointer
EA = 0; // disable interrupts
// change clock speed to slow, then restore later
VDM0CN = 0x80; // enable VDD monitor
RSTSRC = 0x02; // enable VDD monitor as a reset source
pwrite = (UCHAR xdata *) addr;
FLKEY = 0xA5; // Key Sequence 1
FLKEY = 0xF1; // Key Sequence 2
PSCTL |= 0x01; // PSWE = 1
VDM0CN = 0x80; // enable VDD monitor
RSTSRC = 0x02; // enable VDD monitor as a reset source
*pwrite = byte; // write the byte
PSCTL &= ~0x01; // PSWE = 0
EA = EA_SAVE; // restore interrupts
}
#endif
#ifdef CFSL
UCHAR FLASH_PageRead(UINT addr)
{
bit EA_SAVE = EA; // preserve EA
UCHAR dat;
char code * data pread; // FLASH read pointer
EA = 0;
pread=(char code *)addr;
dat=*pread;
EA = EA_SAVE; // restore interrupts
return dat;
}
#endif
/***************************************************************************************
**函数功能:flash_save
**入参: bufaddr s_len
**返回值: 无
**作者: jerkoh
**日期: 2009-03-16
**说明: 无
***************************************************************************************/
void flash_save(unsigned char *source_buf,unsigned int desk_addr,unsigned char s_len)
{
unsigned char j;
if(s_len<=32) //make sure it's not over 512bytes
{
for(j=0;j<3;j++)
{
AT25_WritePage(desk_addr,s_len,source_buf);
desk_addr+=64; //保存3份数据 隔开空间32字节
}
}
}
/***************************************************************************************
**函数功能:flash_boot
**入参: 无
**返回值: 无
**作者: jerkoh
**日期: 2009-06-30
**说明: 提取参数,如果检验失败 设备默认值
***************************************************************************************/
void flash_boot()
{
UCHAR j;
READER_PCS xdata *pt;
UINT nf_addr;
nf_addr=F_ADDR;
for(j=0;j<3;j++)
{
AT25_ReadArray(F_ADDR,32,combuf);
pt=(READER_PCS xdata *)(combuf);
if((cal_crc(combuf,sizeof(READER_PCS)-2))==(pt->pcs_crc16))
{
break; //crc16正确 退出
}
else
{
nf_addr+=64; //错误的话查下一块 不连续 隔开32字节
}
}
// memcpy(combuf,defdata,sizeof(defdata)); //提取默认值
//flash_save(combuf,F_ADDR,32); //保存数据至flash,自动3份;
if(j==0)
{
// set_cs();
//if(DEBUG) Printf_String("\r\n[msg:]flash ok"); //块1正确直接判断正确
}
else if ((j==1)||(j==2))
{
//if(DEBUG) Printf_String("\r\n[msg:]flashok 1-2"); //如果块2或3正确,3块统一
flash_save(combuf,F_ADDR,32);
}
else
{
//if(DEBUG) Printf_String("\r\n[msg:]flash error"); //都不正确,写默认值
memcpy(combuf,defdata,sizeof(defdata)); //提取默认值
flash_save(combuf,F_ADDR,32); //保存数据至flash,自动3份;
//set_cs();
}
set_cs();
}
/***************************************************************************************
**函数功能:set_cs
**入参: 无
**返回值: 无
**作者: jerkoh
**日期: 2009-06-30
**说明: 设置系统参数
***************************************************************************************/
void set_cs()
{
READER_PCS xdata *ptr;
ptr=(READER_PCS xdata *)(combuf);
wiefmt=wie[ptr->pcs_wieformat];
power =pow[ptr->pcs_power];
INACTIVITY_TIME=cardouttime[ptr->pcs_samecardtime];
RELAY_TIME_IN =relay_time[ptr->pcs_relaytime];
RELAY_TIME_OUT =relay_time[ptr->pcs_relaytime];
memcpy(MyID,ptr->pcs_readerid,sizeof(MyID));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -