Modified for compatibility with Rev.E. hardware

Fork of AkmSensor by AKM Development Platform

Revision:
0:7a00359e701e
Child:
7:e269411568c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/akmakd.cpp	Thu Apr 28 21:12:04 2016 +0000
@@ -0,0 +1,190 @@
+#include "akmakd.h"
+#include "ak8963.h"
+#include "ak099xx.h"
+#include "debug.h"
+
+/**
+ * Constructor.
+ *
+ */
+AkmAkd::AkmAkd(){
+    event = false;
+    compass = NULL;
+    drdy = NULL;
+    sensorName = "";
+}
+
+/**
+ * Destructor.
+ *
+ */
+AkmAkd::~AkmAkd(){
+    drdy->rise(0);
+    if (compass) delete compass;
+    if (drdy) delete drdy;
+}
+
+AkmSensor::Status AkmAkd::init(const uint8_t id, const uint8_t subid){
+    primaryId = id;
+    subId = subid;
+    
+    AkmECompass::SensorType type;
+
+    drdy = new InterruptIn(DRDY);    
+    drdy->rise(0);
+
+    if(primaryId == AKM_PRIMARY_ID_AKD_I2C){
+
+        I2C* i2c = new I2C(I2C_SDA,I2C_SCL);
+        i2c->frequency(I2C_SPEED_100KHZ);
+
+        AK099XX* ak099xx;
+        AK8963* ak8963;
+
+        switch(subid){
+            case AkmAkd::SUB_ID_AK8963N:
+            case AkmAkd::SUB_ID_AK8963C:
+                type = AkmECompass::AK8963;
+                ak8963 = new AK8963();
+                compass = ak8963;
+                AkmAkd::sensorName = "AK8963";
+                break;          
+            case AkmAkd::SUB_ID_AK09911:
+                type = AkmECompass::AK09911;
+                ak099xx = new AK099XX();
+                compass = ak099xx;
+                AkmAkd::sensorName = "AK09911";
+                break;
+            case AkmAkd::SUB_ID_AK09912:
+                type = AkmECompass::AK09912;
+                ak099xx = new AK099XX();
+                compass = ak099xx;
+                AkmAkd::sensorName = "AK09912";
+                break;
+            case AkmAkd::SUB_ID_AK09915:
+                type = AkmECompass::AK09915;
+                ak099xx = new AK099XX();
+                compass = ak099xx;
+                AkmAkd::sensorName = "AK09915";
+                break;
+            case AkmAkd::SUB_ID_AK09916C:
+                type = AkmECompass::AK09916C;
+                ak099xx = new AK099XX();
+                compass = ak099xx;
+                AkmAkd::sensorName = "AK09916C";
+                break;
+            default:
+                return AkmSensor::ERROR;
+//                break;
+        }
+        
+        bool foundSensor = false;
+        
+        AkmECompass::SlaveAddress slaveAddr[] 
+            = { AkmECompass::SLAVE_ADDR_1,
+                AkmECompass::SLAVE_ADDR_2,
+                AkmECompass::SLAVE_ADDR_3,
+                AkmECompass::SLAVE_ADDR_4};
+
+        for(int i=0; i<sizeof(slaveAddr); i++)
+        {
+            compass->init(i2c, slaveAddr[i], type);
+            // Checks connectivity
+            if(compass->checkConnection() == AkmECompass::SUCCESS) {
+                // found
+                foundSensor = true;
+                break;
+            }
+        }
+        if(foundSensor != true) return AkmSensor::ERROR;
+        
+        // read a data to reset DRDY 
+        AkmECompass::MagneticVector mag;
+        compass->getMagneticVector(&mag);
+        
+    }else if(primaryId == AKM_PRIMARY_ID_AKD_SPI){
+        MSG("#Error: SPI doesn't support.\n"); 
+
+        return AkmSensor::ERROR_DOESNT_SUPPORT;
+//        spi = new SPI(SPI_MOSI, SPI_MISO, SPI_SCK);
+//        spi->format(8,3);    // 8bit, Mode=3
+//        spi->frequency(100000);
+    }
+    
+    MSG("#%s detected.\n", AkmAkd::sensorName);
+    return AkmSensor::SUCCESS;
+}
+
+
+void AkmAkd::checkDRDY(){
+    AkmECompass::Status  status = compass->isDataReady();
+    if( status == AkmECompass::DATA_READY || 
+        status == AkmECompass::DATA_OVER_RUN ) event = true;
+}
+
+void AkmAkd::detectDRDY(){
+    event = true;
+}
+
+bool AkmAkd::isEvent(){
+    return event;
+}
+
+AkmSensor::Status AkmAkd::startSensor(){
+    // Puts the device into continuous measurement mode.
+    if(compass->setOperationMode((AkmECompass::OperationMode)0x02) != AkmECompass::SUCCESS) {
+        return AkmSensor::ERROR;
+    }
+    
+    // DRDY interrupt enable for AK8963/AK09912/AK09915
+    if(compass->getSensorType() == AkmECompass::AK8963 ||
+       compass->getSensorType() == AkmECompass::AK09912 ||
+       compass->getSensorType() == AkmECompass::AK09915 ){       
+        drdy->rise(this, &AkmAkd::detectDRDY);
+    }
+    else{
+        ticker.attach(this, &AkmAkd::checkDRDY, 0.01);  // 100Hz
+    }
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status AkmAkd::startSensor(const float sec){
+    return AkmSensor::ERROR;    // doesn't support
+}
+
+AkmSensor::Status AkmAkd::stopSensor(){
+    ticker.detach();
+ 
+    // Puts the device into power down mode.
+    if(compass->setOperationMode(AkmECompass::MODE_POWER_DOWN) != AkmECompass::SUCCESS) {
+        return AkmSensor::ERROR;
+    }
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status AkmAkd::readSensorData(Message* msg){
+    event = false;
+
+    AkmECompass::MagneticVector mag;
+    AkmECompass::Status status = compass->getMagneticVector(&mag);
+    if( status != AkmECompass::SUCCESS){
+        return AkmSensor::ERROR;
+    }
+    msg->setCommand(Message::CMD_START_MEASUREMENT);
+    msg->setArgument( 0, (mag.isOverflow ? 1 : 0) );
+    msg->setArgument( 1,(char)((int32_t)(mag.mx/0.15) >> 8));
+    msg->setArgument( 2, (char)((int32_t)(mag.mx/0.15) & 0x00FF) );
+    msg->setArgument( 3, (char)((int32_t)(mag.my/0.15) >> 8) );
+    msg->setArgument( 4, (char)((int32_t)(mag.my/0.15) & 0x00FF) );
+    msg->setArgument( 5, (char)((int32_t)(mag.mz/0.15) >> 8) );
+    msg->setArgument( 6, (char)((int32_t)(mag.mz/0.15) & 0x00FF) );
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status AkmAkd::requestCommand(Message* in, Message* out){    
+    return AkmSensor::SUCCESS;
+}
+
+char* AkmAkd::getSensorName(){
+    return sensorName;
+}
\ No newline at end of file