网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> DSP >> 代码示例 >> TI DSP代码示例 >> DaVinci >> 文章正文
  DM642 I2C通用读写源代码         ★★★ 【字体:
DM642 I2C通用读写源代码
作者:Free    文章来源:本站原创    点击数:    更新时间:2007-11-19    
参考了各家的I2C源代码,均发现有不足之处,经过一周时间的学习,搞了个通用的I2C读写代码,抛砖引玉一下。

#include <csl_i2c.h>
#include <stdio.h>


I2C_Handle        g_I2C_Handle;                // I2C 全局句柄

Bool I2C_Initialize(void)
{
        g_I2C_Handle = I2C_open(I2C_PORT0,I2C_OPEN_RESET);

        if(g_I2C_Handle == INV)
        {
                return FALSE;
        }
        else
        {
                I2C_outOfReset(g_I2C_Handle);                                // 允许I2C总线

                I2C_RSETH(g_I2C_Handle, I2CPSC, 0x0E);                // I2C模块时钟设置为10M 150M/15
                //I2C_RSETH(g_I2C_Handle, I2CCLKL, 0x2D);        // 设置I2C外部时钟为100K
                //I2C_RSETH(g_I2C_Handle, I2CCLKH, 0x2D);        // 设置I2C外部时钟为100K
                //I2C_RSETH(g_I2C_Handle, I2CCLKL, 0x500);                // 设置I2C外部时钟为100K
                //I2C_RSETH(g_I2C_Handle, I2CCLKH, 0x500);                // 设置I2C外部时钟为100K
                I2C_RSETH(g_I2C_Handle, I2CCLKL, 0x300);                // 设置I2C外部时钟为100K
                I2C_RSETH(g_I2C_Handle, I2CCLKH, 0x300);                // 设置I2C外部时钟为100K

                return TRUE;
        }
}

Uint8 I2C_Write(Uint8 dev_addr, Uint8 *sub_addr, Uint8 sub_addr_len, Uint8 *write_buffer, Uint8 write_len)
{
        Uint8 bResult = 0;
        Uint32 I2CState;

    I2C_Config prevI2CCfg;

        if(write_len == 0)
        {
                return 0;
        }
   
    while (I2C_bb(g_I2C_Handle));

    I2C_getConfig(g_I2C_Handle, &prevI2CCfg);

        // clear all interrupt state
        I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, ARDY, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, ICRRDY, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, ICXRDY, 1);

   
        I2C_RSETH(g_I2C_Handle, I2COAR, 0);
        I2C_RSETH(g_I2C_Handle, I2CIER, 0);
        I2C_RSETH(g_I2C_Handle, I2CCNT, 0);
        I2C_RSETH(g_I2C_Handle, I2CSAR, dev_addr);

        I2C_RSETH(g_I2C_Handle, I2CMDR, 0x26A0);

        // wait send start condition
        while(I2C_FGETH(g_I2C_Handle, I2CMDR, STT));

        while(1)
        {
                I2CState = I2C_RGETH(g_I2C_Handle, I2CSTR);

                if(I2CState & 0x01)
                {
                        // Arbitration lost
                        // clear AL state in I2C Status Register
                        I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1);
                        break;
                }

                if(I2CState & 0x04)
                {        // ARDY == 1
                        if(I2CState & 0x02)
                        {        // NACK == 1
                                // clear NACK state in I2C Status Register
                                I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1);
                                break;
                        }
                        else
                        {
                                if(I2CState & 0x10)
                                {        // ICXRDY == 1
                                        if(bResult < sub_addr_len)
                                        {
                                                I2C_RSETH(g_I2C_Handle, I2CDXR, sub_addr[bResult]);
                                                bResult ++;
                                        }
                                        else if(bResult < sub_addr_len + write_len)
                                        {
                                                I2C_RSETH(g_I2C_Handle, I2CDXR, write_buffer[bResult - sub_addr_len]);
                                                bResult ++;
                                        }
                                        else
                                        {
                                                break;
                                        }
                                }
                        }
                }
        }

    I2C_sendStop(g_I2C_Handle); 
        //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP);

    while (I2C_bb(g_I2C_Handle));
           
    I2C_config(g_I2C_Handle, &prevI2CCfg);             
        return (bResult < sub_addr_len) ? 0 : (bResult - sub_addr_len);
}

