SylixOS EEPROM 驱动

1.EEPROM简介

  EEPROM全称为Electrically Erasable Programmable read only memory,带电可擦除可编程只读存储器,是一种掉电数据不会丢失的存储芯片。EEPROM的擦除不需要借助于其它设备,它是以电子信号来修改其内容的,而且是以Byte为最小修改单位,不必将资料全部洗掉才能写入,彻底摆脱了EPROM Eraser和编程器的束缚。EEPROM在写入数据时,仍要利用一定的编程电压,此时,只需用厂商提供的专用刷新程序就可以轻而易举地改写内容,所以,它属于双电压芯片。借助于EEPROM芯片的双电压特性,可以使BIOS具有良好的防毒功能,在升级时,把跳线开关打至“on”的位置,即给芯片加上相应的编程电压,就可以方便地升级;平时使用时,则把跳线开关打至“off”的位置,防止CIH类的病毒对BIOS芯片的非法修改。所以,至今仍有不少主板采用EEPROM作为BIOS芯片并作为自己主板的一大特色。

2 .EEPROM举例

本章以FM25V20A 为例说明EEPROM 的工作原理。

2.1EEPROM的访问方式

根据芯片厂商不同的设计,可以通过SPI或者I2C访问EEPROM。FM25V20A是通过SPI总线访问的。访问芯片时,主机应该先发送操作码,EEPROM识别相应的操作码之后才能继续相应读写操作。FM25V20A定义命令码如图 2.1所示。
SylixOS EEPROM 驱动
图 2.1 Read ID Byte 3 Description

2.2 EEPROM状态寄存器
EEPROM的状态寄存定义如图 2.2-图 2.5所示。
SylixOS EEPROM 驱动
图 2.2状态寄存器
SylixOS EEPROM 驱动
图 2.3状态寄存器位定义

SylixOS EEPROM 驱动
图 2.4块内存写保护
SylixOS EEPROM 驱动

图 2.5写保护
2.3 EEPROM寄存器读写时序
SylixOS EEPROM 驱动
图 2.6寄存器读时序
SylixOS EEPROM 驱动
图 2.7寄存器写时序
2.4 EEPROM内存读写时序
SylixOS EEPROM 驱动

图 2.8内存写时序
SylixOS EEPROM 驱动

图 2.9内存读时序
2.5 代码编写
2.5.1 总体框架

图 2.10 代码主要流程
2.5.2 发送命令接口
程序清单 2.1
#define EEPROM_WRITE_EN() fm25v20aSendVal(EEPROM_CMD_WREN)
/ 向EEPROM发送写使能命令 /
#define
EEPROM_WRITE_DI() fm25v20aSendVal(EEPROM_CMD_WRDI)
/ 向EEPROM发送写禁止命令 /
#define EEPROM_WRITE_CMD() fm25v20aSendVal(EEPROM_CMD_WRITE)
/ 向EEPROM发送写操作命令 /
#define
EEPROM_READ_CMD() fm25v20aSendVal(EEPROM_CMD_READ)
/ 向EEPROM发送读操作命令 /
#define EEPROM_WRSR_CMD() fm25v20aSendVal(EEPROM_CMD_WRSR)
/ 向EEPROM发送写状态寄存器命令 /
#define
EEPROM_RDSR_CMD() fm25v20aSendVal(EEPROM_CMD_RDSR)
/ 向EEPROM发送读状态寄存器命令 /
static INT __fm25v20aSendVal(UINT8 uiE2promVal)
{
UINT8 uiVal[1];
LW_SPI_MESSAGE spiMsg[1];
uiVal[0] = uiE2promVal;
spiMsg[0].SPIMSG_uiLen = 1;
spiMsg[0].SPIMSG_pucRdBuffer = NULL;
spiMsg[0].SPIMSG_pucWrBuffer = uiVal;
return API_SpiDeviceTransfer(_G_PspiDev,spiMsg,1);
}

