A test program for the MMA8452 accelerometer

Dependencies:   MMA8452 mbed

The test program runs a bunch of tests for the MMA8452 accelerometer.

What is below is not the test program, but an example to whet your appetite about the library.

#include "mbed.h"
#include "MMA8452.h"

int main() {
   Serial pc(USBTX,USBRX);
   pc.baud(115200);
   double x = 0, y = 0, z = 0;

   MMA8452 acc(p28, p27, 40000);
   acc.setBitDepth(MMA8452::BIT_DEPTH_12);
   acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
   acc.setDataRate(MMA8452::RATE_100);
   
   while(1) {
      if(!acc.isXYZReady()) {
         wait(0.01);
         continue;
      }
      acc.readXYZGravity(&x,&y,&z);
      pc.printf("Gravities: %lf %lf %lf\r\n",x,y,z);
   }
}

An easy way to test that this actually works is to run the loop above and hold the MMA8452 parallel to the ground along the respective axis (and upsidedown in each axis). You will see 1G on the respective axis and 0G on the others.

Committer:
ashleymills
Date:
Fri Mar 07 14:54:00 2014 +0000
Revision:
7:9b644d1c1405
Parent:
6:e3100f66ed6a
Updated child.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:0c17274c3b7c 1 #include "mbed.h"
ashleymills 0:0c17274c3b7c 2 #include "MMA8452.h"
ashleymills 0:0c17274c3b7c 3
ashleymills 0:0c17274c3b7c 4 DigitalOut myled(LED1);
ashleymills 0:0c17274c3b7c 5
ashleymills 0:0c17274c3b7c 6 Serial pc(USBTX,USBRX);
ashleymills 0:0c17274c3b7c 7
ashleymills 0:0c17274c3b7c 8 #define LOG(...) pc.printf(__VA_ARGS__); pc.printf("\r\n");
ashleymills 0:0c17274c3b7c 9 #define LOGX(...) pc.printf(__VA_ARGS__);
ashleymills 0:0c17274c3b7c 10
ashleymills 0:0c17274c3b7c 11 void printByte(char b) {
ashleymills 0:0c17274c3b7c 12 LOG("%d%d%d%d%d%d%d%d",
ashleymills 0:0c17274c3b7c 13 (b&0x80)>>7,
ashleymills 0:0c17274c3b7c 14 (b&0x40)>>6,
ashleymills 0:0c17274c3b7c 15 (b&0x20)>>5,
ashleymills 0:0c17274c3b7c 16 (b&0x10)>>4,
ashleymills 0:0c17274c3b7c 17 (b&0x08)>>3,
ashleymills 0:0c17274c3b7c 18 (b&0x04)>>2,
ashleymills 0:0c17274c3b7c 19 (b&0x02)>>1,
ashleymills 0:0c17274c3b7c 20 (b&0x01)
ashleymills 0:0c17274c3b7c 21 );
ashleymills 0:0c17274c3b7c 22 }
ashleymills 0:0c17274c3b7c 23
ashleymills 5:756f9b157319 24 enum SampleType {
ashleymills 5:756f9b157319 25 SAMPLE_RAW=0,
ashleymills 5:756f9b157319 26 SAMPLE_COUNT,
ashleymills 5:756f9b157319 27 SAMPLE_GRAVITY
ashleymills 5:756f9b157319 28 };
ashleymills 5:756f9b157319 29
ashleymills 5:756f9b157319 30 void sampleTypeToString(SampleType t, char *dst) {
ashleymills 5:756f9b157319 31 switch(t) {
ashleymills 5:756f9b157319 32 case SAMPLE_RAW:
ashleymills 5:756f9b157319 33 sprintf(dst,"SAMPLE_RAW");
ashleymills 5:756f9b157319 34 break;
ashleymills 5:756f9b157319 35 case SAMPLE_COUNT:
ashleymills 5:756f9b157319 36 sprintf(dst,"SAMPLE_COUNT");
ashleymills 5:756f9b157319 37 break;
ashleymills 5:756f9b157319 38 case SAMPLE_GRAVITY:
ashleymills 5:756f9b157319 39 sprintf(dst,"SAMPLE_GRAVITY");
ashleymills 5:756f9b157319 40 break;
ashleymills 5:756f9b157319 41 };
ashleymills 5:756f9b157319 42 }
ashleymills 5:756f9b157319 43
ashleymills 5:756f9b157319 44 int testSampleTaking(MMA8452 *acc, int nsamples, SampleType sampleType) {
ashleymills 5:756f9b157319 45 int samples = 0;
ashleymills 5:756f9b157319 46 int bufLen = 6;
ashleymills 5:756f9b157319 47
ashleymills 5:756f9b157319 48 // buffers for multi and single raw sampling
ashleymills 5:756f9b157319 49 char bufferMulti[6];
ashleymills 5:756f9b157319 50 char bufferSingle[6];
ashleymills 5:756f9b157319 51 memset(&bufferMulti,0x00,bufLen);
ashleymills 5:756f9b157319 52 memset(&bufferSingle,0x00,bufLen);
ashleymills 5:756f9b157319 53
ashleymills 5:756f9b157319 54 // variables for multi and single count sampling
ashleymills 5:756f9b157319 55 int xCountM = 0, yCountM = 0, zCountM = 0;
ashleymills 5:756f9b157319 56 int xCountS = 0, yCountS = 0, zCountS = 0;
ashleymills 5:756f9b157319 57
ashleymills 5:756f9b157319 58 // variables for multi and single gravity sampling
ashleymills 5:756f9b157319 59 double xGravityM = 0, yGravityM = 0, zGravityM = 0;
ashleymills 5:756f9b157319 60 double xGravityS = 0, yGravityS = 0, zGravityS = 0;
ashleymills 5:756f9b157319 61
ashleymills 5:756f9b157319 62 // keep track of errors
ashleymills 5:756f9b157319 63 int error = 0;
ashleymills 5:756f9b157319 64 // mismatches between multi and single read calls are inevitable
ashleymills 5:756f9b157319 65 // since the MMA8452 has an internal sampling mechanism which is
ashleymills 5:756f9b157319 66 // not synchronous to this test routine. At low internal sampling
ashleymills 5:756f9b157319 67 // rates, these mismatches should be rare, so keep track to
ashleymills 5:756f9b157319 68 // check that this is sane
ashleymills 5:756f9b157319 69 int mismatchCount = 0;
ashleymills 5:756f9b157319 70
ashleymills 5:756f9b157319 71 // take samples
ashleymills 5:756f9b157319 72 while(samples<nsamples) {
ashleymills 5:756f9b157319 73 // wait for device to be ready
ashleymills 5:756f9b157319 74 if(!acc->isXYZReady()) {
ashleymills 5:756f9b157319 75 wait(0.01);
ashleymills 5:756f9b157319 76 continue;
ashleymills 5:756f9b157319 77 }
ashleymills 5:756f9b157319 78
ashleymills 5:756f9b157319 79 switch(sampleType) {
ashleymills 5:756f9b157319 80 case SAMPLE_RAW:
ashleymills 5:756f9b157319 81 // read raw data via multi and single calls
ashleymills 5:756f9b157319 82 memset(&bufferMulti,0x00,bufLen);
ashleymills 5:756f9b157319 83 memset(&bufferSingle,0x00,bufLen);
ashleymills 5:756f9b157319 84 error = 0;
ashleymills 5:756f9b157319 85 error += acc->readXYZRaw((char*)&bufferMulti);
ashleymills 5:756f9b157319 86 error += acc->readXRaw((char*)&bufferSingle[0]);
ashleymills 5:756f9b157319 87 error += acc->readYRaw((char*)&bufferSingle[2]);
ashleymills 5:756f9b157319 88 error += acc->readZRaw((char*)&bufferSingle[4]);
ashleymills 5:756f9b157319 89 if(error) {
ashleymills 5:756f9b157319 90 LOG("Error reading raw accelerometer data. Fail.");
ashleymills 5:756f9b157319 91 return false;
ashleymills 5:756f9b157319 92 }
ashleymills 5:756f9b157319 93 // compare multi and single samples for equivalence
ashleymills 5:756f9b157319 94 // note that this is bound to fail for high data rates
ashleymills 5:756f9b157319 95 if(acc->getBitDepth()==MMA8452::BIT_DEPTH_12) {
ashleymills 5:756f9b157319 96 if(memcmp(bufferMulti,bufferSingle,bufLen)) {
ashleymills 5:756f9b157319 97 LOG("Multi and single sampling mismatch");
ashleymills 5:756f9b157319 98 LOG("Multi: %x %x %x %x %x %x",
ashleymills 5:756f9b157319 99 bufferMulti[0],bufferMulti[1],
ashleymills 5:756f9b157319 100 bufferMulti[2],bufferMulti[3],
ashleymills 5:756f9b157319 101 bufferMulti[4],bufferMulti[5]
ashleymills 5:756f9b157319 102 );
ashleymills 5:756f9b157319 103 LOG("Single: %x %x %x %x %x %x",
ashleymills 5:756f9b157319 104 bufferSingle[0],bufferSingle[1],
ashleymills 5:756f9b157319 105 bufferSingle[2],bufferSingle[3],
ashleymills 5:756f9b157319 106 bufferSingle[4],bufferSingle[5]
ashleymills 5:756f9b157319 107 );
ashleymills 5:756f9b157319 108 mismatchCount++;
ashleymills 5:756f9b157319 109 }
ashleymills 6:e3100f66ed6a 110 LOG("12bit raw sample %d/%d: %x %x %x %x %x %x",
ashleymills 5:756f9b157319 111 samples,nsamples,
ashleymills 5:756f9b157319 112 bufferMulti[0],bufferMulti[1],
ashleymills 5:756f9b157319 113 bufferMulti[2],bufferMulti[3],
ashleymills 5:756f9b157319 114 bufferMulti[4],bufferMulti[5]
ashleymills 5:756f9b157319 115 );
ashleymills 5:756f9b157319 116 } else {
ashleymills 5:756f9b157319 117 if(bufferMulti[0]!=bufferSingle[0]||
ashleymills 5:756f9b157319 118 bufferMulti[1]!=bufferSingle[2]||
ashleymills 5:756f9b157319 119 bufferMulti[2]!=bufferSingle[4]) {
ashleymills 5:756f9b157319 120 LOG("Multi and single sampling mismatch");
ashleymills 5:756f9b157319 121 mismatchCount++;
ashleymills 5:756f9b157319 122 }
ashleymills 6:e3100f66ed6a 123 LOG("8 bit raw sample %d/%d: %x %x %x",
ashleymills 5:756f9b157319 124 samples,nsamples,
ashleymills 5:756f9b157319 125 bufferMulti[0],bufferMulti[1],bufferMulti[2]
ashleymills 5:756f9b157319 126 );
ashleymills 5:756f9b157319 127 }
ashleymills 5:756f9b157319 128 break;
ashleymills 5:756f9b157319 129 case SAMPLE_COUNT:
ashleymills 5:756f9b157319 130 error = 0;
ashleymills 5:756f9b157319 131 error += acc->readXYZCounts(&xCountM,&yCountM,&zCountM);
ashleymills 6:e3100f66ed6a 132 error += acc->readXCount(&xCountS);
ashleymills 6:e3100f66ed6a 133 error += acc->readYCount(&yCountS);
ashleymills 6:e3100f66ed6a 134 error += acc->readZCount(&zCountS);
ashleymills 5:756f9b157319 135 if(error) {
ashleymills 5:756f9b157319 136 LOG("Error reading signed counts. Fail.");
ashleymills 5:756f9b157319 137 break;
ashleymills 5:756f9b157319 138 }
ashleymills 6:e3100f66ed6a 139 // check for equivlance (note this fails sometimes but this is expected)
ashleymills 6:e3100f66ed6a 140 if(xCountS!=xCountM || yCountS!=yCountM || zCountS!=zCountM) {
ashleymills 6:e3100f66ed6a 141 LOG("Multi and single sampling mismatch");
ashleymills 6:e3100f66ed6a 142 mismatchCount++;
ashleymills 6:e3100f66ed6a 143 }
ashleymills 6:e3100f66ed6a 144 LOG("Count sample %d/%d: %d %d %d",samples,nsamples,xCountM,yCountM,zCountM);
ashleymills 5:756f9b157319 145 break;
ashleymills 5:756f9b157319 146 case SAMPLE_GRAVITY:
ashleymills 5:756f9b157319 147 error = 0;
ashleymills 5:756f9b157319 148 error += acc->readXYZGravity(&xGravityM,&yGravityM,&zGravityM);
ashleymills 6:e3100f66ed6a 149 error += acc->readXGravity(&xGravityS);
ashleymills 6:e3100f66ed6a 150 error += acc->readYGravity(&yGravityS);
ashleymills 6:e3100f66ed6a 151 error += acc->readZGravity(&zGravityS);
ashleymills 5:756f9b157319 152 if(error) {
ashleymills 5:756f9b157319 153 LOG("Error reading gravities. Fail.");
ashleymills 5:756f9b157319 154 break;
ashleymills 5:756f9b157319 155 }
ashleymills 6:e3100f66ed6a 156 if(xGravityS!=xGravityM || yGravityS!=yGravityM || zGravityS!=zGravityM) {
ashleymills 6:e3100f66ed6a 157 LOG("Multi and single sampling mismatch");
ashleymills 6:e3100f66ed6a 158 mismatchCount++;
ashleymills 6:e3100f66ed6a 159 }
ashleymills 6:e3100f66ed6a 160 LOG("Gravity sample %d/%d: %lf %lf %lf",samples,nsamples,xGravityM,yGravityM,zGravityM);
ashleymills 5:756f9b157319 161 break;
ashleymills 5:756f9b157319 162 }
ashleymills 5:756f9b157319 163 samples++;
ashleymills 5:756f9b157319 164 }
ashleymills 6:e3100f66ed6a 165 LOG("Mismatches between single and multi-byte reads %d/%d (mismatches are to be expected)",mismatchCount,nsamples);
ashleymills 5:756f9b157319 166 return true;
ashleymills 5:756f9b157319 167 }
ashleymills 5:756f9b157319 168
ashleymills 5:756f9b157319 169 int sampleMMA8452Raw(MMA8452 *acc, int nsamples) {
ashleymills 0:0c17274c3b7c 170 int samples = 0;
ashleymills 0:0c17274c3b7c 171 int bufLen = 6;
ashleymills 0:0c17274c3b7c 172 char buffer[6];
ashleymills 0:0c17274c3b7c 173 memset(&buffer,0x00,bufLen);
ashleymills 0:0c17274c3b7c 174 while(samples<nsamples) {
ashleymills 0:0c17274c3b7c 175 if(!acc->isXYZReady()) {
ashleymills 0:0c17274c3b7c 176 wait(0.01);
ashleymills 0:0c17274c3b7c 177 continue;
ashleymills 0:0c17274c3b7c 178 }
ashleymills 0:0c17274c3b7c 179 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 180 acc->readXYZRaw(buffer);
ashleymills 0:0c17274c3b7c 181 LOGX("Sample %d of %d: ",samples,nsamples);
ashleymills 0:0c17274c3b7c 182 for(int i=0; i<bufLen; i++) {
ashleymills 0:0c17274c3b7c 183 LOGX("%.2x ",buffer[i]);
ashleymills 0:0c17274c3b7c 184 }
ashleymills 0:0c17274c3b7c 185 LOG(" ");
ashleymills 0:0c17274c3b7c 186 samples++;
ashleymills 0:0c17274c3b7c 187 }
ashleymills 5:756f9b157319 188 return true;
ashleymills 0:0c17274c3b7c 189 }
ashleymills 0:0c17274c3b7c 190
ashleymills 5:756f9b157319 191 int sampleMMA8452Counts(MMA8452 *acc, int nsamples) {
ashleymills 1:e9981919b524 192 int samples = 0;
ashleymills 1:e9981919b524 193 int bufLen = 6;
ashleymills 1:e9981919b524 194 char buffer[6];
ashleymills 1:e9981919b524 195 int x = 0, y = 0, z = 0;
ashleymills 1:e9981919b524 196 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 197 while(samples<nsamples) {
ashleymills 1:e9981919b524 198 if(!acc->isXYZReady()) {
ashleymills 1:e9981919b524 199 wait(0.01);
ashleymills 1:e9981919b524 200 continue;
ashleymills 1:e9981919b524 201 }
ashleymills 1:e9981919b524 202 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 203 if(acc->readXYZCounts(&x,&y,&z)) {
ashleymills 1:e9981919b524 204 LOG("Error reading sample");
ashleymills 1:e9981919b524 205 break;
ashleymills 1:e9981919b524 206 }
ashleymills 1:e9981919b524 207 LOG("Sample %d of %d: %d, %d, %d",samples,nsamples,x,y,z);
ashleymills 1:e9981919b524 208 samples++;
ashleymills 1:e9981919b524 209 }
ashleymills 5:756f9b157319 210 return true;
ashleymills 1:e9981919b524 211 }
ashleymills 1:e9981919b524 212
ashleymills 5:756f9b157319 213 int sampleMMA8452Gravities(MMA8452 *acc, int nsamples) {
ashleymills 1:e9981919b524 214 int samples = 0;
ashleymills 1:e9981919b524 215 int bufLen = 6;
ashleymills 1:e9981919b524 216 char buffer[6];
ashleymills 1:e9981919b524 217 double x = 0, y = 0, z = 0;
ashleymills 1:e9981919b524 218 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 219 while(samples<nsamples) {
ashleymills 1:e9981919b524 220 if(!acc->isXYZReady()) {
ashleymills 1:e9981919b524 221 wait(0.01);
ashleymills 1:e9981919b524 222 continue;
ashleymills 1:e9981919b524 223 }
ashleymills 1:e9981919b524 224 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 225 if(acc->readXYZGravity(&x,&y,&z)) {
ashleymills 1:e9981919b524 226 LOG("Error reading sample");
ashleymills 1:e9981919b524 227 break;
ashleymills 1:e9981919b524 228 }
ashleymills 1:e9981919b524 229 LOG("Sample %d of %d: %lf, %lf, %lf",samples,nsamples,x,y,z);
ashleymills 1:e9981919b524 230 samples++;
ashleymills 1:e9981919b524 231 }
ashleymills 5:756f9b157319 232 return true;
ashleymills 5:756f9b157319 233 }
ashleymills 5:756f9b157319 234
ashleymills 5:756f9b157319 235 void bitDepthToString(MMA8452::BitDepth d, char *dst) {
ashleymills 5:756f9b157319 236 switch(d) {
ashleymills 5:756f9b157319 237 case MMA8452::BIT_DEPTH_12:
ashleymills 5:756f9b157319 238 sprintf(dst,"BIT_DEPTH_12");
ashleymills 5:756f9b157319 239 break;
ashleymills 5:756f9b157319 240 case MMA8452::BIT_DEPTH_8:
ashleymills 5:756f9b157319 241 sprintf(dst,"BIT_DEPTH_8");
ashleymills 5:756f9b157319 242 break;
ashleymills 5:756f9b157319 243 }
ashleymills 5:756f9b157319 244 }
ashleymills 5:756f9b157319 245
ashleymills 5:756f9b157319 246 void dynamicRangeToString(MMA8452::DynamicRange r, char *dst) {
ashleymills 5:756f9b157319 247 switch(r) {
ashleymills 5:756f9b157319 248 case MMA8452::DYNAMIC_RANGE_2G:
ashleymills 5:756f9b157319 249 sprintf(dst,"DYNAMIC_RANGE_2G");
ashleymills 5:756f9b157319 250 break;
ashleymills 5:756f9b157319 251 case MMA8452::DYNAMIC_RANGE_4G:
ashleymills 5:756f9b157319 252 sprintf(dst,"DYNAMIC_RANGE_4G");
ashleymills 5:756f9b157319 253 break;
ashleymills 5:756f9b157319 254 case MMA8452::DYNAMIC_RANGE_8G:
ashleymills 5:756f9b157319 255 sprintf(dst,"DYNAMIC_RANGE_8G");
ashleymills 5:756f9b157319 256 break;
ashleymills 5:756f9b157319 257 }
ashleymills 5:756f9b157319 258 }
ashleymills 5:756f9b157319 259
ashleymills 5:756f9b157319 260 void dataRateToString(MMA8452::DataRateHz r, char *dst) {
ashleymills 5:756f9b157319 261 switch(r) {
ashleymills 5:756f9b157319 262 case MMA8452::RATE_800:
ashleymills 5:756f9b157319 263 sprintf(dst,"RATE_800");
ashleymills 5:756f9b157319 264 break;
ashleymills 5:756f9b157319 265 case MMA8452::RATE_400:
ashleymills 5:756f9b157319 266 sprintf(dst,"RATE_400");
ashleymills 5:756f9b157319 267 break;
ashleymills 5:756f9b157319 268 case MMA8452::RATE_200:
ashleymills 5:756f9b157319 269 sprintf(dst,"RATE_200");
ashleymills 5:756f9b157319 270 break;
ashleymills 5:756f9b157319 271 case MMA8452::RATE_100:
ashleymills 5:756f9b157319 272 sprintf(dst,"RATE_100");
ashleymills 5:756f9b157319 273 break;
ashleymills 5:756f9b157319 274 case MMA8452::RATE_50:
ashleymills 5:756f9b157319 275 sprintf(dst,"RATE_50");
ashleymills 5:756f9b157319 276 break;
ashleymills 5:756f9b157319 277 case MMA8452::RATE_12_5:
ashleymills 5:756f9b157319 278 sprintf(dst,"RATE_12_5");
ashleymills 5:756f9b157319 279 break;
ashleymills 5:756f9b157319 280 case MMA8452::RATE_6_25:
ashleymills 5:756f9b157319 281 sprintf(dst,"RATE_6_25");
ashleymills 5:756f9b157319 282 break;
ashleymills 5:756f9b157319 283 case MMA8452::RATE_1_563:
ashleymills 5:756f9b157319 284 sprintf(dst,"RATE_1_563");
ashleymills 5:756f9b157319 285 break;
ashleymills 5:756f9b157319 286 }
ashleymills 1:e9981919b524 287 }
ashleymills 1:e9981919b524 288
ashleymills 0:0c17274c3b7c 289 int test() {
ashleymills 0:0c17274c3b7c 290 MMA8452 acc(p28, p27, 40000);
ashleymills 0:0c17274c3b7c 291
ashleymills 0:0c17274c3b7c 292 acc.debugRegister(MMA8452_CTRL_REG_1);
ashleymills 0:0c17274c3b7c 293
ashleymills 0:0c17274c3b7c 294 LOG("Entering standby");
ashleymills 0:0c17274c3b7c 295 if(acc.standby()) {
ashleymills 0:0c17274c3b7c 296 LOG("Error putting MMA8452 in standby");
ashleymills 0:0c17274c3b7c 297 return false;
ashleymills 0:0c17274c3b7c 298 }
ashleymills 0:0c17274c3b7c 299
ashleymills 0:0c17274c3b7c 300 acc.debugRegister(MMA8452_CTRL_REG_1);
ashleymills 0:0c17274c3b7c 301
ashleymills 0:0c17274c3b7c 302 LOG("Activating MMA8452");
ashleymills 0:0c17274c3b7c 303 if(acc.activate()) {
ashleymills 0:0c17274c3b7c 304 LOG("Error activating MMA8452");
ashleymills 0:0c17274c3b7c 305 return false;
ashleymills 0:0c17274c3b7c 306 }
ashleymills 0:0c17274c3b7c 307
ashleymills 1:e9981919b524 308 char devID = 0;
ashleymills 1:e9981919b524 309 if(acc.getDeviceID(&devID)) {
ashleymills 1:e9981919b524 310 LOG("Error getting device ID");
ashleymills 1:e9981919b524 311 return false;
ashleymills 1:e9981919b524 312 }
ashleymills 1:e9981919b524 313 LOG("DeviceID: 0x%x",devID);
ashleymills 1:e9981919b524 314 if(devID!=0x2a) {
ashleymills 1:e9981919b524 315 LOG("Error, fetched device ID: 0x%x does not match expected 0x2a",devID);
ashleymills 1:e9981919b524 316 return false;
ashleymills 1:e9981919b524 317 } else {
ashleymills 1:e9981919b524 318 LOG("Device ID OK");
ashleymills 1:e9981919b524 319 }
ashleymills 1:e9981919b524 320
ashleymills 0:0c17274c3b7c 321 // test setting dynamic range
ashleymills 0:0c17274c3b7c 322 MMA8452::DynamicRange setRange = MMA8452::DYNAMIC_RANGE_UNKNOWN;
ashleymills 0:0c17274c3b7c 323 MMA8452::DynamicRange readRange = MMA8452::DYNAMIC_RANGE_UNKNOWN;
ashleymills 0:0c17274c3b7c 324 for(int i=0; i<=(int)MMA8452::DYNAMIC_RANGE_8G; i++) {
ashleymills 0:0c17274c3b7c 325 setRange = (MMA8452::DynamicRange)i;
ashleymills 0:0c17274c3b7c 326 if(acc.setDynamicRange(setRange)) {
ashleymills 0:0c17274c3b7c 327 LOG("Error setting dynamic range. Failing.");
ashleymills 0:0c17274c3b7c 328 return false;
ashleymills 0:0c17274c3b7c 329 }
ashleymills 0:0c17274c3b7c 330 readRange = acc.getDynamicRange();
ashleymills 0:0c17274c3b7c 331 if(readRange!=setRange) {
ashleymills 0:0c17274c3b7c 332 LOG("Read dynamic range: 0x%x does not match set: 0x%x",readRange,setRange);
ashleymills 0:0c17274c3b7c 333 return false;
ashleymills 0:0c17274c3b7c 334 }
ashleymills 0:0c17274c3b7c 335 LOG("Success on dynamic range %d",i);
ashleymills 0:0c17274c3b7c 336 }
ashleymills 0:0c17274c3b7c 337
ashleymills 0:0c17274c3b7c 338 // test setting data rate
ashleymills 0:0c17274c3b7c 339 for(int i=0; i<=(int)MMA8452::RATE_1_563; i++) {
ashleymills 0:0c17274c3b7c 340 if(acc.setDataRate((MMA8452::DataRateHz)i)) {
ashleymills 0:0c17274c3b7c 341 LOG("Error setting data rate. Failing.");
ashleymills 0:0c17274c3b7c 342 return false;
ashleymills 0:0c17274c3b7c 343 }
ashleymills 0:0c17274c3b7c 344 if(acc.getDataRate()!=(MMA8452::DataRateHz)i) {
ashleymills 0:0c17274c3b7c 345 LOG("Read data rate: 0x%x does not match set: 0x%x",acc.getDataRate(),(MMA8452::DataRateHz)i);
ashleymills 0:0c17274c3b7c 346 return false;
ashleymills 0:0c17274c3b7c 347 }
ashleymills 0:0c17274c3b7c 348 LOG("Success on data rate %d",i);
ashleymills 0:0c17274c3b7c 349 }
ashleymills 0:0c17274c3b7c 350
ashleymills 5:756f9b157319 351 char depthString[32], rangeString[32], rateString[32], sampleTypeString[32];
ashleymills 5:756f9b157319 352 // draw some samples at each bit depth, rate, and dynamic range
ashleymills 5:756f9b157319 353 for(int depth=0; depth<=(int)MMA8452::BIT_DEPTH_8; depth++) {
ashleymills 5:756f9b157319 354 bitDepthToString((MMA8452::BitDepth)depth,(char*)&depthString);
ashleymills 5:756f9b157319 355 LOG("Setting bit depth to %s",depthString);
ashleymills 5:756f9b157319 356 if(acc.setBitDepth((MMA8452::BitDepth)depth)) {
ashleymills 5:756f9b157319 357 LOG("Error setting bit depth to %s. Fail.",depthString);
ashleymills 5:756f9b157319 358 return false;
ashleymills 5:756f9b157319 359 }
ashleymills 5:756f9b157319 360 for(int range=0; range<=(int)MMA8452::DYNAMIC_RANGE_8G; range++) {
ashleymills 5:756f9b157319 361 dynamicRangeToString((MMA8452::DynamicRange)range,(char*)&rangeString);
ashleymills 5:756f9b157319 362 LOG("Setting dynamic range to %s",rangeString);
ashleymills 5:756f9b157319 363 if(acc.setDynamicRange((MMA8452::DynamicRange)range)) {
ashleymills 5:756f9b157319 364 LOG("Error setting dynamic range to %s. Fail.",rangeString);
ashleymills 5:756f9b157319 365 return false;
ashleymills 5:756f9b157319 366 }
ashleymills 5:756f9b157319 367 for(int rate=0; rate<=(int)MMA8452::RATE_1_563; rate++) {
ashleymills 5:756f9b157319 368 dataRateToString((MMA8452::DataRateHz)rate,(char*)&rateString);
ashleymills 5:756f9b157319 369 LOG("Setting data rate to %s",rateString);
ashleymills 5:756f9b157319 370 if(acc.setDataRate((MMA8452::DataRateHz)rate)) {
ashleymills 5:756f9b157319 371 LOG("Error setting data rate to %s",rateString);
ashleymills 5:756f9b157319 372 return false;
ashleymills 5:756f9b157319 373 }
ashleymills 5:756f9b157319 374 // take samples
ashleymills 5:756f9b157319 375 for(int sampleType=0; sampleType<=(int)SAMPLE_GRAVITY; sampleType++) {
ashleymills 5:756f9b157319 376 sampleTypeToString((SampleType)sampleType,sampleTypeString);
ashleymills 5:756f9b157319 377 LOG("Setting sample type to %s",sampleTypeString);
ashleymills 5:756f9b157319 378 if(testSampleTaking(&acc, 10, (SampleType)sampleType)!=true) {
ashleymills 5:756f9b157319 379 LOG("Sample taking failed for %s, %s, %s, %s",sampleTypeString,depthString,rangeString,rateString);
ashleymills 5:756f9b157319 380 return false;
ashleymills 5:756f9b157319 381 }
ashleymills 5:756f9b157319 382 }
ashleymills 5:756f9b157319 383 }
ashleymills 5:756f9b157319 384 }
ashleymills 5:756f9b157319 385 }
ashleymills 6:e3100f66ed6a 386
ashleymills 6:e3100f66ed6a 387 LOG("Samping gravities for interactive examination");
ashleymills 5:756f9b157319 388 if(acc.setBitDepth(MMA8452::BIT_DEPTH_8)) {
ashleymills 5:756f9b157319 389 LOG("Error setting bit depth. Fail.");
ashleymills 5:756f9b157319 390 return false;
ashleymills 5:756f9b157319 391 }
ashleymills 6:e3100f66ed6a 392 if(acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G)) {
ashleymills 6:e3100f66ed6a 393 LOG("Error setting dynamic range. Fail.");
ashleymills 6:e3100f66ed6a 394 return false;
ashleymills 6:e3100f66ed6a 395 }
ashleymills 6:e3100f66ed6a 396 if(acc.setDataRate(MMA8452::RATE_100)) {
ashleymills 6:e3100f66ed6a 397 LOG("Error setting data rate. Fail");
ashleymills 6:e3100f66ed6a 398 return false;
ashleymills 6:e3100f66ed6a 399 }
ashleymills 6:e3100f66ed6a 400 if(sampleMMA8452Gravities(&acc,1000)!=true) {
ashleymills 6:e3100f66ed6a 401 LOG("Sampling gravities failed");
ashleymills 6:e3100f66ed6a 402 return false;
ashleymills 6:e3100f66ed6a 403 }
ashleymills 0:0c17274c3b7c 404
ashleymills 0:0c17274c3b7c 405 return true;
ashleymills 0:0c17274c3b7c 406 }
ashleymills 0:0c17274c3b7c 407
ashleymills 0:0c17274c3b7c 408 void loop() {
ashleymills 0:0c17274c3b7c 409 while(1) {
ashleymills 0:0c17274c3b7c 410 wait(1);
ashleymills 0:0c17274c3b7c 411 }
ashleymills 0:0c17274c3b7c 412 }
ashleymills 0:0c17274c3b7c 413
ashleymills 1:e9981919b524 414 void u16d(uint16_t n) {
ashleymills 1:e9981919b524 415 int shift = 16;
ashleymills 1:e9981919b524 416 uint16_t mask = 0x8000;
ashleymills 1:e9981919b524 417 while(--shift>=0) {
ashleymills 1:e9981919b524 418 LOGX("%d",(n&mask)>>shift);
ashleymills 1:e9981919b524 419 mask >>= 1;
ashleymills 1:e9981919b524 420 }
ashleymills 1:e9981919b524 421 LOG(" ");
ashleymills 1:e9981919b524 422 }
ashleymills 1:e9981919b524 423
ashleymills 1:e9981919b524 424 int eightBitToSigned(char *buf) {
ashleymills 1:e9981919b524 425 return (int8_t)*buf;
ashleymills 1:e9981919b524 426 }
ashleymills 1:e9981919b524 427
ashleymills 1:e9981919b524 428 int twelveBitToSigned(char *buf) {
ashleymills 1:e9981919b524 429 //LOG("Doing twos complement conversion for 0x%x 0x%x",buf[0],buf[1]);
ashleymills 1:e9981919b524 430
ashleymills 1:e9981919b524 431 // cheat by using the int16_t internal type
ashleymills 1:e9981919b524 432 // all we need to do is convert to little-endian format and shift right
ashleymills 1:e9981919b524 433 int16_t x = 0;
ashleymills 1:e9981919b524 434 ((char*)&x)[1] = buf[0];
ashleymills 1:e9981919b524 435 ((char*)&x)[0] = buf[1];
ashleymills 1:e9981919b524 436 // note this only works because the below is an arithmetic right shift
ashleymills 1:e9981919b524 437 return x>>4;
ashleymills 1:e9981919b524 438
ashleymills 1:e9981919b524 439 // for reference, here is the full conversion, in case you port this somewhere where the above won't work
ashleymills 1:e9981919b524 440 /*
ashleymills 1:e9981919b524 441 uint16_t number = 0x0000;
ashleymills 1:e9981919b524 442 //u16d(number);
ashleymills 1:e9981919b524 443 int negative = false;
ashleymills 1:e9981919b524 444
ashleymills 1:e9981919b524 445 // bit depth 12, is spread over two bytes
ashleymills 1:e9981919b524 446 // put it into a uint16_t for easy manipulation
ashleymills 1:e9981919b524 447 number |= (buf[0]<<8);
ashleymills 1:e9981919b524 448 number |= buf[1];
ashleymills 1:e9981919b524 449
ashleymills 1:e9981919b524 450 // if this is a negative number take the twos complement
ashleymills 1:e9981919b524 451 if(number&0x8000) {
ashleymills 1:e9981919b524 452 negative = true;
ashleymills 1:e9981919b524 453 // flip all bits (doesn't matter about lower 4 bits)
ashleymills 1:e9981919b524 454 number ^= 0xFFFF;
ashleymills 1:e9981919b524 455
ashleymills 1:e9981919b524 456 // add 1 (but do so in a way that deals with overflow and respects our current leftwise shift)
ashleymills 1:e9981919b524 457 number += 0x0010;
ashleymills 1:e9981919b524 458 }
ashleymills 1:e9981919b524 459
ashleymills 1:e9981919b524 460 // shifting down the result by 4 bits gives us the absolute number
ashleymills 1:e9981919b524 461 number >>= 4;
ashleymills 1:e9981919b524 462
ashleymills 1:e9981919b524 463 int result = number;
ashleymills 1:e9981919b524 464 if(negative) {
ashleymills 1:e9981919b524 465 result *= -1;
ashleymills 1:e9981919b524 466 }
ashleymills 1:e9981919b524 467 return result;
ashleymills 1:e9981919b524 468 */
ashleymills 1:e9981919b524 469 }
ashleymills 1:e9981919b524 470
ashleymills 1:e9981919b524 471 int twosCompTest() {
ashleymills 1:e9981919b524 472 // 12 bits of number gives 2048 steps
ashleymills 1:e9981919b524 473 int16_t i = -2047;
ashleymills 1:e9981919b524 474 while(1) {
ashleymills 1:e9981919b524 475 //LOG("number: %d",i);
ashleymills 1:e9981919b524 476 //u16d(number);
ashleymills 1:e9981919b524 477 uint16_t shiftedNumber = i<<4;
ashleymills 1:e9981919b524 478 //LOG("shifted:");
ashleymills 1:e9981919b524 479 //u16d(shiftedNumber);
ashleymills 1:e9981919b524 480 // ARM is little endian whereas 12 bit 2's comp rep is big endian
ashleymills 1:e9981919b524 481 uint16_t flippedNumber = 0x0000;
ashleymills 1:e9981919b524 482 //LOG("switching bytes");
ashleymills 1:e9981919b524 483 //u16d(flippedNumber);
ashleymills 1:e9981919b524 484 ((char*)&flippedNumber)[0] = ((char*)&shiftedNumber)[1];
ashleymills 1:e9981919b524 485
ashleymills 1:e9981919b524 486 //u16d(flippedNumber);
ashleymills 1:e9981919b524 487 ((char*)&flippedNumber)[1] = ((char*)&shiftedNumber)[0];
ashleymills 1:e9981919b524 488
ashleymills 1:e9981919b524 489 //u16d(flippedNumber);
ashleymills 1:e9981919b524 490 int value = twelveBitToSigned((char*)&flippedNumber);
ashleymills 1:e9981919b524 491 //LOG("%d converts to %d",i,value);
ashleymills 1:e9981919b524 492 if(i!=value) {
ashleymills 1:e9981919b524 493 return false;
ashleymills 1:e9981919b524 494 }
ashleymills 1:e9981919b524 495 if(i==2047) {
ashleymills 1:e9981919b524 496 break;
ashleymills 1:e9981919b524 497 }
ashleymills 1:e9981919b524 498 i++;
ashleymills 1:e9981919b524 499 }
ashleymills 1:e9981919b524 500
ashleymills 1:e9981919b524 501 int8_t n = -127;
ashleymills 1:e9981919b524 502 while(1) {
ashleymills 1:e9981919b524 503 int value = eightBitToSigned((char*)&n);
ashleymills 1:e9981919b524 504 //LOG("%d converts to %d",n,value);
ashleymills 1:e9981919b524 505 if(n!=value) {
ashleymills 1:e9981919b524 506 return false;
ashleymills 1:e9981919b524 507 }
ashleymills 1:e9981919b524 508 if(n==127) {
ashleymills 1:e9981919b524 509 break;
ashleymills 1:e9981919b524 510 }
ashleymills 1:e9981919b524 511 n++;
ashleymills 1:e9981919b524 512 }
ashleymills 1:e9981919b524 513
ashleymills 1:e9981919b524 514 return true;
ashleymills 1:e9981919b524 515 }
ashleymills 1:e9981919b524 516
ashleymills 0:0c17274c3b7c 517 int main() {
ashleymills 0:0c17274c3b7c 518 pc.baud(115200);
ashleymills 0:0c17274c3b7c 519 LOG("Begin");
ashleymills 6:e3100f66ed6a 520 LOG("Executing twos complement test");
ashleymills 1:e9981919b524 521 if(!twosCompTest()) {
ashleymills 6:e3100f66ed6a 522 LOG("Twos complement test failed");
ashleymills 1:e9981919b524 523 loop();
ashleymills 1:e9981919b524 524 }
ashleymills 6:e3100f66ed6a 525 LOG("Twos complement test passed");
ashleymills 6:e3100f66ed6a 526
ashleymills 6:e3100f66ed6a 527 LOG("Executing MMA8452 tests");
ashleymills 0:0c17274c3b7c 528 if(!test()) {
ashleymills 6:e3100f66ed6a 529 LOG("MMA8452 test failed.");
ashleymills 0:0c17274c3b7c 530 loop();
ashleymills 0:0c17274c3b7c 531 }
ashleymills 6:e3100f66ed6a 532 LOG("MMA8452 test passed");
ashleymills 6:e3100f66ed6a 533 LOG("All tests passed");
ashleymills 0:0c17274c3b7c 534 loop();
ashleymills 0:0c17274c3b7c 535 }