/**
******************************************************************************
* @file eeprom.c
* @author Tony Li
* @brief
*EEPROM的驱动函数采用的HAL_I2C的MEM读写函数,驱动函数可以完成页内写,全区域读取。
*EEPROM_BufferWrite()实现了eeprom全地址写操作。
*支持24c01,24c02,24c04,24c08,24c16。
*24C32及以上需要调整为16地址模块
*写操作中,页切换的延时时间设计的是8mS。
*读写失败则退出,不影响系统其它模块执行。
******************************************************************************
* @attention
*
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "eeprom.h"
#include "sys.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern I2C_HandleTypeDef hi2c1;
#define EEPROM_I2C_PORT hi2c1
#ifdef EEPROMTEST
/* Buffer used for transmission */
uint8_t aTxBuffer[] = " ****I2C_TwoBoards communication based on Polling**** ****I2C_TwoBoards communication based on Polling**** ****I2C_TwoBoards communication based on Polling**** ";
/* Buffer used for reception */
uint8_t aRxBuffer[RXBUFFERSIZE];
#define I2C_ADDRESS 0x0
/* Size of Transmission buffer */
#define TXBUFFERSIZE (COUNTOF(aTxBuffer) - 1)
#define RXBUFFERSIZE TXBUFFERSIZE
static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
#endif
bool eepromInit(void)
{
EEPROMWrEnable();
return true;
}
bool EEPROM_BufferWrite(uint8_t *pBuffer,uint16_t WriteAddr,uint16_t NumByte){
uint16_t Amount_Page,PageBegin;//要写入的页数,页内起始地址
uint8_t Amount_Byte;//按页写入数据剩余的字节数
uint8_t count;//写入计数
uint16_t AddrBegin;
PageBegin=WriteAddr/EEPROMPAGESIZE;//起始页数
AddrBegin=WriteAddr%EEPROMPAGESIZE;//页内偏移地址
count=EEPROMPAGESIZE-AddrBegin;//页内写入数量
Amount_Byte=0;
EEPROMWrEnable();
if(AddrBegin+NumByte<=EEPROMPAGESIZE)//写入的内容不跨页
{
if(PwrGood()!=true)
return HAL_ERROR;
if(HAL_I2C_Mem_Write(&EEPROM_I2C_PORT,M24CxxDevAddr|(WriteAddr>>7&0xfe), (uint16_t) WriteAddr, (uint16_t)MEMADDRSIZE, pBuffer, (uint16_t)NumByte, (uint32_t)EEPROMTIMOUT)==HAL_OK){
delay_ms(8);
return true;
}
else
return false;
}
else //跨页写
{
//写入第一页
PageBegin=WriteAddr;
count=EEPROMPAGESIZE-AddrBegin;
if(PwrGood()!=true)
return false;
if(HAL_I2C_Mem_Write(&EEPROM_I2C_PORT,M24CxxDevAddr|(PageBegin>>7&0xfe), \
(uint16_t) PageBegin, (uint16_t)MEMADDRSIZE, pBuffer, (uint16_t)count, (uint32_t)EEPROMTIMOUT)!=HAL_OK)
{
return false;
}
delay_ms(20);
PageBegin+=count;
pBuffer+=count;
NumByte-=count;
Amount_Page=NumByte/EEPROMPAGESIZE;
Amount_Byte=NumByte%EEPROMPAGESIZE;
//写入后续满页
if(Amount_Page!=0)
{
do
{
if(PwrGood()!=true)
return false;
if(HAL_I2C_Mem_Write(&EEPROM_I2C_PORT,M24CxxDevAddr|(PageBegin>>7&0xfe), \
(uint16_t) PageBegin, (uint16_t)MEMADDRSIZE, pBuffer, (uint16_t)EEPROMPAGESIZE, (uint32_t)EEPROMTIMOUT)!=HAL_OK)
{
return HAL_ERROR;
}
else
{
delay_ms(20);
Amount_Page--;
PageBegin+=EEPROMPAGESIZE;
NumByte-=EEPROMPAGESIZE;
pBuffer+=EEPROMPAGESIZE;
}
} while(Amount_Page!=0);
}
//写入尾页
if(NumByte>0)
{
if(PwrGood()!=true)
return false;
if(HAL_I2C_Mem_Write(&EEPROM_I2C_PORT,M24CxxDevAddr|(PageBegin>>7&0xfe), \
(uint16_t) PageBegin, (uint16_t)MEMADDRSIZE, pBuffer, (uint16_t)NumByte, (uint32_t)EEPROMTIMOUT)!=HAL_OK)
{
return false;
}
else
{
delay_ms(8);
return true;
}
}
}
return false;
}
bool EEPROM_BufRead(uint8_t *pBuffer,uint16_t ReadAddr,uint16_t NumByte){
uint8_t i;
for(i=0;i<6;i++){
if(HAL_I2C_Mem_Read(&EEPROM_I2C_PORT,M24CxxDevAddr|(ReadAddr>>7&0xfe), (uint16_t) ReadAddr, (uint16_t)MEMADDRSIZE, pBuffer, (uint16_t)NumByte, (uint32_t)EEPROMTIMOUT)==HAL_OK){
return true;
}
else
{
delay_ms(5);
if(i>=6)
return false;
}
}
return false;
}
#ifdef EEPROMTEST
/**
* @brief Compares two buffers.
* @param pBuffer1, pBuffer2: buffers to be compared.
* @param BufferLength: buffer's length
* @retval 0 : pBuffer1 identical to pBuffer2
* >0 : pBuffer1 differs from pBuffer2
*/
static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
while (BufferLength--)
{
if ((*pBuffer1) != *pBuffer2)
{
return BufferLength;
}
pBuffer1++;
pBuffer2++;
}
return 0;
}
void EEPROM_TEST(void){
EEPROM_BufferWrite(aTxBuffer,I2C_ADDRESS,RXBUFFERSIZE);
EEPROM_BufRead(aRxBuffer,I2C_ADDRESS,RXBUFFERSIZE);
Buffercmp(aTxBuffer,aRxBuffer,7);
}
#endif