首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

gpio模拟i2c 读取24c02寄存器的值替0xff

2012-09-13 
gpio模拟i2c 读取24c02寄存器的值为0xff?我把24c02的A0,A1,A2悬空,把wp接地,用的是hi3515板子,下面是我的

gpio模拟i2c 读取24c02寄存器的值为0xff?
我把24c02的A0,A1,A2悬空,把wp接地,用的是hi3515板子,下面是我的代码:
  
#include <linux/module.h>  
#include <linux/config.h>  
#include <linux/errno.h>  
#include <linux/miscdevice.h>  
#include <linux/fcntl.h>  
  
#include <linux/init.h>  
#include <linux/delay.h>  
#include <linux/proc_fs.h>  
#include <linux/workqueue.h>  
  
#include <asm/uaccess.h>  
#include <asm/system.h>  
#include <asm/io.h>  
  
#include "gpio_i2c.h"  
  
  
/* GPIO0_0 */  
#define SCL (1 << 6) /* 6 indicated 6th bit*/  
  
/* GPIO0_1 */  
#define SDA (1 << 7)  
  
  
#define GPIO_I2C_BASE 0x20180000  
  
#define GPIO_I2C_DIR IO_ADDRESS(GPIO_I2C_BASE + 0x400)  
  
#define GPIO_I2C_SDA_REG IO_ADDRESS(GPIO_I2C_BASE + (SDA<<2)) /* data reg */  
#define GPIO_I2C_SCL_REG IO_ADDRESS(GPIO_I2C_BASE + (SCL<<2))  
  
#define GPIO_I2C_SCLSDA_REG IO_ADDRESS(GPIO_I2C_BASE + 0x300)  
  
#define HW_REG(reg) *((volatile unsigned int *)(reg))  
#define DELAY(us) time_delay_us(us)  
  
  

static void i2c_clr(unsigned char whichline)  
{  
  unsigned char regvalue;  
   
  if(whichline == SCL)  
  {  
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue |= SCL;  
  HW_REG(GPIO_I2C_DIR) = regvalue; /* set scl dir output */  
   
  HW_REG(GPIO_I2C_SCL_REG) = 0; /* set scl data 0 */  
  return;  
  }  
  else if(whichline == SDA)  
  {  
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue |= SDA;  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
   
  HW_REG(GPIO_I2C_SDA_REG) = 0;  
  return;  
  }  
  else if(whichline == (SDA|SCL))  
  {  
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue |= (SDA|SCL);  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
   
  HW_REG(GPIO_I2C_SCLSDA_REG) = 0;  
  return;  
  }  
  else  
  {  
  printk("Error input.\n");  
  return;  
  }  
   
}  
  

static void i2c_set(unsigned char whichline)  
{  
  unsigned char regvalue;  
   
  if(whichline == SCL)  
  {  
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue |= SCL;  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
   
  HW_REG(GPIO_I2C_SCL_REG) = SCL;  
  return;  
  }  
  else if(whichline == SDA)  
  {  
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue |= SDA;  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
   
  HW_REG(GPIO_I2C_SDA_REG) = SDA;  


  return;  
  }  
  else if(whichline == (SDA|SCL))  
  {  
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue |= (SDA|SCL);  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
   
  HW_REG(GPIO_I2C_SCLSDA_REG) = (SDA|SCL);  
  return;  
  }  
  else  
  {  
  printk("Error input.\n");  
  return;  
  }  
}  
  
void time_delay_us(unsigned int usec)  
{  
  int i,j;  
   
  for(i=0;i<usec * 5;i++)  
  {  
  for(j=0;j<47;j++)  
  {;}  
  }  
}  
  
   
static unsigned char i2c_data_read(void)  
{  
  unsigned char regvalue;  
   
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue &= (~SDA);  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
  DELAY(1);  
   
  regvalue = HW_REG(GPIO_I2C_SDA_REG);  
  if((regvalue & SDA) != 0)  
  return 1;  
  else  
  return 0;  
}  
  
  
static void i2c_start_bit(void)  
{  
  DELAY(1);  
  i2c_set(SDA | SCL);  
  DELAY(1);  
  i2c_clr(SDA);  
  DELAY(2);  
}  
  

static void i2c_stop_bit(void)  
{  
  /* clock the ack */  
  DELAY(1);  
  i2c_set(SCL);  
  DELAY(1);  
  i2c_clr(SCL);  
  
  /* actual stop bit */  
  DELAY(1);  
  i2c_clr(SDA);  
  DELAY(1);  
  i2c_set(SCL);  
  DELAY(1);  
  i2c_set(SDA);  
  DELAY(1);  
}  
  

