Honeywell HMC6352 digital compass library.

Dependents:   HMC6352_HelloWorld TrackerFinal AntennaTracker TrackingAntenna ... more

Files at this revision

API Documentation at this revision

Comitter:
aberk
Date:
Sat Nov 27 12:15:03 2010 +0000
Commit message:
Version 1.0

Changed in this revision

HMC6352.cpp Show annotated file Show diff for this revision Revisions of this file
HMC6352.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 83c0cb554099 HMC6352.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC6352.cpp	Sat Nov 27 12:15:03 2010 +0000
@@ -0,0 +1,270 @@
+/**
+ * @author Aaron Berk
+ * 
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * Honeywell HMC6352 digital compass.
+ *
+ * Datasheet:
+ *
+ * http://www.ssec.honeywell.com/magnetic/datasheets/HMC6352.pdf
+ */
+
+/**
+ * Includes
+ */
+#include "HMC6352.h"
+
+HMC6352::HMC6352(PinName sda, PinName scl) {
+
+    i2c_ = new I2C(sda, scl);
+    //100KHz, as specified by the datasheet.
+    i2c_->frequency(100000);
+
+    operationMode_ = getOpMode();
+
+}
+
+int HMC6352::sample(void) {
+
+    char tx[1];
+    char rx[2];
+
+    if (operationMode_ == HMC6352_STANDBY || operationMode_ == HMC6352_QUERY) {
+        tx[0] = HMC6352_GET_DATA;
+
+        i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 1);
+        wait_ms(1);
+    }
+
+    i2c_->read((HMC6352_I2C_ADDRESS << 1) | 0x01, rx, 2);
+    wait_ms(1);
+
+    return (((int)rx[0] << 8) | (int)rx[1]);
+
+}
+
+void HMC6352::setSleepMode(int exitOrEnter) {
+
+    char tx[1];
+
+    tx[0] = exitOrEnter;
+
+    i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 1);
+    wait_ms(1);
+
+}
+
+void HMC6352::setReset(void) {
+
+    char tx[1];
+
+    tx[0] = HMC6352_SET_RESET;
+
+    i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 1);
+    wait_ms(7);
+
+}
+
+void HMC6352::setCalibrationMode(int exitOrEnter) {
+
+    char tx[1];
+    int delay = 0;
+
+    tx[0] = exitOrEnter;
+
+    if (exitOrEnter == HMC6352_EXIT_CALIB) {
+        delay = 15;
+    } else if (exitOrEnter == HMC6352_ENTER_CALIB) {
+        delay = 1;
+    }
+
+    i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 1);
+    wait_ms(delay);
+
+}
+
+void HMC6352::saveOpMode(void) {
+
+    char tx[1];
+
+    tx[0] = HMC6352_SAVE_OPMODE;
+
+    i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 1);
+    wait_ms(1);
+
+}
+
+int HMC6352::getSlaveAddress(void) {
+
+    return read(HMC6352_EEPROM_READ, HMC6352_SLAVE_ADDR);
+
+}
+
+int HMC6352::getOffset(int axis) {
+
+    char rx[2] = {0x00, 0x00};
+
+    if (axis == HMC6352_MX_OFFSET) {
+
+        rx[0] = read(HMC6352_EEPROM_READ, HMC6352_MX_OFF_MSB);
+        rx[1] = read(HMC6352_EEPROM_READ, HMC6352_MX_OFF_LSB);
+
+    } else if (axis == HMC6352_MY_OFFSET) {
+
+        rx[0] = read(HMC6352_EEPROM_READ, HMC6352_MY_OFF_MSB);
+        rx[1] = read(HMC6352_EEPROM_READ, HMC6352_MY_OFF_LSB);
+
+    }
+
+    return ((rx[0] << 8) | (rx[1]));
+
+}
+
+void HMC6352::setOffset(int axis, int offset) {
+
+    char tx[2] = {0x00, 0x00};
+
+    tx[0] = (offset & 0x0000FF00) >> 8;
+    tx[1] = (offset & 0x000000FF);
+
+    if (axis == HMC6352_MX_OFFSET) {
+
+        write(HMC6352_EEPROM_WRITE, HMC6352_MX_OFF_MSB, tx[0]);
+        write(HMC6352_EEPROM_WRITE, HMC6352_MX_OFF_MSB, tx[1]);
+
+    } else if (axis == HMC6352_MY_OFFSET) {
+
+        write(HMC6352_EEPROM_WRITE, HMC6352_MY_OFF_MSB, tx[0]);
+        write(HMC6352_EEPROM_WRITE, HMC6352_MY_OFF_MSB, tx[1]);
+
+    }
+
+}
+
+int HMC6352::getTimeDelay(void) {
+
+    return read(HMC6352_EEPROM_READ, HMC6352_TIME_DELAY);
+
+}
+
+void HMC6352::setTimeDelay(int delay) {
+
+    write(HMC6352_EEPROM_WRITE, HMC6352_TIME_DELAY, delay);
+
+}
+
+int HMC6352::getSumNumber(void) {
+
+    return read(HMC6352_EEPROM_READ, HMC6352_SUMMED);
+
+}
+
+void HMC6352::setSumNumber(int sum) {
+
+    write(HMC6352_EEPROM_WRITE, HMC6352_SUMMED, sum);
+
+}
+
+int HMC6352::getSoftwareVersion(void) {
+
+    return read(HMC6352_EEPROM_READ, HMC6352_SOFT_VER);
+
+}
+
+int HMC6352::getOpMode(void) {
+
+    int response = 0;
+
+    response = read(HMC6352_RAM_READ, HMC6352_RAM_OPMODE);
+
+    return (response & 0x00000003);
+
+}
+
+void HMC6352::setOpMode(int mode, int periodicSetReset, int measurementRate) {
+
+    char opModeByte = mode;
+
+    if (periodicSetReset == 1) {
+        opModeByte |= HMC6352_PERIODIC_SR;
+    }
+
+    if (measurementRate == 5) {
+        opModeByte |= HMC6352_CM_MR_5HZ;
+    } else if (measurementRate == 10) {
+        opModeByte |= HMC6352_CM_MR_10HZ;
+    } else if (measurementRate == 20) {
+        opModeByte |= HMC6352_CM_MR_20HZ;
+    }
+
+    write(HMC6352_RAM_WRITE, HMC6352_RAM_OPMODE, opModeByte);
+    write(HMC6352_EEPROM_WRITE, HMC6352_OPMODE, opModeByte);
+
+    operationMode_ = mode;
+
+}
+
+int HMC6352::getOutputMode(void) {
+
+    return read(HMC6352_RAM_READ, HMC6352_RAM_OUTPUT);
+
+}
+
+void HMC6352::setOutputMode(int mode) {
+
+    write(HMC6352_RAM_WRITE, HMC6352_RAM_OUTPUT, mode);
+
+}
+
+void HMC6352::write(int EepromOrRam, int address, int data) {
+
+    char tx[3];
+
+    tx[0] = EepromOrRam;
+    tx[1] = address;
+    tx[2] = data;
+
+    i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 3);
+    wait_ms(1);
+
+}
+
+int HMC6352::read(int EepromOrRam, int address) {
+
+    char tx[2];
+    char rx[1];
+
+    tx[0] = EepromOrRam;
+    tx[1] = address;
+
+    i2c_->write((HMC6352_I2C_ADDRESS << 1) & 0xFE, tx, 2);
+    wait_ms(1);
+    i2c_->read((HMC6352_I2C_ADDRESS << 1) | 0x01, rx, 1);
+    wait_ms(1);
+
+    return (rx[0]);
+
+}
diff -r 000000000000 -r 83c0cb554099 HMC6352.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HMC6352.h	Sat Nov 27 12:15:03 2010 +0000
@@ -0,0 +1,283 @@
+/**
+ * @author Aaron Berk
+ * 
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * Honeywell HMC6352 digital compass.
+ *
+ * Datasheet:
+ *
+ * http://www.ssec.honeywell.com/magnetic/datasheets/HMC6352.pdf
+ */
+
+#ifndef HMC6352_H
+#define HMC6352_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/**
+ * Defines
+ */
+#define HMC6352_I2C_ADDRESS  0x21 //7-bit address. 0x43 write, 0x42 read.
+
+//Commands.
+#define HMC6352_EEPROM_WRITE 0x77
+#define HMC6352_EEPROM_READ  0x72
+#define HMC6352_RAM_WRITE    0x47
+#define HMC6352_RAM_READ     0x67
+#define HMC6352_ENTER_SLEEP  0x53
+#define HMC6352_EXIT_SLEEP   0x57
+#define HMC6352_SET_RESET    0x4F
+#define HMC6352_ENTER_CALIB  0x43
+#define HMC6352_EXIT_CALIB   0x45
+#define HMC6352_SAVE_OPMODE  0x4C
+#define HMC6352_GET_DATA     0x41
+
+//EEPROM locations.
+#define HMC6352_SLAVE_ADDR   0x00
+#define HMC6352_MX_OFF_MSB   0x01
+#define HMC6352_MX_OFF_LSB   0x02
+#define HMC6352_MY_OFF_MSB   0x03
+#define HMC6352_MY_OFF_LSB   0x04
+#define HMC6352_TIME_DELAY   0x05
+#define HMC6352_SUMMED       0x06
+#define HMC6352_SOFT_VER     0x07
+#define HMC6352_OPMODE       0x08
+
+//RAM registers.
+#define HMC6352_RAM_OPMODE   0x74
+#define HMC6352_RAM_OUTPUT   0x4E
+
+#define HMC6352_MX_OFFSET    0x00
+#define HMC6352_MY_OFFSET    0x01
+
+#define HMC6352_HEADING_MODE 0x00
+#define HMC6352_RAWMAGX_MODE 0x01
+#define HMC6352_RAWMAGY_MODE 0x02
+#define HMC6352_MAGX_MODE    0x03
+#define HMC6352_MAGY_MODE    0x04
+
+//Operational mode register masks.
+#define HMC6352_CM_MR_1HZ    0x00
+#define HMC6352_CM_MR_5HZ    0x20
+#define HMC6352_CM_MR_10HZ   0x40
+#define HMC6352_CM_MR_20HZ   0x60
+
+#define HMC6352_PERIODIC_SR  0x10
+
+#define HMC6352_STANDBY      0x00
+#define HMC6352_QUERY        0x01
+#define HMC6352_CONTINUOUS   0x02
+
+/**
+ * Honeywell HMC6352 digital compass.
+ */
+class HMC6352 {
+
+public:
+
+    /**
+     * Constructor.
+     *
+     * @param sda mbed pin to use for SDA line of I2C interface.
+     * @param scl mbed pin to use for SCL line of I2C interface.
+     */
+    HMC6352(PinName sda, PinName scl);
+
+    /**
+     * Sample the device and return the result.
+     *
+     * @return In heading output mode, the current heading as a number between
+     *         0-3599, representing 0-359.9 degrees.
+     *         In raw magnetometer X output mode, the raw output of the X-axis
+     *         magnetometer.
+     *         In raw magnetometer Y mode, the raw output of the Y-axis
+     *         magnetometer.
+     *         In magnetometer X mode, the corrected output of the X-axis
+     *         magnetometer.
+     *         In magnetometer Y mode, the corrected output of the Y-axis
+     *         magnetometer.
+     */
+    int sample(void);
+
+    /**
+     * Enter into or exit from sleep mode.
+     *
+     * @param enterOrExit 0x57 -> Exit sleep mode
+     *                    0x53 -> Enter
+     */
+    void setSleepMode(int enterOrExit);
+
+    /**
+     * Update bridge offsets.
+     *
+     * Performs a set/reset immediately.
+     */
+    void setReset(void);
+
+    /**
+     * Enter into or exit from calibration mode.
+     *
+     * @param enterOrExit 0x45 -> Exit
+     *                    0x43 -> Enter
+     */
+    void setCalibrationMode(int enterOrExit);
+
+    /**
+     * Save the current operation mode byte to EEPROM.
+     */
+    void saveOpMode(void);
+
+    /**
+     * Read the memory location on the device which contains the slave address.
+     *
+     * @return The slave address of the device.
+     */
+    int getSlaveAddress(void);
+
+    /**
+     * Read the current offset for X or Y axis magnetometer.
+     *
+     * @param axis 0x00 -> X-axis
+     *             0x01 -> Y-axis
+     * @return The current offset for the axis as a 16-bit number.
+     */
+    int getOffset(int axis);
+
+    /**
+     * Set the offset for X or Y axis magnetometer.
+     *
+     * @param axis 0x00 -> X-axis
+     *             0x01 -> Y-axis
+     * @param offset The offset to set for the axis (set to a 16-bit number).
+     */
+    void setOffset(int axis, int offset);
+
+    /**
+     * Get the current time delay.
+     *
+     * @return The time delay in milliseconds.
+     */
+    int getTimeDelay(void);
+
+    /**
+     * Set the time delay of the device.
+     *
+     * @param delay The time delay to set in milliseconds (between 0-255);
+     */
+    void setTimeDelay(int delay);
+
+    /**
+     * Get the number of measurements being summed each sample.
+     *
+     * @return The number of summed measurement.
+     */
+    int getSumNumber(void);
+
+    /**
+     * Set the number of measurements being summed each sample.
+     *
+     * @param sum The number of measurements to be summed (between 0-16);
+     */
+    void setSumNumber(int sum);
+
+    /**
+     * Get the software version on the device.
+     *
+     * @return The software version number.
+     */
+    int getSoftwareVersion(void);
+
+    /**
+     * Get the current operation mode.
+     *
+     * @return 0x00 -> Standby mode
+     *         0x01 -> Query mode
+     *         0x02 -> Continuous mode
+     */
+    int getOpMode(void);
+
+    /**
+     * Set the operation mode.
+     *
+     * @param mode 0x00 -> Standby mode
+     *             0x01 -> Query mode
+     *             0x02 -> Continuous mode
+     * @param periodicSetReset 0x00 -> No periodic set/reset
+     *                         0x01 -> Periodic set/reset
+     * @measurementRate Measurement rate in Hz for continuous rate.
+     *                  Possible rates: {1, 5, 10, 20}Hz.
+     */
+    void setOpMode(int mode, int periodicSetReset, int measurementRate = 0);
+
+    /**
+     * Get the current output mode of the device.
+     *
+     * @return The current output mode.
+     */
+    int getOutputMode(void);
+
+    /**
+     * Set the output mode of the device.
+     *
+     * @param mode 0x00 -> Heading mode
+     *             0x01 -> Raw magnetometer X mode
+     *             0x02 -> Raw magnetometer Y mode
+     *             0x03 -> Magnetometer X mode
+     *             0x04 -> Magnetometer Y mode
+     */
+    void setOutputMode(int mode);
+
+private:
+
+    I2C* i2c_;
+    int  operationMode_;
+
+    /**
+     * Write to EEPROM or RAM on the device.
+     *
+     * @param EepromOrRam 0x77 -> Writing to EEPROM
+     *                    0x47 -> Writing to RAM
+     * @param address Address to write to.
+     * @param data Data to write.
+     */
+    void write(int EepromOrRam, int address, int data);
+
+    /**
+     * Read EEPROM or RAM on the device.
+     *
+     * @param EepromOrRam 0x72 -> Reading from EEPROM
+     *                    0x67 -> Reading from RAM
+     * @param address Address to read from.
+     * @return The contents of the memory address.
+     */
+    int read(int EepromOrRam, int address);
+
+};
+
+#endif /* HMC6352_H */