⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drviic.c

📁 mstar 776 开发的车载dvd
💻 C
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////////
//
// 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 + -