2.5.3 读状寄存器接口
程序清单 2.2
/*
函数名称: __fm25v20aReadStatus
功能描述: 读设备状态寄存器函数
输 入 : NOEN
输 出 : NONE
* 返 回 : ERROR_CODE
/
static INT __fm25v20aReadStatus()
{
UINT8 iRet;
UINT8 uiStatusReg[1] = {0x00};
LW_SPI_MESSAGE spiCmdMsg[1];

__SPI0_CS_EN();

iRet = __fm25v20aSendVal(__EEPROM_CMD_RDSR);

if(PX_ERROR == iRet)
{
    EEPROM_DBG("__fm25v20aSendVal failed\n");
    return PX_ERROR;
}

spiCmdMsg[0].SPIMSG_uiLen = 1;
spiCmdMsg[0].SPIMSG_pucWrBuffer = NULL;
spiCmdMsg[0].SPIMSG_pucRdBuffer = uiStatusReg;

iRet = API_SpiDeviceTransfer(_G_PspiDev, spiCmdMsg,1);

__SPI0_CS_DIS();

//*puiStatus = uiStatusReg[0];
EEPROM_DBG("uiStatusReg = 0x%x\n",uiStatusReg[0]);

return iRet;

}
2.5.4 读存储数据接口
程序清单 2.3
/
函数名称: __fm25v20aReadData
功能描述: 从EEPROM读数据函数
输 入 : uiE2promAddr 读地址
uiLen 读数据长度
输 出 : pcuData 读数据缓冲区
返 回 : ERROR_CODE
/

static INT fm25v20aReadData(UINT32 uiE2promAddr,UINT8* pcuData,UINT32 uiLen)
{
UINT8 uiIdx;
UINT8 uiReadAddr[
EEPROM_ADDR_BYTES];

uiReadAddr[0] = (uiE2promAddr & 0xff0000) >> 16;
uiReadAddr[1] = (uiE2promAddr & 0xff00) >> 8;
uiReadAddr[2] = (uiE2promAddr & 0xff);

__SPI0_CS_EN();
__EEPROM_READ_CMD();
__EEPROM_SENT_ADDR(uiReadAddr);

__fm25v20aReceiveVal(pcuData,uiLen);

__fm25v20aDelay(1);
__SPI0_CS_DIS();

return  (ERROR_NONE);

}
2.5.5 写存储数据接口
程序清单 2.4
/*
函数名称: __fm25v20aWriteData
功能描述: 向EEPROM写数据函数
输 入 : uiE2promAddr 写地址
pucData 写数据缓冲区
uiLen 写入数据长度
输 出 : NONE
* 返 回 : ERROR_CODE
/
static INT fm25v20aWriteData(UINT32 uiE2promAddr,UINT8* pucData,UINT32 uiLen)
{
UINT8 uiRet;
UINT8 uiAddr[
EEPROM_ADDR_BYTES];
UINT8 uiData[uiLen];
UINT32 uiIdx;

uiAddr[0] = (uiE2promAddr & 0xff0000) >> 16;
uiAddr[1] = (uiE2promAddr & 0xff00) >> 8;
uiAddr[2] = (uiE2promAddr & 0xff);

/*
*  写使能
*/
__SPI0_CS_EN(); 
__EEPROM_WRITE_EN();    
__fm25v20aDelay(1);
__SPI0_CS_DIS();    

__fm25v20aDelay(1);

/*
*  发送写命令、写地址和写数据
*/
__SPI0_CS_EN(); 
__EEPROM_WRITE_CMD();
__EEPROM_SENT_ADDR(uiAddr);
__EEPROM_SENT_DATA(pucData,uiLen);
__SPI0_CS_DIS();

__fm25v20aDelay(1);

/*
*  写禁止
*/
__SPI0_CS_EN(); 
__EEPROM_WRITE_DI();
__fm25v20aDelay(1);
__SPI0_CS_DIS();

return  (uiRet);

}
3 参考资料
《SylixOS_driver_usermanual》

猜你喜欢

转载自blog.51cto.com/12142768/2150018
今日推荐