Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of AK9752 by
Diff: AK9752.cpp
- Revision:
- 0:51fa46d39a3e
- Child:
- 1:2035a4a54d3f
- Child:
- 2:0b59cfeee8ee
--- /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), ®isterAddress, 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;
+}
