📄 i2c_api.c
字号:
/******************************************************************************
* File name : I2C_api.c *
* Start date : *
* By : S.C.Kwon *
* Contact : *
* Description: I2C control Low Level API *
* $Log:$ *
*****************************************************************************/
/******************************************************************************
* INCLUDES *
******************************************************************************/
#include "Basic_typedefs.h"
#include "Sys_call_abstract.h"
#include "S5h_common_reg.h"
#include "Select_cap.h"
#include "I2c_api.h"
//#if MAY_POWER_RESUME//maymeng 051011 added
// extern SysSema_t gSema_eeprom;
//#endif
/******************************************************************************
* Function Defines *
******************************************************************************/
#define I2C_TIMEOUT_PENDING_CHECK 2500//10000 //3000
#if _SUPPORT_EEPROM_PAGE_ACCESS
volatile UCHAR gEeprom_dump[EEPROM_SIZE];
#endif
/******************************************************************************
* Function name : I2C_DelayForWait
* Arguments : void
* Return : void
* By :
* Description :
*****************************************************************************/
void I2C_DelayForWait(void)
{
#if 0
volatile UINT wait_tick, i;
// Make some delay
wait_tick = (UINT) SysMSecToTick(30);
/* To check transfer done interrupt */
for (i=0; i<wait_tick; i++)
{
;
}
#else
volatile ULONG wait_tick, i;
// Make some delay
wait_tick = (ULONG) SysMSecToTick(30);
/* To check transfer done interrupt */
for (i=0; i<wait_tick; i++)
{
;
}
#endif
}
/******************************************************************************
* Function name : I2C_Initilize
* Arguments : void
* Return : void
* By :
* Description :
*****************************************************************************/
void I2C_Initilize(void)
{
ULONG temp1;
DI();
IO_WData32((unsigned char *)& rI2CADD_H,0,I2C_SLAVE); /* Enable Rx/Tx */
IO_WData32((unsigned char *)& rI2CSTAT_H,0,0x10);
temp1 = (0/*0*/ << I2C_ACK) | (1 << I2C_512CK) |I2C_PENDING | I2C_PRESCALE ;
//IO_WData32((unsigned char *)& rI2CCON_H,0,((0 << I2C_ACK) | (1 << I2C_512CK) |I2C_PENDING | I2C_PRESCALE));
IO_WData32((unsigned char *)& rI2CCON_H,0,temp1);
//rI2CCON = (0 << I2C_ACK) | (1 << I2C_512CK) |I2C_PENDING | I2C_PRESCALE ;
EI();
}
/******************************************************************************
* Function name : I2C_Stop
* Arguments : void
* Return : void
* By :
* Description :
*****************************************************************************/
void I2C_Stop(void)
{
int i;
ULONG temp1,temp2,temp3;
I2C_CheckComplete();
if(rI2CSTAT_L & I2C_AckFlag)
{
/* ACK was not received */
}
DI();
temp1=IO_RData32((unsigned char *)&rI2CSTAT_H);
temp1&=~(I2C_CmdSTART<<5);
temp2=IO_RData32((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
temp3=IO_RData32((unsigned char *)&rI2CSTAT_H);
temp3 &=~(I2C_Enable);
//* Stop condition, Disable Rx/Tx */
IO_WData32((unsigned char *)& rI2CSTAT_H,0,temp1);
IO_WData32((unsigned char *)& rI2CCON_H,0,temp2);
EI();
for(i=0; i<1000; i++)
I2C_DelayForWait(); // delay > 3.7ms
IO_WData32_EX((unsigned char *)& rI2CSTAT_H,0,temp3);
}
/******************************************************************************
* Function name : I2C_WriteBusyChk
* Arguments : void
* Return : void
* By :
* Description :
*****************************************************************************/
void I2C_WriteBusyChk(UCHAR device_address) // EEPROM write busy check
{
#if 0
volatile UINT i, wait_tick;
UINT timeout = I2C_TIMEOUT_PENDING_CHECK;
ULONG temp1,temp2,temp3;
wait_tick = (UINT) SysMSecToTick(30);
/* To check transfer done interrupt */
for (i=0; i<wait_tick; i++)
{
volatile UINT j;
for(j=0; j<10; j++);
}
#else
volatile ULONG i, wait_tick;
ULONG timeout = I2C_TIMEOUT_PENDING_CHECK;
ULONG temp1,temp2,temp3;
wait_tick = (ULONG) SysMSecToTick(30);
/* To check transfer done interrupt */
for (i=0; i<wait_tick; i++)
{
volatile ULONG j;
for(j=0; j<10; j++);
}
#endif
DI();
IO_WData32((unsigned char *)& rI2CDS_H,0,device_address);
temp1 = (I2C_MasterTx <<6)|(I2C_CmdSTART <<5)|I2C_Enable; // Start condition
IO_WData32((unsigned char *)& rI2CSTAT_H,0,temp1);
temp2=IO_RData32((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32((unsigned char *)& rI2CCON_H,0,temp2);
EI();
while(1)
{
while(1)
{
if(rI2CCON_L & I2C_PENDING)
{
if(rI2CSTAT_L & 0x8)
{
// Arbitration Fail
temp2=IO_RData32_EX((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32_EX((unsigned char *)& rI2CCON_H,0,temp2);
#if 0
SysPrintf("\n[I2C] I2C Bus arbitration fail ");
#endif
}
else if(rI2CSTAT_L & 0x4)
{
// Address-as-slave status
temp2=IO_RData32_EX((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32_EX((unsigned char *)& rI2CCON_H,0,temp2);
// SysPrintf("\n[I2C] I2C Fatal Error ");
}
else
{
// transmit or receive operation is completed.
break;
}
}
else
{
// Previous transfer finish check :Cycle time = 80us
timeout--;
if( timeout == 0 )
{
//SysPrintf("\n[I2C] I2C_Operation fail Wrietbusycheck");
break;
}
I2C_DelayForWait();
}
}
if(!(rI2CSTAT_L & I2C_AckFlag) || timeout == 0)
{
break;
}
DI();
temp3 = (I2C_MasterTx <<6)|(I2C_CmdSTART <<5)|I2C_Enable; // Start condition
IO_WData32((unsigned char *)& rI2CSTAT_H,0,temp3);
temp2=IO_RData32((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32((unsigned char *)& rI2CCON_H,0,temp2);
EI();
}
DI();
temp3 =IO_RData32((unsigned char *)&rI2CSTAT_H);
temp3 &=~(I2C_CmdSTART<<5);
IO_WData32((unsigned char *)& rI2CSTAT_H,0,temp3);
temp2 =IO_RData32((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32((unsigned char *)& rI2CCON_H,0,temp2);
EI();
}
/******************************************************************************
* Function name : I2C_SlaveAddress *
* Revision : 0.0 *
* Arguments : void *
* Return : void *
* By : *
* Description : *
*****************************************************************************/
void I2C_SlaveAddress(UCHAR device_address, UCHAR word_address)
{
volatile UINT i;
ULONG temp1,temp2;
for(i=0; i<200; i++);
IO_WData32_EX((unsigned char *)& rI2CDS_H,0,device_address);
temp1 = (I2C_MasterTx <<6)|(I2C_CmdSTART <<5)|I2C_Enable; // Start condition
IO_WData32_EX((unsigned char *)& rI2CSTAT_H,0,temp1);
/* Pending clear : Restart operation */
temp2=IO_RData32_EX((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32_EX((unsigned char *)& rI2CCON_H,0,temp2);
I2C_CheckComplete();
if(rI2CSTAT_L & I2C_AckFlag)
{
/* ACK was not received */
}
IO_WData32_EX((unsigned char *)& rI2CDS_H,0,word_address);
temp2=IO_RData32_EX((unsigned char *)&rI2CCON_H);
temp2 |=I2C_PENDING;
IO_WData32_EX((unsigned char *)& rI2CCON_H,0,temp2);
}
/******************************************************************************
* Function name : I2C_WriteByte *
* Revision : 0.0 *
* Arguments : void *
* Return : void *
* By : *
* Description : *
*****************************************************************************/
void I2C_WriteByte(UCHAR data)
{
ULONG temp2;
I2C_CheckComplete();
if(rI2CSTAT_L & I2C_AckFlag)
{
/* ACK was not received */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -