Modified for compatibility with Rev.E. hardware

Fork of AkmSensor by AKM Development Platform

Revision:
10:5c69b067d88a
Child:
11:cef8dc1cf010
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ak7401ctrl.cpp	Fri Jul 08 22:26:26 2016 +0000
@@ -0,0 +1,163 @@
+#include "ak7401ctrl.h"
+#include "debug.h"
+
+/**
+ * Constructor.
+ *
+ */
+Ak7401Ctrl::Ak7401Ctrl(){
+    ak7401 = NULL;
+    event = false;
+}
+
+/**
+ * Destructor.
+ *
+ */
+Ak7401Ctrl::~Ak7401Ctrl(){
+    if (ak7401) delete ak7401;
+}
+
+AkmSensor::Status Ak7401Ctrl::init(const uint8_t id, const uint8_t subid){
+    primaryId = id;
+    subId = subid;
+    
+    if(subId == SUB_ID_AK7401){
+        SPI* mSpi;
+        DigitalOut* mCs;
+        AK7401::Status status = AK7401::ERROR;        
+        mSpi = new SPI(SPI_MOSI, SPI_MISO, SPI_SCK);
+        mSpi->format(8,1);    // 8bit, Mode=1
+        mSpi->frequency(1000000);
+        mCs = new DigitalOut(SPI_CS);
+        ak7401 = new AK7401();
+        ak7401->begin(mSpi, mCs);
+
+        status = ak7401->setOperationMode(AK7401::AK7401_USER_MODE);
+        if( status != AK7401::SUCCESS ){
+            MSG("#AK7401 user mode failed.\n"); 
+            return AkmSensor::ERROR;
+        }
+        MSG("#AK7401 user mode succeed.\n"); 
+                
+        char data[2] = {0x00,0x07};                 // set clockwise rotation
+        status = ak7401->writeEEPROM(0x05,data);    // set clockwise
+        if( status != AK7401::SUCCESS ){
+            MSG("#AK7401 write EEPROM failed.\n"); 
+            return AkmSensor::ERROR;
+        }
+        MSG("#AK7401 write EEPROM succeed.\n"); 
+        
+        status = ak7401->setOperationMode(AK7401::AK7401_NORMAL_MODE);
+        if( status != AK7401::SUCCESS ){
+            MSG("#AK7401 normal mode failed.\n"); 
+            return AkmSensor::ERROR;
+        }
+        MSG("#AK7401 normal mode succeed.\n"); 
+    }
+    else{
+        return AkmSensor::ERROR;
+    }
+
+    return AkmSensor::SUCCESS;
+}
+
+void Ak7401Ctrl::eventCallback(){
+    event = true;
+}
+
+bool Ak7401Ctrl::isEvent(){
+    return event;
+}
+
+AkmSensor::Status Ak7401Ctrl::startSensor(){
+    interval = 0.1;  // 10Hz
+    ticker.attach(this, &Ak7401Ctrl::eventCallback, interval);
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status Ak7401Ctrl::startSensor(const float sec){
+    interval = sec;
+    ticker.attach(this, &Ak7401Ctrl::eventCallback, interval);
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status Ak7401Ctrl::stopSensor(){
+    ticker.detach();
+    event = false;
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status Ak7401Ctrl::readSensorData(Message* msg){
+    event = false;
+    char angle[2] = {0x00,0x00};
+    AK7401::Status status = ak7401->readAngle(angle);
+    
+    msg->setCommand(Message::CMD_START_MEASUREMENT);
+    msg->setArgument( 0, status );
+    msg->setArgument( 1, angle[0] );
+    msg->setArgument( 2, angle[1] );
+
+    if( status != SUCCESS){
+        return AkmSensor::ERROR;
+    }
+    return AkmSensor::SUCCESS;
+}
+
+AkmSensor::Status Ak7401Ctrl::requestCommand(Message* in, Message* out){
+    AkmSensor::Status status = AkmSensor::SUCCESS;
+    
+    Message::Command cmd = in->getCommand();
+
+    switch(cmd){
+         case Message::CMD_ANGLE_ZERO_RESET:
+         {
+             AK7401::Status st;
+            if( Ak7401Ctrl::stopSensor() != AkmSensor::SUCCESS ){
+                MSG("#Error stop sensor\n");
+                status = AkmSensor::ERROR;
+            }
+            
+            st = ak7401->setOperationMode(AK7401::AK7401_USER_MODE);
+            if( st != AK7401::SUCCESS ){
+                MSG("#Error when set user mode\n");
+                status = AkmSensor::ERROR;
+            }
+            char temp[2] = {0x00,0x00};
+            st = ak7401->writeRegister(0x06,temp);
+            if( st != AK7401::SUCCESS ){
+                MSG("#Error temp read: code=%d\n",st);
+                status =  AkmSensor::ERROR;
+            }
+            st = ak7401->setAngleZero();    // reset ZP data
+            if( st != AK7401::SUCCESS ){
+                MSG("#Error setAngleZero: code=%d\n",st);
+                status =  AkmSensor::ERROR;
+            }
+            st = ak7401->setOperationMode(AK7401::AK7401_NORMAL_MODE);
+            if( st != AK7401::SUCCESS ){
+                MSG("#Error when set normal mode\n");
+                status =  AkmSensor::ERROR;
+            }
+            if( Ak7401Ctrl::startSensor(interval) != AkmSensor::SUCCESS ){
+                MSG("#Error start sensor\n");
+                status =  AkmSensor::ERROR;
+            }
+            if( status == AkmSensor::ERROR ){
+                out->setArgument(0,1);
+            }else{
+                out->setArgument(0,0);
+            }
+            break;
+        }
+        default:
+        {
+            MSG("#Error no command.\n");
+            status =  AkmSensor::ERROR;
+            break;
+        }
+    }
+    
+    return status;
+}
+