1. #include <errno.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <linux/i2c-dev.h>
  7. #include <linux/i2c.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12.  
  13. #include "adxl345.h"
  14.  
  15. #define DEVID 0x53
  16.  
  17. #define THRESH_TAP 0x1D
  18. #define OFSX 0x1E
  19. #define OFXY 0x1F
  20. #define OFSZ 0x20
  21. #define DUR 0x21
  22. #define LATENT 0x22
  23. #define WINDOW 0x23
  24. #define THRESH_ACT 0x24
  25. #define THRESH_INACT 0x25
  26. #define TIME_INACT 0x26
  27. #define ACT_INACT_CTL 0x27
  28. #define THRESH_FF 0x28
  29. #define TIME_FF 0x29
  30. #define TAP_AXES 0x2A
  31. #define ACT_TAP_STATUS 0x2B
  32. #define BW_RATE 0x2C
  33. #define POWER_CTL 0x2D
  34. #define INT_ENABLE 0x2E
  35. #define INT_MAP 0x2F
  36. #define INT_SOURCE 0x30
  37. #define DATA_FORMAT 0x31
  38. #define DATAX0 0x32
  39. #define DATAX1 0x33
  40. #define DATAY0 0x34
  41. #define DATAY1 0x35
  42. #define DATAZ0 0x36
  43. #define DATAZ1 0x37
  44. #define FIFO_CTL 0x38
  45. #define FIFO_STATUS 0x39
  46.  
  47. static int i2c_file;
  48. static char buf[10] = {0};
  49. char range = 8;
  50. char offset_x = 0;
  51. char offset_y = 0;
  52. char offset_z = 0;
  53.  
  54. //Put this in .h
  55. int get_range();
  56.  
  57. int accelerometer_init(){
  58.     char i2c_filename[40];
  59.     sprintf(i2c_filename,"/dev/i2c-2");
  60.  
  61.     //Open the I2C bus
  62.     if ((i2c_file = open(i2c_filename,O_RDWR)) < 0) {
  63.         //printf("Failed to open the bus.");
  64.         return 0;
  65.     }
  66.  
  67.     int addr = DEVID;        // The I2C address
  68.     //Talk to a particular chip
  69.     if (ioctl(i2c_file,I2C_SLAVE,addr) < 0) {
  70.         //printf("Failed to acquire bus access and/or talk to slave.\n");
  71.         //printf("%s\n\n",strerror(errno));
  72.         return 0;
  73.     }
  74.     get_range();
  75.     return 1;
  76. }
  77.  
  78. //Write only an address
  79. int write_address(unsigned char reg){
  80.     buf[0] = reg;
  81.     if (write(i2c_file,buf,1) != 1) {
  82.         //printf("Failed to write to the i2c bus.\n");
  83.         //printf("%s\n\n",strerror(errno));
  84.         return 0;
  85.     }
  86.     return 1;
  87. }
  88.  
  89. //Write a byte to an address
  90. int write_byte(unsigned char reg, unsigned char data){
  91.     buf[0] = reg;
  92.     buf[1] = data;
  93.  
  94.     if (write(i2c_file,buf,2) != 2) {
  95.         //printf("Failed to write to the i2c bus.\n");
  96.         //printf("%s\n\n",strerror(errno));
  97.         return 0;
  98.     }
  99.  
  100.     return 1;
  101. }
  102.  
  103. //Read the current register at an address, then change only the masked bytes based on data
  104. int write_masked_byte(unsigned char reg, unsigned char data, char mask){
  105.     unsigned char current_data;
  106.     //Write desired register
  107.     if(write_address(reg) == 0)
  108.         return 0;
  109.     //Read current value of register
  110.     if(read_current_byte(&current_data) == 0)
  111.         return 0;
  112.     //printf("Current data: %x\n",current_data);
  113.     //Write masked data
  114.     data = (current_data & ~mask) | (data & mask);
  115.     //printf("Writing data: %x\n",data);
  116.     return write_byte(reg, data);
  117. }
  118.  
  119. //Read a byte from the current address
  120. int read_current_byte(unsigned char * data){
  121.     if (read(i2c_file,buf,1) != 1) {
  122.         //printf("Failed to read from the i2c bus.\n");
  123.         //printf("%s\n\n",strerror(errno));
  124.         return 0;
  125.     }
  126.  
  127.     *data = buf[0];
  128.     return 1;
  129. }
  130.  
  131. //Read a byte from the passed register
  132. int read_byte(unsigned char reg, unsigned char * data){
  133.     //Write the register's address
  134.     if(write_address(reg) == 0)
  135.         return 0;
  136.  
  137.     //Read from that address
  138.     return read_current_byte(data);
  139. }
  140.  
  141. //Go from standby to measurement mode
  142. int measure_mode(){
  143.     //printf("Go to measure mode... ");
  144.     if(write_masked_byte(POWER_CTL,0x08,0x08) == 0)
  145.         return 0;
  146.     //printf("Set to measure mode okay.\n");
  147.     return 1;
  148. }
  149.  
  150. //Go to standby mode
  151. int standby_mode(){
  152.     //printf("Go to standby mode... ");
  153.         if(write_masked_byte(POWER_CTL,0x00,0x08) == 0)
  154.                 return 0;
  155.         //printf("Set to standby mode okay.\n");
  156.         return 1;
  157. }
  158.  
  159. //Pass 1 to set power mode, 0 to turn off
  160. //0 by default
  161. int set_low_power(unsigned char power){
  162.     return write_masked_byte(BW_RATE, power<<3,0x10);
  163. }
  164.  
  165. //Pass a value to set sensed range
  166. //Potential values are 2,4,8,16g
  167. int set_range(char range_set){
  168.     unsigned char rate = 0xF;
  169.     switch(range_set){
  170.         case 2: rate = 0x0; break;
  171.         case 4: rate = 0x1; break;
  172.         case 8: rate = 0x2; break;
  173.         case 16: rate = 0x3; break;
  174.         default: printf("Not a valid range.\n"); return 0;
  175.     }
  176.     if(write_masked_byte(DATA_FORMAT,rate,0x3) == 0)
  177.         return 0;
  178.     range = range_set;
  179.     return 1;
  180. }
  181.  
  182. int get_range(){
  183.     unsigned char data;
  184.     if(read_byte(DATA_FORMAT,&data) == 0)
  185.         return 0;
  186.     //Mask off non-range bits
  187.     data = data & 0x3;
  188.         switch(data){
  189.                 case 0x0: range = 2; break;
  190.                 case 0x1: range = 4; break;
  191.                 case 0x2: range = 8; break;
  192.                 case 0x3: range = 16; break;
  193.                 default: printf("Not a valid range.\n"); return 0;
  194.         }
  195.     return 1;
  196. }
  197.  
  198.  
  199. float convert_to_g(unsigned short raw){
  200.     char negative = 0;
  201.     float result;
  202.     //Convert from twos complement
  203.     if((raw >> 15) == 1){
  204.                 raw = ~raw + 1;
  205.                 negative = 1;
  206.         }
  207.         result = (float)raw;
  208.         if(negative)
  209.                 result *= -1;
  210.  
  211.     //1FF is the maximum value of a 10-bit signed register
  212.     result = (float)range * (result/(0x1FF));
  213. }
  214.  
  215. int get_data_x(float * result){
  216.     unsigned char data;
  217.     unsigned short raw;
  218.     char negative = 0;
  219.     //read data0 from X-Axis
  220.     if(read_byte(DATAX0, &data) == 0)
  221.         return 0;
  222.     //printf("X-Axis Data0:  %02d\n",data);
  223.     raw = data;
  224.  
  225.     //read data1 from X-Axis
  226.     if(read_byte(DATAX1, &data) == 0)
  227.         return 0;
  228.  
  229.     //printf("X-Axis Data1:  %02d -- %02x\n",data, data);
  230.     raw += data<<8;
  231.  
  232.         *result = convert_to_g(raw);
  233.     return 1;
  234. }
  235.  
  236. int get_data_y(float * result){
  237.         unsigned char data;
  238.         unsigned short raw;
  239.  
  240.         //read data0 from Y-Axis
  241.         if(read_byte(DATAY0, &data) == 0)
  242.                 return 0;
  243.         //printf("X-Axis Data0:  %02d\n",data);
  244.         raw = data;
  245.  
  246.         //read data1 from Y-Axis
  247.         if(read_byte(DATAY1, &data) == 0)
  248.                 return 0;
  249.  
  250.         //printf("Y-Axis Data1:  %02d -- %02x\n",data, data);
  251.     raw += data<<8;
  252.  
  253.     *result = convert_to_g(raw);
  254.  
  255.         return 1;
  256. }
  257.  
  258. int get_data_z(float * result){
  259.         unsigned char data;
  260.         unsigned short raw;
  261.  
  262.         //read data0 from Z-Axis
  263.         if(read_byte(DATAZ0, &data) == 0)
  264.                 return 0;
  265.         //printf("Z-Axis Data0:  %02d\n",data);
  266.         raw = data;
  267.  
  268.         //read data1 from Z-Axis
  269.         if(read_byte(DATAZ1, &data) == 0)
  270.                 return 0;
  271.  
  272.         //printf("Z-Axis Data1:  %02d -- %02x\n",data, data);
  273.     raw += data << 8;
  274.  
  275.         *result = convert_to_g(raw);
  276.  
  277.         return 1;
  278. }