Driving

Dependencies:   FSR LIS3DH USBDevice mbed

Fork of MMA8452_Demo by Ivan Rush

Revision:
1:e9981919b524
Parent:
0:0c17274c3b7c
Child:
2:0630128bdb32
diff -r 0c17274c3b7c -r e9981919b524 main.cpp
--- a/main.cpp	Tue Mar 04 17:51:27 2014 +0000
+++ b/main.cpp	Wed Mar 05 15:04:45 2014 +0000
@@ -21,7 +21,7 @@
    );
 }
 
-void sampleMMA8452(MMA8452 *acc, int nsamples) {
+void sampleMMA8452Raw(MMA8452 *acc, int nsamples) {
    int samples = 0;
    int bufLen = 6;
    char buffer[6];
@@ -32,7 +32,7 @@
          continue;
       }
       memset(&buffer,0x00,bufLen);
-      acc->readRawXYZ(buffer);
+      acc->readXYZRaw(buffer);
       LOGX("Sample %d of %d: ",samples,nsamples);
       for(int i=0; i<bufLen; i++) {
          LOGX("%.2x ",buffer[i]);
@@ -42,6 +42,48 @@
    }
 }
 
+void sampleMMA8452Counts(MMA8452 *acc, int nsamples) {
+   int samples = 0;
+   int bufLen = 6;
+   char buffer[6];
+   int x = 0, y = 0, z = 0;
+   memset(&buffer,0x00,bufLen);
+   while(samples<nsamples) {
+      if(!acc->isXYZReady()) {
+         wait(0.01);
+         continue;
+      }
+      memset(&buffer,0x00,bufLen);
+      if(acc->readXYZCounts(&x,&y,&z)) {
+         LOG("Error reading sample");
+         break;
+      }
+      LOG("Sample %d of %d: %d, %d, %d",samples,nsamples,x,y,z);
+      samples++;
+   }
+}
+
+void sampleMMA8452Gravities(MMA8452 *acc, int nsamples) {
+   int samples = 0;
+   int bufLen = 6;
+   char buffer[6];
+   double x = 0, y = 0, z = 0;
+   memset(&buffer,0x00,bufLen);
+   while(samples<nsamples) {
+      if(!acc->isXYZReady()) {
+         wait(0.01);
+         continue;
+      }
+      memset(&buffer,0x00,bufLen);
+      if(acc->readXYZGravity(&x,&y,&z)) {
+         LOG("Error reading sample");
+         break;
+      }
+      LOG("Sample %d of %d: %lf, %lf, %lf",samples,nsamples,x,y,z);
+      samples++;
+   }
+}
+
 int test() {
     MMA8452 acc(p28, p27, 40000);
     
@@ -61,6 +103,19 @@
        return false;
     }
     
+    char devID = 0;
+    if(acc.getDeviceID(&devID)) {
+       LOG("Error getting device ID");
+       return false;
+    }
+    LOG("DeviceID: 0x%x",devID);
+    if(devID!=0x2a) {
+       LOG("Error, fetched device ID: 0x%x does not match expected 0x2a",devID);
+       return false;
+    } else {
+       LOG("Device ID OK");
+    }
+    
     // test setting dynamic range
     MMA8452::DynamicRange setRange = MMA8452::DYNAMIC_RANGE_UNKNOWN;
     MMA8452::DynamicRange readRange = MMA8452::DYNAMIC_RANGE_UNKNOWN;
@@ -94,13 +149,20 @@
     // set bit depth to 8 and read some values
     LOG("Sampling at BIT_DEPTH_8");
     acc.setBitDepth(MMA8452::BIT_DEPTH_8);
-    sampleMMA8452(&acc,10);
+    sampleMMA8452Raw(&acc,10);
     
     // set bit depth to 12 and read some values
     LOG("Sampling at BIT_DEPTH_12");
     acc.setDataRate(MMA8452::RATE_100);
     acc.setBitDepth(MMA8452::BIT_DEPTH_12);
