#include #include #include #include #include #include #include #include #include #include #include #include "adxl345.h" #define DEVID 0x53 #define THRESH_TAP 0x1D #define OFSX 0x1E #define OFXY 0x1F #define OFSZ 0x20 #define DUR 0x21 #define LATENT 0x22 #define WINDOW 0x23 #define THRESH_ACT 0x24 #define THRESH_INACT 0x25 #define TIME_INACT 0x26 #define ACT_INACT_CTL 0x27 #define THRESH_FF 0x28 #define TIME_FF 0x29 #define TAP_AXES 0x2A #define ACT_TAP_STATUS 0x2B #define BW_RATE 0x2C #define POWER_CTL 0x2D #define INT_ENABLE 0x2E #define INT_MAP 0x2F #define INT_SOURCE 0x30 #define DATA_FORMAT 0x31 #define DATAX0 0x32 #define DATAX1 0x33 #define DATAY0 0x34 #define DATAY1 0x35 #define DATAZ0 0x36 #define DATAZ1 0x37 #define FIFO_CTL 0x38 #define FIFO_STATUS 0x39 static int i2c_file; static char buf[10] = {0}; char range = 8; char offset_x = 0; char offset_y = 0; char offset_z = 0; //Put this in .h int get_range(); int accelerometer_init(){ char i2c_filename[40]; sprintf(i2c_filename,"/dev/i2c-2"); //Open the I2C bus if ((i2c_file = open(i2c_filename,O_RDWR)) < 0) { //printf("Failed to open the bus."); return 0; } int addr = DEVID; // The I2C address //Talk to a particular chip if (ioctl(i2c_file,I2C_SLAVE,addr) < 0) { //printf("Failed to acquire bus access and/or talk to slave.\n"); //printf("%s\n\n",strerror(errno)); return 0; } get_range(); return 1; } //Write only an address int write_address(unsigned char reg){ buf[0] = reg; if (write(i2c_file,buf,1) != 1) { //printf("Failed to write to the i2c bus.\n"); //printf("%s\n\n",strerror(errno)); return 0; } return 1; } //Write a byte to an address int write_byte(unsigned char reg, unsigned char data){ buf[0] = reg; buf[1] = data; if (write(i2c_file,buf,2) != 2) { //printf("Failed to write to the i2c bus.\n"); //printf("%s\n\n",strerror(errno)); return 0; } return 1; } //Read the current register at an address, then change only the masked bytes based on data int write_masked_byte(unsigned char reg, unsigned char data, char mask){ unsigned char current_data; //Write desired register if(write_address(reg) == 0) return 0; //Read current value of register if(read_current_byte(¤t_data) == 0) return 0; //printf("Current data: %x\n",current_data); //Write masked data data = (current_data & ~mask) | (data & mask); //printf("Writing data: %x\n",data); return write_byte(reg, data); } //Read a byte from the current address int read_current_byte(unsigned char * data){ if (read(i2c_file,buf,1) != 1) { //printf("Failed to read from the i2c bus.\n"); //printf("%s\n\n",strerror(errno)); return 0; } *data = buf[0]; return 1; } //Read a byte from the passed register int read_byte(unsigned char reg, unsigned char * data){ //Write the register's address if(write_address(reg) == 0) return 0; //Read from that address return read_current_byte(data); } //Go from standby to measurement mode int measure_mode(){ //printf("Go to measure mode... "); if(write_masked_byte(POWER_CTL,0x08,0x08) == 0) return 0; //printf("Set to measure mode okay.\n"); return 1; } //Go to standby mode int standby_mode(){ //printf("Go to standby mode... "); if(write_masked_byte(POWER_CTL,0x00,0x08) == 0) return 0; //printf("Set to standby mode okay.\n"); return 1; } //Pass 1 to set power mode, 0 to turn off //0 by default int set_low_power(unsigned char power){ return write_masked_byte(BW_RATE, power<<3,0x10); } //Pass a value to set sensed range //Potential values are 2,4,8,16g int set_range(char range_set){ unsigned char rate = 0xF; switch(range_set){ case 2: rate = 0x0; break; case 4: rate = 0x1; break; case 8: rate = 0x2; break; case 16: rate = 0x3; break; default: printf("Not a valid range.\n"); return 0; } if(write_masked_byte(DATA_FORMAT,rate,0x3) == 0) return 0; range = range_set; return 1; } int get_range(){ unsigned char data; if(read_byte(DATA_FORMAT,&data) == 0) return 0; //Mask off non-range bits data = data & 0x3; switch(data){ case 0x0: range = 2; break; case 0x1: range = 4; break; case 0x2: range = 8; break; case 0x3: range = 16; break; default: printf("Not a valid range.\n"); return 0; } return 1; } float convert_to_g(unsigned short raw){ char negative = 0; float result; //Convert from twos complement if((raw >> 15) == 1){ raw = ~raw + 1; negative = 1; } result = (float)raw; if(negative) result *= -1; //1FF is the maximum value of a 10-bit signed register result = (float)range * (result/(0x1FF)); } int get_data_x(float * result){ unsigned char data; unsigned short raw; char negative = 0; //read data0 from X-Axis if(read_byte(DATAX0, &data) == 0) return 0; //printf("X-Axis Data0: %02d\n",data); raw = data; //read data1 from X-Axis if(read_byte(DATAX1, &data) == 0) return 0; //printf("X-Axis Data1: %02d -- %02x\n",data, data); raw += data<<8; *result = convert_to_g(raw); return 1; } int get_data_y(float * result){ unsigned char data; unsigned short raw; //read data0 from Y-Axis if(read_byte(DATAY0, &data) == 0) return 0; //printf("X-Axis Data0: %02d\n",data); raw = data; //read data1 from Y-Axis if(read_byte(DATAY1, &data) == 0) return 0; //printf("Y-Axis Data1: %02d -- %02x\n",data, data); raw += data<<8; *result = convert_to_g(raw); return 1; } int get_data_z(float * result){ unsigned char data; unsigned short raw; //read data0 from Z-Axis if(read_byte(DATAZ0, &data) == 0) return 0; //printf("Z-Axis Data0: %02d\n",data); raw = data; //read data1 from Z-Axis if(read_byte(DATAZ1, &data) == 0) return 0; //printf("Z-Axis Data1: %02d -- %02x\n",data, data); raw += data << 8; *result = convert_to_g(raw); return 1; }