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

📄 i2c.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.
//
////////////////////////////////////////////////////////////////////////////////

#pragma OPTIMIZE(8)

#include "mreg51.h"
#include "board.h"

#if ( ENABLE_EEPROM )

#include "hwreg.h"

#include "i2c.h"
#include <intrins.h>

#define mcuSetIntEn()                   ;//(EA = 1)
#define mcuClrIntEn()                   ;//(EA = 0)

#ifndef EEPROM_CLK_SEL
#define EEPROM_CLK_SEL EEPROM_CLK_100KHZ
#endif

#if EEPROM_CLK_SEL == EEPROM_CLK_400KHZ
#define i2c_Delay()  \
    { \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); _nop_(); _nop_(); _nop_(); \
        _nop_(); \
    }
#elif EEPROM_CLK_SEL == EEPROM_CLK_200KHZ
void i2c_Delay(void)
{
    _nop_(); _nop_(); _nop_(); _nop_();
    _nop_(); _nop_(); _nop_(); _nop_();
    _nop_(); _nop_(); _nop_(); _nop_();
    _nop_(); _nop_(); _nop_(); _nop_();
    _nop_(); _nop_(); _nop_();
}
#else
void i2c_Delay(void)
{
    U8 u8Loop;

    u8Loop = 30;				// 99Khz

    while (u8Loop-- > 0)
    {
        _nop_();
    }
}
#endif
#if ( _EEPROM_ACCESS == IIC_BY_SW )
////////////////////////////////////////////////////////////////////////////////
// Set I2C SCL pin high/low.
//
// Arguments: bSet - high/low bit
////////////////////////////////////////////////////////////////////////////////
void i2cSetSCL_Chk(bit bSet)
{
    BYTE ucDummy;       // loop dummy

    i2cSCL_PIN_OUT();
    i2cSetSCL(bSet);    // set SCL pin

    if (bSet == _HIGH)  // if set pin high
    {
        ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy

        i2cSCL_PIN_IN();

        while ((GetPinI2cSCL() == _LOW) && (ucDummy--)) ; // check SCL pull high

        i2cSCL_PIN_OUT();
    }
}

////////////////////////////////////////////////////////////////////////////////
// Set I2C SDA pin high/low
//
// Arguments: bSet - high/low bit
////////////////////////////////////////////////////////////////////////////////
void i2cSetSDA_Chk(bit bSet)
{
    BYTE ucDummy;       // loop dummy

	i2cSDA_PIN_OUT();

	i2cSetSDA(bSet);    // set SDA pin

    if (bSet == _HIGH)  // if set pin high
    {
        ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy

		i2cSDA_PIN_IN();

        while ((GetPinI2cSDA() == _LOW) && (ucDummy--)) ; // check SDA pull high

		i2cSDA_PIN_OUT();
    }
}

////////////////////////////////////////////////////////////////////////////////
// I2C start signal.
// <comment>
//  SCL ________
//              \_________
//  SDA _____
//           \____________
//
// Return value: None
////////////////////////////////////////////////////////////////////////////////
BOOL i2c_Start(void)
{
    BOOL bStatus = TRUE;    // success status
    mcuClrIntEn();          // disable all interrupt

    i2cSetSDA_Chk(_HIGH);

    i2c_Delay();

    i2cSetSCL_Chk(_HIGH);

    i2c_Delay();

    // check pin error
    i2cSCL_PIN_IN();

    i2cSDA_PIN_IN();

    if ((GetPinI2cSCL() == _LOW) || (GetPinI2cSDA() == _LOW))
    {
        i2cSCL_PIN_OUT();
        i2cSDA_PIN_OUT();
        bStatus = FALSE;
    }
    else // success
    {
        i2cSDA_PIN_OUT();
        i2cSetSDA(_LOW);
        i2c_Delay();
        i2cSCL_PIN_OUT();
        i2cSetSCL(_LOW);
    }

    mcuSetIntEn(); // release EA bit

    return bStatus;
}

////////////////////////////////////////////////////////////////////////////////
// I2C stop signal.
// <comment>
//              ____________
//  SCL _______/
//                 _________
//  SDA __________/
////////////////////////////////////////////////////////////////////////////////
void i2c_Stop(void)
{
    mcuClrIntEn(); // disable all interrupt

    i2cSetSCL(_LOW);
    i2c_Delay();
    i2cSetSDA(_LOW);
    i2c_Delay();
    i2cSetSCL_Chk(_HIGH);
    i2c_Delay();
    i2cSetSDA_Chk(_HIGH);
    i2c_Delay();

    mcuSetIntEn(); // release EA bit
}

////////////////////////////////////////////////////////////////////////////////
// I2C receive byte from device.
//
// Return value: receive byte
////////////////////////////////////////////////////////////////////////////////
BYTE i2c_ReceiveByte(BOOL bAck)
{
    BYTE ucReceive = 0;
    BYTE ucMask = 0x80;

    mcuClrIntEn();

    i2cSDA_PIN_IN();

    while ( ucMask )
    {
        i2cSetSCL_Chk(_HIGH);
        i2c_Delay();

        if (GetPinI2cSDA() == _HIGH)
        {
            ucReceive |= ucMask;
        }

        i2cSetSCL(_LOW);
        i2c_Delay();

        ucMask >>= 1; // next
    }

    i2cSDA_PIN_OUT();

    if (bAck)
    {
        // acknowledge
        i2cSetSDA_Chk(I2C_ACKNOWLEDGE);
    }
    else
    {
        // non-acknowledge
        i2cSetSDA_Chk(I2C_NON_ACKNOWLEDGE);
    }

    i2c_Delay();
    i2cSetSCL_Chk(_HIGH);
    i2c_Delay();
    i2cSetSCL(_LOW);
    i2c_Delay();

    mcuSetIntEn(); // release EA bit

    return ucReceive;
}


////////////////////////////////////////////////////////////////////////////////
// I2C send byte to device.
//
// Arguments: ucVal - send byte
// Return value: I2C acknowledge bit
//               I2C_ACKNOWLEDGE/I2C_NON_ACKNOWLEDGE
////////////////////////////////////////////////////////////////////////////////
bit i2c_SendByte(BYTE ucVal)
{
    BYTE    ucMask = 0x80;
    bit     bAck; // acknowledge bit

    mcuClrIntEn();

    while ( ucMask )
    {
        if (ucVal & ucMask)
        {
            i2cSetSDA_Chk(_HIGH);
        }
        else
        {
            i2cSetSDA_Chk(_LOW);
        }

        i2c_Delay();
        i2cSetSCL_Chk(_HIGH); // clock
        i2c_Delay();
        i2cSetSCL(_LOW);
        i2c_Delay();

        ucMask >>= 1; // next
    }

    // recieve acknowledge
    i2cSDA_PIN_IN();
    i2c_Delay();
    i2cSetSCL_Chk(_HIGH);
    i2c_Delay();
    bAck = GetPinI2cSDA(); // recieve acknowlege
    i2cSDA_PIN_OUT();
    i2cSetSCL(_LOW);
    i2c_Delay();

    mcuSetIntEn(); // release EA bit

    return (bAck);
}

////////////////////////////////////////////////////////////////////////////////
// I2C access start.
//
// Arguments: ucSlaveAdr - slave address
//            trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
////////////////////////////////////////////////////////////////////////////////
BOOL i2c_AccessStart(BYTE ucSlaveAdr, I2cIoTransType trans_t)
{
    BYTE ucDummy; // loop dummy

    if (trans_t == I2C_TRANS_READ) // check i2c read or write
    {
        ucSlaveAdr = I2C_DEVICE_ADR_READ(ucSlaveAdr); // read
    }
    else
    {
        ucSlaveAdr = I2C_DEVICE_ADR_WRITE(ucSlaveAdr); // write
    }

    // enlarge retry count to cover internal write period

    ucDummy = 60;  //I2C_ACCESS_DUMMY_TIME;

    while (ucDummy--)
    {
        if (i2c_Start() == FALSE)
        {
            continue;
        }

        if (i2c_SendByte(ucSlaveAdr) == I2C_ACKNOWLEDGE) // check acknowledge
        {
            return TRUE;
        }

        i2c_Stop();
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -