📄 24c16.c
字号:
/*====================================================================
*
* Copyright (C) 1997 Acer Labs, Inc. All Rights Reserved.
*
* File: 24c16.c
*
* Contents: I2c EEPROM read/write routines,
* for 24c16,24c08,24c04,24c02,24c01
* (2048, 1024, 512, 256, 128 byte)
*
* History:
* Date By Reason
* =========== ========= ======
* 19-May-1999 Charlemage for timing/ack process
* 09-Oct-2001 Dick Ma Porting to M6311/M3325
********************************************************************/
#include <platform.h>
#include <comsub.h>
#include <iic.h>
int I2CIsBusy=0;
void I2CBusBusy()
{
DisInt();
I2CIsBusy++;
EnInt();
}
void I2CBusRelease()
{
DisInt();
I2CIsBusy--;
EnInt();
}
/*----------------------------------------------------------------------
* Function_Name: I2cReadEEPROM
*
* Description: Perform bytes read process
* Stream Format:
* S<SLV_W><Addr>S<SLV_R><Read>P
* S : Start
* P : Stop
* <SLV_W> : Set Slave addr & Write Mode
* <SLV_R> : Set Slave addr & Read Mode
* <Addr> : Set DATA address
* <Read> : Read DATA
*
* Arguments:
* LPBYTE lpbData - DATA to write
* BYTE wReg_Addr - DATA address
* BYTE wLen - length of buffer
*
* Return Value:
* int IIC_OK
* IIC_TRANS_ERR
*----------------------------------------------------------------------*/
int I2cReadEEPROM(WORD wReg_Addr,LPBYTE lpbData,WORD wLen)
{
BYTE bHI_Addr, bSlv_Addr=0xa0;
int i, iRV=IIC_TRANS_ERR;
bHI_Addr=HiByte(wReg_Addr)&0x7;/* only 3 bits */
bSlv_Addr=(bSlv_Addr&0xF0)|(bHI_Addr<<1);/* first 4 bits is device ID */
bSlv_Addr&=0xFE;/* mark write */
Enter_GPIOSection();
I2CBusBusy();
dis_dsp();
for(i=0;i<IIC_POLL_TIMES;i++)/* /Ack polling !! */
{
iRV=I2cStart();
if(iRV!=IIC_OK)
{
ena_dsp();
I2CBusRelease();
Leave_GPIOSection();
dly_tsk(1); // for loading balance
return iRV;
}
iRV=IIC_TRANS_ERR;
if(!I2cSetByte(bSlv_Addr)) /* has /ACK => I2cStart transfer */
if(!I2cSetByte(LoByte(wReg_Addr)))
{
iRV=IIC_OK;
break;
}
/* device is busy, issue I2cStop and chack again later */
I2cStop();
delay(1);
}
/* Now Addr set ok, process sequential current reading */
if(iRV==IIC_OK)
{
I2cStart();/* Restart a reading process */
bSlv_Addr|=0x01;/*Set Read bit*/
I2cSetByte(bSlv_Addr);
for(i=0;i<wLen-1;i++,lpbData++) /* the last byte should process w/o /ACK !!*/
*lpbData=I2cGetByte(0);
*lpbData=I2cGetByte(1); /* the last byte to read*/
I2cStop();
}
ena_dsp();
I2CBusRelease();
Leave_GPIOSection();
dly_tsk(1); // for loading balance
return iRV;
}
/*----------------------------------------------------------------------
* Function_Name: I2cWriteEEPROM
*
* Description: Perform bytes write process
* Stream Format:
* S<SLV_W><Addr><Write>P
* S : Start
* P : Stop
* <SLV_W> : Set Slave addr & Write Mode
* <Addr> : Set DATA address
* <Write> : Send DATA
*
* Arguments:
* LPBYTE lpbData - DATA to write
* BYTE wReg_Addr - DATA address
* BYTE wLen - length of buffer
*
* Return Value:
* int IIC_OK
* IIC_TRANS_ERR
*----------------------------------------------------------------------*/
int I2cWriteEEPROM(WORD wReg_Addr,LPBYTE lpbData,WORD wLen)
{
BYTE bHI_Addr, bSlv_Addr=0xa0;
int i, j, iRV=IIC_TRANS_ERR;
BOOL fNeedI2cStart=TRUE;
Enter_GPIOSection();
I2CBusBusy();
dis_dsp();
for(i=0;i<wLen;i++,lpbData++,wReg_Addr++)
{
for(j=0;(j<IIC_POLL_TIMES)&fNeedI2cStart;j++)/* /Ack polling !! */
{
bHI_Addr=HiByte(wReg_Addr)&0x7;/* only 3 bits */
bSlv_Addr=(bSlv_Addr&0xF0)|(bHI_Addr<<1); /* first 4 bits is device ID */
bSlv_Addr&=0xFE; /* mark write */
iRV=I2cStart();
if(iRV!=IIC_OK)
{
I2CBusRelease();
ena_dsp();
Leave_GPIOSection();
dly_tsk(1); // for loading balance
return iRV;
}
iRV=IIC_TRANS_ERR;
if(!I2cSetByte(bSlv_Addr))/* has /ACK => I2cStart transfer */
if(!I2cSetByte(LoByte(wReg_Addr)))
{
fNeedI2cStart=FALSE;
iRV=IIC_OK;
break;
}
/* device is busy, issue I2cStop and chack again later */
I2cStop();
delay(1);
}
/* Now Addr set ok, just send data */
if(iRV==IIC_OK)
{
if(I2cSetByte(*lpbData))
{
fNeedI2cStart=TRUE;
iRV=IIC_TRANS_ERR;
i--,lpbData--,wReg_Addr--;/* resend this byte */
}
if((wReg_Addr&0x7)==0x7) /* Cross page bounding*/
{
fNeedI2cStart=TRUE;
}
if(fNeedI2cStart)/* Last write no /ack, send with new start */
{
I2cStop();
}
}
}
if(!fNeedI2cStart) /* check if need send I2cStop cond. */
{
I2cStop();
}
I2CBusRelease();
ena_dsp();
Leave_GPIOSection();
dly_tsk(1); // for loading balance
return iRV;
}
/*----------------------------------------------------------------------
* Function_Name: I2cTestEEPROM
*
* Description: Perform bytes write process
*
* Arguments:
*
* Return Value: void
*----------------------------------------------------------------------*/
#if 0
void I2cTestEEPROM()
{
int i, j;
BYTE bRV, bChipType;
BYTE bR[16], bW[16];
PRINTF("\nI2c Test Program begin!\n");
bChipType = 0xa0;
bRV = I2cFindChip(bChipType);
if(bRV==IIC_CHIP_OK)
{
PRINTF("I2C chip: 0x%x : Ready!\n", bChipType);
}
else if(bRV==IIC_CHIP_NULL)
{
PRINTF("No I2C chip: 0x%x!\n");
}
for(i=0;i<10;i++)
{
for(j=0;j<16;j++)
{
bW[j]=i+j;
}
if(I2cWriteEEPROM(START_EEP_OFFSET+i*16,bW,(WORD)16)==IIC_OK)
{
PRINTF("Write to IIC EEPROM success!, block %d\n", i);
}
else
{
PRINTF("Write to IIC EEPROM error!\n");
}
if(I2cReadEEPROM(START_EEP_OFFSET+i*16,bR,(WORD)16)==IIC_OK)
{
PRINTF("Read from IIC EEPROM, block %d\n", i);
PRINTF("0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",
bR[0],bR[1],bR[2],bR[3],bR[4],bR[5],bR[6],bR[7],bR[8],bR[9],bR[10],bR[11],bR[12],bR[13],bR[14],bR[15]);
}
else
{
PRINTF("Read from IIC EEPROM error!");
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -