📄 i2c_drv.c
字号:
/***************************************************************************
Project : Car two ting dvd System
Compiler : ST7 HiCross C (HiWARE)
Module : autos.c
Version : V 1.0
Created : 24 11, 2005
Author : tomi / SA
Description
- I2c.
Modified
- tomi
***************************************************************************/
#include "I2c_drv.h"
#include "Libr.h"
#include "St72321.h"
#include "IOport.h"
#include "TW101reg.h"
static void StartCondition(void);
static void StopCondition(void);
static unsigned char Send_Byte(unsigned char cData);
static unsigned char Read_Byte(unsigned char cNum);
unsigned char I2CReadByte(unsigned char cDevAddr, unsigned char cReg);
unsigned char I2CReadByte_no_sub(unsigned char cDevAddr);
unsigned char I2CWriteByte(unsigned char cDevAddr, unsigned char cReg, unsigned char cData);
unsigned char I2CReadBytes(unsigned char cDevAddr, unsigned char cReg, unsigned char *pString, unsigned char cNum);
unsigned char I2CWriteByte_noAddrsss(unsigned char cDevAddr,unsigned char cData);
unsigned char I2CWrite_nBytes(unsigned char cDevAddr,unsigned char *buff,unsigned char num);
/**********************************************************
Function:I2c start command
**********************************************************/
static void StartCondition(void)
{
unsigned char ix;
unsigned char cTWtrytime=0;
while(++cTWtrytime)
{
Set_SDA_High;
Set_SCL_High; /* make sure two line is release */
for(ix = 0; ix < TWD_LONG_TIME; ix++)
{ }; /* Delay 12us */
Set_SDA_Low;
for(ix = 0; ix < TWD_LONG_TIME; ix++)
{ }; /* Delay 12us */
if((SCL_High)&&(SDA_Low))
break;
}
for(ix = 0; ix < TWD_SHORT_TIME; ix++)
{ }; /* Delay 12us */
}
/**********************************************************
Function:I2c stop command
**********************************************************/
static void StopCondition(void)
{
unsigned char ix;
unsigned char cTWtrytime=0;
Set_SDA_Low;
Set_SCL_High;
for(ix = 0; ix < TWD_SHORT_TIME; ix++)
{ }; /* delay 12us */
while(SCL_Low && ++cTWtrytime)
{ };
for(ix = 0; ix < TWD_SHORT_TIME; ix++)
{ }; /* delay 12us */
Set_SDA_High;
for(ix = 0; ix < TWD_SHORT_TIME; ix++)
{ }; /* delay 12us */
}
/**********************************************************
Function:I2c send one byte to the slower
**********************************************************/
static unsigned char Send_Byte(unsigned char cData)
{
unsigned char ix, j, cAcknowledge;
unsigned char cTWtrytime=0;
cAcknowledge = 0;
for(ix = 0; ix < 8; ix++)
{
Set_SCL_Low;
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
if(cData&0x80)Set_SDA_High;
else Set_SDA_Low;
cData<<=1;
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
Set_SCL_High;
while(SCL_Low && ++cTWtrytime)
{ };
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
}
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
Set_SCL_Low;
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
Set_SDA_High; /* release data line for acknowledge */
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
SET_SDA_AS_INPUT; /*This is tomi new adding,because the ST IO not same as the 8051*/
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
Set_SCL_High; /* Send a clock for Acknowledge */
while(SCL_Low)
{ };
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
if(SDA_High)
cAcknowledge = 1; /* No Acknowledge */
Set_SCL_Low; /* Finish Acknoledge */
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
SET_SDA_AS_OUTPUT; /*This is tomi new adding,because the ST IO not same as the 8051*/
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
return(cAcknowledge);
}
/**************************************************************
Function:Read a byte from slower with a acknowledge bit
**************************************************************/
static unsigned char Read_Byte(unsigned char cNum)
{
unsigned char ix, j;
unsigned char cRetval=0;
SET_SDA_AS_INPUT; /*This is tomi new adding,because the ST IO not same as the 8051*/
for(j=0;j<TWD_SHORT_TIME;j++)
{};
for(ix=0;ix<8;ix++){
Set_SCL_High;
while(SCL_Low){};
for(j=0;j<TWD_SHORT_TIME;j++){};
cRetval = (SDA_High)? (cRetval|(1<<(7-ix))):cRetval ; /* MSB First */
Set_SCL_Low;
}
if(cNum==1)
Set_SDA_High;
else
Set_SDA_Low;
//SDA = (cNum==1) 1:0;
Set_SCL_High;
while(SCL_Low){};
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
Set_SCL_Low;
SET_SDA_AS_OUTPUT; /*This is tomi new adding,because the ST IO not same as the 8051*/
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
Set_SDA_High;
for(j = 0; j < TWD_SHORT_TIME; j++)
{ };
return cRetval;
}
/*******************************************************************
Function:Maker read one byte from the slower's appointed address
*******************************************************************/
unsigned char I2CReadByte(unsigned char cDevAddr, unsigned char cReg)
{
unsigned char cResult = 0;
/* write reg offset */
StartCondition();
if(Send_Byte(cDevAddr))
return 0; // Write address
if(Send_Byte(cReg))
return 0;
/* read data */
StartCondition();
if (Send_Byte(cDevAddr | 0x01)) // Read address
return 0;
cResult = Read_Byte(1);
StopCondition();
return cResult;
}
/*******************************************************************
Function:
*******************************************************************/
unsigned char I2CReadByte_no_sub(unsigned char cDevAddr)
{
unsigned char cResult = 0;
/* write reg offset */
StartCondition();
if(Send_Byte(cDevAddr))
return 0; // Write address
/* read data */
StartCondition();
if (Send_Byte(cDevAddr | 0x01)) // Read address
return 0;
cResult = Read_Byte(1);
StopCondition();
return cResult;
}
/*******************************************************************
Function:Maker send one byte to the slower's appointed address
*******************************************************************/
unsigned char I2CWriteByte(unsigned char cDevAddr, unsigned char cReg, unsigned char cData)
{
/* start condition */
StartCondition();
cDevAddr &= 0xFE; // Force WRITE address
/* send device ID and write data */
if(!Send_Byte(cDevAddr))
{
if(!Send_Byte(cReg))
{
if(!Send_Byte(cData))
{
StopCondition();
return(0); /* success */
}
}
}
StopCondition();
return(1);
}
/*********************************************************************
Function:Read more than one byte from the slower to the appointed address
*********************************************************************/
unsigned char I2CReadBytes(unsigned char cDevAddr, unsigned char cReg, unsigned char *pString, unsigned char cNum)
{
/* write reg offset */
StartCondition();
if(Send_Byte(cDevAddr))
return 0; // Write address
if(Send_Byte(cReg))
return 0;
/* read data */
StartCondition();
if (Send_Byte(cDevAddr | 0x01)) // Read address
return 0;
while(cNum)
{
*pString++ = Read_Byte(cNum);
cNum--;
}
StopCondition();
return 1;
}
/*********************************************************************
Function:Send one byte to the slower no the appointed address
*********************************************************************/
unsigned char I2CWriteByte_noAddrsss(unsigned char cDevAddr,unsigned char cData)
{
/* start condition */
StartCondition();
cDevAddr &= 0xFE; // Force WRITE address
/* send device ID and write data */
if(!Send_Byte(cDevAddr))
{
if(!Send_Byte(cData))
{
StopCondition();
return(0); /* success */
}
}
StopCondition();
return(1);
}
/****************************************************************
Function:I2c write n bytes
****************************************************************/
unsigned char I2CWrite_nBytes(unsigned char cDevAddr,unsigned char *buff,unsigned char num)
{
unsigned char i;
unsigned char Ack;
/* start condition */
StartCondition();
cDevAddr &= 0xFE; // Force WRITE address
/* send device ID and write data */
Ack = Send_Byte(cDevAddr);
if(!Ack)
{
for (i=0; i<num; i++)
{
if (!Ack)
Ack = Send_Byte (*buff++);
}
StopCondition();
return(0); /* success */
}
StopCondition();
return(1);
}
/***********************************************************
Function:I2C write have sub address and write n bytes
***********************************************************/
unsigned char I2C_write_sub(unsigned char cDevAddr,unsigned char sub_addr,unsigned char *buff,unsigned char num)
{
unsigned char i;
unsigned char Ack;
/* start condition */
StartCondition();
cDevAddr &= 0xFE; // Force WRITE address
/* send device ID and write data */
Ack = Send_Byte(cDevAddr);
if(!Ack)
Ack = Send_Byte(sub_addr);
if(!Ack)
{
for (i=0; i<num; i++)
{
if (!Ack)
Ack = Send_Byte (*buff++);
}
StopCondition();
return(0); /* success */
}
StopCondition();
return(1);
}
/***********************************************************
Function:Configure the T100's A0/A1 IO port
***********************************************************/
void OSDCfgWr(unsigned char index,unsigned char dat)
{
I2CWriteByte(TW101,OSD_CFG_INDEX,index);
I2CWriteByte(TW101,OSD_CFG_DATA,dat);
}
unsigned char twdWr_Burst_A(unsigned char cReg)
{
StartCondition();
if(!Send_Byte(TW101))
{
if(!Send_Byte(cReg))
{
return(0); //
}
}
return(1); //
}
void twdWr_Burst_D(unsigned char cData)
{
unsigned char ix;
for(ix = 0; ix < 8; ix++)
{
Set_SCL_Low;
if(cData&0x80)Set_SDA_High;
else Set_SDA_Low;
cData<<=1;
Set_SCL_High;
}
Set_SCL_Low;
Set_SDA_High; /* release data line for acknowledge */
Set_SCL_High; /* Send a clock for Acknowledge */
// if(SDA_High) cAcknowledge = 1; /* No Acknowledge */
Set_SCL_Low; /* Finish Acknoledge */
// return(cAcknowledge);
}
void twdWr_Burst_P(void)
{
StopCondition();
}
void twdDelay(unsigned short wLoops)
{
unsigned short wTemp;
while (wLoops--) {
wTemp = 1000/6; // one loop below takes about 11 us
while (wTemp--);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -