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

📄 davincihd_i2c.c

📁 用于dm6467 开发平台的uboot源码
💻 C
字号:
/*
 *  Copyright 2007 by Spectrum Digital Incorporated.
 *  All rights reserved. Property of Spectrum Digital Incorporated.
 */

/*
 *  I2C implementation
 *
 */

#include "davincihd_i2c.h"

static Int32 i2c_timeout = ( 0x00010000 );

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_init( )                                                            *
 *      Setup I2C module                                                    *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_I2C_init( )
{
    /* Reset I2C */
    I2C_ICMDR = 0;

    /*
     *  Setup I2C SCL clock
     *      [ 27 MHz input ] -> [ 100 kHz output ]
     */
    I2C_ICPSC = 337;
    I2C_ICCLKL = 4;
    I2C_ICCLKH = 4;

    /* Release from Reset */
    I2C_ICMDR |= ICMDR_IRS;
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_close( )                                                           *
 *      Close I2C module                                                    *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_I2C_close( )
{
    /* Reset I2C */
    I2C_ICMDR = 0;
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_reset( )                                                           *
 *      Reset I2C module.                                                   *
 *                                                                          *
 *      Used in order to bring SDA & SCL to HIGH.  This can be used after   *
 *      issuing a command to an I2C device, but sends back no response to   *
 *      the host.                                                           *
 *                                                                          *
 * ------------------------------------------------------------------------ */
static Int16 _I2C_reset( )
{
    /* Reset I2C */
	DAVINCIHD_I2C_init( );
    return -1;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_tx_ready( timeout )                                                *
 *      Wait for TX ready, if not then return timeout.                      *
 *                                                                          *
 *      Returns:                                                            *
 *              0 -> I2C TX Ready                                           *
 *             -1 -> I2C Timeout                                            *
 *                                                                          *
 * ------------------------------------------------------------------------ */
static Int16 _I2C_tx_ready( Int32 timeout )
{
    while ( ! ( I2C_ICSTR & ICSTR_ICXRDY ) )// Wait while not Ready
        if ( timeout-- <= 0  )
            return _I2C_reset( );           // Reset I2C

    return 0;                               // TX Ready
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_write( address, tx, len )                                          *
 *      Write to I2C device                                                 *
 *                                                                          *
 *      Inputs:                                                             *
 *              address     <- device address                               *
 *              tx          <- data                                         *
 *              len         <- #bytes to write                              *
 *                                                                          *
 *      Returns:                                                            *
 *              0 -> Pass                                                   *
 *             +1 -> Fail                                                   *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_I2C_write( Uint16 address, Uint8* tx, Uint16 len )
{
    Int16 i;
    Uint8* tx8 = tx;

    I2C_ICCNT = len;                        // Set length
    I2C_ICSAR = address;                    // Set I2C slave address
    I2C_ICMDR = ICMDR_STT                   // Set DSP for Master Write
              | ICMDR_TRX                   // START
              | ICMDR_MST
              | ICMDR_IRS
              | ICMDR_FREE;

    _wait( 10 );

    for ( i = 1 ; i <= len ; i++ )          // Write from 1 byte onward
    {
        I2C_ICDXR = *tx8++;                 // Write 1 byte
        if ( _I2C_tx_ready( i2c_timeout ) ) // Wait for TX Ready
            return i;
    }

    I2C_ICMDR |= ICMDR_STP;                 // STOP
    return 0;
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_rx_ready( timeout )                                                *
 *      Wait for RX ready, if not then return timeout.                      *
 *                                                                          *
 *      Returns:                                                            *
 *              0 -> I2C Rx Ready                                           *
 *             -1 -> I2C Timeout                                            *
 *                                                                          *
 * ------------------------------------------------------------------------ */
static Int16 _I2C_rx_ready( Int32 timeout )
{
    while ( ! ( I2C_ICSTR & ICSTR_ICRRDY ) )// Wait while not Ready
        if ( timeout-- < 0 )
            return _I2C_reset( );           // Reset I2C

    return 0;                               // RX Ready
}

/* ------------------------------------------------------------------------ *
 *                                                                          *
 *  _I2C_read( address, rx, len )                                           *
 *      Read from I2C device                                                *
 *                                                                          *
 *      Inputs:                                                             *
 *              address     <- device address                               *
 *              rx          <- data                                         *
 *              len         <- #bytes to read                               *
 *                                                                          *
 *      Returns:                                                            *
 *              0 -> Pass                                                   *
 *             +1 -> Fail                                                   *
 *                                                                          *
 * ------------------------------------------------------------------------ */
Int16 DAVINCIHD_I2C_read( Uint16 address, Uint8* rx, Uint16 len )
{
    Int16 i;
    Uint8* rx8 = rx;

    I2C_ICCNT = len;                        // Set length
    I2C_ICSAR = address;                    // Set I2C address
    I2C_ICMDR = ICMDR_STT                   // Set for Master Read
              | ICMDR_MST                   // START
              | ICMDR_IRS
              | ICMDR_FREE;

    _wait( 10 );

    for ( i = 1 ; i <= len ; i++ )          // Read from 1 byte onward
    {
        if ( _I2C_rx_ready( i2c_timeout ) ) // Wait for Rx Ready
            return i;

        *rx8++ = I2C_ICDRR;                 // Read 1 byte
    }

    I2C_ICMDR |= ICMDR_STP;                 // STOP
    return 0;
}

⌨️ 快捷键说明

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