beagleboneblack - I am trying to use i2c on the beagle bone black with c++ but I keep getting 0x00 returned -
hi trying read , write data i2c bus on beagle bone black. keep reading 0x00 whenever try access register on mma84152 (or other register matter), constant register means value not change. trying read i2c-1 character driver located in /dev , connect sda , scl of mma852 lines pins 19 , 20 on p9 header. sda , scl lines both pulled high 10 k resistors. both pin 19 , pin 20 show 00000073 pin mux means set i2c functionality , slew control slow, reciever active, pin using pull resistor, , pull enabled. ran i2cdetect -r 1 , device shows 0x1d correct address. ran i2cdump 1 0x1d , 0x2a shows under 0x0d register trying read device , contains correct value according datasheet. when read it returns 0x00 me. running latest angstrom distribution , logged in under root no need sudo.i'm lost now. here code:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/i2c-dev.h> #include <linux/i2c.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string> using namespace std; int main(int argc, char **argv){ int x_orientation=0; char buffer1[256]; string i2cdevicedriver="/dev/i2c-1"; int filehandler; if((filehandler=open(i2cdevicedriver.c_str(),o_rdwr))<0){ perror("failed open i2c-1 bus"); exit(1); } if(ioctl(filehandler,i2c_slave,0x1d)<0){ perror("failed acquire i2c bus access , talk slave"); exit(1); } char buffer[1]={0x0d}; if(write(filehandler,buffer,1)!=1){ perror("failed write byte accelerometer"); exit(1); } if(read(filehandler,buffer1,1)!=1){ perror("failed read byte accelerometer"); exit(1); } printf("contents of 0x%02x\n",buffer1[0]); }
it i2c device not support using separate write()
, read()
commands query registers (or equivalent i2c_smbus_write_byte()
, i2c_smbus_read_byte()
commands). kernel adds 'stop bit' separate messages on wire, , devices not support mode.
to confirm:
try using linux i2cget
command -c
('write byte/read byte' mode, uses separate read , write messages stop bit between) flag:
$ i2cget -c 1 0x1d 0x0d expected result: 0x00 (incorrect response)
then try using i2cget
-b
('read byte data' mode, combines read , write messages without stop bit) flag:
$ i2cget -b 1 0x1d 0x0d expected result: 0x2a (correct response)
to resolve:
replace read()
, write()
commands combined i2c_smbus_read_byte_data()
command if available on system:
const char register_id = 0x0d; char result = i2c_smbus_read_byte_data(filehandler, register_id);
alternatively (if above not available), can use the ioctl i2c_rdwr option:
const char slave_id = 0x1d; const char register_id = 0x0d; struct i2c_rdwr_ioctl_data readbytedata; struct i2c_msg messages[2]; readbytedata.nmsgs = 2; readbytedata.msgs = messages; // write portion (send register wish read) char request = register_id; i2c_msg& message = messages[0]; message.addr = slave_id; message.flags = 0; // 0 = write message.len = 1; message.buf = &request; // read portion (read in value of register) char response; message = messages[1]; message.addr = slave_id; message.flags = i2c_m_rd; message.len = 1; // number of bytes read message.buf = &response; // place result // submit combined read+write message ioctl(filehandler, i2c_rdwr, &readbytedata); // output result printf("contents of register 0x%02x 0x%02x\n", register_id, response);
Comments
Post a Comment