AKM Development Platform / AK9752_tkstreet

Fork of AK9752 by AKM Development Platform

Revision:
0:51fa46d39a3e
Child:
1:2035a4a54d3f
Child:
2:0b59cfeee8ee
diff -r 000000000000 -r 51fa46d39a3e AK9752.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AK9752.cpp	Fri Jul 08 22:27:55 2016 +0000
@@ -0,0 +1,232 @@
+#include "AK9752.h"
+#include "AK9752_reg.h"
+
+#define CONV16I(high,low)  ((int16_t)(((high) << 8) | (low)))
+
+#define LEN_ONE_BYTE            1       /**<! Data length of 1 byte data. */
+#define LEN_BUF_THRESHOLD       8       /**<! Data length of Threshold settings. From THIRH to THTMPL */
+#define LEN_BUF_IR_DATA         7       /**<! Data length of IR sensor data. From ST1 to ST2. */
+#define VAL_SOFTWARE_RESET      0x01    
+#define ST1_STATUS_FLAG_DRDY    0x01
+#define INT_STATUS_FLAG_DR      0x01
+#define INT_STATUS_FLAG_TMPL    0x02
+#define INT_STATUS_FLAG_TMPH    0x04
+#define INT_STATUS_FLAG_IRL     0x08
+#define INT_STATUS_FLAG_IRH     0x10
+#define INT_STATUS_MASK         0x1F
+#define ST2_STATUS_FLAG_DOR     0x01
+
+
+AK9752::AK9752() {
+}
+
+void AK9752::init(I2C *conn, SlaveAddress addr) {
+    slaveAddress = addr;
+    connection = conn;
+}
+
+AK9752::Status AK9752::checkConnection() {
+    AK9752::Status status = AK9752::SUCCESS;
+    
+    // Gets the WIA register value.
+    char buf[2];
+    if ((status=AK9752::read(AK9752_REG_ADDR_WIA1, buf, 2)) != SUCCESS) {
+        return status;
+    }
+
+    // Checks the obtained value equals to the supposed value.
+    if ( (buf[0] != AK9752_REG_VALUE_WIA1) ||  (buf[1] != AK9752_REG_VALUE_WIA2) ) {
+        return AK9752::ERROR;
+    }
+    
+    return status;
+}
+
+AK9752::Status AK9752::read(char registerAddress, char *buf, int length) {
+    // Writes a start address
+    if (connection->write((slaveAddress << 1), &registerAddress, LEN_ONE_BYTE) != 0) {
+        // I2C write failed.
+        return AK9752::ERROR_I2C_WRITE;
+    }
+    
+    // Reads register data
+    if (connection->read((slaveAddress << 1), buf, length) != 0) {
+        // I2C read failed.
+        return AK9752::ERROR_I2C_READ;
+    }
+    
+    return AK9752::SUCCESS;
+}
+
+AK9752::Status AK9752::write(char registerAddress, const char *buf, int length) {
+    int bufLength = length + 1;
+    char data[bufLength];
+
+    // Creates data to be sent.
+    data[0] = registerAddress;    
+    for (int i=0; i < length; i++) {
+        data[1+i] = buf[i];
+    }
+    
+    // Writes a start address. 
+    if (connection->write((slaveAddress << 1), data, bufLength) != 0) {
+        // I2C write failed.
+        return AK9752::ERROR_I2C_WRITE;
+    }
+
+    return AK9752::SUCCESS;
+}
+
+AK9752::Status AK9752::getInterruptEnable(InterruptStatus *intStatus){
+    Status status;
+    
+    char buf = 0;
+    if((status=read(AK9752_REG_ADDR_INTEN, &buf, LEN_ONE_BYTE)) != SUCCESS) {
+        return status;
+    }
+    
+    intStatus->irh = ((buf & INT_STATUS_FLAG_IRH) > 0) ? true : false;
+    intStatus->irl = ((buf & INT_STATUS_FLAG_IRL) > 0) ? true : false;
+    intStatus->tmph = ((buf & INT_STATUS_FLAG_TMPH) > 0) ? true : false;
+    intStatus->tmpl = ((buf & INT_STATUS_FLAG_TMPL) > 0) ? true : false;
+    intStatus->dr = ((buf & INT_STATUS_FLAG_DR) > 0) ? true : false;
+    
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::setInterruptEnable(const AK9752::InterruptStatus *intStatus) {
+    char buf = 0;
+    
+    buf += intStatus->irh ? INT_STATUS_FLAG_IRH : 0;
+    buf += intStatus->irl ? INT_STATUS_FLAG_IRL : 0;
+    buf += intStatus->tmph ? INT_STATUS_FLAG_TMPH : 0;
+    buf += intStatus->tmpl ? INT_STATUS_FLAG_TMPL : 0;
+    buf += intStatus->dr ? INT_STATUS_FLAG_DR : 0;
+    
+    Status status;
+    if ((status=write(AK9752_REG_ADDR_INTEN, &buf, LEN_ONE_BYTE)) != SUCCESS) {
+        return status;    
+    }
+    
+    char readback = 0;
+    if ((status=read(AK9752_REG_ADDR_INTEN, &readback, LEN_ONE_BYTE)) != SUCCESS) {
+        return status;
+    }
+    if ((readback & INT_STATUS_MASK) != buf) {
+        return ERROR;
+    }
+    
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::getData(char *buf) {
+    Status status;
+    if ((status=read(AK9752_REG_ADDR_ST1, buf, LEN_BUF_IR_DATA)) != SUCCESS) {
+        return status;
+    }
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::setThreshold(const Threshold *th) {
+    Status status;
+    char buf[LEN_BUF_THRESHOLD];
+    
+    buf[0] = (char)(((uint16_t)th->thirh & 0x00FF));         // THIRHL
+    buf[1] = (char)(((uint16_t)th->thirh & 0xFF00) >> 8);    // THIRHH
+    buf[2] = (char)(((uint16_t)th->thirl & 0x00FF));         // THIRLL 
+    buf[3] = (char)(((uint16_t)th->thirl & 0xFF00) >> 8);    // THIRLH
+    buf[4] = (char)(((uint16_t)th->thtmph & 0x00FF));        // THTMPHL
+    buf[5] = (char)(((uint16_t)th->thtmph & 0xFF00) >> 8);   // THTMPHH
+    buf[6] = (char)(((uint16_t)th->thtmpl & 0x00FF));        // THTMPLL 
+    buf[7] = (char)(((uint16_t)th->thtmpl & 0xFF00) >> 8);   // THTMPLH
+    
+    if ((status=write(AK9752_REG_ADDR_THIRHL, buf, LEN_BUF_THRESHOLD)) != SUCCESS) {
+        return status;
+    }
+
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::getThreshold(Threshold *th) {
+    Status status;
+    char buf[LEN_BUF_THRESHOLD];
+    
+    if ((status=read(AK9752_REG_ADDR_THIRHL, buf, LEN_BUF_THRESHOLD)) != SUCCESS) {
+        return status;
+    }
+    
+    th->thirh = CONV16I(buf[1], buf[0]);
+    th->thirl = CONV16I(buf[3], buf[2]);
+    th->thtmph = CONV16I(buf[5], buf[4]);
+    th->thtmpl = CONV16I(buf[7], buf[6]);
+    
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::getOperationMode(OperationMode *mode, FcTmp *fc_tmp, FcIr *fc_ir){
+        Status status;
+    
+    char buf[2];
+    if ((status=read(AK9752_REG_ADDR_CNTL1, buf, 2)) != SUCCESS) {
+        return status;
+    }
+    *fc_tmp = AK9752::FcTmp((buf[0] & 0x1C)>>2);
+    *fc_ir = AK9752::FcIr(buf[0] & 0x03);
+    *mode = AK9752::OperationMode(buf[1] & 0x03);
+    
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::setOperationMode(OperationMode mode, FcTmp fc_tmp, FcIr fc_ir){
+    Status status;
+    
+    char buf[2];
+    buf[0] = (fc_tmp<<2 | fc_ir&0x03);
+    buf[1] = mode;
+    if ((status=write(AK9752_REG_ADDR_CNTL1, buf, 2)) != SUCCESS) {
+        return status;
+    }
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::reset() {
+    Status status;
+    char val = VAL_SOFTWARE_RESET;
+    if ((status=write(AK9752_REG_ADDR_CNTL3, &val, LEN_ONE_BYTE)) != SUCCESS) {
+        return status;
+    }    
+    return SUCCESS;
+}
+
+AK9752::Status AK9752::getSensorData(AK9752::SensorData *data) {
+    Status status;
+    char buf[LEN_BUF_IR_DATA];
+    
+    if ((status=getData(buf)) != SUCCESS) {
+        return status;
+    }
+
+    // check DRDY 
+    if( (buf[0] & ST1_STATUS_FLAG_DRDY) == 0 ){
+        // DRDY=0, data not ready
+        return ERROR;
+    }
+    
+    // Interrupt Status
+    data->intStatus.irh = ((buf[1] & INT_STATUS_FLAG_IRH) > 0) ? true : false;
+    data->intStatus.irl = ((buf[1] & INT_STATUS_FLAG_IRL) > 0) ? true : false;
+    data->intStatus.tmph = ((buf[1] & INT_STATUS_FLAG_TMPH) > 0) ? true : false;
+    data->intStatus.tmpl = ((buf[1] & INT_STATUS_FLAG_TMPL) > 0) ? true : false;
+    data->intStatus.dr = ((buf[1] & INT_STATUS_FLAG_DR) > 0) ? true : false;
+    
+    // IR sensor data
+    data->ir = (int16_t)((buf[3] << 8) | buf[2]);
+    
+    // Temperature sensor data
+    data->temperature = (int16_t)((buf[5] << 8) | buf[4]);
+
+    // DOR Status
+    data->dor = ((buf[1] & ST2_STATUS_FLAG_DOR) > 0) ? true : false;
+    
+    return SUCCESS;    
+}