Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/i2c/dev-interface
- // read and write code, without stops, from
- // http://bunniestudios.com/blog/images/infocast_i2c.c
- #include <stdio.h>
- #include <errno.h>
- #include <linux/i2c-dev.h>
- #include <linux/i2c.h>
- #include <fcntl.h>
- #include "include/beaglebone_i2c.h"
- // chain specified should match the /dev/i2c-%d entry.
- // i2c-2 is hidden, so don't incrlude it in the list.
- #define NUM_I2C_CHAINS 4
- #define VALID_I2C_CHAINS {-1, 1, -1, 3}
- typedef struct I2C_Chain {
- int file;
- unsigned char valid;
- pthread_mutex_t lock;
- } I2C_Chain;
- struct I2C_Chain i2cChains[NUM_I2C_CHAINS];
- int I2C_Chain_init( I2C_Chain *i2cChain ){
- int retval = 0;
- pthread_mutex_init(&i2cChain->lock, NULL);
- i2cChain->valid = 0;
- i2cChain->file = -1;
- return retval;
- }
- #define ERROR_I2C -1
- #define ERROR_I2C_HW -2
- // i2c-dev.h
- // 00040 #define I2C_M_TEN 0x10 /* we have a ten bit chip address */
- // 00041 #define I2C_M_RD 0x01
- // 00042 #define I2C_M_NOSTART 0x4000
- // 00043 #define I2C_M_REV_DIR_ADDR 0x2000
- // 00044 #define I2C_M_IGNORE_NAK 0x1000
- // 00045 #define I2C_M_NO_RD_ACK 0x0800
- int checkChain(unsigned char chain){
- // returns true if the chain is invalid
- if(chain < NUM_I2C_CHAINS){
- if( i2cChains[chain].valid ){
- return 0;
- }
- }
- fprintf(stderr, "I2C chain specified is invalid: %d\n", chain);
- return -ECHRNG;
- }
- int i2cChain_writeMessages(unsigned char chain, struct i2c_rdwr_ioctl_data *msgset){
- // returns 0 on success.
- int retval = 0;
- if(retval = checkChain(chain)){
- return retval;
- }
- retval = ioctl(i2cChains[chain].file, I2C_RDWR, msgset);
- return retval;
- }
- int i2c_write(const unsigned char chain, const unsigned int address, unsigned char *data, const unsigned int numBytes){
- // 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.
- // Note: For register writing, the first data bit will usually contain the address of the device register to write.
- struct i2c_rdwr_ioctl_data i2cCommand;
- struct i2c_msg msgs[1];
- // set up write operation
- msgs[0].addr = address;
- msgs[0].flags = 0; // no flags
- msgs[0].len = numBytes*sizeof(unsigned char);
- msgs[0].buf = data;
- i2cCommand.msgs = msgs;
- i2cCommand.nmsgs = 1;
- return i2cChain_writeMessages(chain, &i2cCommand);
- }
- int i2c_wtf(){
- int addr = 0x20;
- int chain = 3;
- int retval = 0;
- if( (retval = ioctl(i2cChains[chain].file, I2C_SLAVE, addr)) < 0 ){
- printf("Couldn't set ioctl i2c_slave addr: %d\n", retval);
- return -1;
- }
- printf("Errno: %d\n", errno);
- int reg = 0x05;
- unsigned char data;
- if( (retval = read(i2cChains[chain].file, &data, 1)) != 1){
- printf("Couldn't read the byte from file %d: retval = %d\n", i2cChains[chain].file, retval);
- printf("Errno: %d\n", errno);
- return retval;
- }else{
- printf("Read: %d\n", data);
- }
- return retval;
- }
- int i2c_read(const unsigned char chain, const unsigned int address, unsigned char reg, unsigned char *data, const unsigned char numBytes){
- // 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.
- struct i2c_rdwr_ioctl_data i2cCommand;
- struct i2c_msg msgs[2];
- // write the i2c address
- msgs[0].addr = address;
- msgs[0].flags = 0;
- msgs[0].len = sizeof(reg);
- msgs[0].buf = ®
- // read the contents
- msgs[1].addr = address;
- msgs[1].flags = I2C_M_RD;
- msgs[1].len = numBytes;
- msgs[1].buf = data;
- i2cCommand.msgs = msgs;
- i2cCommand.nmsgs = 2;
- return i2cChain_writeMessages(chain, &i2cCommand);
- }
- // int i2c_TenBitAddr(unsigned int *chain, long *select{
- // // enable 10 bit addressing
- // if( ioctl(i2cChains_files[*chain], I2C_TENBIT, long select) < 0 ){
- // fprintf( stderr, "Failed to set address mode to 10 bits for i2c chain %d.\n", *chain );
- // return I2C_ERROR;
- // }
- // return 0;
- // }
- int i2c_initialize( void ){
- printf("Initializing I2C...\n");
- char filename[256] = {0};
- int valid_chains[] = VALID_I2C_CHAINS;
- int i, i2;
- for(i=0; i < NUM_I2C_CHAINS; i++){
- I2C_Chain_init( &i2cChains[i] );
- //printf(" i2c chain %d....", i);
- if( valid_chains[i] >= 0 ){
- sprintf(filename,"/dev/i2c-%d", valid_chains[i]);
- printf(" %s", filename);
- if( (i2cChains[i].file = open(filename, O_RDWR)) <= 0){
- fprintf(stderr, ", failed, retval = %d\n", i, i2cChains[i].file);
- for(i2 = i-1; i2 < NUM_I2C_CHAINS; i2++){
- close(i2cChains[i2].file);
- }
- return -1;
- }else{
- i2cChains[i].valid = 1;
- printf("\n");
- }
- }else{
- // -1 means ignore the entry.
- }
- }
- return 0;
- }
- int i2c_cleanup( void ){
- printf("Cleaning up I2C...");
- int i;
- for(i=0; i < NUM_I2C_CHAINS; i++){
- if( i2cChains[i].valid ){
- close(i2cChains[i].file); // don't care if it errors.
- }
- }
- printf("done.\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement