Advertisement
Guest User

beaglebone_i2c.c

a guest
May 2nd, 2013
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.90 KB | None | 0 0
  1. // http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/i2c/dev-interface
  2. // read and write code, without stops, from
  3. // http://bunniestudios.com/blog/images/infocast_i2c.c
  4. #include <stdio.h>
  5. #include <errno.h>
  6. #include <linux/i2c-dev.h>
  7. #include <linux/i2c.h>
  8. #include <fcntl.h>
  9. #include "include/beaglebone_i2c.h"
  10.  
  11. // chain specified should match the /dev/i2c-%d entry.
  12. // i2c-2 is hidden, so don't incrlude it in the list.
  13. #define NUM_I2C_CHAINS 4
  14. #define VALID_I2C_CHAINS {-1, 1, -1, 3}
  15.  
  16. typedef struct I2C_Chain {
  17.     int file;
  18.     unsigned char valid;
  19.     pthread_mutex_t lock;
  20. } I2C_Chain;
  21.  
  22. struct I2C_Chain i2cChains[NUM_I2C_CHAINS];
  23.  
  24. int I2C_Chain_init( I2C_Chain *i2cChain ){
  25.     int retval = 0;
  26.     pthread_mutex_init(&i2cChain->lock, NULL);
  27.     i2cChain->valid = 0;
  28.     i2cChain->file = -1;
  29.     return retval;
  30. }
  31.  
  32. #define ERROR_I2C -1
  33. #define ERROR_I2C_HW -2
  34.  
  35. // i2c-dev.h
  36. // 00040 #define I2C_M_TEN 0x10  /* we have a ten bit chip address */
  37. // 00041 #define I2C_M_RD  0x01
  38. // 00042 #define I2C_M_NOSTART 0x4000
  39. // 00043 #define I2C_M_REV_DIR_ADDR  0x2000
  40. // 00044 #define I2C_M_IGNORE_NAK  0x1000
  41. // 00045 #define I2C_M_NO_RD_ACK   0x0800
  42.  
  43. int checkChain(unsigned char chain){
  44.     // returns true if the chain is invalid
  45.     if(chain < NUM_I2C_CHAINS){
  46.         if( i2cChains[chain].valid ){
  47.             return 0;
  48.         }
  49.     }
  50.     fprintf(stderr, "I2C chain specified is invalid: %d\n", chain);
  51.     return -ECHRNG;
  52. }
  53.  
  54. int i2cChain_writeMessages(unsigned char chain, struct i2c_rdwr_ioctl_data *msgset){
  55.     // returns 0 on success.
  56.     int retval = 0;
  57.     if(retval = checkChain(chain)){
  58.         return retval;
  59.     }
  60.     retval = ioctl(i2cChains[chain].file, I2C_RDWR, msgset);
  61.     return retval;
  62. }
  63.  
  64. int i2c_write(const unsigned char chain, const unsigned int address, unsigned char *data, const unsigned int numBytes){
  65.     // assumes address is not 10bit. if we need 10bit in the future, need to check if 10bit has been set, and enable the bit in the flags below.
  66.     // Note: For register writing, the first data bit will usually contain the address of the device register to write.
  67.     struct i2c_rdwr_ioctl_data i2cCommand;
  68.     struct i2c_msg msgs[1];
  69.    
  70.     // set up write operation
  71.     msgs[0].addr = address;
  72.     msgs[0].flags = 0;  // no flags
  73.     msgs[0].len = numBytes*sizeof(unsigned char);
  74.     msgs[0].buf = data;
  75.  
  76.     i2cCommand.msgs = msgs;
  77.     i2cCommand.nmsgs = 1;
  78.  
  79.     return i2cChain_writeMessages(chain, &i2cCommand);
  80. }
  81.  
  82. int i2c_wtf(){
  83.     int addr = 0x20;
  84.     int chain = 3;
  85.     int retval = 0;
  86.         if( (retval = ioctl(i2cChains[chain].file, I2C_SLAVE, addr)) < 0 ){
  87.         printf("Couldn't set ioctl i2c_slave addr: %d\n", retval);
  88.         return -1;
  89.     }
  90.     printf("Errno: %d\n", errno);
  91.     int reg = 0x05;
  92.     unsigned char data;
  93.     if( (retval = read(i2cChains[chain].file, &data, 1)) != 1){
  94.         printf("Couldn't read the byte from file %d: retval = %d\n", i2cChains[chain].file, retval);
  95.         printf("Errno: %d\n", errno);
  96.         return retval;
  97.     }else{
  98.         printf("Read: %d\n", data);
  99.     }
  100.    
  101.     return retval;
  102. }
  103.  
  104. int i2c_read(const unsigned char chain, const unsigned int address, unsigned char reg, unsigned char *data, const unsigned char numBytes){
  105.     // assumes address is not 10bit. if we need 10bit in the future, need to check if 10bit has been set, and enable the bit in the flags below.
  106.     struct i2c_rdwr_ioctl_data i2cCommand;
  107.     struct i2c_msg msgs[2];
  108.     // write the i2c address
  109.     msgs[0].addr = address;
  110.     msgs[0].flags = 0;
  111.     msgs[0].len = sizeof(reg);
  112.     msgs[0].buf = &reg;
  113.    
  114.     // read the contents
  115.     msgs[1].addr = address;
  116.     msgs[1].flags = I2C_M_RD;
  117.     msgs[1].len = numBytes;
  118.     msgs[1].buf = data;
  119.    
  120.     i2cCommand.msgs = msgs;
  121.     i2cCommand.nmsgs = 2;
  122.    
  123.     return i2cChain_writeMessages(chain, &i2cCommand);
  124. }
  125.  
  126. // int i2c_TenBitAddr(unsigned int *chain, long *select{
  127.     // // enable 10 bit addressing
  128.     // if( ioctl(i2cChains_files[*chain], I2C_TENBIT, long select) < 0 ){
  129.         // fprintf( stderr, "Failed to set address mode to 10 bits for i2c chain %d.\n", *chain );
  130.         // return I2C_ERROR;
  131.     // }
  132.     // return 0;
  133. // }
  134.  
  135. int i2c_initialize( void ){
  136.     printf("Initializing I2C...\n");
  137.     char filename[256] = {0};
  138.     int valid_chains[] = VALID_I2C_CHAINS;
  139.     int i, i2;
  140.    
  141.     for(i=0; i < NUM_I2C_CHAINS; i++){
  142.         I2C_Chain_init( &i2cChains[i] );
  143.         //printf("  i2c chain %d....", i);
  144.         if( valid_chains[i] >= 0 ){
  145.             sprintf(filename,"/dev/i2c-%d", valid_chains[i]);
  146.             printf("  %s", filename);
  147.             if( (i2cChains[i].file = open(filename, O_RDWR)) <= 0){
  148.                 fprintf(stderr, ", failed, retval = %d\n", i, i2cChains[i].file);
  149.                 for(i2 = i-1; i2 < NUM_I2C_CHAINS; i2++){
  150.                     close(i2cChains[i2].file);
  151.                 }
  152.                 return -1;
  153.             }else{
  154.                 i2cChains[i].valid = 1;
  155.                 printf("\n");
  156.             }
  157.         }else{
  158.             // -1 means ignore the entry.
  159.         }
  160.     }
  161.     return 0;
  162. }
  163.  
  164. int i2c_cleanup( void ){
  165.     printf("Cleaning up I2C...");
  166.     int i;
  167.     for(i=0; i < NUM_I2C_CHAINS; i++){
  168.         if( i2cChains[i].valid ){
  169.             close(i2cChains[i].file);   // don't care if it errors.
  170.         }
  171.     }  
  172.     printf("done.\n");
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement