📄 drviic.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.
//
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///@file Drviic.h
///@brief Driver interface of IIC (I2C)
///
///@author MStarSemi Inc.
///
///- This is the IIC Driver interface, providing I2C Init/Read/Write function.
///- I2C interface is a two-wire interface which is designed for communicating between ICs.
///
///@par Example
///@code
/// //#define u8SlaveID 0x80, Slave address for device ABC
/// //#define u8StatusReg 0x20, status register of device ABC
/// // BIT0:toggle for get status, BIT1: status
/// BOOL msAPI_GetDevABCStatus(void)
/// {
/// U8 temp;
/// if(MDrv_IIC_ReadByte (u8SlaveID, u8StatusReg, *temp))
/// {
/// // toggle
/// MDrv_IIC_WriteByte( u8SlaveID, u8StatusReg, temp|BIT0);
/// // read status register
/// MDrv_IIC_ReadByte (u8SlaveID, u8StatusReg, *temp)
/// if(temp & BIT1)
/// {
/// return TRUE;
/// }
/// }
/// return FALSE;
/// }
///@endcode
///////////////////////////////////////////////////////////////////////////////
/******************************************************************************/
/* Header Files */
/******************************************************************************/
#include <stdio.h>
#include "datatype.h"
#include "hwreg.h"
#include "mreg51.h"
#include "drvuart.h"
#include "drvtimer.h"
#include "drviic.h"
#include "drvglobal.h"
#define I2C_DEBUGINFO(x)
/******************************************************************************/
/* Macro */
/******************************************************************************/
#define IIC_PollingTimes 1000//20
#define IIC_StopTime 500//2000
#define MIIC_RETRY_COUNT 0
//-------------------------------------------------
//
//-------------------------------------------------
void MiicMode( void )
{
printf("\r\n MIIC");
MDrv_WriteByteMask(BK_CHIPTOP_03_H,_BIT5|_BIT4,_BIT5|_BIT4);
MDrv_WriteByteMask(BK_CHIPTOP_4D_H,0x00,_BIT0);
MDrv_WriteByteMask(BK_CHIPTOP_5E_L,0x00,_BIT6|_BIT5);
MDrv_WriteByteMask(BK_CHIPTOP_5F_L,0x00,_BIT1);
MDrv_WriteByteMask(BK_CHIPTOP_5F_H,_BIT5,_BIT5);
MDrv_WriteByteMask(BK_CHIPTOP_64_L,_BIT6,_BIT6);
}
//-------------------------------------------------
/******************************************************************************/
///I2C Initialize: set I2C Clock, IC pad and enable I2C
/******************************************************************************/
void MDrv_IIC_Init()
{
MiicMode();
XBYTE[IIC0_CLK_SEL] = 4; // speed 111khz , IIC clock = sysclk / 128
XBYTE[IIC0_CTRL] = 0x80; // Enable IIC
}
/******************************************************************************/
///Generate a start pulse
/******************************************************************************/
void IIC_Start(void)
{
XBYTE[IIC0_CTRL] = 0xC0; // enable IIC, start-bit
}
void IIC_StartW(U8 u8SlaveID)
{
XBYTE[IIC0_STATUS]=0x02; // clear interrupt status
XBYTE[IIC0_WDATA] = u8SlaveID;
XBYTE[IIC0_CTRL] = 0xC0; // enable IIC, start-bit
while( 1 ) //for(i=0;i<IIC_PollingTimes;i++)
{
if(XBYTE[IIC0_STATUS]&0x1)
{
XBYTE[IIC0_STATUS]=0x02; //clear iic0 int status
break;
}
}
}
/******************************************************************************/
///Generate a stop pulse
/******************************************************************************/
void IIC_Stop(void)
{
U16 i;
XBYTE[IIC0_CTRL] = 0xA0;
for(i=0;i<IIC_StopTime;i++);
}
/******************************************************************************/
///Generate a Non-Acknowledge pulse
/******************************************************************************/
static void IIC_NoAck(void)
{
XBYTE[IIC0_CTRL] = 0x90;
}
/******************************************************************************/
///Send 1 bytes data
///@param u8dat \b IN: 1 byte data to send
/******************************************************************************/
static BOOLEAN SendByte(U8 u8dat) // Be used int IIC_SendByte
{
//U16 i=0;
U8 regval;
XBYTE[IIC0_STATUS]=0x02; // clear interrupt status
XBYTE[IIC0_WDATA] = u8dat;
while( 1 ) //for(i=0;i<IIC_PollingTimes;i++)
{
regval = XBYTE[IIC0_STATUS];
if(regval&0x1)
{
XBYTE[IIC0_STATUS]=0x02; //clear iic0 int status
regval =XBYTE[IIC0_CTRL];
if(regval&0x8) // no get ack
return FALSE;
else
return TRUE;
}
}
return FALSE;
}
/******************************************************************************/
///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<(1+MIIC_RETRY_COUNT);i++)
{
if(SendByte(u8dat)==TRUE)
return TRUE;
}
I2C_DEBUGINFO(printf("IIC write byte 0x%bx fail!!\r\n", u8dat));
return FALSE;
}
/******************************************************************************/
///Get 1 bytes data,it will wait till IIC is completed.
///@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
{
//U8 i;
U8 regval;
XBYTE[IIC0_STATUS] = 0x04; //start byte read
while( 1 ) //for(i=0;i<IIC_PollingTimes;i++)
{
regval = XBYTE[IIC0_STATUS];
if(regval&0x1)
{
XBYTE[IIC0_STATUS] = 0x02;
*pu8data = XBYTE[IIC0_RDATA];
return TRUE;
}
}
return FALSE;
}
/******************************************************************************/
///Write bytes, be able to write 1 byte or several bytes to several register offsets in same slave address.
///@param u8SlaveID \b IN: Slave ID (Address)
///@param u8addrcount \b IN: register NO to write, this parameter is the NO of register offsets in pu8addr buffer,
///it should be 0 when *pu8addr = NULL.
///@param *pu8addr \b IN: pointer to a buffer containing target register offsets to write
///@param u16size \b IN: Data length (in byte) to write
///@param *pu8data \b IN: pointer to the data buffer for write
///@return BOOLEAN:
///- TRUE: Success
///- FALSE: Fail
/******************************************************************************/
BOOLEAN MDrv_IIC_WriteBytes(U8 u8SlaveID, U8 u8addrcount, U8* pu8addr, U16 u16size, U8* pu8data)
{
#if 1
U16 i;
BOOLEAN flag=TRUE;
IIC_StartW(u8SlaveID);
for(i=0;i<u8addrcount;i++)
{
if(IIC_SendByte(pu8addr[i])==FALSE)
flag=FALSE;
}
for(i=0;i<u16size;i++)
{
if(IIC_SendByte(pu8data[i])==FALSE)
flag=FALSE;
}
IIC_Stop();
return flag;
#else
U16 i;
IIC_Start();
if(IIC_SendByte(u8SlaveID&0xFE)==FALSE)
return FALSE;
if(u8addrcount > 0)
{
for(i=0;i<u8addrcount;i++)
{
if(IIC_SendByte(pu8addr[i])==FALSE)
return FALSE;
}
}
for(i=0;i<u16size;i++)
{
if(IIC_SendByte(pu8data[i])==FALSE)
return FALSE;
}
IIC_Stop();
return TRUE;
#endif
}
/******************************************************************************/
///Read bytes, be able to read 1 byte or several bytes from several register offsets in same slave address.
///@param u8SlaveID \b IN: Slave ID (Address)
///@param u8AddrNum \b IN: register NO to read, this parameter is the NO of register offsets in pu8addr buffer,
///it should be 0 when *paddr = NULL.
///@param *paddr \b IN: pointer to a buffer containing target register offsets to read
///@param u16size \b IN: Data length (in byte) to read
///@param *pu8data \b IN: pointer to retun data buffer.
///@return BOOLEAN:
///- TRUE: Success
///- FALSE: Fail
/******************************************************************************/
BOOLEAN MDrv_IIC_ReadBytes(U8 u8SlaveID, U8 u8AddrNum, U8* paddr, U16 u16size, U8* pu8data)
{
#if 1
U16 i;
BOOLEAN flag=TRUE;
IIC_StartW(u8SlaveID);
for(i=0;i<u8AddrNum;i++)
{
if(IIC_SendByte(*(paddr+i))==FALSE)
flag=FALSE;
}
if(u16size > 0)
{
IIC_Stop();
IIC_StartW(u8SlaveID|0x1);
for(i=0;i<u16size;i++)
{
if(i==(u16size-1))
IIC_NoAck();
if(IIC_GetByte(pu8data++)==FALSE)
flag=FALSE;
}
}
IIC_Stop();
return flag;
#else
U16 i;
IIC_Start();
if(IIC_SendByte(u8SlaveID&0xFE)==FALSE)
return FALSE;
if(u8AddrNum>0)
{
for(i=0;i<u8AddrNum;i++)
{
if(IIC_SendByte(*(paddr+i))==FALSE)
return FALSE;
}
}
if(u16size > 0)
{
IIC_Start();
if(IIC_SendByte(u8SlaveID|0x1)==FALSE)
return FALSE;
for(i=0;i<u16size;i++)
{
if(i==(u16size-1))
IIC_NoAck();
if(IIC_GetByte(pu8data++)==FALSE)
return FALSE;
}
}
IIC_Stop();
return TRUE;
#endif
}
/******************************************************************************/
///Read 1 byte through IIC
///@param u8SlaveID \b IN: Slave ID
///@param u8RegAddr \b IN: Target register offset to read
///@param *pu8Data \b IN: pointer to 1 byte return data.
///@return BOOLEAN:
///- TRUE: Success
///- FALSE: Fail
/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -