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:
- 1:2035a4a54d3f
- Parent:
- 0:51fa46d39a3e
--- a/AK9752.cpp Fri Jul 08 22:27:55 2016 +0000
+++ b/AK9752.cpp Tue Nov 01 17:03:31 2016 +0000
@@ -1,20 +1,23 @@
#include "AK9752.h"
#include "AK9752_reg.h"
+/**
+ * Combine low and high int8_t bytes of Temp/IR data and store in int16_t variable
+ */
#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
+#define LEN_BUF_IR_DATA 7 /**<! Data length of IR sensor data: ST1,INTCAUSE,IR(16),TMP(16),ST2. */
+#define VAL_SOFTWARE_RESET 0x01 /**<! Software reset value. */
+#define ST1_STATUS_FLAG_DRDY 0x01 /**<! Data Ready*/
+#define INT_STATUS_FLAG_DR 0x01 /**<! Data Read */
+#define INT_STATUS_FLAG_TMPL 0x02 /**<! Temp low threshold reached */
+#define INT_STATUS_FLAG_TMPH 0x04 /**<! Temp high threshold reached */
+#define INT_STATUS_FLAG_IRL 0x08 /**<! IR low threshold reached */
+#define INT_STATUS_FLAG_IRH 0x10 /**<! IR high threshold reached */
+#define INT_STATUS_MASK 0x1F /**<! Mask highest 3 bits of status */
+#define ST2_STATUS_FLAG_DOR 0x01 /**<! Data overrun (data read is required) */
AK9752::AK9752() {
@@ -43,13 +46,13 @@
}
AK9752::Status AK9752::read(char registerAddress, char *buf, int length) {
- // Writes a start address
+ // Tell slave address of where to read data
if (connection->write((slaveAddress << 1), ®isterAddress, LEN_ONE_BYTE) != 0) {
// I2C write failed.
return AK9752::ERROR_I2C_WRITE;
}
- // Reads register data
+ // Read register data (converts 7-bit address to 8-bit)
if (connection->read((slaveAddress << 1), buf, length) != 0) {
// I2C read failed.
return AK9752::ERROR_I2C_READ;
@@ -59,16 +62,16 @@
}
AK9752::Status AK9752::write(char registerAddress, const char *buf, int length) {
- int bufLength = length + 1;
+ int bufLength = length + 1; // Increase size to account for address byte
char data[bufLength];
// Creates data to be sent.
- data[0] = registerAddress;
+ data[0] = registerAddress; // Place register address in first byte
for (int i=0; i < length; i++) {
- data[1+i] = buf[i];
+ data[1+i] = buf[i]; // Load write data starting at second byte (i.e. data[1])
}
- // Writes a start address.
+ // Initiate I2C write command
if (connection->write((slaveAddress << 1), data, bufLength) != 0) {
// I2C write failed.
return AK9752::ERROR_I2C_WRITE;
@@ -82,48 +85,45 @@
char buf = 0;
if((status=read(AK9752_REG_ADDR_INTEN, &buf, LEN_ONE_BYTE)) != SUCCESS) {
- return status;
+ return status; // Read failed
}
+ // Set interrupt status flags individually
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;
+ return SUCCESS; // Read succeeded
}
-AK9752::Status AK9752::setInterruptEnable(const AK9752::InterruptStatus *intStatus) {
+AK9752::Status AK9752::setInterruptEnable(const InterruptStatus *intStatus) {
char buf = 0;
+ // If interrupt bit is 1, set corresponding buf bit to 1, otherwise set to 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;
+ // Perform interrupt status write operation
Status status;
if ((status=write(AK9752_REG_ADDR_INTEN, &buf, LEN_ONE_BYTE)) != SUCCESS) {
return status;
}
+ // Read back the interrupt 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 status; // Read back operation failed
}
- 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;
+ if ((readback & INT_STATUS_MASK) != buf) {
+ return ERROR; // Read back succeeded, but values incorrect
}
+
return SUCCESS;
}
@@ -131,101 +131,110 @@
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
+ // Mask off irrelevant byte, cast 8-bit values to 16-bit
+ //
+ buf[0] = (char)(((uint16_t)th->thirh & 0x00FF)); // THIRHL Register
+ buf[1] = (char)(((uint16_t)th->thirh & 0xFF00) >> 8); // THIRHH Register
+ buf[2] = (char)(((uint16_t)th->thirl & 0x00FF)); // THIRLL Register
+ buf[3] = (char)(((uint16_t)th->thirl & 0xFF00) >> 8); // THIRLH Register
+ buf[4] = (char)(((uint16_t)th->thtmph & 0x00FF)); // THTMPHL Register
+ buf[5] = (char)(((uint16_t)th->thtmph & 0xFF00) >> 8); // THTMPHH Register
+ buf[6] = (char)(((uint16_t)th->thtmpl & 0x00FF)); // THTMPLL Register
+ buf[7] = (char)(((uint16_t)th->thtmpl & 0xFF00) >> 8); // THTMPLH Register
+ // Perform threshold register write operaton
if ((status=write(AK9752_REG_ADDR_THIRHL, buf, LEN_BUF_THRESHOLD)) != SUCCESS) {
- return status;
+ return status; // Write operation failed
}
- return SUCCESS;
+ return SUCCESS; // Write operation succeeded
}
AK9752::Status AK9752::getThreshold(Threshold *th) {
Status status;
char buf[LEN_BUF_THRESHOLD];
+ // Perform threshold register read operation
if ((status=read(AK9752_REG_ADDR_THIRHL, buf, LEN_BUF_THRESHOLD)) != SUCCESS) {
- return status;
+ return status; // Read operation failed
}
+ // Combine low and high bytes of data
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;
+ return SUCCESS; // Read operation succeeded
}
AK9752::Status AK9752::getOperationMode(OperationMode *mode, FcTmp *fc_tmp, FcIr *fc_ir){
- Status status;
+ Status status;
char buf[2];
if ((status=read(AK9752_REG_ADDR_CNTL1, buf, 2)) != SUCCESS) {
- return status;
+ return status; // Read operation failed
}
- *fc_tmp = AK9752::FcTmp((buf[0] & 0x1C)>>2);
- *fc_ir = AK9752::FcIr(buf[0] & 0x03);
- *mode = AK9752::OperationMode(buf[1] & 0x03);
- return SUCCESS;
+ *fc_tmp = AK9752::FcTmp((buf[0] & 0x1C)>>2); // Read CNTL1[2]-CNTL1[4]
+ *fc_ir = AK9752::FcIr(buf[0] & 0x03); // Read CNTL1[0]-CNTL1[1]
+ *mode = AK9752::OperationMode(buf[1] & 0x03); // Read CNTL2[0]-CNTL2[1]
+
+ return SUCCESS; // Read operation succeeded
}
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[0] = (fc_tmp<<2 | fc_ir&0x03); // Combine FCTMP & FCIR in 1 byte
buf[1] = mode;
+
+ // Write 2 bytes starting from CNTL1 -> write CNTL1 and CNTL2
if ((status=write(AK9752_REG_ADDR_CNTL1, buf, 2)) != SUCCESS) {
- return status;
+ return status; // Write operation failed
}
- return SUCCESS;
+ return SUCCESS; // Write operation succeeded
}
AK9752::Status AK9752::reset() {
Status status;
- char val = VAL_SOFTWARE_RESET;
+
+ char val = VAL_SOFTWARE_RESET; // char instance required for write()
if ((status=write(AK9752_REG_ADDR_CNTL3, &val, LEN_ONE_BYTE)) != SUCCESS) {
- return status;
+ return status; // Write operation failed
}
- return SUCCESS;
+ return SUCCESS; // Write operation succeeded
}
-AK9752::Status AK9752::getSensorData(AK9752::SensorData *data) {
- Status status;
+AK9752::Status AK9752::getSensorData(SensorData *data) {
+
char buf[LEN_BUF_IR_DATA];
- if ((status=getData(buf)) != SUCCESS) {
- return status;
+ // Read 7 bytes starting at ST1: reads ST1, INTCAUSE, data and ST2 at once
+ if ((read(AK9752_REG_ADDR_ST1, buf, LEN_BUF_IR_DATA)) != SUCCESS) {
+ return ERROR; // Read operation failed
}
- // check DRDY
- if( (buf[0] & ST1_STATUS_FLAG_DRDY) == 0 ){
- // DRDY=0, data not ready
+ // Check Data ReaDY
+ if( (buf[0] & ST1_STATUS_FLAG_DRDY) == 0 ){ // DRDY=0, data not ready
return ERROR;
}
- // Interrupt Status
+ // Read IR threshold, temp threshold and data ready flags
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]);
+ // Extract IR sensor data
+ data->ir = (int16_t)((buf[3] << 8) | buf[2]); // Combine IRL & IRH
- // Temperature sensor data
- data->temperature = (int16_t)((buf[5] << 8) | buf[4]);
+ // Extract Temperature sensor data
+ data->temperature = (int16_t)((buf[5] << 8) | buf[4]); // Combine TMPL & TMPH
- // DOR Status
+ // Extract Data Overrun status
data->dor = ((buf[1] & ST2_STATUS_FLAG_DOR) > 0) ? true : false;
return SUCCESS;
