Craig Evans
/
2645_FXOS8700CQ_Functions
Sample code for interfacing with FXOS8700CQ with I2C functions
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* K64F Accelerometer & Magnetometer 00002 00003 Sample code for reading data from on-board FXOS8700CQ sensor 00004 00005 Craig A. Evans 00006 Jan 2017 00007 00008 */ 00009 00010 #include "mbed.h" 00011 00012 ///////////// defines ////////////////////////////////// 00013 00014 // mbed API uses 8-bit addresses so need to left-shift 7-bit addresses by 1 00015 #define FXOS8700CQ_ADDR (0x1D << 1) // for K64F board 00016 // values from 13.2 datasheet 00017 #define FXOS8700CQ_STATUS 0x00 00018 #define FXOS8700CQ_WHO_AM_I 0x0D 00019 #define FXOS8700CQ_XYZ_DATA_CFG 0x0E 00020 #define FXOS8700CQ_CTRL_REG1 0x2A 00021 #define FXOS8700CQ_M_CTRL_REG1 0x5B 00022 #define FXOS8700CQ_M_CTRL_REG2 0x5C 00023 #define FXOS8700CQ_WHO_AM_I_VAL 0xC7 00024 #define FXOS8700CQ_READ_LEN 13 00025 00026 // struct to hold 6 DOF values 00027 struct Data { 00028 float ax; 00029 float ay; 00030 float az; 00031 float mx; 00032 float my; 00033 float mz; 00034 }; 00035 00036 ////////// mbed API objects //////////////////////////// 00037 00038 // I2C connection for FXOS8700CQ accelerometer/magnetometer 00039 I2C fxos8700cq(I2C_SDA,I2C_SCL); // PTE25/PTE24 00040 00041 //////// function prototypes /////////////////////////// 00042 // setup accelerometer/magnetometer 00043 void init_fxos8700cq(); 00044 // i2c primitive functions 00045 void send_byte_to_reg(char byte,char reg); 00046 char read_byte_from_reg(char reg); 00047 void read_bytes_from_reg(char reg,int number_of_bytes,char bytes[]); 00048 // FXOS8700CQ values 00049 Data get_values(); 00050 00051 ///////// functions //////////////////////////////////// 00052 00053 int main() 00054 { 00055 printf("K64F FXOS8700CQ Example Code\n\n"); 00056 init_fxos8700cq(); 00057 00058 while(1) { 00059 00060 Data values = get_values(); 00061 00062 printf("ax = %f ay = %f az = %f | mx = %f my = %f mz = %f\n" 00063 ,values.ax, values.ay, values.az 00064 ,values.mx, values.my, values.mz); 00065 00066 wait(1.0); 00067 } 00068 00069 } 00070 00071 // gets the status, acceleration and magnetometer data 00072 Data get_values() 00073 { 00074 printf("Reading values..."); 00075 // 13 bytes - status plus 6 channels (2 bytes each) 00076 // x,y,z for accelerometer and magnetometer 00077 char data[FXOS8700CQ_READ_LEN]; 00078 read_bytes_from_reg(FXOS8700CQ_STATUS,FXOS8700CQ_READ_LEN,data); 00079 00080 // copy the 14 bit accelerometer byte data into 16 bit words 00081 int acc_x = (int16_t)(((data[1] << 8) | data[2]))>> 2; 00082 int acc_y = (int16_t)(((data[3] << 8) | data[4]))>> 2; 00083 int acc_z = (int16_t)(((data[5] << 8) | data[6]))>> 2; 00084 00085 // copy the magnetometer byte data into 16 bit words 00086 int mag_x = (int16_t) (data[7] << 8) | data[8]; 00087 int mag_y = (int16_t) (data[9] << 8) | data[10]; 00088 int mag_z = (int16_t) (data[11] << 8) | data[12]; 00089 00090 Data values; // struct to hold values 00091 00092 // 0.488 mg/LSB in 4 g mode (8.1 data sheet) 00093 values.ax = 0.488e-3*acc_x; 00094 values.ay = 0.488e-3*acc_y; 00095 values.az = 0.488e-3*acc_z; 00096 00097 // the magnetometer sensitivity is fixed at 0.1 μT/LSB 00098 values.mx = 0.1e-6*mag_x; 00099 values.my = 0.1e-6*mag_y; 00100 values.mz = 0.1e-6*mag_z; 00101 00102 printf("Done.\n"); 00103 00104 return values; 00105 } 00106 00107 /// primitive i2c functions //// 00108 00109 // sends a byte to a specific register 00110 void send_byte_to_reg(char byte,char reg) 00111 { 00112 char data[2]; 00113 data[0] = reg; 00114 data[1] = byte; 00115 // send the register address, followed by the data 00116 int nack = fxos8700cq.write(FXOS8700CQ_ADDR,data,2); 00117 if (nack) 00118 error("No ACK"); // if we don't receive acknowledgement, flash error message 00119 } 00120 00121 // reads a byte from a specific register 00122 char read_byte_from_reg(char reg) 00123 { 00124 int nack = fxos8700cq.write(FXOS8700CQ_ADDR,®,1,true); // send the register address to the slave 00125 // true as need to send repeated start condition (5.10.1 datasheet) 00126 // http://www.i2c-bus.org/repeated-start-condition/ 00127 if (nack) 00128 error("No ACK"); // if we don't receive acknowledgement, flash error message 00129 00130 char rx; 00131 nack = fxos8700cq.read(FXOS8700CQ_ADDR,&rx,1); // read a byte from the register and store in buffer 00132 if (nack) 00133 error("No ACK"); // if we don't receive acknowledgement, flash error message 00134 00135 return rx; 00136 } 00137 00138 // reads a series of bytes, starting from a specific register 00139 void read_bytes_from_reg(char reg,int number_of_bytes,char bytes[]) 00140 { 00141 int nack = fxos8700cq.write(FXOS8700CQ_ADDR,®,1,true); // send the slave write address and the configuration register address 00142 // true as need to send repeated start condition (5.10.1 datasheet) 00143 // http://www.i2c-bus.org/repeated-start-condition/ 00144 00145 if (nack) 00146 error("No ACK"); // if we don't receive acknowledgement, flash error message 00147 00148 nack = fxos8700cq.read(FXOS8700CQ_ADDR,bytes,number_of_bytes); // read bytes 00149 if (nack) 00150 error("No ACK"); // if we don't receive acknowledgement, flash error message 00151 00152 } 00153 00154 /// init functions ///// 00155 00156 // based on 13.4 in datasheet - 200 Hz hybrid mode (both acc and mag) 00157 void init_fxos8700cq() 00158 { 00159 printf("Initialising....\n"); 00160 00161 // i2c fast-mode - 10.1.1 data sheet 00162 fxos8700cq.frequency(400000); 00163 00164 // the device has an ID number so we check the value to ensure the correct 00165 // drive is on the i2c bus 00166 char data = read_byte_from_reg(FXOS8700CQ_WHO_AM_I); 00167 if (data != FXOS8700CQ_WHO_AM_I_VAL) { // if correct ID not found, hang and flash error message 00168 error("Not correct ID"); 00169 } 00170 00171 printf("Read correct WHO_AM_I value: 0x%X\n",data); 00172 00173 // write 0000 0000 = 0x00 to accelerometer control register 1 to place 00174 // FXOS8700CQ into standby 00175 // [7-1] = 0000 000 00176 // [0]: active=0 00177 data = 0x00; 00178 send_byte_to_reg(data,FXOS8700CQ_CTRL_REG1); 00179 00180 // write 0001 1111 = 0x1F to magnetometer control register 1 00181 // [7]: m_acal=0: auto calibration disabled 00182 // [6]: m_rst=0: no one-shot magnetic reset 00183 // [5]: m_ost=0: no one-shot magnetic measurement 00184 // [4-2]: m_os=111=7: 8x oversampling (for 200Hz) to reduce magnetometer noise 00185 // [1-0]: m_hms=11=3: select hybrid mode with accel and magnetometer active 00186 data = 0x1F; 00187 send_byte_to_reg(data,FXOS8700CQ_M_CTRL_REG1); 00188 00189 // write 0010 0000 = 0x20 to magnetometer control register 2 00190 // [7]: reserved 00191 // [6]: reserved 00192 // [5]: hyb_autoinc_mode=1 to map the magnetometer registers to follow 00193 // the accelerometer registers 00194 // [4]: m_maxmin_dis=0 to retain default min/max latching even though not used 00195 // [3]: m_maxmin_dis_ths=0 00196 // [2]: m_maxmin_rst=0 00197 // [1-0]: m_rst_cnt=00 to enable magnetic reset each cycle 00198 data = 0x20; 00199 send_byte_to_reg(data,FXOS8700CQ_M_CTRL_REG2); 00200 00201 // write 0000 0001= 0x01 to XYZ_DATA_CFG register 00202 // [7]: reserved 00203 // [6]: reserved 00204 // [5]: reserved 00205 // [4]: hpf_out=0 00206 // [3]: reserved 00207 // [2]: reserved 00208 // [1-0]: fs=01 for accelerometer range of +/-4g range with 0.488mg/LSB 00209 data = 0x01; 00210 send_byte_to_reg(data,FXOS8700CQ_XYZ_DATA_CFG); 00211 00212 // write 0000 1101 = 0x0D to accelerometer control register 1 00213 // [7-6]: aslp_rate=00 00214 // [5-3]: dr=001 for 200Hz data rate (when in hybrid mode) 00215 // [2]: lnoise=1 for low noise mode 00216 // [1]: f_read=0 for normal 16 bit reads 00217 // [0]: active=1 to take the part out of standby and enable sampling 00218 data = 0x0D; 00219 send_byte_to_reg(data,FXOS8700CQ_CTRL_REG1); 00220 00221 printf("Initialisation complete!\n"); 00222 00223 }
Generated on Tue Jul 19 2022 02:33:20 by 1.7.2