-    sampleMMA8452(&acc,10);
+    sampleMMA8452Raw(&acc,10);
+   
+    LOG("Sampling counts");
+    acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_2G);
+    sampleMMA8452Counts(&acc,100);
+
+    LOG("Samping gravities");
+    sampleMMA8452Gravities(&acc,100);
 
     return true;
 }
@@ -111,9 +173,120 @@
    }
 }
 
+void u16d(uint16_t n) {
+   int shift = 16;
+   uint16_t mask = 0x8000;
+   while(--shift>=0) {
+      LOGX("%d",(n&mask)>>shift);
+      mask >>= 1;
+   }
+   LOG(" ");
+}
+
+int eightBitToSigned(char *buf) {
+   return (int8_t)*buf;
+}
+
+int twelveBitToSigned(char *buf) {
+   //LOG("Doing twos complement conversion for 0x%x 0x%x",buf[0],buf[1]);
+   
+   // cheat by using the int16_t internal type
+   // all we need to do is convert to little-endian format and shift right
+   int16_t x = 0;
+   ((char*)&x)[1] = buf[0];
+   ((char*)&x)[0] = buf[1];
+   // note this only works because the below is an arithmetic right shift
+   return x>>4; 
+
+   // for reference, here is the full conversion, in case you port this somewhere where the above won't work
+   /*
+   uint16_t number = 0x0000;
+   //u16d(number);
+   int negative = false;
+   
+   // bit depth 12, is spread over two bytes
+   // put it into a uint16_t for easy manipulation
+   number |= (buf[0]<<8);
+   number |= buf[1];
+
+   // if this is a negative number take the twos complement
+   if(number&0x8000) {
+       negative = true;
+       // flip all bits (doesn't matter about lower 4 bits)
+       number ^= 0xFFFF;
+
+       // add 1 (but do so in a way that deals with overflow and respects our current leftwise shift)
+       number += 0x0010;
+   }
+   
+   // shifting down the result by 4 bits gives us the absolute number
+   number >>= 4;
+
+   int result = number;
+   if(negative) {
+      result *= -1;
+   }
+   return result;
+   */
+}
+
+int twosCompTest() {
+    u16d((int16_t)5);
+    u16d((int16_t)-5);
+    // 12 bits of number gives 2048 steps
+    int16_t i = -2047;
+    while(1) {
+       //LOG("number: %d",i);
+       //u16d(number);
+       uint16_t shiftedNumber = i<<4;
+       //LOG("shifted:");
+       //u16d(shiftedNumber);
+       // ARM is little endian whereas 12 bit 2's comp rep is big endian
+       uint16_t flippedNumber = 0x0000;
+       //LOG("switching bytes");
+       //u16d(flippedNumber);
+       ((char*)&flippedNumber)[0] = ((char*)&shiftedNumber)[1];
+       
+       //u16d(flippedNumber);
+       ((char*)&flippedNumber)[1] = ((char*)&shiftedNumber)[0]; 
+       
+       //u16d(flippedNumber);
+       int value = twelveBitToSigned((char*)&flippedNumber);
+       //LOG("%d converts to %d",i,value);
+       if(i!=value) {
+          return false;
+       }
+       if(i==2047) {
+          break;
+       }
+       i++;
+    }
+    
+    int8_t n = -127;
+    while(1) {
+       int value = eightBitToSigned((char*)&n);
+       //LOG("%d converts to %d",n,value);
+       if(n!=value) {
+          return false;
+       }
+       if(n==127) {
+          break;
+       }
+       n++;
+    }
+ 
+    return true;
+}
+
 int main() {
     pc.baud(115200);
     LOG("Begin");
+    if(!twosCompTest()) {
+       LOG("twos comp test failed");
+       loop();
+    }
+    LOG("twos comp test passed");
+    //loop();
     for(int i=0; i<20; i++) {
        LOG(" ");
     }