MTK方案gpio模拟i2c的一个例子

#define RT2860REG(addr) (*(volatile u32 *)(addr))  
  
static void gpio_i2c_set_bit(int id, int onoff)  
{     
    int tmp;  
  
    if(id<=21&&id>=0)  
    {  
        tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODIR));  
        tmp |= (1<<(id));  
        *(volatile u32 *)(RALINK_REG_PIODIR) = tmp;  
  
  
        tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA));  
        tmp = (tmp&~(1<<(id)))|(onoff<<(id));  
        *(volatile u32 *)(RALINK_REG_PIODATA) = tmp;  
    }  
    else if(id>=22&&id<=27)  
    {  


    }  
    else  
    {  
        printk("####HU#### %s id %d invalid \r\n",__FUNCTION__,id);  
    }  
}  
  
static int gpio_i2c_get_bit(int id)  
{     
    int tmp;  
  
    if(id<=21&&id>=0)  
    {  
        tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODIR));  
        tmp &= ~(1<<(id));  
        *(volatile u32 *)(RALINK_REG_PIODIR) = tmp;  
  
  
        tmp = le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA));  
        return (tmp>>id&0x01);  
    }  
    else if(id>=22&&id<=27)  
    {  


    }  
    else  
    {  
        printk("####HU#### %s id %d invalid \r\n",__FUNCTION__,id);  
    }  
}  
  
static void i2c_clk(int onoff)  
{     
    gpio_i2c_set_bit(2,onoff);  
}  
  
static void i2c_dat(int onoff)  
{     
    gpio_i2c_set_bit(1,onoff);  
}  
    
   
static unsigned char i2c_data_read(void)  
{  
    return gpio_i2c_get_bit(1);  
}  
  
  
  
/* 
 * sends a start bit via I2C rountine. 
 * 
 */  
static void i2c_start_bit(void)  
{  
        DELAY(1);  
        i2c_clk(1);  
        i2c_dat(1);  
        DELAY(3);  
        i2c_dat(0);  
        DELAY(1);  
}  
  
/* 
 * sends a stop bit via I2C rountine. 
 * 
 */  
