00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef __DIMU_H__
00013 #define __DIMU_H__
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #pragma systemFile
00038
00039 #ifndef __COMMON_H__
00040 #include "common.h"
00041 #endif
00042
00043
00044
00045 #ifdef STRUCT_CODE_ENABLED
00046 #warn "You have enabled experimental code!"
00047 #endif
00048
00049 #define DIMU_GYRO_I2C_ADDR 0xD2
00050
00051 #define DIMU_GYRO_RANGE_250 0x00
00052 #define DIMU_GYRO_RANGE_500 0x10
00053 #define DIMU_GYRO_RANGE_2000 0x30
00054 #define DIMU_CTRL4_BLOCKDATA 0x80
00055
00056 #define DIMU_GYRO_CTRL_REG1 0x20
00057 #define DIMU_GYRO_CTRL_REG2 0x21
00058 #define DIMU_GYRO_CTRL_REG3 0x22
00059 #define DIMU_GYRO_CTRL_REG4 0x23
00060 #define DIMU_GYRO_CTRL_REG5 0x24
00061
00062 #define DIMU_GYRO_ALL_AXES 0x28
00063 #define DIMU_GYRO_X_AXIS 0x2A
00064 #define DIMU_GYRO_Y_AXIS 0x28
00065 #define DIMU_GYRO_Z_AXIS 0x2C
00066
00067 #define DIMU_ACC_I2C_ADDR 0x3A
00068 #define DIMU_ACC_RANGE_2G 0x04
00069 #define DIMU_ACC_RANGE_4G 0x08
00070 #define DIMU_ACC_RANGE_8G 0x00
00071 #define DIMU_ACC_MODE_STBY 0x00
00072 #define DIMU_ACC_MODE_MEAS 0x01
00073 #define DIMU_ACC_MODE_LVLD 0x02
00074 #define DIMU_ACC_MODE_PLSE 0x03
00075 #define DIMU_ACC_X_AXIS 0x00
00076 #define DIMU_ACC_Y_AXIS 0x02
00077 #define DIMU_ACC_Z_AXIS 0x04
00078
00079 #define DIMUreadGyroXAxis(X) DIMUreadGyroAxis(X, DIMU_GYRO_X_AXIS)
00080 #define DIMUreadGyroYAxis(X) DIMUreadGyroAxis(X, DIMU_GYRO_Y_AXIS)
00081 #define DIMUreadGyroZAxis(X) DIMUreadGyroAxis(X, DIMU_GYRO_Z_AXIS)
00082
00083 #define DIMUreadAccelXAxis10Bit(X) DIMUreadAccelAxis10Bit(X, DIMU_ACC_X_AXIS)
00084 #define DIMUreadAccelYAxis10Bit(X) DIMUreadAccelAxis10Bit(X, DIMU_ACC_Y_AXIS)
00085 #define DIMUreadAccelZAxis10Bit(X) DIMUreadAccelAxis10Bit(X, DIMU_ACC_Z_AXIS)
00086
00087 #define DIMUreadAccelXAxis8Bit(X) DIMUreadAccelAxis8Bit(X, DIMU_ACC_X_AXIS)
00088 #define DIMUreadAccelYAxis8Bit(X) DIMUreadAccelAxis8Bit(X, DIMU_ACC_Y_AXIS)
00089 #define DIMUreadAccelZAxis8Bit(X) DIMUreadAccelAxis8Bit(X, DIMU_ACC_Z_AXIS)
00090
00091
00092 #ifdef STRUCT_CODE_ENABLED
00093 typedef struct
00094 {
00095 ubyte I2CAddress;
00096 tSensors link;
00097 tByteArray I2CRequest;
00098 tByteArray I2CReply;
00099 float gyroDivisor;
00100 float accelDivisor;
00101 float axesAccel8Bit[3];
00102 float axesAccel10Bit[3];
00103 float axesGyro8Bit[3];
00104 float axesGyro10Bit[3];
00105 } tDIMUdata, *tDIMUdataPtr;
00106 #endif
00107
00108 float DIMU_Gyro_divisor[4] = {0.0, 0.0, 0.0, 0.0};
00109 float DIMU_Accel_divisor[4] = {0.0, 0.0, 0.0, 0.0};
00110
00111 tByteArray DIMU_I2CRequest;
00112 tByteArray DIMU_I2CReply;
00113
00114
00115 bool DIMUconfigGyro(tSensors link, ubyte range, bool lpfenable=true);
00116 float DIMUreadGyroAxis(tSensors link, ubyte axis);
00117 void DIMUreadGyroAxes(tSensors link, float &_x, float &_y, float &_z);
00118 bool DIMUconfigAccel(tSensors link, ubyte range);
00119 float DIMUreadAccelAxis8Bit(tSensors link, ubyte axis);
00120 bool DIMUsetAccelAxisOffset(tSensors link, ubyte drift_reg, ubyte drift_LSB, ubyte drift_MSB);
00121 float DIMUreadAccelAxis10Bit(tSensors link, ubyte axis, bool calibrate = false);
00122 void DIMUreadAccelAxes8Bit(tSensors link, float &_x, float &_y, float &_z);
00123 void DIMUreadAccelAxes10Bit(tSensors link, float &_x, float &_y, float &_z);
00124 void DIMUcalAccel(tSensors link);
00125 bool DIMUconfigIMU(tSensors link, ubyte accelRange=DIMU_ACC_RANGE_8G, ubyte gyroRange=DIMU_GYRO_RANGE_250, bool lpfenable=true);
00126
00127 #ifdef STRUCT_CODE_ENABLED
00128 bool DIMUconfigGyro(tDIMUdataPtr sensor, ubyte range, bool lpfenable=true);
00129 void DIMUreadGyroAxes(tDIMUdataPtr sensor);
00130 bool DIMUconfigAccel(tDIMUdataPtr sensor, ubyte range);
00131 void DIMUreadAccelAxes8Bit(tDIMUdataPtr sensor);
00132 void DIMUreadAccelAxes10Bit(tDIMUdataPtr sensor);
00133 void DIMUcalAccel(tDIMUdataPtr sensor);
00134 bool DIMUconfigIMU(tDIMUdataPtr sensor, ubyte accelRange=DIMU_ACC_RANGE_8G, ubyte gyroRange=DIMU_GYRO_RANGE_250, bool lpfenable=true);
00135 #endif
00136
00137
00138
00139
00140
00141
00142
00143
00144 bool DIMUconfigGyro(tSensors link, ubyte range, bool lpfenable){
00145 memset(DIMU_I2CRequest, 0, sizeof(DIMU_I2CRequest));
00146
00147
00148 DIMU_I2CRequest[0] = 3;
00149 DIMU_I2CRequest[1] = 0xD2;
00150
00151
00152
00153 DIMU_I2CRequest[2] = DIMU_GYRO_CTRL_REG2;
00154 DIMU_I2CRequest[3] = 0x00;
00155 if (!writeI2C(link, DIMU_I2CRequest))
00156 return false;
00157
00158
00159
00160
00161 DIMU_I2CRequest[2] = DIMU_GYRO_CTRL_REG3;
00162 DIMU_I2CRequest[3] = 0x08;
00163 if(!writeI2C(link, DIMU_I2CRequest))
00164 return false;
00165
00166
00167
00168 DIMU_I2CRequest[2] = DIMU_GYRO_CTRL_REG4;
00169 DIMU_I2CRequest[3] = range + DIMU_CTRL4_BLOCKDATA;
00170 writeI2C(link, DIMU_I2CRequest);
00171
00172
00173 DIMU_I2CRequest[2] = DIMU_GYRO_CTRL_REG5;
00174 DIMU_I2CRequest[3] = (lpfenable) ? 0x02 : 0x00;
00175 if (!writeI2C(link, DIMU_I2CRequest))
00176 return false;
00177
00178
00179
00180 DIMU_I2CRequest[2] = DIMU_GYRO_CTRL_REG1;
00181 DIMU_I2CRequest[3] = 0x0F;
00182 if (!writeI2C(link, DIMU_I2CRequest))
00183 return false;
00184
00185
00186
00187
00188 if(range == 0)
00189 DIMU_Gyro_divisor[link] = 114.28571;
00190 else if (range == 0x10)
00191 DIMU_Gyro_divisor[link] = 57.142857;
00192 else if (range == 0x30)
00193 DIMU_Gyro_divisor[link] = 14.285714;
00194
00195 return true;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 float DIMUreadGyroAxis(tSensors link, ubyte axis){
00206
00207
00208
00209 DIMU_I2CRequest[0] = 2;
00210 DIMU_I2CRequest[1] = DIMU_GYRO_I2C_ADDR;
00211 DIMU_I2CRequest[2] = axis + 0x80;
00212
00213 if (!writeI2C(link, DIMU_I2CRequest, DIMU_I2CReply, 2)) {
00214 writeDebugStreamLine("error write");
00215 return 0;
00216 }
00217
00218 return (DIMU_I2CReply[0]+((long)(DIMU_I2CReply[1]<<8)))/DIMU_Gyro_divisor[link];
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 void DIMUreadGyroAxes(tSensors link, float &_x, float &_y, float &_z){
00231 DIMU_I2CRequest[0] = 2;
00232 DIMU_I2CRequest[1] = DIMU_GYRO_I2C_ADDR;
00233 DIMU_I2CRequest[2] = DIMU_GYRO_ALL_AXES + 0x80;
00234
00235 if (!writeI2C(link, DIMU_I2CRequest, DIMU_I2CReply, 6)) {
00236 writeDebugStreamLine("error write");
00237 return;
00238 }
00239
00240 _y = (DIMU_I2CReply[0]+((long)(DIMU_I2CReply[1]<<8)))/DIMU_Gyro_divisor[link];
00241 _x = (DIMU_I2CReply[2]+((long)(DIMU_I2CReply[3]<<8)))/DIMU_Gyro_divisor[link];
00242 _z = (DIMU_I2CReply[4]+((long)(DIMU_I2CReply[5]<<8)))/DIMU_Gyro_divisor[link];
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252 bool DIMUconfigAccel(tSensors link, ubyte range) {
00253 switch(range) {
00254 case DIMU_ACC_RANGE_2G: DIMU_Accel_divisor[link] = 64.0; break;
00255 case DIMU_ACC_RANGE_4G: DIMU_Accel_divisor[link] = 32.0; break;
00256 case DIMU_ACC_RANGE_8G: DIMU_Accel_divisor[link] = 16.0; break;
00257 }
00258
00259 DIMU_I2CRequest[0] = 3;
00260 DIMU_I2CRequest[1] = DIMU_ACC_I2C_ADDR;
00261
00262
00263
00264 DIMU_I2CRequest[2] = 0x16;
00265 DIMU_I2CRequest[3] = range | DIMU_ACC_MODE_MEAS;
00266 if (!writeI2C(link, DIMU_I2CRequest))
00267 return false;
00268
00269 DIMUcalAccel(link);
00270 return true;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280 float DIMUreadAccelAxis8Bit(tSensors link, ubyte axis){
00281 int sensorReading = 0;
00282 DIMU_I2CRequest[0] = 2;
00283 DIMU_I2CRequest[1] = DIMU_ACC_I2C_ADDR;
00284
00285 switch (axis) {
00286 case DIMU_ACC_X_AXIS: DIMU_I2CRequest[2] = 0x06; break;
00287 case DIMU_ACC_Y_AXIS: DIMU_I2CRequest[2] = 0x07; break;
00288 case DIMU_ACC_Z_AXIS: DIMU_I2CRequest[2] = 0x08; break;
00289 }
00290
00291 if (!writeI2C(link, DIMU_I2CRequest, DIMU_I2CReply, 1))
00292 return 0;
00293
00294 sensorReading = (int)DIMU_I2CReply[0];
00295 return ((sensorReading > 128) ? sensorReading - 256 : sensorReading) / DIMU_Accel_divisor[link];
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 bool DIMUsetAccelAxisOffset(tSensors link, ubyte drift_reg, ubyte drift_LSB, ubyte drift_MSB){
00308 DIMU_I2CRequest[0] = 3;
00309 DIMU_I2CRequest[1] = DIMU_ACC_I2C_ADDR;
00310
00311 DIMU_I2CRequest[2] = drift_reg;
00312 DIMU_I2CRequest[3] = drift_LSB;
00313 if (!writeI2C(link, DIMU_I2CRequest))
00314 return false;
00315
00316 DIMU_I2CRequest[2] = drift_reg + 1;
00317 DIMU_I2CRequest[3] = drift_MSB;
00318 return writeI2C(link, DIMU_I2CRequest);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 float DIMUreadAccelAxis10Bit(tSensors link, ubyte axis, bool calibrate){
00330 int ureading = 0;
00331 int sreading = 0;
00332 int drift_offset = 0;
00333
00334 if (calibrate == true) {
00335 writeDebugStreamLine("axis: %d", axis);
00336 DIMUsetAccelAxisOffset(link, 0x10 + axis, 0x00, 0x00);
00337 wait1Msec(50);
00338 }
00339
00340 DIMU_I2CRequest[0] = 2;
00341 DIMU_I2CRequest[1] = DIMU_ACC_I2C_ADDR;
00342 DIMU_I2CRequest[2] = axis;
00343
00344 if (!writeI2C(link, DIMU_I2CRequest, DIMU_I2CReply, 2))
00345 return 0;
00346
00347 ureading = DIMU_I2CReply[0] + (DIMU_I2CReply[1] << 8) & 0x3FF;
00348 sreading = (ureading > 511) ? ureading - 1024 : ureading;
00349
00350
00351 if (calibrate == true) {
00352 wait1Msec(50);
00353 switch (axis) {
00354 case DIMU_ACC_X_AXIS: drift_offset = ( 0 - sreading ) * 2; break;
00355 case DIMU_ACC_Y_AXIS: drift_offset = ( 0 - sreading ) * 2; break;
00356 case DIMU_ACC_Z_AXIS: drift_offset = ( 64 - sreading ) * 2; break;
00357 }
00358 DIMUsetAccelAxisOffset(link, 0x10 + axis, drift_offset & 0x00ff, (drift_offset & 0xff00 ) >> 8);
00359 }
00360
00361 return sreading / 64.0;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 void DIMUreadAccelAxes8Bit(tSensors link, float &_x, float &_y, float &_z){
00373 _x = DIMUreadAccelAxis8Bit(link, DIMU_ACC_X_AXIS);
00374 _y = DIMUreadAccelAxis8Bit(link, DIMU_ACC_Y_AXIS);
00375 _z = DIMUreadAccelAxis8Bit(link, DIMU_ACC_Z_AXIS);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 void DIMUreadAccelAxes10Bit(tSensors link, float &_x, float &_y, float &_z){
00387 _x = DIMUreadAccelAxis10Bit(link, DIMU_ACC_X_AXIS);
00388 _y = DIMUreadAccelAxis10Bit(link, DIMU_ACC_Y_AXIS);
00389 _z = DIMUreadAccelAxis10Bit(link, DIMU_ACC_Z_AXIS);
00390 }
00391
00392
00393
00394
00395
00396
00397 void DIMUcalAccel(tSensors link){
00398 DIMUreadAccelAxis10Bit(link, DIMU_ACC_X_AXIS, true);
00399 DIMUreadAccelAxis10Bit(link, DIMU_ACC_Y_AXIS, true);
00400 DIMUreadAccelAxis10Bit(link, DIMU_ACC_Z_AXIS, true);
00401 wait1Msec(100);
00402 }
00403
00404
00405 bool DIMUconfigIMU(tSensors link, ubyte accelRange, ubyte gyroRange, bool lpfenable)
00406 {
00407 if (!DIMUconfigGyro(link, gyroRange, lpfenable))
00408 return false;
00409
00410 return DIMUconfigAccel(link, accelRange);
00411 }
00412
00413
00414 #ifdef STRUCT_CODE_ENABLED
00415 bool DIMUconfigGyro(tDIMUdataPtr sensor, ubyte range, bool lpfenable)
00416 {
00417 memset(sensor->I2CRequest, 0, sizeof(tByteArray));
00418
00419
00420 sensor->I2CRequest[0] = 3;
00421 sensor->I2CRequest[1] = 0xD2;
00422
00423
00424
00425 sensor->I2CRequest[2] = DIMU_GYRO_CTRL_REG2;
00426 sensor->I2CRequest[3] = 0x00;
00427 if (!writeI2C(link, sensor->I2CRequest))
00428 return false;
00429
00430
00431
00432
00433 sensor->I2CRequest[2] = DIMU_GYRO_CTRL_REG3;
00434 sensor->I2CRequest[3] = 0x08;
00435 if(!writeI2C(link, sensor->I2CRequest))
00436 return false;
00437
00438
00439
00440 sensor->I2CRequest = DIMU_GYRO_CTRL_REG4;
00441 sensor->I2CRequest[3] = range + DIMU_CTRL4_BLOCKDATA;
00442 writeI2C(link, sensor->I2CRequest);
00443
00444
00445 sensor->I2CRequest[2] = DIMU_GYRO_CTRL_REG5;
00446 sensor->I2CRequest[3] = (lpfenable) ? 0x02 : 0x00;
00447 if (!writeI2C(link, sensor->I2CRequest))
00448 return false;
00449
00450
00451
00452 sensor->I2CRequest[2] = DIMU_GYRO_CTRL_REG1;
00453 sensor->I2CRequest[3] = 0x0F;
00454 if (!writeI2C(link, sensor->I2CRequest))
00455 return false;
00456
00457
00458
00459
00460 if(range == 0)
00461 DIMU_Gyro_divisor[link] = 114.28571;
00462 else if (range == 0x10)
00463 DIMU_Gyro_divisor[link] = 57.142857;
00464 else if (range == 0x30)
00465 DIMU_Gyro_divisor[link] = 14.285714;
00466
00467 return true;
00468 }
00469
00470 void DIMUreadGyroAxes(tDIMUdataPtr sensor)
00471 {
00472
00473 }
00474 bool DIMUconfigAccel(tDIMUdataPtr sensor, ubyte range)
00475 {
00476
00477 }
00478 void DIMUreadAccelAxes8Bit(tDIMUdataPtr sensor)
00479 {
00480
00481 }
00482 void DIMUreadAccelAxes10Bit(tDIMUdataPtr sensor)
00483 {
00484
00485 }
00486 void DIMUcalAccel(tDIMUdataPtr sensor)
00487 {
00488
00489 }
00490 bool DIMUconfigIMU(tDIMUdataPtr sensor, ubyte accelRange, ubyte gyroRange, bool lpfenable)
00491 {
00492
00493 }
00494 #endif
00495
00496 #endif // __DIMU_H__
00497
00498
00499
00500
00501
00502