Osamu Koizumi / AK8963

Dependents:   SimpleSample combination combination

Revision:
1:a362b9e3aac2
Parent:
0:fc56973c077a
Child:
2:9dff393e5e86
--- a/ak8963.cpp	Wed Aug 05 23:08:02 2015 +0000
+++ b/ak8963.cpp	Tue Aug 18 18:06:02 2015 +0000
@@ -35,6 +35,8 @@
 
 #define AK8963_BIT_MASK_DRDY        0x01
 
+#define AK8963_BIT_MASK_HOFL        0x08
+
 #define AK8963_REG_WIA_VAL          0x48
 
 #define AK8963_BUF_LENGTH_ASA          3
@@ -43,7 +45,7 @@
 #define AK8963_DEFAULT_OUTPUT_BIT   AK8963_CNTL1_OUTPUT_16BIT
 #define AK8963_SENSITIVITY          (0.15)   // uT/LSB
 
-#define AK8963_WAIT_POWER_DOWN_US    200
+#define AK8963_WAIT_POWER_DOWN_US    100
 
 #define LEN_ONE_BYTE  1
 
@@ -140,7 +142,7 @@
     AK8963::Status status = AK8963::ERROR;
     
     // The device has to be put into power-down mode first before switching mode.
-    char buf = (char)AK8963::MODE_POWER_DOWN;
+    char buf = AK8963::MODE_POWER_DOWN;
     if (mode != AK8963::MODE_POWER_DOWN) {
         if ((status=AK8963::write(AK8963_REG_CNTL1, &buf, LEN_ONE_BYTE)) != AK8963::SUCCESS) {
             // I2C write failed.
@@ -151,7 +153,7 @@
 
 
     // Switch to the specified mode.
-    buf = (char)(mode | AK8963_CNTL1_OUTPUT_16BIT);    
+    buf = (mode | AK8963_CNTL1_OUTPUT_16BIT);    
     if ((status=AK8963::write(AK8963_REG_CNTL1, &buf, LEN_ONE_BYTE)) != AK8963::SUCCESS) {
         // I2C write failed.
         return status;
@@ -171,14 +173,22 @@
         return status;
     }
     
-    int16_t xi = (int16_t)((buf[2] << 8) | buf[1]);
-    int16_t yi = (int16_t)((buf[4] << 8) | buf[3]);
-    int16_t zi = (int16_t)((buf[6] << 8) | buf[5]);
-    
-    vec->mx = (float)(xi * ((sensitivityAdjustment.x + 128)/256.0));
-    vec->my = (float)(yi * ((sensitivityAdjustment.y + 128)/256.0));
-    vec->mz = (float)(zi * ((sensitivityAdjustment.z + 128)/256.0));
-    
+    // Checks sensor overflow
+    if ((buf[7] & AK8963_BIT_MASK_HOFL) > 0) {
+        // Magnetic sensor overflow
+        vec->isOverflow = true;
+    } else {
+        // Magnetic sensor didn't overflow.
+        vec->isOverflow = false;
+        // Calculates magnetic field value
+        int16_t xi = (int16_t)((buf[2] << 8) | buf[1]);
+        int16_t yi = (int16_t)((buf[4] << 8) | buf[3]);
+        int16_t zi = (int16_t)((buf[6] << 8) | buf[5]);
+        vec->mx = (float)(xi * ((sensitivityAdjustment.x + 128)/256.0) * AK8963_SENSITIVITY);
+        vec->my = (float)(yi * ((sensitivityAdjustment.y + 128)/256.0) * AK8963_SENSITIVITY);
+        vec->mz = (float)(zi * ((sensitivityAdjustment.z + 128)/256.0) * AK8963_SENSITIVITY);
+    }
+        
     return AK8963::SUCCESS;
 }