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

📄 eeprom.c

📁 c8051f310xmodembootloader.rar
💻 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 + -