#include "mcp79411.h"
#define RTCC_SRAM_CTR_READ 0xDF
#define RTCC_SRAM_CTR_WRITE 0xDE
#define EE_SLAVE_ADDR_READ 0xAF
#define EE_SLAVE_ADDR_WRITE 0xAE
#define MCP79410_SRAM_ADDR_MIN 0x20
#define MCP79410_SRAM_ADDR_MAX 0x5F
#define MCP79410_RTC_ADDR_MAX 0x1F
#define MCP79410_EEPROM_ADDR_MAX 0x7F
#define MCP79410_RTC_LEN 0x20 //byte
#define MCP79410_SRAM_LEN 0x40 //byte
#define MCP79410_EEPROM_RD_LEN 0x100 //byte
#define MCP79410_EEPROM_WR_LEN 0x80 //byte
#define EE_BUFFER_MAX 0x10 //最大为0x7F,考虑到空间和实际应用暂定为16
#define RTC_SEC_ADDR 0
#define RTC_CONTROL_ADDR 0x07
#define MCP79410_RTCSEC_ST 0x80
#define MCP79410_RTCHOUR_12 0x40
#define MCP79410_RTCWKDAY_VBATEN 0x08
#define MCP79410_RTCWKDAY_PWRFAIL 0x10
#define MCP79410_RTCCONTROL_EXTOSC 0x08
uint8_t EE_ByteWrite(uint8_t ucType, uint8_t ucAddr, uint8_t *pData, uint8_t ucLen)
{
static uint8_t ucWrDatas[EE_BUFFER_MAX+2]; //多了控制欲和地址,故需要增加2byte
static uint8_t ucRdDatas[EE_BUFFER_MAX];
uint8_t ucAddrTmp;
uint8_t error = 0;
uint8_t ucCtrByte = 0;
uint8_t ucPage,i;
uint32_t n;
if (MCP79410_TYPE_RTC == ucType)
{
if (((ucLen+ucAddr) > MCP79410_RTC_LEN) || (ucLen > EE_BUFFER_MAX))
{
error = 0xAA;
return error;
}
ucCtrByte = RTCC_SRAM_CTR_WRITE;
ucAddrTmp = ucAddr;
}
else if (MCP79410_TYPE_SRAM == ucType)
{
if (((ucLen+ucAddr) > MCP79410_SRAM_LEN) || (ucLen > EE_BUFFER_MAX))
{
error = 0xAA;
return error;
}
ucCtrByte = RTCC_SRAM_CTR_WRITE;
ucAddrTmp = MCP79410_SRAM_ADDR_MIN + ucAddr;
}
else if (MCP79410_TYPE_EEPROM == ucType)
{
if (((ucLen+ucAddr) > MCP79410_EEPROM_WR_LEN) || (ucLen > EE_BUFFER_MAX))
{
error = 0xAA;
return error;
}
ucCtrByte = EE_SLAVE_ADDR_WRITE;
ucAddrTmp = ucAddr;
}
ucWrDatas[0] = ucCtrByte;
if (MCP79410_TYPE_EEPROM == ucType)
{
if (ucAddrTmp % 8)
{
//待完善
}
else
{
if (ucLen < 8)
{
ucWrDatas[1] = ucAddrTmp;
memcpy(&ucWrDatas[2], pData, ucLen);
error = I2C_WriteBytes(ucWrDatas, ucLen+2);
}
else
{
ucPage = ucLen/8;
for (i=0;i<ucPage;i++)
{
ucWrDatas[1] = ucAddrTmp+i*8;
memcpy(&ucWrDatas[2], pData+i*8, 8);
error = I2C_WriteBytes(ucWrDatas, 10);
if (0 != error)
{
return error;
}
for (n=0; n< 12000; n++);
}
if (ucLen % 8)
{
for (n=0; n< 12000; n++);
ucWrDatas[1] = ucAddrTmp+ucPage*8;
memcpy(&ucWrDatas[2], pData+ucPage*8, ucLen%8);
error = I2C_WriteBytes(ucWrDatas, ucLen%8+2);
if (0 != error)
{
return error;
}
}
}
}
}
else
{
ucWrDatas[1] = ucAddrTmp;
memcpy(&ucWrDatas[2], pData, ucLen);
error = I2C_WriteBytes(ucWrDatas, ucLen+2);
}
if (0 != error)
{
return error;
}
if (MCP79410_TYPE_EEPROM == ucType)
{
for (n=0; n< 12000; n++);
}
error = I2C_ReadBytes(ucCtrByte, ucAddrTmp, ucRdDatas, ucLen);
if (0 != error)
{
return error;
}
if (0 != memcmp(&ucWrDatas[2], ucRdDatas, ucLen))
{
error = I2C_WriteBytes(ucWrDatas, ucLen+2);
}
return error;
}
uint8_t EE_ByteRead(uint8_t ucType, uint8_t ucAddr, uint8_t *pData, uint8_t ucLen)
{
uint8_t ucAddrTmp = ucAddr;
uint8_t error = 0;
uint8_t ucCtrByte = 0;
if (MCP79410_TYPE_RTC == ucType)
{
if (((ucLen+ucAddr) > MCP79410_RTC_LEN) || (ucLen > EE_BUFFER_MAX))
{
error = 0xAA;
return error;
}
ucCtrByte = RTCC_SRAM_CTR_WRITE;
ucAddrTmp = ucAddr;
}
else if (MCP79410_TYPE_SRAM == ucType)
{
if (((ucLen+ucAddr) > MCP79410_SRAM_LEN) || (ucLen > EE_BUFFER_MAX))
{
error = 0xAA;
return error;
}
ucCtrByte = RTCC_SRAM_CTR_WRITE;
ucAddrTmp = MCP79410_SRAM_ADDR_MIN + ucAddr;
}
else if (MCP79410_TYPE_EEPROM == ucType)
{
if (((ucLen+ucAddr) > MCP79410_EEPROM_RD_LEN) || (ucLen > EE_BUFFER_MAX))
{
error = 0xAA;
return error;
}
ucCtrByte = EE_SLAVE_ADDR_WRITE;
ucAddrTmp = ucAddr;
}
error = I2C_ReadBytes(ucCtrByte, ucAddrTmp, pData, ucLen);
return error;
}
uint8_t EE_GetRtcTime(RTC_ST *pstrSystime)
{
uint8_t ucRdDatas[7];
uint8_t error = 0;
// error = I2C_ReadBytes(RTCC_SRAM_CTR_WRITE, RTCSEC_ADDR, ucRdDatas, 7);
EE_ByteRead(MCP79410_TYPE_RTC, 0, ucRdDatas, 7);
if (0 != error)
return error;
pstrSystime->second = ((ucRdDatas[0] & 0x70) >>4 ) * 10 + (ucRdDatas[0] & 0x0F);
pstrSystime->minute = ((ucRdDatas[1] & 0x70) >>4 ) * 10 + (ucRdDatas[1] & 0x0F);
pstrSystime->hour = ((ucRdDatas[2] & 0x30) >>4 ) * 10 + (ucRdDatas[2] & 0x0F);
pstrSystime->week = ucRdDatas[3] & 0x07;
pstrSystime->day = ((ucRdDatas[4] & 0x30) >>4 ) * 10 + (ucRdDatas[4] & 0x0F);
pstrSystime->month = ((ucRdDatas[5] & 0x10) >>4 ) * 10 + (ucRdDatas[5] & 0x0F);
pstrSystime->year = ((ucRdDatas[6] & 0xF0) >>4 ) * 10 + (ucRdDatas[6] & 0x0F);
return error;
}
void EE_Init(void)
{
uint8_t strRdDatas[8];
uint32_t uiFirst;
uint32_t uiTmp, uiRd0, uiRd1;
EE_ByteRead(MCP79410_TYPE_RTC, 0, strRdDatas, 8);
if ((0 == (strRdDatas[0] & MCP79410_RTCSEC_ST))
|| (0 != (strRdDatas[2] & MCP79410_RTCHOUR_12))
|| (0 == (strRdDatas[3] & MCP79410_RTCWKDAY_VBATEN))
|| (0 != (strRdDatas[3] & MCP79410_RTCWKDAY_PWRFAIL))
|| (0 != (strRdDatas[7] & MCP79410_RTCCONTROL_EXTOSC)))
{
strRdDatas[0] |= MCP79410_RTCSEC_ST;
strRdDatas[3] = strRdDatas[3] & (~MCP79410_RTCWKDAY_PWRFAIL) | MCP79410_RTCWKDAY_VBATEN; //注意符号优先级
strRdDatas[2] &= (~MCP79410_RTCHOUR_12);
strRdDatas[7] &= (~MCP79410_RTCCONTROL_EXTOSC);
console_printf("Rewrite ee-rtc\n");
EE_ByteWrite(MCP79410_TYPE_RTC, RTC_SEC_ADDR, strRdDatas, 8);
}
}
|