Erik van de Coevering
/
Multicopter_2018
Latest version of my quadcopter controller with an LPC1768 and MPU9250.
Embed:
(wiki syntax)
Show/hide line numbers
MPU9250_SPI.cpp
00001 /*CODED by Qiyong Mu on 21/06/2014 00002 kylongmu@msn.com 00003 */ 00004 00005 #include <mbed.h> 00006 #include "MPU9250_SPI.h" 00007 00008 mpu9250_spi::mpu9250_spi(SPI& _spi, PinName _cs) : spi(_spi), cs(_cs) {} 00009 00010 unsigned int mpu9250_spi::WriteReg( uint8_t WriteAddr, uint8_t WriteData ) 00011 { 00012 unsigned int temp_val; 00013 select(); 00014 spi.write(WriteAddr); 00015 temp_val=spi.write(WriteData); 00016 deselect(); 00017 wait_us(5); 00018 return temp_val; 00019 } 00020 unsigned int mpu9250_spi::ReadReg( uint8_t WriteAddr, uint8_t WriteData ) 00021 { 00022 return WriteReg(WriteAddr | READ_FLAG,WriteData); 00023 } 00024 void mpu9250_spi::ReadRegs( uint8_t ReadAddr, uint8_t *ReadBuf, unsigned int Bytes ) 00025 { 00026 unsigned int i = 0; 00027 00028 select(); 00029 spi.write(ReadAddr | READ_FLAG); 00030 for(i=0; i<Bytes; i++) 00031 ReadBuf[i] = spi.write(0x00); 00032 deselect(); 00033 //wait_us(50); 00034 } 00035 00036 /*----------------------------------------------------------------------------------------------- 00037 INITIALIZATION 00038 usage: call this function at startup, giving the sample rate divider (raging from 0 to 255) and 00039 low pass filter value; suitable values are: 00040 BITS_DLPF_CFG_256HZ_NOLPF2 00041 BITS_DLPF_CFG_188HZ 00042 BITS_DLPF_CFG_98HZ 00043 BITS_DLPF_CFG_42HZ 00044 BITS_DLPF_CFG_20HZ 00045 BITS_DLPF_CFG_10HZ 00046 BITS_DLPF_CFG_5HZ 00047 BITS_DLPF_CFG_2100HZ_NOLPF 00048 returns 1 if an error occurred 00049 -----------------------------------------------------------------------------------------------*/ 00050 #define MPU_InitRegNum 17 00051 00052 bool mpu9250_spi::init(int sample_rate_div,int low_pass_filter){ 00053 uint8_t i = 0; 00054 uint8_t MPU_Init_Data[MPU_InitRegNum][2] = { 00055 {0x80, MPUREG_PWR_MGMT_1}, // Reset Device 00056 {0x01, MPUREG_PWR_MGMT_1}, // Clock Source 00057 {0x00, MPUREG_PWR_MGMT_2}, // Enable Acc & Gyro 00058 {0x01, MPUREG_CONFIG}, // Use DLPF set Gyroscope bandwidth 184Hz, temperature bandwidth 188Hz //3 00059 {0x08, MPUREG_GYRO_CONFIG}, // +-1000dps = 10 / 500 00060 {0x00, MPUREG_ACCEL_CONFIG}, // +-2G 00061 {0x03, MPUREG_ACCEL_CONFIG_2}, // Set Acc Data Rates, Enable Acc LPF , Bandwidth 41Hz 00062 {0x30, MPUREG_INT_PIN_CFG}, // 00063 //{0x40, MPUREG_I2C_MST_CTRL}, // I2C Speed 348 kHz 00064 //{0x20, MPUREG_USER_CTRL}, // Enable AUX 00065 {0x20, MPUREG_USER_CTRL}, // I2C Master mode 00066 {0x0D, MPUREG_I2C_MST_CTRL}, // I2C configuration multi-master IIC 400KHz 00067 00068 {AK8963_I2C_ADDR, MPUREG_I2C_SLV0_ADDR}, //Set the I2C slave addres of AK8963 and set for write. 00069 //{0x09, MPUREG_I2C_SLV4_CTRL}, 00070 //{0x81, MPUREG_I2C_MST_DELAY_CTRL}, //Enable I2C delay 00071 00072 {AK8963_CNTL2, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer 00073 {0x01, MPUREG_I2C_SLV0_DO}, // Reset AK8963 00074 {0x81, MPUREG_I2C_SLV0_CTRL}, //Enable I2C and set 1 byte 00075 00076 {AK8963_CNTL1, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer 00077 {0x12, MPUREG_I2C_SLV0_DO}, // Register value to continuous measurement in 16bit 00078 {0x81, MPUREG_I2C_SLV0_CTRL} //Enable I2C and set 1 byte 00079 00080 }; 00081 spi.format(8,0); 00082 spi.frequency(4000000); 00083 00084 for(i=0; i<MPU_InitRegNum; i++) { 00085 WriteReg(MPU_Init_Data[i][1], MPU_Init_Data[i][0]); 00086 wait(0.001); //I2C must slow down the write speed, otherwise it won't work 00087 } 00088 00089 set_acc_scale(BITS_FS_2G); 00090 set_gyro_scale(BITS_FS_1000DPS); 00091 00092 //AK8963_calib_Magnetometer(); //Can't load this function here , strange problem? 00093 return 0; 00094 } 00095 00096 bool mpu9250_spi::init2(int sample_rate_div,int low_pass_filter){ 00097 uint8_t i = 0; 00098 uint8_t MPU_Init_Data[MPU_InitRegNum][2] = { 00099 {0x80, MPUREG_PWR_MGMT_1}, // Reset Device 00100 {0x01, MPUREG_PWR_MGMT_1}, // Clock Source 00101 {0x00, MPUREG_PWR_MGMT_2}, // Enable Acc & Gyro 00102 {0x01, MPUREG_CONFIG}, // Use DLPF set Gyroscope bandwidth 184Hz, temperature bandwidth 188Hz //3 00103 {0x08, MPUREG_GYRO_CONFIG}, // +-1000dps = 10 / 500 00104 {0x00, MPUREG_ACCEL_CONFIG}, // +-2G 00105 {0x08, MPUREG_ACCEL_CONFIG_2}, // Set Acc Data Rates, Enable Acc LPF , Bandwidth 41Hz 00106 {0x30, MPUREG_INT_PIN_CFG}, // 00107 //{0x40, MPUREG_I2C_MST_CTRL}, // I2C Speed 348 kHz 00108 //{0x20, MPUREG_USER_CTRL}, // Enable AUX 00109 {0x20, MPUREG_USER_CTRL}, // I2C Master mode 00110 {0x0D, MPUREG_I2C_MST_CTRL}, // I2C configuration multi-master IIC 400KHz 00111 00112 {AK8963_I2C_ADDR, MPUREG_I2C_SLV0_ADDR}, //Set the I2C slave addres of AK8963 and set for write. 00113 //{0x09, MPUREG_I2C_SLV4_CTRL}, 00114 //{0x81, MPUREG_I2C_MST_DELAY_CTRL}, //Enable I2C delay 00115 00116 {AK8963_CNTL2, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer 00117 {0x01, MPUREG_I2C_SLV0_DO}, // Reset AK8963 00118 {0x81, MPUREG_I2C_SLV0_CTRL}, //Enable I2C and set 1 byte 00119 00120 {AK8963_CNTL1, MPUREG_I2C_SLV0_REG}, //I2C slave 0 register address from where to begin data transfer 00121 {0x12, MPUREG_I2C_SLV0_DO}, // Register value to continuous measurement in 16bit 00122 {0x81, MPUREG_I2C_SLV0_CTRL} //Enable I2C and set 1 byte 00123 00124 }; 00125 spi.format(8,0); 00126 spi.frequency(4000000); 00127 00128 for(i=0; i<MPU_InitRegNum; i++) { 00129 WriteReg(MPU_Init_Data[i][1], MPU_Init_Data[i][0]); 00130 wait(0.001); //I2C must slow down the write speed, otherwise it won't work 00131 } 00132 00133 set_acc_scale(BITS_FS_2G); 00134 set_gyro_scale(BITS_FS_1000DPS); 00135 00136 //AK8963_calib_Magnetometer(); //Can't load this function here , strange problem? 00137 return 0; 00138 } 00139 /*----------------------------------------------------------------------------------------------- 00140 ACCELEROMETER SCALE 00141 usage: call this function at startup, after initialization, to set the right range for the 00142 accelerometers. Suitable ranges are: 00143 BITS_FS_2G 00144 BITS_FS_4G 00145 BITS_FS_8G 00146 BITS_FS_16G 00147 returns the range set (2,4,8 or 16) 00148 -----------------------------------------------------------------------------------------------*/ 00149 unsigned int mpu9250_spi::set_acc_scale(int scale){ 00150 unsigned int temp_scale; 00151 //WriteReg(MPUREG_ACCEL_CONFIG, scale); 00152 00153 switch (scale){ 00154 case BITS_FS_2G: 00155 acc_divider=16384; 00156 break; 00157 case BITS_FS_4G: 00158 acc_divider=8192; 00159 break; 00160 case BITS_FS_8G: 00161 acc_divider=4096; 00162 break; 00163 case BITS_FS_16G: 00164 acc_divider=2048; 00165 break; 00166 } 00167 //temp_scale=WriteReg(MPUREG_ACCEL_CONFIG|READ_FLAG, 0x00); 00168 00169 switch (temp_scale){ 00170 case BITS_FS_2G: 00171 temp_scale=2; 00172 break; 00173 case BITS_FS_4G: 00174 temp_scale=4; 00175 break; 00176 case BITS_FS_8G: 00177 temp_scale=8; 00178 break; 00179 case BITS_FS_16G: 00180 temp_scale=16; 00181 break; 00182 } 00183 return temp_scale; 00184 } 00185 00186 00187 /*----------------------------------------------------------------------------------------------- 00188 GYROSCOPE SCALE 00189 usage: call this function at startup, after initialization, to set the right range for the 00190 gyroscopes. Suitable ranges are: 00191 BITS_FS_250DPS 00192 BITS_FS_500DPS 00193 BITS_FS_1000DPS 00194 BITS_FS_2000DPS 00195 returns the range set (250,500,1000 or 2000) 00196 -----------------------------------------------------------------------------------------------*/ 00197 unsigned int mpu9250_spi::set_gyro_scale(int scale){ 00198 unsigned int temp_scale; 00199 //WriteReg(MPUREG_GYRO_CONFIG, scale); 00200 switch (scale){ 00201 case BITS_FS_250DPS: 00202 gyro_divider=131; 00203 break; 00204 case BITS_FS_500DPS: 00205 gyro_divider=65.5; 00206 break; 00207 case BITS_FS_1000DPS: 00208 gyro_divider=32.8; 00209 break; 00210 case BITS_FS_2000DPS: 00211 gyro_divider=16.4; 00212 break; 00213 } 00214 //temp_scale=WriteReg(MPUREG_GYRO_CONFIG|READ_FLAG, 0x00); 00215 switch (temp_scale){ 00216 case BITS_FS_250DPS: 00217 temp_scale=250; 00218 break; 00219 case BITS_FS_500DPS: 00220 temp_scale=500; 00221 break; 00222 case BITS_FS_1000DPS: 00223 temp_scale=1000; 00224 break; 00225 case BITS_FS_2000DPS: 00226 temp_scale=2000; 00227 break; 00228 } 00229 return temp_scale; 00230 } 00231 00232 00233 /*----------------------------------------------------------------------------------------------- 00234 WHO AM I? 00235 usage: call this function to know if SPI is working correctly. It checks the I2C address of the 00236 mpu9250 which should be 104 when in SPI mode. 00237 returns the I2C address (104) 00238 -----------------------------------------------------------------------------------------------*/ 00239 unsigned int mpu9250_spi::whoami(){ 00240 unsigned int response; 00241 response=WriteReg(MPUREG_WHOAMI|READ_FLAG, 0x00); 00242 return response; 00243 } 00244 00245 00246 /*----------------------------------------------------------------------------------------------- 00247 READ ACCELEROMETER 00248 usage: call this function to read accelerometer data. Axis represents selected axis: 00249 0 -> X axis 00250 1 -> Y axis 00251 2 -> Z axis 00252 -----------------------------------------------------------------------------------------------*/ 00253 void mpu9250_spi::read_acc() 00254 { 00255 uint8_t response[6]; 00256 int16_t bit_data; 00257 float data; 00258 int i; 00259 ReadRegs(MPUREG_ACCEL_XOUT_H,response,6); 00260 for(i=0; i<3; i++) { 00261 bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; 00262 data=(float)bit_data; 00263 accelerometer_data[i]=data/acc_divider; 00264 } 00265 00266 } 00267 00268 /*----------------------------------------------------------------------------------------------- 00269 READ GYROSCOPE 00270 usage: call this function to read gyroscope data. Axis represents selected axis: 00271 0 -> X axis 00272 1 -> Y axis 00273 2 -> Z axis 00274 -----------------------------------------------------------------------------------------------*/ 00275 void mpu9250_spi::read_rot() 00276 { 00277 uint8_t response[6]; 00278 int16_t bit_data; 00279 float data; 00280 int i; 00281 ReadRegs(MPUREG_GYRO_XOUT_H,response,6); 00282 for(i=0; i<3; i++) { 00283 bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; 00284 data=(float)bit_data; 00285 gyroscope_data[i]=data/gyro_divider; 00286 } 00287 00288 } 00289 00290 /*----------------------------------------------------------------------------------------------- 00291 READ TEMPERATURE 00292 usage: call this function to read temperature data. 00293 returns the value in °C 00294 -----------------------------------------------------------------------------------------------*/ 00295 void mpu9250_spi::read_temp(){ 00296 uint8_t response[2]; 00297 int16_t bit_data; 00298 float data; 00299 ReadRegs(MPUREG_TEMP_OUT_H,response,2); 00300 00301 bit_data=((int16_t)response[0]<<8)|response[1]; 00302 data=(float)bit_data; 00303 Temperature=(data/340)+36.53; 00304 deselect(); 00305 } 00306 00307 /*----------------------------------------------------------------------------------------------- 00308 READ ACCELEROMETER CALIBRATION 00309 usage: call this function to read accelerometer data. Axis represents selected axis: 00310 0 -> X axis 00311 1 -> Y axis 00312 2 -> Z axis 00313 returns Factory Trim value 00314 -----------------------------------------------------------------------------------------------*/ 00315 void mpu9250_spi::calib_acc() 00316 { 00317 uint8_t response[4]; 00318 int temp_scale; 00319 //READ CURRENT ACC SCALE 00320 temp_scale=WriteReg(MPUREG_ACCEL_CONFIG|READ_FLAG, 0x00); 00321 set_acc_scale(BITS_FS_8G); 00322 //ENABLE SELF TEST need modify 00323 //temp_scale=WriteReg(MPUREG_ACCEL_CONFIG, 0x80>>axis); 00324 00325 ReadRegs(MPUREG_SELF_TEST_X,response,4); 00326 calib_data[0]=((response[0]&11100000)>>3)|((response[3]&00110000)>>4); 00327 calib_data[1]=((response[1]&11100000)>>3)|((response[3]&00001100)>>2); 00328 calib_data[2]=((response[2]&11100000)>>3)|((response[3]&00000011)); 00329 00330 set_acc_scale(temp_scale); 00331 } 00332 uint8_t mpu9250_spi::AK8963_whoami(){ 00333 uint8_t response; 00334 WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read. 00335 WriteReg(MPUREG_I2C_SLV0_REG, AK8963_WIA); //I2C slave 0 register address from where to begin data transfer 00336 WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81); //Read 1 byte from the magnetometer 00337 00338 //WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81); //Enable I2C and set bytes 00339 wait(0.001); 00340 response=WriteReg(MPUREG_EXT_SENS_DATA_00|READ_FLAG, 0x00); //Read I2C 00341 //ReadRegs(MPUREG_EXT_SENS_DATA_00,response,1); 00342 //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00); //Read I2C 00343 00344 return response; 00345 } 00346 void mpu9250_spi::AK8963_calib_Magnetometer(){ 00347 uint8_t response[3]; 00348 float data; 00349 int i; 00350 00351 WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read. 00352 WriteReg(MPUREG_I2C_SLV0_REG, AK8963_ASAX); //I2C slave 0 register address from where to begin data transfer 00353 WriteReg(MPUREG_I2C_SLV0_CTRL, 0x83); //Read 3 bytes from the magnetometer 00354 00355 //WriteReg(MPUREG_I2C_SLV0_CTRL, 0x81); //Enable I2C and set bytes 00356 wait(0.001); 00357 //response[0]=WriteReg(MPUREG_EXT_SENS_DATA_01|READ_FLAG, 0x00); //Read I2C 00358 ReadRegs(MPUREG_EXT_SENS_DATA_00,response,3); 00359 00360 //response=WriteReg(MPUREG_I2C_SLV0_DO, 0x00); //Read I2C 00361 for(i=0; i<3; i++) { 00362 data=response[i]; 00363 Magnetometer_ASA[i]=((data-128)/256+1)*Magnetometer_Sensitivity_Scale_Factor; 00364 } 00365 } 00366 void mpu9250_spi::AK8963_read_Magnetometer(){ 00367 uint8_t response[7]; 00368 int16_t bit_data; 00369 float data; 00370 int i; 00371 00372 WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read. 00373 WriteReg(MPUREG_I2C_SLV0_REG, AK8963_HXL); //I2C slave 0 register address from where to begin data transfer 00374 WriteReg(MPUREG_I2C_SLV0_CTRL, 0x87); //Read 6 bytes from the magnetometer 00375 00376 wait(0.001); 00377 ReadRegs(MPUREG_EXT_SENS_DATA_00,response,7); 00378 //must start your read from AK8963A register 0x03 and read seven bytes so that upon read of ST2 register 0x09 the AK8963A will unlatch the data registers for the next measurement. 00379 for(i=0; i<3; i++) { 00380 bit_data=((int16_t)response[i*2+1]<<8)|response[i*2]; 00381 data=(float)bit_data; 00382 Magnetometer[i]=data*Magnetometer_ASA[i]; 00383 } 00384 } 00385 void mpu9250_spi::read_all(){ 00386 uint8_t response[21]; 00387 int16_t bit_data; 00388 float data; 00389 int i; 00390 spi.format(8,0); 00391 spi.frequency(4000000); 00392 //Send I2C command at first 00393 WriteReg(MPUREG_I2C_SLV0_ADDR,AK8963_I2C_ADDR|READ_FLAG); //Set the I2C slave addres of AK8963 and set for read. 00394 WriteReg(MPUREG_I2C_SLV0_REG, AK8963_HXL); //I2C slave 0 register address from where to begin data transfer 00395 WriteReg(MPUREG_I2C_SLV0_CTRL, 0x87); //Read 7 bytes from the magnetometer 00396 //must start your read from AK8963A register 0x03 and read seven bytes so that upon read of ST2 register 0x09 the AK8963A will unlatch the data registers for the next measurement. 00397 00398 //wait(0.001); 00399 ReadRegs(MPUREG_ACCEL_XOUT_H,response,21); 00400 //Get accelerometer value 00401 for(i=0; i<3; i++) { 00402 bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; 00403 data=(float)bit_data; 00404 accelerometer_data[i]=data/16384; 00405 } 00406 //Get temperature 00407 bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; 00408 data=(float)bit_data; 00409 Temperature=((data-21)/333.87)+21; 00410 //Get gyroscop value 00411 for(i=4; i<7; i++) { 00412 bit_data=((int16_t)response[i*2]<<8)|response[i*2+1]; 00413 data=(float)bit_data; 00414 gyroscope_data[i-4]=data/65.5; //32.8 00415 } 00416 //Get Magnetometer value 00417 for(i=7; i<10; i++) { 00418 bit_data=((int16_t)response[i*2+1]<<8)|response[i*2]; 00419 data=(float)bit_data; 00420 Magnetometer[i-7]=data*Magnetometer_ASA[i-7]; 00421 } 00422 } 00423 00424 /*----------------------------------------------------------------------------------------------- 00425 SPI SELECT AND DESELECT 00426 usage: enable and disable mpu9250 communication bus 00427 -----------------------------------------------------------------------------------------------*/ 00428 void mpu9250_spi::select() { 00429 //Set CS low to start transmission (interrupts conversion) 00430 cs = 0; 00431 } 00432 void mpu9250_spi::deselect() { 00433 //Set CS high to stop transmission (restarts conversion) 00434 cs = 1; 00435 } 00436
Generated on Fri Jul 15 2022 02:25:27 by 1.7.2