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

📄 i2c.c

📁 ADV7181B视频解码设置和控制实验 FreeDev Digital Application Board采用了ADI公司的 ADV7181B视频解码芯片。控制接口使用I2C
💻 C
字号:
/***************************************************
模块说明      :I2C控制接口模块
芯片类型      :Nios II
作    者      :柳军胜
公    司      :杭州自由电子科技
            :http://www.freefpga.com
电   话       :0571-85084089
修    改      :
日期时间      :20060522
说    明      :本程序模块仅提供I2C接口设备底层读写流程,不涉及
             具体应用芯片控制逻辑。
****************************************************/
#include <stdio.h>
#include <io.h>
#include <system.h>
#include <i2c_master.h>

static void *gBaseAddr=NULL;

/*********************************************
函数名:init_i2c
功  能:初始化I2C控制器、应用环境参数初始化设置
输  入:外设地址
返  回: 
备  注:
      应用I2C函数前必须先调用此函数设置I2C外设基地址
      预分频允许100K~400K
**********************************************/
int init_i2c(void *baseAddr)
{
  unsigned char uc,rdata;
  
  if(gBaseAddr==NULL)
    gBaseAddr=baseAddr;
    
  //setup prer
  IOWR(gBaseAddr , OC_I2C_PRER_LO ,0x63 );
  IOWR(gBaseAddr,  OC_I2C_PRER_HI, 0x00);
  
  //setup ctr
  IOWR(gBaseAddr , OC_I2C_CTR ,0x80 );
  
  //read_status
  //uc=IORD(gBaseAddr,OC_I2C_SR);
  
  //send stop
  IOWR(gBaseAddr,OC_I2C_TXR,0x55);
  IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR|OC_I2C_STO);
  
  return 0;
}

/*********************************************
函数名:wait_nTip_ACK
功  能:等待传输结束和应答
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断状态寄存器标志位完成功能
**********************************************/
//wait transmit over and wait ACK
int wait_nTip_ACK()
{
    unsigned char uc;
    int i;
    
    if(gBaseAddr==NULL)
      return -1;
      
    i=0;
    while(1){
      //read_status TIP
      uc=IORD(gBaseAddr,OC_I2C_SR);
      if(OC_ISCLEAR(uc,OC_I2C_TIP))break;
      i++;
      if(i>10000)return -2;
    }
    
    i=0;
     while(1){
      //read_status ACK
      uc=IORD(gBaseAddr,OC_I2C_SR);
      if(OC_ISCLEAR(uc,OC_I2C_RXACK))break;
      i++;
      if(i>10000)
      {
        //I2C器件没有应答时加入STOP发送 20060523
        IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STO); 
        return -3;
      }
    } 
    return 0;
}

/*********************************************
函数名:wait_nTip
功  能:等待传输结束
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断状态寄存器标志位完成功能
**********************************************/
//wait transmit over 
int wait_nTip()
{
    unsigned char uc;
    int i;
    
    if(gBaseAddr==NULL)
      return -1;
      
    i=0;
     while(1){
      //read_status TIP
      uc=IORD(gBaseAddr,OC_I2C_SR);
      if(OC_ISCLEAR(uc,OC_I2C_TIP))break;
      i++;
      if(i>10000)return -1;
    }
    return 0;
}

/*********************************************
函数名:wait_idle
功  能:等待空闲
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断状态寄存器标志位完成功能
**********************************************/
//wait i2c idle 
int wait_idle()
{
    unsigned char uc;
    int i;
    
    if(gBaseAddr==NULL)
      return -1;
      
    i=0;
     while(1){
      //read_status TIP
      uc=IORD(gBaseAddr,OC_I2C_SR);
      if(OC_ISCLEAR(uc,OC_I2C_BUSY))break;
      i++;
      if(i>10000)return -1;
    }
    return 0;
}

/*********************************************
函数名:start_write_waitack()
功  能:I2C启动、写数据、等待ACK
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断I2C状态寄存器标志位完成功能
**********************************************/
int start_write_waitack(unsigned char data)
{
    int iRet;
    
    if(wait_idle()<0){
      printf("i2c control is busy\n");
      return -1;
    }
    
    IOWR(gBaseAddr,OC_I2C_TXR,data);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
    iRet=wait_nTip_ACK();
    if(iRet<0){
      printf("1wait _nTip_ACK timeover\n");
      return -2;
    }
    
    return 0;
}

