Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of ITG3200 by
ITG3200.cpp
00001 /** 00002 * @file ITG3200.cpp 00003 * @author Aaron Berk 00004 * 00005 * @section LICENSE 00006 * 00007 * Copyright (c) 2010 ARM Limited 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining a copy 00010 * of this software and associated documentation files (the "Software"), to deal 00011 * in the Software without restriction, including without limitation the rights 00012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 * copies of the Software, and to permit persons to whom the Software is 00014 * furnished to do so, subject to the following conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be included in 00017 * all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 * THE SOFTWARE. 00026 * 00027 * @section DESCRIPTION 00028 * 00029 * ITG-3200 triple axis, digital interface, gyroscope. 00030 * 00031 * Datasheet: 00032 * 00033 * http://invensense.com/mems/gyro/documents/PS-ITG-3200-00-01.4.pdf 00034 */ 00035 00036 #include "ITG3200.h " 00037 #include <new> 00038 00039 ITG3200::ITG3200(PinName sda, PinName scl, bool fastmode) : calibSamples(0), i2c_(*reinterpret_cast<I2C*>(i2cRaw)){ 00040 // Placement new to avoid additional heap memory allocation. 00041 new(i2cRaw) I2C(sda, scl); 00042 00043 offset[0] = offset[1] = offset[2] = 0; 00044 00045 if(fastmode){ 00046 //400kHz, fast mode. 00047 i2c_.frequency(400000); 00048 } 00049 else 00050 i2c_.frequency(100000); 00051 } 00052 00053 ITG3200::~ITG3200(){ 00054 // If the I2C object is initialized in the buffer in this object, call destructor of it. 00055 if(&i2c_ == reinterpret_cast<I2C*>(&i2cRaw)) 00056 reinterpret_cast<I2C*>(&i2cRaw)->~I2C(); 00057 } 00058 00059 void ITG3200::init(){ 00060 //Set FS_SEL to 0x03 for proper operation. 00061 //See datasheet for details. 00062 char tx[2]; 00063 tx[0] = DLPF_FS_REG; 00064 //FS_SEL bits sit in bits 4 and 3 of DLPF_FS register. 00065 tx[1] = 0x03 << 3; 00066 00067 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, tx, 2); 00068 00069 } 00070 00071 void ITG3200::setCalibrationCurve(const float offset[3], const float slope[3]){ 00072 if(offset){ 00073 for(int i = 0; i < 3; i++) 00074 this->foffset[i] = offset[i]; 00075 } 00076 if(slope){ 00077 for(int i = 0; i < 3; i++) 00078 this->slope[i] = slope[i]; 00079 } 00080 } 00081 00082 char ITG3200::getWhoAmI(void){ 00083 00084 //WhoAmI Register address. 00085 char tx = WHO_AM_I_REG; 00086 char rx; 00087 00088 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00089 00090 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00091 00092 return rx; 00093 00094 } 00095 00096 void ITG3200::setWhoAmI(char address){ 00097 00098 char tx[2]; 00099 tx[0] = WHO_AM_I_REG; 00100 tx[1] = address; 00101 00102 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, tx, 2); 00103 00104 } 00105 00106 char ITG3200::getSampleRateDivider(void){ 00107 00108 char tx = SMPLRT_DIV_REG; 00109 char rx; 00110 00111 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00112 00113 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00114 00115 return rx; 00116 00117 } 00118 00119 void ITG3200::setSampleRateDivider(char divider){ 00120 00121 char tx[2]; 00122 tx[0] = SMPLRT_DIV_REG; 00123 tx[1] = divider; 00124 00125 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, tx, 2); 00126 00127 } 00128 00129 int ITG3200::getInternalSampleRate(void){ 00130 00131 char tx = DLPF_FS_REG; 00132 char rx; 00133 00134 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00135 00136 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00137 00138 //DLPF_CFG == 0 -> sample rate = 8kHz. 00139 if(rx == 0){ 00140 return 8; 00141 } 00142 //DLPF_CFG = 1..7 -> sample rate = 1kHz. 00143 else if(rx >= 1 && rx <= 7){ 00144 return 1; 00145 } 00146 //DLPF_CFG = anything else -> something's wrong! 00147 else{ 00148 return -1; 00149 } 00150 00151 } 00152 00153 void ITG3200::setLpBandwidth(char bandwidth){ 00154 00155 char tx[2]; 00156 tx[0] = DLPF_FS_REG; 00157 //Bits 4,3 are required to be 0x03 for proper operation. 00158 tx[1] = bandwidth | (0x03 << 3); 00159 00160 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, tx, 2); 00161 00162 } 00163 00164 char ITG3200::getInterruptConfiguration(void){ 00165 00166 char tx = INT_CFG_REG; 00167 char rx; 00168 00169 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00170 00171 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00172 00173 return rx; 00174 00175 } 00176 00177 void ITG3200::setInterruptConfiguration(char config){ 00178 00179 char tx[2]; 00180 tx[0] = INT_CFG_REG; 00181 tx[1] = config; 00182 00183 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, tx, 2); 00184 00185 } 00186 00187 bool ITG3200::isPllReady(void){ 00188 00189 char tx = INT_STATUS; 00190 char rx; 00191 00192 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00193 00194 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00195 00196 //ITG_RDY bit is bit 4 of INT_STATUS register. 00197 if(rx & 0x04){ 00198 return true; 00199 } 00200 else{ 00201 return false; 00202 } 00203 00204 } 00205 00206 bool ITG3200::isRawDataReady(void){ 00207 00208 char tx = INT_STATUS; 00209 char rx; 00210 00211 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00212 00213 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00214 00215 //RAW_DATA_RDY bit is bit 1 of INT_STATUS register. 00216 if(rx & 0x01){ 00217 return true; 00218 } 00219 else{ 00220 return false; 00221 } 00222 00223 } 00224 00225 int ITG3200::getWord(int regi){ 00226 00227 char tx = regi; 00228 char rx[2]; 00229 00230 i2c_.write(I2C_ADDRESS, &tx, 1); 00231 00232 i2c_.read(I2C_ADDRESS, rx, 2); 00233 00234 return swapExtend(rx); 00235 } 00236 00237 float ITG3200::getTemperature(){ 00238 //Offset = -35 degrees, 13200 counts. 280 counts/degrees C. 00239 return 35.0 + ((getRawTemperature() + 13200)/280.0); 00240 00241 } 00242 00243 void ITG3200::getRawGyroXYZ(int readings[3]){ 00244 00245 char tx = GYRO_XOUT_H_REG; 00246 char rx[2]; 00247 00248 i2c_.write(I2C_ADDRESS, &tx, 1); 00249 00250 i2c_.read(I2C_ADDRESS, rx, 6); 00251 00252 for(int i = 0; i < 3; i++) 00253 readings[i] = swapExtend(&rx[i * 2]); 00254 } 00255 00256 void ITG3200::getGyroXYZ(int readings[3], Correction corr){ 00257 getRawGyroXYZ(readings); 00258 switch(corr){ 00259 case OffsetCorrection: 00260 for(int i = 0; i < 3; i++) 00261 readings[i] -= offset[i]; 00262 break; 00263 case Calibration: 00264 { 00265 float temp = getTemperature(); 00266 for(int i = 0; i < 3; i++) 00267 readings[i] -= slope[i] * temp + foffset[i]; 00268 } 00269 break; 00270 } 00271 } 00272 00273 00274 char ITG3200::getPowerManagement(void){ 00275 00276 char tx = PWR_MGM_REG; 00277 char rx; 00278 00279 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, &tx, 1); 00280 00281 i2c_.read((ITG3200_I2C_ADDRESS << 1) | 0x01, &rx, 1); 00282 00283 return rx; 00284 00285 } 00286 00287 void ITG3200::setPowerManagement(char config){ 00288 00289 char tx[2]; 00290 tx[0] = PWR_MGM_REG; 00291 tx[1] = config; 00292 00293 i2c_.write((ITG3200_I2C_ADDRESS << 1) & 0xFE, tx, 2); 00294 00295 } 00296 00297 void ITG3200::calibrate(double time){ 00298 long sum[3] = {0}; 00299 int sumCount = 0; 00300 Timer t; 00301 t.start(); 00302 while(t.read() < time){ 00303 int gyro[3]; 00304 getRawGyroXYZ(gyro); 00305 for(int i = 0; i < 3; i++) 00306 sum[i] += gyro[i]; 00307 sumCount++; 00308 } 00309 t.stop(); 00310 00311 // Avoid zero division 00312 if(0 < sumCount){ 00313 for(int i = 0; i < 3; i++) 00314 offset[i] = sum[i] / sumCount; 00315 // Update member variable only if successful 00316 calibSamples = sumCount; 00317 } 00318 }
Generated on Wed Jul 20 2022 11:54:17 by
1.7.2