Uint8 I2C_Read(Uint8 dev_addr, Uint8 *sub_addr, Uint8 sub_addr_len, Uint8 *read_buffer, Uint8 read_len)
{
        Uint8 bResult = 0;
        Uint32 I2CState;

    I2C_Config prevI2CCfg;

        if(read_len == 0)
        {
                return 0;
        }
   
    while (I2C_bb(g_I2C_Handle));
   
    I2C_getConfig(g_I2C_Handle, &prevI2CCfg);

        // clear all interrupt state
        I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, ARDY, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, ICRRDY, 1);
        I2C_FSETH(g_I2C_Handle, I2CSTR, ICXRDY, 1);

        // 写子地址
        if(sub_addr_len)
        {
                I2C_RSETH(g_I2C_Handle, I2COAR, 0);
                I2C_RSETH(g_I2C_Handle, I2CIER, 0);
                I2C_RSETH(g_I2C_Handle, I2CCNT, 0);
                I2C_RSETH(g_I2C_Handle, I2CSAR, dev_addr);

                I2C_RSETH(g_I2C_Handle, I2CMDR, 0x26A0);

                // wait send start condition
                while(I2C_FGETH(g_I2C_Handle, I2CMDR, STT));

                while(1)
                {
                        I2CState = I2C_RGETH(g_I2C_Handle, I2CSTR);

                        if(I2CState & 0x01)
                        {        // Arbitration lost
                                I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1);

                                I2C_sendStop(g_I2C_Handle); 
                                //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP);

                                while (I2C_bb(g_I2C_Handle));
                                           
                                I2C_config(g_I2C_Handle, &prevI2CCfg);             
                                return 0;
                        }

                        if(I2CState & 0x04)
                        {        // ARDY == 1
                                if(I2CState & 0x02)
                                {        // NACK == 1
                                        I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1);

                                    I2C_sendStop(g_I2C_Handle); 
                                        //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP);

                                    while (I2C_bb(g_I2C_Handle));
                                           
                                    I2C_config(g_I2C_Handle, &prevI2CCfg);             
                                        return 0;
                                }
                                else
                                {
                                        if(I2CState & 0x10)
                                        {        // ICXRDY == 1
                                                if(bResult < sub_addr_len)
                                                {
                                                        I2C_RSETH(g_I2C_Handle, I2CDXR, sub_addr[bResult]);
                                                        bResult ++;
                                                }
                                                else
                                                {
                                                        break;
                                                }
                                        }
                                }
                        }
                }
        }

        // 是否需要等待由发送转换为接收 重复起始条件

        bResult = 0;

        I2C_RSETH(g_I2C_Handle, I2COAR, 0);
        I2C_RSETH(g_I2C_Handle, I2CIER, 0);
        I2C_RSETH(g_I2C_Handle, I2CCNT, 0);
        I2C_RSETH(g_I2C_Handle, I2CSAR, dev_addr);

        I2C_RSETH(g_I2C_Handle, I2CMDR, 0x24A0);

        // wait send start condition
        while(I2C_FGETH(g_I2C_Handle, I2CMDR, STT));

        while(1)
        {
                I2CState = I2C_RGETH(g_I2C_Handle, I2CSTR);

                if(I2CState & 0x01)
                {        // Arbitration lost
                        I2C_FSETH(g_I2C_Handle, I2CSTR, AL, 1);
                        break;
                }

                if(I2CState & 0x04)
                {        // ARDY == 1
                        if(I2CState & 0x02)
                        {        // NACK == 1
                                I2C_FSETH(g_I2C_Handle, I2CSTR, NACK, 1);
                                break;
                        }
                        else if(I2CState & 0x2000)
                        {        // NACKSNT == 1
                                I2C_FSETH(g_I2C_Handle, I2CSTR, NACKSNT, 1);
                                break;
                        }
                        else
                        {
                                if(I2CState & 0x08)
                                {        // ICRRDY == 1
                                        if(bResult < read_len)
                                        {
                                                read_buffer[bResult] = I2C_RGETH(g_I2C_Handle, I2CDRR);
                                                bResult ++;

                                                if(bResult >= read_len)
                                                {        // 如果收完所有字节 则发送NACK
                                                        I2C_FSETSH(g_I2C_Handle,I2CMDR,NACKMOD,NACK);
                                                }
                                        }
                                        else
                                        {
                                                I2C_FSETSH(g_I2C_Handle,I2CMDR,NACKMOD,NACK);
                                                I2C_RGETH(g_I2C_Handle, I2CDRR);
                                        }
                                }
                        }
                }
        }
   
    I2C_sendStop(g_I2C_Handle); 
        //I2C_FSETSH(g_I2C_Handle,I2CMDR,STP,STOP);

    while (I2C_bb(g_I2C_Handle));
           
    I2C_config(g_I2C_Handle, &prevI2CCfg);             
        return bResult;
}
               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    DM642上TCP/IP协议的实现及性…
    基于DM642嵌入式无线视频监控…
    基于AVS-M和DM642视频服务器…
    DM642 Ver2.0多路实时图像处…
    DM642与百兆以太网接口设计
    DM642与1394a的接口设计
    DM642和线阵CCD的接口
    DM642与以太网的接口
    DM642与CMOS图像传感器的接口
    在DM642平台上实现高速USB主…
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号