i2c - Why doesn't this program in C compile? Error: undefined reference to `i2c_smbus_read_byte_data' -
edit: created other topic title , more appropriate/clear details:
how resolve link error "undefined reference `i2c_smbus_read_byte_data'"
__
i've tried compile single program in c read , write device through i2c bus i'm getting error:
error: undefined reference i2c_smbus_read_byte_data
i have installed these packages: libi2c-dev
, i2c-tools
.
i'm using ubuntu , arm-linux-gnueabi-gcc compiler (cross compile eclipse luna ide)
here whole code:
/* http://www.zerozone.it/2014/05/primi-esperimenti-con-la-beaglebone-black-collegare-10dof-via-i2c/ dof10 i2c test program v0.1 - 05.05.2014 wrote program test dof10 funcionality beaglebone black. can buy dof10 module , beaglebone ebay few dollars...have fun ! written michele <o-zone@zerozone.it> pinassi blog @ www.zerozone.it feel free use code want. no warranty, in case: use @ own risks ! */ #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <linux/i2c-dev.h> #include <linux/i2c.h> #define debug #define l3g4200d_i2c_addr 0x69 #define adxl345_i2c_addr 0x53 typedef signed char s8; typedef unsigned char u8; typedef signed short s16; typedef unsigned short u16; typedef signed int s32; typedef unsigned int u32; typedef signed long s64; typedef unsigned long u64; int i2chandle; // bus i2c file handle int i2c_setaddress(unsigned char deviceaddr) { if (ioctl(i2chandle, i2c_slave, deviceaddr) < 0) { printf("error while set i2c address 0x%x: %d error\n",deviceaddr,errno); return -1; } return 0; } unsigned char i2c_readbyte(unsigned char deviceaddr,unsigned char regaddr) { unsigned char res; i2c_setaddress(deviceaddr); res = i2c_smbus_read_byte_data(i2chandle,regaddr); #ifdef debug printf("[debug] 0x%x @ 0x%x => 0x%x\n",deviceaddr,regaddr,res); #endif return res; } int i2c_writeword(unsigned char deviceaddr, __u8 regaddr, __u16 value) { int res; i2c_setaddress(deviceaddr); res = i2c_smbus_write_word_data(i2chandle, regaddr, value); if(res < 0) { printf("error writing 0x%x 0x%x register on i2c bus\n",value, regaddr); return -1; } return 1; } int i2c_writebyte(unsigned char deviceaddr, __u8 regaddr, __u8 value) { int res; i2c_setaddress(deviceaddr); res = i2c_smbus_write_byte_data(i2chandle, regaddr, value); if(res < 0) { printf("error writing 0x%x 0x%x register on i2c bus\n",value, regaddr); return -1; } return 1; } // 0: 250 dps - 1: 500 dps - 2: 2000 dps int l3g4200d_init(char fullscale) { if(i2c_readbyte(l3g4200d_i2c_addr,0x0f)!=0xd3) { printf("error communicating l3d4200d !\n"); return -1; } // enable x, y, z , turn off power down: i2c_writebyte(l3g4200d_i2c_addr, 0x20, 0b00001111); // if you'd adjust/use hpf, can edit line below configure ctrl_reg2: i2c_writebyte(l3g4200d_i2c_addr, 0x21, 0b00000000); // configure ctrl_reg3 generate data ready interrupt on int2 // no interrupts used on int1, if you'd configure int1 // or int2 otherwise, consult datasheet: i2c_writebyte(l3g4200d_i2c_addr, 0x22, 0b00001000); // ctrl_reg4 controls full-scale range, among other things: fullscale &= 0x03; i2c_writebyte(l3g4200d_i2c_addr, 0x23, fullscale<<4); // ctrl_reg5 controls high-pass filtering of outputs, use if you'd like: i2c_writebyte(l3g4200d_i2c_addr, 0x24, 0b00000000); } void l3g4200d_getgyrovalues() { int x,y,z; x = (i2c_readbyte(l3g4200d_i2c_addr, 0x29)&0xff)<<8; // msb x |= (i2c_readbyte(l3g4200d_i2c_addr, 0x28)&0xff); // lsb y = (i2c_readbyte(l3g4200d_i2c_addr, 0x2b)&0xff)<<8; y |= (i2c_readbyte(l3g4200d_i2c_addr, 0x2a)&0xff); z = (i2c_readbyte(l3g4200d_i2c_addr, 0x2d)&0xff)<<8; z |= (i2c_readbyte(l3g4200d_i2c_addr, 0x2c)&0xff); printf("l2d4200d = x:%d y:%d z:%d\n",x,y,z); } void adxl345_init() { // set +/- 4g range writing value 0x01 data_format register. i2c_writebyte(adxl345_i2c_addr,0x31,0x01); // put adxl345 measurement mode writing 0x08 power_ctl register. i2c_writebyte(adxl345_i2c_addr,0x2d,0x08); } void adxl345_readaccel() { int x,y,z; // each axis reading comes in 10 bit resolution, ie 2 bytes. lsb first, msb next x = (i2c_readbyte(adxl345_i2c_addr, 0x33)&0xff)<<8; // msb x |= (i2c_readbyte(adxl345_i2c_addr, 0x32)&0xff); // lsb y = (i2c_readbyte(adxl345_i2c_addr, 0x35)&0xff)<<8; // msb y |= (i2c_readbyte(adxl345_i2c_addr, 0x34)&0xff); // lsb z = (i2c_readbyte(adxl345_i2c_addr, 0x37)&0xff)<<8; // msb z |= (i2c_readbyte(adxl345_i2c_addr, 0x36)&0xff); // lsb printf("adxl345 = x:%d y:%d z:%d\n",x,y,z); } void main(int argc, char *argv[]) { char filename[20]; printf("open i2c bus..."); snprintf(filename, 19, "/dev/i2c-1"); i2chandle = open(filename, o_rdwr); if (i2chandle < 0) { printf("error while opening device %s: %d error\n",filename,errno); exit(1); } printf("ok !\ninitializing l3g4200d..."); l3g4200d_init(2); printf("ok !\ninitializing adxl345..."); adxl345_init(); printf("ok !\n"); while(1) { l3g4200d_getgyrovalues(); adxl345_readaccel(); sleep(1); } close(i2chandle); }
if library installed looks linker issue means.
can verify i2c_smbus_read_byte_data()
defined in
linux/drivers/i2c/i2c-core.c
and has function prototype in,
include/linux/i2c.h
so may
#include <linux/i2c.h>
Comments
Post a Comment