static void i2c_send_byte(unsigned char c)  
{  
  int i;  
  local_irq_disable();  
  for (i=0; i<8; i++)  
  {  
  DELAY(1);  
  i2c_clr(SCL);  
  DELAY(1);  
  
  if (c & (1<<(7-i)))  
  i2c_set(SDA);  
  else  
  i2c_clr(SDA);  
  
  DELAY(1);  
  i2c_set(SCL);  
  DELAY(1);  
  i2c_clr(SCL);  
  }  
  DELAY(1);  
  local_irq_enable();  
}  
  

static unsigned char i2c_receive_byte(void)  
{  
  int j=0;  
  int i;  
  unsigned char regvalue;  
  
  local_irq_disable();  
  for (i=0; i<8; i++)  
  {  
  DELAY(1);  
  i2c_clr(SCL);  
  DELAY(2);  
  i2c_set(SCL);  
   
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue &= (~SDA);  
  HW_REG(GPIO_I2C_DIR) = regvalue;  


  DELAY(1);  
   
  if (i2c_data_read())  
  j+=(1<<(7-i));  
  
  DELAY(1);  
  i2c_clr(SCL);  
  }  
  local_irq_enable();  
  DELAY(1);  
  
  return j;  
}  
 
static int i2c_receive_ack(void)  
{  
  int nack;  
  unsigned char regvalue;  
   
  DELAY(1);  
   
  regvalue = HW_REG(GPIO_I2C_DIR);  
  regvalue &= (~SDA);  
  HW_REG(GPIO_I2C_DIR) = regvalue;  
   
  DELAY(1);  
  i2c_clr(SCL);  
  DELAY(1);  
  i2c_set(SCL);  
  DELAY(1);  
   
  
  nack = i2c_data_read();  
  
  DELAY(1);  
  i2c_clr(SCL);  
  DELAY(1);  
  
  if (nack == 0)  
  return 1;  
  
  return 0;  
}  
  
  
  

static void i2c_send_ack(void)  
{  
  DELAY(1);  
  i2c_clr(SCL);  
  DELAY(1);  
  i2c_set(SDA);  
  DELAY(1);  
  i2c_set(SCL);  
  DELAY(1);  
  i2c_clr(SCL);  
  DELAY(1);  
  i2c_clr(SDA);  
  DELAY(1);  
}  
  

  
unsigned char gpio_i2c_read(unsigned char devaddress, unsigned char address)  
{  
  int rxdata;  
   
  i2c_start_bit();  
  i2c_send_byte((unsigned char)(devaddress));  
  i2c_receive_ack();  
  i2c_send_byte(address);  
  i2c_receive_ack();  
  i2c_start_bit();  
  i2c_send_byte((unsigned char)(devaddress) | 1);  
  i2c_receive_ack();  
  rxdata = i2c_receive_byte();  
  i2c_send_ack();  
  i2c_stop_bit();  
  
  return rxdata;  
}  
  

  
void gpio_i2c_write(unsigned char devaddress, unsigned char address, unsigned char data)  
{  
  i2c_start_bit();  
  i2c_send_byte((unsigned char)(devaddress));  
  i2c_receive_ack();  
  i2c_send_byte(address);  
  i2c_receive_ack();  
  i2c_send_byte(data);  
  i2c_stop_bit();  
}  
  
   
unsigned char gpio_sccb_read(unsigned char devaddress, unsigned char address)  
{  
  int rxdata;  
  
  i2c_start_bit();  
  i2c_send_byte((unsigned char)(devaddress));  
  i2c_receive_ack();  
  i2c_send_byte(address);  
  i2c_receive_ack();  
  i2c_stop_bit();  
  i2c_start_bit();  
  i2c_send_byte((unsigned char)(devaddress) | 1);  
  i2c_receive_ack();  
  rxdata = i2c_receive_byte();  
  i2c_send_ack();  
  i2c_stop_bit();  
  
  return rxdata;  
}  
  
static unsigned int gpioinitialized =0;  



static int __init gpio_i2c_init(void)  
{  
  if(gpioinitialized == 0)  
  {  
  printk(KERN_INFO "Hisilicon GPIO control for I2C Driver \n");  
  i2c_clr(SCL | SDA);  
  gpioinitialized =1;  
   
  return 0;  
  }  
  else  
  {  
  printk("GPIO control for I2C has been initialized.\n");  
  return 0;  
  }  
}  
  
static void __exit gpio_i2c_exit(void)  
{  
  gpioinitialized =0;  
}  
  
module_init(gpio_i2c_init);  
module_exit(gpio_i2c_exit);  
  
#ifdef MODULE  
#include <linux/compile.h>  
#endif  
MODULE_INFO(build, UTS_VERSION);  
MODULE_LICENSE("GPL");  
  
EXPORT_SYMBOL(gpio_i2c_read);  
EXPORT_SYMBOL(gpio_i2c_write);  

 
运行./i2c_write(0xa0,0x10,0x22)

./i2c_read(0xa0,0x10)

结果为0xff
求高人指点。。。

[解决办法]
帮你顶》。。。。

热点排行