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

📄 i2c.c

📁 视频601芯片的驱动源码,你可以完全掌控该芯片了,对于其它多媒体芯片的设计具有参考价值
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
        *ptr++ =I2CReadData();      // Fetch data  byte by byte
        rtnvar |=I2CReadAck();          /* ack all but last byte*/
    }
    *ptr++ = I2CReadData();         // Fetch last byte 
                                        /* and DON't Ack it */

    I2CStop();


    return rtnvar;

}



DLLEXPORT int I2CWriteData(byte data)
/******************************************************************
Processing:     Send a data byte out.  

Inputs:         data is the byte to send

Outputs:        return success or failure.  
Side-effects    None.
*******************************************************************/
{

    int     i;
    unsigned int    mask = 0x80;
    int     rtnvar;


    // Send out LSB first
    for (i = 0; i < 8; i++)
    {
        rtnvar = I2CBitWrite((byte )(data & mask) );
        if (rtnvar)
            break;
        mask >>=1;
    }
    rtnvar |= I2CWriteAck();
    return rtnvar;
}


DLLEXPORT byte I2CReadData(void)
/******************************************************************
Processing:     read a data byte in.  

Inputs:         data is the byte to send

Outputs:        return DATA BYTE READ.  
Side-effects    None.
*******************************************************************/
{
    int     i;
    int     newbyte ;

    // Disable SDA OUT (just in case !)
    clr_mcsrbit(SDA_OE);

    // Receive MSB first
    newbyte = I2CBitRead();             /* get 1st bit */
    for (i = 0; i < 7; i++)
    {
        newbyte <<= 1;                  /* shift 7 times */
        newbyte |= I2CBitRead();        /* don't shift last bit in */
    }

    return newbyte ;
}




DLLEXPORT int I2CStart()
/******************************************************************
Processing:     Start of message.

Inputs:         

Outputs:        return success or clockstuck.  
Side-effects    None.
*******************************************************************/
{
    int clockstuck;


    clocklow();
    set_mcsrbit(SDA | SDA_OE);          /* Drive Data Line hi */
    Delay (2);
    clockstuck = clockhigh();           // Set SCL  high
    Delay (2);
    clr_mcsrbit(SDA);                   /* take SDA low while clk hi */
    // Delay 4 clock
    Delay(4);
    clocklow();
    Delay(4);


    return clockstuck;
}


DLLEXPORT int I2CStop()
/******************************************************************
Processing:     End of message processing

Inputs:

Outputs:        return success or clock stuck.  
Side-effects    None.
*******************************************************************/
{
    int clockstuck;

    clocklow();
    clr_mcsrbit (SDA);
    set_mcsrbit(SDA_OE);                /* drive SDA low */

    Delay(2);
    clockstuck = clockhigh();           // Set SCL high
    Delay(4);
    set_mcsrbit(SDA);                   /* raise SDA while clock is hi */

    Delay(2);
    clr_mcsrbit(SDA_OE);                /* Tristate the data line */

    return clockstuck;
}


DLLEXPORT int I2CWriteAck()
/******************************************************************
Processing:     Look for Ack

Inputs:         

Outputs:        return success or BAD_ACK or CLOCK STUCK
Side-effects    None.
*******************************************************************/
{
    int rtnvar;
    int i;
    int clockstuck;
    int databit;
    

    clocklow();
    clr_mcsrbit(SDA_OE);
    Delay(4);
    clockstuck = clockhigh();
    if (! clockstuck)
    {
        rtnvar = I2C_BAD_ACK;           /* assume failure */
        for (i =0; i < 10; i++)
        {    
            Delay(1);
            databit = *ptr2pal;         /* read acknowledge bit from slave */
            databit &= SDA;             /* mask off all but SDA bit     */
            if (databit == 0)
            {
                rtnvar = SUCCESS;
                break;
            }
        }
    }
    else
        rtnvar = clockstuck;
    clocklow();
    return rtnvar;
}


DLLEXPORT int I2CReadAck()
/******************************************************************
Processing:     Give the chip an ack.  

Inputs:         

Outputs:        return success or clock stuck.  
Side-effects    None.
*******************************************************************/
{
    int clockstuck;


    clocklow();
    clr_mcsrbit(SDA);
    set_mcsrbit(SDA_OE);            /* Drive SDA low  */
    // Delay 2 clock cycle
    Delay(4);
    clockstuck = clockhigh();
    // Delay 2 clock cycle
    Delay(2);
    clocklow();
    clr_mcsrbit(SDA_OE);              /* Release Data Line */
    return clockstuck;
}

