ARM11 GPIO口模拟I2C驱动AT24C08

简单的测试通信时序

 

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/ctype.h>
#include <linux/pagemap.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>

#include <mach/regs-gpio.h>
#include <mach/gpio.h>
#include <mach/hardware.h>
#include <mach/map.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/signal.h>
#include <asm/uaccess.h>
#include <plat/regs-timer.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-b.h>

#define write_cmd 0xa0
#define read_cmd 0xa1

#define SDA_output  s3c_gpio_cfgpin(S3C64XX_GPB(6),S3C_GPIO_OUTPUT)
#define SDA_input   s3c_gpio_cfgpin(S3C64XX_GPB(6),S3C_GPIO_INPUT)

//#define SDA_output  s3c_gpio_cfgpin(S3C64XX_GPB(6),S3C64XX_GPB_OUTPUT(6))
//#define SDA_input   s3c_gpio_cfgpin(S3C64XX_GPB(6),S3C64XX_GPB_INPUT(6)) 

#define SCLK_output s3c_gpio_cfgpin(S3C64XX_GPB(5),S3C64XX_GPB_OUTPUT(5))

#define DEVICE_NAME "yzh_eeprom"


void SDA_set(unsigned int value)
{
 int temp;
 
 temp = __raw_readl(S3C64XX_GPBDAT);
 temp &= ~(1<<6);
 temp |= (value << 6);
 __raw_writel(temp,S3C64XX_GPBDAT);
}

unsigned int Get_SDA(void)
{
 int tmp;
 
 tmp = __raw_readl(S3C64XX_GPBDAT);
 tmp = tmp & (1 << 6);

 return tmp;
}

void SCLK_set(unsigned int value)
{
 int tp;

 tp = __raw_readl(S3C64XX_GPBDAT);
 tp &= ~(1<<5);
 tp |= (value << 5);
 __raw_writel(tp,S3C64XX_GPBDAT);
}

void AT_eeprom_start(void)
{
 SDA_output;
 SCLK_output;
 
 SDA_set(1);
 SCLK_set(1);
 mdelay(1);

 SDA_set(0);
 mdelay(2);
 SCLK_set(0);
 udelay(10);

void AT_eeprom_stop(void)
{
 SDA_output;
 SCLK_output;
 
 SCLK_set(1);
 SDA_set(0);
 mdelay(1);

 SDA_set(1);
 mdelay(2);
 SCLK_set(0);
 udelay(10);
}

void master_noack(void)
{
 SDA_output;
 SCLK_output;
 
 SDA_set(1);
 mdelay(3);
 SCLK_set(0);
 mdelay(2);
 SCLK_set(1);
 SCLK_set(0);
 mdelay(2);
}

unsigned int master_get_ack(void)
{
 int ack; 
  
 SDA_output;
 SCLK_output;

 SDA_set(1);
 SCLK_set(0);
 mdelay(3);

 SDA_input; 
 SCLK_set(1);
 mdelay(5);
 ack = Get_SDA();

 SCLK_set(0);

 return ack;
}

void AT_eeprom_byte_program(unsigned int dat)
{
 int i;
 SDA_output;
 SCLK_output;

 SDA_set(1);

 for(i=0; i<8; i++)
 {
  if(dat & 0x80)
  {
   SDA_set(1);
  }
  else
  {
   SDA_set(0);
  }
 // udelay(100);
  SCLK_set(1);
  udelay(100);
  SCLK_set(0);
  dat <<= 1;
 }

unsigned int AT_eeprom_byte_read(void)
{
 int j;
 unsigned int result = 0;
 SCLK_output; 
 SDA_input;

 SCLK_set(0);
 udelay(10);

 for(j=0; j<8; j++)
 {     
  result <<= 1;
  SCLK_set(0);
  udelay(10);
  SCLK_set(1);  
  udelay(10);
  
  
//  result |= Get_SDA();
  if(Get_SDA() == 0)
  {
   result &= ~0x01;
  }
  else
  {
   result |= 0x01;
  }
  
  
      
 } 
 return result;
}

void AT_eeprom_write(unsigned int addr,unsigned int dat)
{
 int ack_flag =1;

 AT_eeprom_start();
 udelay(200);
 AT_eeprom_byte_program(write_cmd);
 udelay(200);
 ack_flag = master_get_ack();
 printk("write_1: %x \n",ack_flag);
 if(ack_flag == 0)
 {
  AT_eeprom_byte_program(addr);
  ack_flag = master_get_ack();
  printk("write_2: %x \n",ack_flag);
  if(ack_flag == 0)
  { 
   AT_eeprom_byte_program(dat);
   ack_flag = master_get_ack();
   printk("write_3: %x \n",ack_flag);
   if(ack_flag == 0)
   {
    AT_eeprom_stop();
    udelay(200);
   }
  }
 }
}

unsigned int AT_eeprom_read(unsigned int address)
{
 int ack_read = 1;
 unsigned int read_value = 0;
 
 AT_eeprom_start();
 udelay(200);
 AT_eeprom_byte_program(write_cmd);
 udelay(200);
 ack_read = master_get_ack();
 printk("read_1: %x \n",ack_read);
 if(ack_read == 0)
 {
  AT_eeprom_byte_program(address); 
  ack_read = master_get_ack();
  printk("read_2: %x \n",ack_read);
  if(ack_read == 0)
  {
   AT_eeprom_start();
   udelay(100);
   AT_eeprom_byte_program(read_cmd);
   ack_read = master_get_ack();
   printk("read_3: %x \n",ack_read);
   if(ack_read == 0)
   {
    read_value = AT_eeprom_byte_read();
    master_noack();
    AT_eeprom_stop();
    udelay(100); 
   }
  }
 }
 return read_value;
}

void eeprom_test(void)
{
 unsigned int last_value = 0;
 
 AT_eeprom_write(0x01,0x11);
 last_value = AT_eeprom_read(0x01);
 printk("eeprom_value1: %x \n\r",last_value);

 AT_eeprom_write(0x01,0x22);
 last_value = AT_eeprom_read(0x01);
 printk("eeprom_value2: %x \n\r",last_value);

 AT_eeprom_write(0x01,0x33);
 last_value = AT_eeprom_read(0x01);
 printk("eeprom_value3: %x \n\r",last_value);
}

static int eeprom_open(struct inode *inode, struct file *filp)
{
 printk("the eeprom module has opened \n\r");
 eeprom_test();
 return 0;
}

static int eeprom_release(struct inode *inode, struct file *filp)
{
 printk("the eeprom module has release \n\r");

 return 0;
}

static struct file_operations eeprom_fops = {
 .open = eeprom_open,
 .release = eeprom_release,
};

static struct miscdevice eeprom_misc = {
 .minor = MISC_DYNAMIC_MINOR,
 .name = DEVICE_NAME,
 .fops = &eeprom_fops,
};

static int eeprom_init(void)
{
 int ret;
 ret = misc_register(&eeprom_misc);
 printk("the eeprom module has up \n\r");
 return ret;
}

static void eeprom_exit(void)
{
 misc_deregister(&eeprom_misc);
 printk("the eeprom module has exit \n\r");
}

module_init(eeprom_init);
module_exit(eeprom_exit);

MODULE_LICENSE("GPL"); 

你可能感兴趣的:(linux,嵌入式,eeprom,i2c,ARM11)