/*********************************************
函数名:start_read_waitack()
功  能:I2C启动、写数据、等待ACK
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断I2C状态寄存器标志位完成功能
**********************************************/
int start_read_waitack(unsigned char data)
{
    int iRet;
    
    /* restart时状态不是 IDLE 所以不需要等待idle */
    /*
      if(wait_idle()<0){
      printf("i2c control is busy\n");
      return -1;
    }
    */
    
    /* 这里写的数据里面 R/W位为1,但是控制标志置OC_I2C_WR控制输出从机地址 */
    IOWR(gBaseAddr,OC_I2C_TXR,data);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
    iRet=wait_nTip_ACK();
    if(iRet<0){
      printf("1wait _nTip_ACK timeover\n");
      return -2;
    }
    
    return 0;
}

/*********************************************
函数名:write_waitack()
功  能:写数据、等待ACK
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断I2C状态寄存器标志位完成功能
**********************************************/
int write_waitack(unsigned char data)
{
    int iRet;
    
    IOWR(gBaseAddr,OC_I2C_TXR,data);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR);
    iRet=wait_nTip_ACK();
    if(iRet<0){
      printf("1wait _nTip_ACK timeover\n");
      return -2;
    }
    
    return 0;
}

/*********************************************
函数名:write_waitack_stop()
功  能:写数据、等待ACK、发送STOP
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断I2C状态寄存器标志位完成功能
**********************************************/
int write_waitack_stop(unsigned char data)
{
    int iRet;
  
    IOWR(gBaseAddr,OC_I2C_TXR,data);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR|OC_I2C_STO);
    iRet=wait_nTip_ACK();
    if(iRet<0){
      printf("1wait _nTip_ACK timeover\n");
      return -2;
    }
    
    return 0;
}

/*********************************************
函数名:read_sendack()
功  能:读数据、发送ACK
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断I2C状态寄存器标志位完成功能
**********************************************/
int read_sendack(unsigned char *data)
{
    int iRet;
  
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_RD|OC_I2C_ACK); 
    iRet=wait_nTip();
    if(iRet<0)
      return -1;
    
    *data=IORD(gBaseAddr,OC_I2C_RXR);
    return 0; 
}

/*********************************************
函数名:read_sendack_stop()
功  能:读数据、发送ACK、STOP
输  入:外设地址
返  回: 0 成功 <0失败
备  注:
      判断I2C状态寄存器标志位完成功能
**********************************************/
int read_sendack_stop(unsigned char *data)
{
    int iRet;
  
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_RD|OC_I2C_ACK|OC_I2C_STO); 
    iRet=wait_nTip();
    if(iRet<0)
      return -1;
    
    *data=IORD(gBaseAddr,OC_I2C_RXR);
    return 0; 
}



/*********************************************
函数名:read_I2c_EEprom
功  能:读EEPROM
输  入:外设地址,设备地址,字节地址
返  回: 读取的数据
备  注:
**********************************************/
unsigned char read_I2C_EEprom(unsigned char slaveAddr,unsigned char addr)
{
    unsigned char rdata;
      
    //write chip addr and write bit
    IOWR(gBaseAddr,OC_I2C_TXR,slaveAddr);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
    wait_nTip_ACK();
    
    //write eeprom addr 
    IOWR(gBaseAddr,OC_I2C_TXR,addr);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR);
    wait_nTip_ACK();
    
    //write chip addr and read bit
    IOWR(gBaseAddr,OC_I2C_TXR,slaveAddr|0x01);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
    wait_nTip_ACK();
    
    //read eeprom data
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_RD|OC_I2C_STO|OC_I2C_ACK); 
    wait_nTip();
    
    rdata=IORD(gBaseAddr,OC_I2C_RXR);    
    return rdata;
  }

/*********************************************
函数名:write_I2c_EEprom
功  能:写EEPROM
输  入:外设地址,设备地址,字节地址
返  回: 
备  注:
**********************************************/
unsigned char write_I2C_EEprom(unsigned char slaveAddr,unsigned char addr,unsigned char data)
{
    unsigned char rdata;
    unsigned char rc;
    
    if(wait_idle()<0){
      printf("i2c control is busy\n");
      return 0;
    }
    
    //write chip addr and write bit
    IOWR(gBaseAddr,OC_I2C_TXR,slaveAddr);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_STA|OC_I2C_WR);
    printf("w1\n");
    rc=wait_nTip_ACK();
    
    //write eeprom addr 
    IOWR(gBaseAddr,OC_I2C_TXR,addr);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR);
    printf("w2\n");
    rc=wait_nTip_ACK();
    
    //write data 
    IOWR(gBaseAddr,OC_I2C_TXR,data);
    IOWR(gBaseAddr,OC_I2C_CR, OC_I2C_WR|OC_I2C_STO);
    printf("w3\n");
    rc=wait_nTip_ACK();
       
    return data;
  }

⌨️ 快捷键说明

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