DLLEXPORT int I2CBitWrite(byte bit)
/******************************************************************
Processing:     Write single bit from I2cbus slave.  Assert the
                data bit on the data line, wait half period, assert
                the clock, wait half period and remove clock.
                Allow slave to request a delay by holding SCLock low.
                SCLock has a pullup resistor and will go high if we
                stop driving it AND the slave stops pulling it 
                down.  
Inputs:         bit to write.  Not zero writes a 1, 0 writes a 0.
Outputs:        As declared.
Side-effects    None.
*******************************************************************/

{
    int clockstuck;

//    clocklow();

    if (bit)                            // Set data bit before clock it out
        set_mcsrbit(SDA);
    else
        clr_mcsrbit(SDA);
    set_mcsrbit(SDA_OE);                /* Drive SDA line   */
    clockstuck = clockhigh();
    clocklow();                         // Set SCL low
    return clockstuck;
}

DLLEXPORT byte I2CBitRead()
/******************************************************************
Processing:     Read single bit from I2cbus slave.  Allow slave to 
                request a delay by holding SCLock low. SCLock
                has a pullup resistor and will go high if we
                stop driving it AND the slave stops pulling it 
                down.  We MUST NOT drive SDAata line, to allow the
                slave to talk to us.
Inputs:         As declared.
Outputs:        return 1 or 0 from I2Cbus slave
Side-effects    None.
*******************************************************************/

{
    byte bit;
    int clockstuck;


    clr_mcsrbit(SDA_OE);
    clocklow();

    clockstuck = clockhigh();
    if (! clockstuck)
        bit = (*ptr2pal & SDA) ? 1 : 0; /* Read data bit */
    else
        bit = (byte) clockstuck;
    clocklow();
    return bit;
}

#define DRIVE_HI    TRUE

int clockhigh ()
/******************************************************************
Processing:     Put the clock line high by tri stating it.
                If it stays low someone else is driving it, or
                it is stuck.

Inputs:         

Outputs:        return success or I2C_STUCK_CLK.  
Side-effects    None.
*******************************************************************/
{
    int i;                              /* loop counter */

    halfperiod ();                      /* wait 1/2 clock period */
#if DRIVE_HI
    set_mcsrbit (SCL);                  /* Drive SCLock line high   */
#else
    clr_mcsrbit (SCL_OE);               /* let SCLock line float high   */
#endif
    for (i = 0; i < 10; i++)            /* Give slave 5 clocks to get rdy*/
    {
        halfperiod();                   /* wait 1/2 clk period */
        if (*ptr2pal & SCL)
            return SUCCESS;             /* OK, slave is ready */
                                        /* else, wait for slave to*/
                                        /* let go of SCLock     */
    }
    return I2C_STUCK_CLK;               /* Clock Line stuck down */
}                                       /* end function */
void    clocklow()
/******************************************************************
Processing:     Make clock go low by driving it

Inputs:         data is the byte to send

Outputs:        return success or failure.  
Side-effects    None.
*******************************************************************/
{
    halfperiod ();                      /* wait 1/2 clock period */
    clr_mcsrbit(SCL);                   /* make clock bit low */
    set_mcsrbit(SCL_OE);                /* and drive clock line */

}

static  word   mcsr_image = 0;          /* the PAL bits are write only
                                        so we keep a copy of the last
                                        thing we wrote to the PAL*/

DLLEXPORT word set_mcsrbit (word bits2set)
/******************************************************************
Processing:     Set bits in the Main Control & Status register (PAL)

Inputs:         

Outputs:        return last thing written in case caller wants
                to know what's in the mcsr.
Side-effects    None.
*******************************************************************/
{

    mcsr_image |= bits2set;
    *ptr2pal = mcsr_image;
    return mcsr_image;
}

DLLEXPORT word clr_mcsrbit (word bits2clr)
/******************************************************************
Processing:     Inverse of set_mcsrbit();

Inputs:         

Outputs:        return last thing written.  
Side-effects    None.
*******************************************************************/
{

    mcsr_image &= ~bits2clr;

    *ptr2pal =  mcsr_image;
    return mcsr_image;
}

⌨️ 快捷键说明

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