GPIO模拟I2C

原来新的kernel中已经提供了一种通过两个gpio口调用i2c-core的机制,而且还能在这两个gpio口挂载多个设备,用起来就像真的i2c总线一样。所以以后我们都应该用kernel中的这种机制!毕竟自己写的模拟代码不是很可靠的,而且不方便挂载多个设备(当然,你可以通过复杂的逻辑和方法去实现,但是这不值得,除非你是本着学习的目的)

不过这个自己写的gpio模拟i2c的代码通过对gpio的不停的拉高拉低来模拟scl和sda线的动作可以让我们对i2c的操作和协议认识的更清楚。

代码如下: 

[cpp]  view plain copy
  1. /****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C****/   
  2. #define DELAY   1   
  3. #define SCL     89   
  4. #define SDA     20   
  5. #define RST     19   
  6. #define IRQ     108   
  7. void i2c_start(void)  
  8. {       
  9.     gpio_direction_output(SDA, 1);    
  10.     gpio_direction_output(SCL, 1);  
  11.     udelay(DELAY);  
  12.       
  13.     gpio_set_value(SDA, 0);  
  14.     udelay(DELAY);      
  15.             
  16.     gpio_set_value(SCL, 0);  
  17.     udelay(DELAY);  
  18. }  
  19. void i2c_stop(void)  
  20. {   
  21.     gpio_set_value(SCL, 0);  
  22.     gpio_set_value(SDA, 0);  
  23.     udelay(DELAY);  
  24.       
  25.     gpio_set_value(SCL, 1);  
  26.     udelay(DELAY);  
  27.     gpio_set_value(SDA, 1);  
  28.     udelay(DELAY);  
  29. }  
  30. void i2c_send_ack(u8 ack)  
  31. {  
  32.     if(ack)  
  33.         gpio_direction_output(SDA, 1);   
  34.     else   
  35.         gpio_direction_output(SDA, 0);  
  36.     udelay(DELAY);  
  37.       
  38.     gpio_set_value(SCL, 1);  
  39.     udelay(DELAY);  
  40.       
  41.     gpio_set_value(SCL, 0);  
  42.     udelay(DELAY);    
  43. }  
  44. u8 i2c_receive_ack(void)  
  45. {  
  46.     u8 rc = 0;  
  47.       
  48.     gpio_direction_input(SDA);  
  49.     gpio_set_value(SCL, 1);  
  50.     udelay(DELAY);  
  51.       
  52.     if(gpio_get_value(SDA)) {  
  53.         rc = 1;  
  54.     }  
  55.     gpio_set_value(SCL, 0);  
  56.     gpio_direction_output(SDA, 1);                
  57.     return rc;  
  58. }  
  59. u8 i2c_send_byte(u8 send_byte)  
  60. {  
  61.     u8 rc = 0;  
  62.     u8 out_mask = 0x80;  
  63.     u8 value;  
  64.     u8 count = 8;  
  65.     while(count > 0) {                  
  66.         value = ((send_byte & out_mask) ? 1 : 0);     
  67.         if (value == 1) {                                     
  68.             gpio_set_value(SDA, 1);       
  69.         }      
  70.         else {                                    
  71.             gpio_set_value(SDA, 0);  
  72.         }      
  73.         udelay(DELAY);  
  74.                                     
  75.         gpio_set_value(SCL, 1);                       
  76.         udelay(DELAY);  
  77.                        
  78.         gpio_set_value(SCL, 0);       
  79.         udelay(DELAY);  
  80.                     
  81.         out_mask >>= 1;        
  82.         count--;         
  83.     }  
  84.       
  85.     gpio_set_value(SDA, 1);    
  86.     rc = i2c_receive_ack();  
  87.     return rc;  
  88. }  
  89. void i2c_read_byte(u8 *buffer, u8 ack)  
  90. {  
  91.     u8 count = 0x08;  
  92.     u8 data = 0x00;  
  93.     u8 temp = 0;  
  94.       
  95.     gpio_direction_input(SDA);   
  96.     while(count > 0) {  
  97.         gpio_set_value(SCL, 1);  
  98.         udelay(DELAY);  
  99.         temp = gpio_get_value(SDA);       
  100.         data <<= 1;  
  101.         if (temp)  
  102.             data |= 0x01;  
  103.         gpio_set_value(SCL, 0);  
  104.         udelay(DELAY);  
  105.         count--;  
  106.     }  
  107.     i2c_send_ack(ack);//0 = ACK    1 = NACK   
  108.     *buffer = data;           
  109. }  
  110. //向client的某个寄存器写入多个字节,len是要写入的数据的长度   
  111. u8 i2c_write(u8 device_id, u8 reg_address, u8* data, u8 len)  
  112. {  
  113.     u8 rc = 0;  
  114.     u8 i;  
  115.     i2c_start();    
  116.       
  117.     rc |= i2c_send_byte( (device_id << 1) | 0x00 );  
  118.     rc |= i2c_send_byte(reg_address);  
  119.     if(data==NULL ||0==len) {  
  120.         i2c_stop();  
  121.         return rc;  
  122.     }  
  123.           
  124.     for(i=0; i
  125.         rc |= i2c_send_byte(*data);  
  126.         data++;  
  127.     }  
  128.       
  129.     i2c_stop();       
  130.     if(rc) {  
  131.         printk("ERROR!  ssd2531_i2c_write failed/n");  
  132.     }  
  133.     return rc;    
  134. }  
  135. //从某个register中读取len个字节放在长度为len的缓冲区buffer中   
  136. u8 i2c_read(u8 device_id, u8 reg_address, u8 *buffer, u8 len)  
  137. {  
  138.     u8 rc = 0;  
  139.     u8 i;  
  140.       
  141.     i2c_start();    
  142.     rc |= i2c_send_byte( (device_id << 1) | 0x00 );  
  143.     rc |= i2c_send_byte(reg_address);  
  144.     i2c_start();//restart I2C      
  145.     rc |= i2c_send_byte( (device_id << 1) | 0x01 );  
  146.       
  147.     for(i=0;i
  148.         i2c_read_byte(buffer++, !(len-i-1));//  !(len-i-1)  这个用来保证在读到每个字节后发送一个ACK并能在最后一个字节读完后发送一个NACK   
  149.     }  
  150.       
  151.     i2c_stop();   
  152.     if(rc) {  
  153.         printk("ERROR!   ssd2531_i2c_read failed/n");  
  154.         return rc;  
  155.     }  
  156.     return rc;    
  157. }  
  158. /****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C****/  
[cpp]  view plain copy
  1. /****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C****/   
  2. #define DELAY   1  
  3. #define SCL     89  
  4. #define SDA     20  
  5. #define RST     19  
  6. #define IRQ     108  
  7. void i2c_start(void)  
  8. {       
  9.     gpio_direction_output(SDA, 1);    
  10.     gpio_direction_output(SCL, 1);  
  11.     udelay(DELAY);  
  12.       
  13.     gpio_set_value(SDA, 0);  
  14.     udelay(DELAY);      
  15.             
  16.     gpio_set_value(SCL, 0);  
  17.     udelay(DELAY);  
  18. }  
  19. void i2c_stop(void)  
  20. {   
  21.     gpio_set_value(SCL, 0);  
  22.     gpio_set_value(SDA, 0);  
  23.     udelay(DELAY);  
  24.       
  25.     gpio_set_value(SCL, 1);  
  26.     udelay(DELAY);  
  27.     gpio_set_value(SDA, 1);  
  28.     udelay(DELAY);  
  29. }  
  30. void i2c_send_ack(u8 ack)  
  31. {  
  32.     if(ack)  
  33.         gpio_direction_output(SDA, 1);   
  34.     else   
  35.         gpio_direction_output(SDA, 0);  
  36.     udelay(DELAY);  
  37.       
  38.     gpio_set_value(SCL, 1);  
  39.     udelay(DELAY);  
  40.       
  41.     gpio_set_value(SCL, 0);  
  42.     udelay(DELAY);    
  43. }  
  44. u8 i2c_receive_ack(void)  
  45. {  
  46.     u8 rc = 0;  
  47.       
  48.     gpio_direction_input(SDA);  
  49.     gpio_set_value(SCL, 1);  
  50.     udelay(DELAY);  
  51.       
  52.     if(gpio_get_value(SDA)) {  
  53.         rc = 1;  
  54.     }  
  55.     gpio_set_value(SCL, 0);  
  56.     gpio_direction_output(SDA, 1);                
  57.     return rc;  
  58. }  
  59. u8 i2c_send_byte(u8 send_byte)  
  60. {  
  61.     u8 rc = 0;  
  62.     u8 out_mask = 0x80;  
  63.     u8 value;  
  64.     u8 count = 8;  
  65.     while(count > 0) {                  
  66.         value = ((send_byte & out_mask) ? 1 : 0);     
  67.         if (value == 1) {                                     
  68.             gpio_set_value(SDA, 1);       
  69.         }      
  70.         else {                                    
  71.             gpio_set_value(SDA, 0);  
  72.         }      
  73.         udelay(DELAY);  
  74.                                     
  75.         gpio_set_value(SCL, 1);                       
  76.         udelay(DELAY);  
  77.                        
  78.         gpio_set_value(SCL, 0);       
  79.         udelay(DELAY);  
  80.                     
  81.         out_mask >>= 1;        
  82.         count--;         
  83.     }  
  84.       
  85.     gpio_set_value(SDA, 1);    
  86.     rc = i2c_receive_ack();  
  87.     return rc;  
  88. }  
  89. void i2c_read_byte(u8 *buffer, u8 ack)  
  90. {  
  91.     u8 count = 0x08;  
  92.     u8 data = 0x00;  
  93.     u8 temp = 0;  
  94.       
  95.     gpio_direction_input(SDA);   
  96.     while(count > 0) {  
  97.         gpio_set_value(SCL, 1);  
  98.         udelay(DELAY);  
  99.         temp = gpio_get_value(SDA);       
  100.         data <<= 1;  
  101.         if (temp)  
  102.             data |= 0x01;  
  103.         gpio_set_value(SCL, 0);  
  104.         udelay(DELAY);  
  105.         count--;  
  106.     }  
  107.     i2c_send_ack(ack);//0 = ACK    1 = NACK  
  108.     *buffer = data;           
  109. }  
  110. //向client的某个寄存器写入多个字节,len是要写入的数据的长度  
  111. u8 i2c_write(u8 device_id, u8 reg_address, u8* data, u8 len)  
  112. {  
  113.     u8 rc = 0;  
  114.     u8 i;  
  115.     i2c_start();    
  116.       
  117.     rc |= i2c_send_byte( (device_id << 1) | 0x00 );  
  118.     rc |= i2c_send_byte(reg_address);  
  119.     if(data==NULL ||0==len) {  
  120.         i2c_stop();  
  121.         return rc;  
  122.     }  
  123.           
  124.     for(i=0; i
  125.         rc |= i2c_send_byte(*data);  
  126.         data++;  
  127.     }  
  128.       
  129.     i2c_stop();       
  130.     if(rc) {  
  131.         printk("ERROR!  ssd2531_i2c_write failed/n");  
  132.     }  
  133.     return rc;    
  134. }  
  135. //从某个register中读取len个字节放在长度为len的缓冲区buffer中  
  136. u8 i2c_read(u8 device_id, u8 reg_address, u8 *buffer, u8 len)  
  137. {  
  138.     u8 rc = 0;  
  139.     u8 i;  
  140.       
  141.     i2c_start();    
  142.     rc |= i2c_send_byte( (device_id << 1) | 0x00 );  
  143.     rc |= i2c_send_byte(reg_address);  
  144.     i2c_start();//restart I2C     
  145.     rc |= i2c_send_byte( (device_id << 1) | 0x01 );  
  146.       
  147.     for(i=0;i
  148.         i2c_read_byte(buffer++, !(len-i-1));//  !(len-i-1)  这个用来保证在读到每个字节后发送一个ACK并能在最后一个字节读完后发送一个NACK  
  149.     }  
  150.       
  151.     i2c_stop();   
  152.     if(rc) {  
  153.         printk("ERROR!   ssd2531_i2c_read failed/n");  
  154.         return rc;  
  155.     }  
  156.     return rc;    
  157. }  
  158. /****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C*****I2C****/  

你可能感兴趣的:(内核)