📄 drvswiic.c
字号:
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2007 MStar Semiconductor, Inc.
// All rights reserved.
//
// Unless otherwise stipulated in writing, any and all information contained
// herein regardless in any format shall remain the sole proprietary of
// MStar Semiconductor Inc. and be kept in strict confidence
// (¨MStar Confidential Information〃) by the recipient.
// Any unauthorized act including without limitation unauthorized disclosure,
// copying, use, reproduction, sale, distribution, modification, disassembling,
// reverse engineering and compiling of the contents of MStar Confidential
// Information is unlawful and strictly prohibited. MStar hereby reserves the
// rights to any and all damages, losses, costs and expenses resulting therefrom.
//
////////////////////////////////////////////////////////////////////////////////
#include "mreg51.h"
#include "board.h"
#include "hwreg.h"
//#include "i2c.h"
#include <intrins.h>
#include "DataType.h"
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef BOOL
#define BOOL unsigned char
#endif
#if 1 // kevin 20070829
#define SCL_PIN BIT5
#define SDA_PIN BIT6
#define SWIIC_SCL_PIN(x) ((x==_OUTPUT)? ( XBYTE[REG_MUX_DTCON_GPIO_SEL] |= SCL_PIN):( XBYTE[REG_MUX_DTCON_GPIO_SEL] &= ~SCL_PIN) )
#define SWIIC_SDA_PIN(x) ((x==_OUTPUT)? ( XBYTE[REG_MUX_DTCON_GPIO_SEL] |= SDA_PIN):( XBYTE[REG_MUX_DTCON_GPIO_SEL] &= ~SDA_PIN) )
#define SWIIC_SCL_OUT(x) ((x==_HIGH)? ( XBYTE[REG_MUX_TOP0_GPIO] |= SCL_PIN):( XBYTE[REG_MUX_TOP0_GPIO] &= ~SCL_PIN) )
#define SWIIC_SDA_OUT(x) ((x==_HIGH)? ( XBYTE[REG_MUX_TOP0_GPIO] |= SDA_PIN):( XBYTE[REG_MUX_TOP0_GPIO] &= ~SDA_PIN) )
#define GET_SWIIC_SCL() ( ( XBYTE[REG_TOP0_GPIO_R] & SCL_PIN ) ? 1:0 )
#define GET_SWIIC_SDA() ( ( XBYTE[REG_TOP0_GPIO_R] & SDA_PIN ) ? 1:0 )
#else
//#define SCL BIT4
//#define SDA BIT3
#define SWIIC_SCL_PIN(x) ((x==_INPUT)? ( XBYTE[REG_GPIO_OE_1] |=BIT4):( XBYTE[REG_GPIO_OE_1] &=~BIT4) )
#define SWIIC_SDA_PIN(x) ((x==_INPUT)? ( XBYTE[REG_GPIO_OE_1] |=BIT3):( XBYTE[REG_GPIO_OE_1] &=~BIT3) )
//#define SWIIC_SCL(x) ((x==_HIGH)? ( XBYTE[REG_GPIO_OUT_HIGH] |=BIT4):( XBYTE[REG_GPIO_OUT_HIGH] &=~BIT4) )
//#define SWIIC_SDA(x) ((x==_HIGH)? ( XBYTE[REG_GPIO_OUT_HIGH] |=BIT3):( XBYTE[REG_GPIO_OUT_HIGH] &=~BIT3) )
#define SWIIC_SCL_OUT(x) ((x==_HIGH)? ( XBYTE[REG_GPIO_OUT_HIGH] |=BIT4):( XBYTE[REG_GPIO_OUT_HIGH] &=~BIT4) )
#define SWIIC_SDA_OUT(x) ((x==_HIGH)? ( XBYTE[REG_GPIO_OUT_HIGH] |=BIT3):( XBYTE[REG_GPIO_OUT_HIGH] &=~BIT3) )
#define GET_SWIIC_SCL() ( ( XBYTE[REG_GPIO_IN_HIGH] & BIT4 ) ? 1:0 )
#define GET_SWIIC_SDA() ( ( XBYTE[REG_GPIO_IN_HIGH] & BIT3 ) ? 1:0 )
#endif
#define SWIIC_READ 0
#define SWIIC_WRITE 1
#define I2C_CHECK_PIN_DUMMY 100
#define I2C_ACKNOWLEDGE _LOW
#define I2C_NON_ACKNOWLEDGE _HIGH
#define I2C_ACCESS_DUMMY_TIME 3
#define HIBYTE(value) ((BYTE)((value) / 0x100))
#define LOBYTE(value) ((BYTE)(value))
static U8 _u8Delay=100;
#define SWI2C_DEBUGINFO(x) //x
void SWIIC_Delay(void)
{
U8 u8Loop;
u8Loop = _u8Delay; //30 // 99Khz
while (u8Loop-- > 0)
{
_nop_();
}
}
/******************************************************************************/
///I2C Initialize: set I2C Clock and enable I2C
/******************************************************************************/
void MDrv_IIC_Init()
{
#if 1// kevin 20070829
//puts("\r\nSWI2C Init");
XBYTE[ REG_MUX_DTCON_GPIO_SEL] |= (SCL_PIN|SDA_PIN);
#else
XBYTE[0x1eA1] &=0xf8; //clear bit0/1/2
XBYTE[0x1ee0]|=BIT7;
XBYTE[ REG_GPIO_OE_1] |= (BIT4|BIT3);
#endif
// XBYTE[ REG_GPIO_OE_1] &= ~(BIT4|BIT3); //set to output first
// XBYTE[ REG_GPIO_OUT_HIGH] |= (BIT4|BIT3); //inital SDA/SCL high
}
/******************************************************************************/
/******************************************************************************/
void SWIIC_SCL( U8 x )
{
if ( x == _HIGH )
{
SWIIC_SCL_PIN(_INPUT); //set to input
}
else
{
SWIIC_SCL_OUT(_LOW);
SWIIC_SCL_PIN(_OUTPUT);
}
}
/******************************************************************************/
/******************************************************************************/
void SWIIC_SDA( U8 x )
{
if ( x == _HIGH )
{
SWIIC_SDA_PIN(_INPUT); //set to input
}
else
{
SWIIC_SDA_OUT(_LOW);
SWIIC_SDA_PIN(_OUTPUT); //set to output
}
}
/******************************************************************************/
void SWIIC_SDA_Chk(bit bSet)
{
/* BYTE ucDummy; // loop dummy
SWIIC_SDA(bSet); // set SDA pin
SWIIC_SDA_PIN(_OUTPUT);
if (bSet == _HIGH) // if set pin high
{
ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
SWIIC_SDA_PIN(_INPUT);
while ((GET_SWIIC_SDA() == _LOW) && (ucDummy--)) ; // check SDA pull high
}
SWIIC_SDA_PIN(_OUTPUT);
//*/
BYTE ucDummy; // loop dummy
if (bSet == _HIGH) // if set pin high
{
SWIIC_SDA_PIN(_INPUT);
ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
while ((GET_SWIIC_SDA() == _LOW) && (ucDummy--)) ; // check SDA pull high
}
else
{
SWIIC_SDA(_LOW); // set SDA pin
SWIIC_SDA_PIN(_OUTPUT);
}
}
/******************************************************************************/
void SWIIC_SCL_Chk(bit bSet)
{
/* BYTE ucDummy; // loop dummy
SWIIC_SCL_PIN(_OUTPUT);
SWIIC_SCL(bSet); // set SCL pin
if (bSet == _HIGH) // if set pin high
{
ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
SWIIC_SCL_PIN(_INPUT);
while ((GET_SWIIC_SCL() == _LOW) && (ucDummy--)) ; // check SCL pull high
SWIIC_SCL_PIN(_OUTPUT);
}
//*/
BYTE ucDummy; // loop dummy
if (bSet == _HIGH) // if set pin high
{
SWIIC_SCL_PIN(_INPUT);
ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
while ((GET_SWIIC_SCL() == _LOW) && (ucDummy--)) ; // check SCL pull high
}
else
{
SWIIC_SCL(_LOW); // set SCL pin
SWIIC_SCL_PIN(_OUTPUT);
}
}
/******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// I2C start signal.
// <comment>
// SCL ________
// \_________
// SDA _____
// \____________
//
// Return value: None
////////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
BOOL IIC_Start(void)
{
BOOL bStatus = TRUE; // success status
SWIIC_SDA_Chk(_HIGH);
SWIIC_Delay();
SWIIC_SCL_Chk(_HIGH);
SWIIC_Delay();
// check pin error
SWIIC_SCL_PIN(_INPUT);
SWIIC_SDA_PIN(_INPUT);
if ((GET_SWIIC_SCL() == _LOW) || (GET_SWIIC_SDA() == _LOW))
{
SWIIC_SCL_PIN(_OUTPUT);
SWIIC_SDA_PIN(_OUTPUT);
bStatus = FALSE;
}
else // success
{
SWIIC_SDA(_LOW);
SWIIC_Delay();
SWIIC_SCL(_LOW);
}
return bStatus; //vain
}
////////////////////////////////////////////////////////////////////////////////
// I2C stop signal.
// <comment>
// ____________
// SCL _______/
// _________
// SDA __________/
////////////////////////////////////////////////////////////////////////////////
void IIC_Stop(void)
{
SWIIC_SCL(_LOW);
SWIIC_Delay();
SWIIC_SDA(_LOW);
SWIIC_Delay();
SWIIC_SCL_Chk(_HIGH);
SWIIC_Delay();
SWIIC_SDA_Chk(_HIGH);
SWIIC_Delay();
}
/******************************************************************************/
///Send 1 bytes data
///@param u8dat \b IN: 1 byte data to send
/******************************************************************************/
static BOOLEAN SendByte(U8 u8dat) // Be used int IIC_SendByte
{
BYTE ucMask = 0x80;
bit bAck; // acknowledge bit
while ( ucMask )
{
if (u8dat & ucMask)
{
SWIIC_SDA_Chk(_HIGH);
}
else
{
SWIIC_SDA_Chk(_LOW);
}
SWIIC_Delay();
SWIIC_SCL_Chk(_HIGH); // clock
SWIIC_Delay();
SWIIC_SCL(_LOW);
//SWIIC_Delay(); //delete
ucMask >>= 1; // next
}
// recieve acknowledge
SWIIC_SDA_PIN(_INPUT);
SWIIC_Delay();
SWIIC_SCL_Chk(_HIGH);
SWIIC_Delay();
bAck = GET_SWIIC_SDA(); // recieve acknowlege
// SWIIC_SDA(bAck); //for I2c waveform sharp
// SWIIC_SDA_PIN(_OUTPUT);
SWIIC_SCL(_LOW);
SWIIC_Delay();
SWIIC_SDA(bAck); //for I2c waveform sharp
SWIIC_SDA_PIN(_OUTPUT);
SWIIC_Delay(); //jaly test
SWIIC_Delay();
SWIIC_Delay();
SWIIC_Delay(); //jaly test
SWIIC_Delay();
SWIIC_Delay();
return (bAck);
}
/******************************************************************************/
///Send 1 bytes data, this function will retry 5 times until success.
///@param u8dat \b IN: 1 byte data to send
///@return BOOLEAN:
///- TRUE: Success
///- FALSE: Fail
/******************************************************************************/
static BOOLEAN IIC_SendByte(U8 u8dat)
{
U8 i;
for(i=0;i<5;i++)
{
if(SendByte(u8dat)==I2C_ACKNOWLEDGE)
return TRUE;
}
SWI2C_DEBUGINFO(printf("IIC write byte 0x%bx fail!!\r\n", u8dat));
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// I2C access start.
//
// Arguments: ucSlaveAdr - slave address
// trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
////////////////////////////////////////////////////////////////////////////////
BOOL IIC_AccessStart(BYTE ucSlaveAdr, BYTE trans_t)
{
BYTE ucDummy; // loop dummy
if (trans_t == SWIIC_READ) // check i2c read or write
{
ucSlaveAdr = ucSlaveAdr | 0x01; // read
}
else
{
ucSlaveAdr = ucSlaveAdr & 0xfe; // write
}
ucDummy = I2C_ACCESS_DUMMY_TIME;
while (ucDummy--)
{
if ( IIC_Start() == FALSE)
{
continue;
}
if ( IIC_SendByte(ucSlaveAdr) == TRUE ) //I2C_ACKNOWLEDGE) // check acknowledge
{
return TRUE;
}
IIC_Stop();
}
return FALSE;
}
/******************************************************************************/
///Get 1 bytes data, this function will retry 5 times until success.
///@param *u8dat \b IN: pointer to 1 byte data buffer for getting data
///@return BOOLEAN:
///- TRUE: Success
///- FALSE: Fail
/******************************************************************************///
//static BOOLEAN IIC_GetByte(U8* pu8data) // Auto generate ACK
BYTE IIC_GetByte (U16 bAck)
{
BYTE ucReceive = 0;
BYTE ucMask = 0x80;
SWIIC_SDA_PIN(_INPUT); //SWIIC_SDA_PIN
while ( ucMask )
{
SWIIC_Delay();
SWIIC_SCL_Chk(_HIGH); //SWIIC_SCL_Chk
SWIIC_Delay();
if (GET_SWIIC_SDA() == _HIGH) //GET_SWIIC_SDA
{
ucReceive |= ucMask;
}
ucMask >>= 1; // next
SWIIC_SCL(_LOW); //SWIIC_SCL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -