You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
5.5 KiB

/*
* Copyright (c) 2021 Phytium Information Technology, Inc.
*
* SPDX-License-Identifier: Apache-2.0.
*
* @Date: 2021-07-28 15:33:35
* @LastEditTime: 2021-08-04 08:30:32
* @Description:  This files is for
*
* @Modify History:
* Ver   Who        Date         Changes
* ----- ------     --------    --------------------------------------
*/
#include <string.h>
#include "sdkconfig.h"
#include "parameters.h"
#include "ft_assert.h"
#include "dw_i2c.h"
#include "dw_i2c_hw.h"
#include "eeprom.h"
#include "fsleep.h"
#define EEPROM_LEN 128
typedef struct
{
I2cCtrl master;
u8 buf[EEPROM_LEN];
u32 bufIdx;
u32 bufLen;
} I2cEepromMaster;
I2cEepromMaster masterEeprom;
static u32 I2cEeWriteRaw(I2cCtrl *pCtrl, I2cTransPack *pack)
{
FT_ASSERTZERONUM(pCtrl && pack);
u32 ret = I2C_SUCCESS;
if (pack->bufLen > AT24C02_BLK_SIZE)
{
return I2C_ERR_NOT_SUPPORT;
}
ret = I2cMasterWrite(pCtrl, pack);
fsleep_millisec(200); /* wait write finish */
return ret;
}
void I2cEeMasterReadDoneCB(void *pPara)
{
FT_ASSERTVOID(pPara);
I2cCtrl *pCtrl = (I2cCtrl *)pPara;
FT_ASSERTVOID(pCtrl->prv);
I2cEepromMaster *pEeprom = (I2cEepromMaster *)pCtrl->prv;
s32 rxValid;
I2C_INFO("Master Read Done");
rxValid = I2C_READ_REG32(pCtrl, I2C_RXFLR_OFFSET);
while ((pEeprom->bufIdx < pEeprom->bufLen) && (rxValid > 0))
{
pEeprom->buf[pEeprom->bufIdx] = (I2C_DATA_MASK & I2C_READ_DATCMD(pCtrl));
pEeprom->bufIdx++;
rxValid--;
fsleep_millisec(2);
if (pEeprom->bufIdx != pEeprom->bufLen)
{
I2C_WRITE_DATCMD(pCtrl, I2C_DATA_CMD_RESTART | I2C_DATA_CMD_READ);
}
else
{
I2C_WRITE_DATCMD(pCtrl, I2C_DATA_CMD_STOP | I2C_DATA_CMD_READ);
fsleep_millisec(2);
I2cSetIntrruptMask(pCtrl, I2C_INTR_RX_FULL, FALSE);
}
}
}
void I2cEeMasterWriteDoneCB(void *pPara)
{
FT_ASSERTVOID(pPara);
I2cCtrl *pCtrl = (I2cCtrl *)pPara;
FT_ASSERTVOID(pCtrl->prv);
I2cEepromMaster *pEeprom = (I2cEepromMaster *)pCtrl->prv;
I2C_INFO("Write Done");
if (pEeprom->bufIdx == pEeprom->bufLen)
{
I2C_WRITE_DATCMD(pCtrl, I2C_DATA_CMD_STOP);
fsleep_millisec(2);
I2cSetIntrruptMask(pCtrl, I2C_INTR_TX_EMPTY, FALSE);
}
else
{
I2C_WRITE_DATCMD(pCtrl, (I2C_DATA_MASK & pEeprom->buf[pEeprom->bufIdx]));
fsleep_millisec(2);
pEeprom->bufIdx++;
}
}
static u32 I2cEeReadRaw(I2cCtrl *pCtrl, I2cTransPack *pack)
{
return I2cMasterRead(pCtrl, pack);
}
u32 I2cEeMasterWrite(u32 slaveAddr, u8 offset, u8 *pBuf, u32 bufLen)
{
I2cEepromMaster *pEeprom = &masterEeprom;
I2cCtrl *pCtrl = &pEeprom->master;
I2cTransPack pack;
u32 ret = I2C_SUCCESS;
const u8 transSize = AT24C02_BLK_SIZE;
const u32 transTimes = bufLen / transSize;
const u32 lastTransLen = bufLen % transSize;
u8 loop;
pCtrl->prv = pEeprom;
memset(&pack, 0, sizeof(pack));
pack.slaveAddr = slaveAddr;
pack.addrLen = 1; /* use u8 offset */
for (loop = 0; loop < transTimes; loop++)
{
pack.transBuf = pBuf + loop * transSize;
pack.bufLen = transSize;
pack.inChipAddr = offset + loop * transSize;
I2C_INFO("write %d buf 0x%x len 0x%x", loop, pack.transBuf, pack.bufLen);
ret = I2cEeWriteRaw(pCtrl, &pack);
if (I2C_SUCCESS != ret)
return ret;
}
if (0 != lastTransLen)
{
pack.transBuf = pBuf + transTimes * transSize;
pack.bufLen = lastTransLen;
pack.inChipAddr = offset + transTimes * transSize;
I2C_INFO("write last buf 0x%x len 0x%x", pack.transBuf, pack.bufLen);
ret = I2cEeWriteRaw(pCtrl, &pack);
}
return ret;
}
u32 I2cEeMasterRead(u32 slaveAddr, u8 offset, u8 *pBuf, u32 bufLen)
{
I2cEepromMaster *pEeprom = &masterEeprom;
I2cCtrl *pCtrl = &pEeprom->master;
I2cTransPack pack;
u32 ret = I2C_SUCCESS;
const u8 transSize = bufLen; //6; //4; //AT24C02_BLK_SIZE - 1;
const u32 transTimes = bufLen / transSize;
const u32 lastTransLen = bufLen % transSize;
u8 loop;
pCtrl->prv = pEeprom;
memset(&pack, 0, sizeof(pack));
pack.slaveAddr = slaveAddr;
pack.addrLen = 1; /* use u8 offset */
for (loop = 0; loop < transTimes; loop++)
{
pack.transBuf = pBuf + loop * transSize;
pack.bufLen = transSize;
pack.inChipAddr = offset + loop * transSize;
ret = I2cEeReadRaw(pCtrl, &pack);
if (I2C_SUCCESS != ret)
return ret;
}
if (0 != lastTransLen)
{
pack.transBuf = pBuf + transTimes * transSize;
pack.bufLen = lastTransLen;
pack.inChipAddr = offset + transTimes * transSize;
ret = I2cEeReadRaw(pCtrl, &pack);
}
return ret;
}
u32 I2cEeMasterInit()
{
I2cEepromMaster *pEeprom = &masterEeprom;
I2cCtrl *pCtrl = &pEeprom->master;
u32 i2cId = I2C_INSTANCE_0;
u32 ret = I2C_SUCCESS;
pEeprom->bufIdx = 0;
pEeprom->bufLen = EEPROM_LEN;
memset(pCtrl, 0, sizeof(I2cCtrl));
pCtrl->config = *I2cLookupConfig(i2cId);
ret = I2cInit(pCtrl, &pCtrl->config);
I2C_INFO("i2c init result : 0x%x", ret);
if (I2C_SUCCESS != ret)
return ret;
pCtrl->prv = pEeprom;
I2cRegisterEvtCallback(pCtrl, I2C_EVT_MASTER_READ_DONE, I2cEeMasterReadDoneCB);
I2cRegisterEvtCallback(pCtrl, I2C_EVT_MASTER_WRITE_DONE, I2cEeMasterWriteDoneCB);
return ret;
}