static void i2c_stop_bit(void)  
{  
        
        i2c_clk(0);  
        i2c_dat(0);  
        DELAY(1);  
        i2c_clk(1);  
        DELAY(1);  
        i2c_dat(1);  



/*  
 * sends an acknowledge over I2C rountine. 
 * 
 */  
static void i2c_send_ack(void)  
{  
    i2c_clk(0);  
    i2c_dat(0);  
    DELAY(1);  
      
    i2c_clk(1);  
    DELAY(1);  
      
}  
  
static void i2c_send_nack(void)  
{  
    i2c_clk(0);  
    i2c_dat(1);  
    DELAY(1);  
      
    i2c_clk(1);  
    DELAY(1);  
      
}  


  
/* 
 * sends a character over I2C rountine. 
 * 
 * @param  c: character to send 
 * 
 */  
static void i2c_send_byte(unsigned char c)  
{  
    int i;  
    //local_irq_disable();  
    //i2c_clk(1);  
    for (i=0; i<8; i++)  
    {  
        i2c_clk(0);  
        if (c & (1<<(7-i)))  
            i2c_dat(1);  
        else  
            i2c_dat(0);  
          
        DELAY(1);  
          
        i2c_clk(1);  
        DELAY(1);  
    }  
   // i2c_dat(1);  
    //local_irq_enable();  
}  
  
/*  receives a character from I2C rountine. 
 * 
 *  @return value: character received 
 * 
 */  
static unsigned char i2c_receive_byte_ack(void)  
{  
    int j=0;  
    int i;  
    unsigned char regvalue;  
  
    //local_irq_disable();  
  
    //i2c_data_read();  
    for (i=0; i<8; i++)  
    {  
        i2c_clk(0);  
        DELAY(1);  
         
        i2c_clk(1);  
          
        set_gpio_direction(SDA,INP);   
        if (i2c_data_read())  
            j+=(1<<(7-i));  
          
        DELAY(1);  
          
          
    }  


    i2c_clk(0);  
    i2c_dat(0);  
    DELAY(1);  
      
    i2c_clk(1);  
    DELAY(1);  
    
    //local_irq_enable();  
   // i2c_dat(0);  
   // DELAY(1);  
  
    return j; 
}  


static unsigned char i2c_receive_byte_noack(void)  
{  
    int j=0;  
    int i;  
    unsigned char regvalue;  
  
    //local_irq_disable();  
  
    i2c_data_read();  
    for (i=0; i<8; i++)  
    {  
        i2c_clk(0);  
        DELAY(1);  
  
        i2c_clk(1);  
          
        i2c_data_read();  
        if (i2c_data_read())  
            j+=(1<<(7-i));  
          
        DELAY(1);  
          
          
    }  


    i2c_clk(0);  
    i2c_dat(1);  
    DELAY(1);  
      
    i2c_clk(1);  
    DELAY(1);  
    
    //local_irq_enable();  
   // i2c_dat(0);  
   // DELAY(1);  
  
    return j; 



  
/*  receives an acknowledge from I2C rountine. 
 * 
 *  @return value: 0--Ack received; 1--Nack received 
 *           
 */  
static int i2c_receive_ack(void)  
{  
    int nack;  
      
    i2c_data_read();  
    i2c_clk(0);  
    DELAY(1);  
    i2c_clk(1);  
      
    //i2c_data_read();  
    nack = i2c_data_read();  
    DELAY(1);  
  
    i2c_dat(1);  
  
  
    return nack;  
}  
  


  


  
  
  
/*   
 *  read data from the I2C bus by GPIO simulated of a device rountine. 
 * 
 *  @param  devaddress:  address of the device 
 *  @param  address: address of register within device 
 *    
 *  @return value: data from the device readed 
 *  
 */  
int gpio_i2c_read(unsigned char devaddress, unsigned char address,unsigned char *buff, int ByteNo)  
{  
    unsigned long flags;  
    int rxdata=-1;  
    int i;
      
      
    i2c_start_bit();  
    i2c_send_byte((unsigned char)((devaddress<<1)|0));  
    if(i2c_receive_ack()==1)  
    {  
        printk("error in %s,%d !!!",__FILE__,__LINE__);
        goto EXIT;  
    }  
    i2c_send_byte(address); 
    if(i2c_receive_ack()==1)  
    {  
        printk("error in %s,%d !!!",__FILE__,__LINE__);
        goto EXIT;  
    } 
    
    i2c_clk(0); 
    i2c_start_bit();  
    i2c_send_byte((unsigned char)(0xC1));  
    if(i2c_receive_ack())  
    {  
        printk("error in %s,%d !!!",__FILE__,__LINE__);
        goto EXIT;  
    } 
    //rxdata = i2c_receive_byte();  
    for(i=0;i<ByteNo;i++)
    {
        if(i<ByteNo-1)
        {
            buff[i] = i2c_receive_byte_ack();  
        }
        else
        {
            buff[i] = i2c_receive_byte_noack();  
        }
    }
    
    i2c_stop_bit(); 
    rxdata = 0;
  
EXIT:  


    return rxdata;  
}  
EXPORT_SYMBOL(gpio_i2c_read);  
  
  
/* 
 *  writes data to a device on the I2C bus rountine.  
 * 
 *  @param  devaddress:  address of the device 
 *  @param  address: address of register within device 
 *  @param  data:   data for write to device 
 * 
 */  
  
int gpio_i2c_write(unsigned char devaddress, unsigned char address, unsigned char *data, int len)  
{  
    int ret = -1;  
    unsigned long flags;  
    int i;
      
    //spin_lock_irqsave(&i2c_lock,flags);  
    spin_lock(&i2c_lock);  
      
      
    i2c_start_bit();  
    i2c_send_byte((unsigned char)((devaddress<<1)|0));  
    if(i2c_receive_ack()==1)  
    {  
        printk("error in %s,%d !!!",__FILE__,__LINE__);
        goto EXIT;  
    }  
    i2c_send_byte(address);  
    if(i2c_receive_ack()==1)  
    {  
        printk("error in %s,%d !!!",__FILE__,__LINE__);
        goto EXIT;  
    }  
    for(i=0 ; i<len;i++)
    {
        i2c_send_byte(data[i]);
        if(i2c_receive_ack()==1)  
        {  
            printk("error in %s,%d !!!",__FILE__,__LINE__);
            goto EXIT;  
        }
    }
      
    i2c_stop_bit();  
  
    ret=0;  
EXIT:  
    //spin_unlock_irqrestore(&i2c_lock,flags);  
    spin_unlock(&i2c_lock);  
    return ret;  
}  
EXPORT_SYMBOL(gpio_i2c_write); 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值