Committer:
ssozonoff
Date:
Fri Apr 29 22:10:27 2011 +0000
Revision:
0:5b09476278da
Child:
1:bdf678f27614
1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ssozonoff 0:5b09476278da 1 /**
ssozonoff 0:5b09476278da 2 * @author Aaron Berk
ssozonoff 0:5b09476278da 3 * @author Serge Sozonoff
ssozonoff 0:5b09476278da 4 * Based on the work of Aaron Berk for the HMC6343
ssozonoff 0:5b09476278da 5 *
ssozonoff 0:5b09476278da 6 * @section LICENSE
ssozonoff 0:5b09476278da 7 *
ssozonoff 0:5b09476278da 8 * Copyright (c) 2010 ARM Limited
ssozonoff 0:5b09476278da 9 *
ssozonoff 0:5b09476278da 10 * Permission is hereby granted, free of charge, to any person obtaining a copy
ssozonoff 0:5b09476278da 11 * of this software and associated documentation files (the "Software"), to deal
ssozonoff 0:5b09476278da 12 * in the Software without restriction, including without limitation the rights
ssozonoff 0:5b09476278da 13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
ssozonoff 0:5b09476278da 14 * copies of the Software, and to permit persons to whom the Software is
ssozonoff 0:5b09476278da 15 * furnished to do so, subject to the following conditions:
ssozonoff 0:5b09476278da 16 *
ssozonoff 0:5b09476278da 17 * The above copyright notice and this permission notice shall be included in
ssozonoff 0:5b09476278da 18 * all copies or substantial portions of the Software.
ssozonoff 0:5b09476278da 19 *
ssozonoff 0:5b09476278da 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
ssozonoff 0:5b09476278da 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
ssozonoff 0:5b09476278da 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
ssozonoff 0:5b09476278da 23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
ssozonoff 0:5b09476278da 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ssozonoff 0:5b09476278da 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
ssozonoff 0:5b09476278da 26 * THE SOFTWARE.
ssozonoff 0:5b09476278da 27 *
ssozonoff 0:5b09476278da 28 * @section DESCRIPTION
ssozonoff 0:5b09476278da 29 *
ssozonoff 0:5b09476278da 30 * Honeywell HMC6343 digital compass.
ssozonoff 0:5b09476278da 31 *
ssozonoff 0:5b09476278da 32 * Datasheet:
ssozonoff 0:5b09476278da 33 *
ssozonoff 0:5b09476278da 34 * http://www.ssec.honeywell.com/magnetic/datasheets/HMC6343.pdf
ssozonoff 0:5b09476278da 35 */
ssozonoff 0:5b09476278da 36
ssozonoff 0:5b09476278da 37 /**
ssozonoff 0:5b09476278da 38 * Includes
ssozonoff 0:5b09476278da 39 */
ssozonoff 0:5b09476278da 40 #include "HMC6343.h"
ssozonoff 0:5b09476278da 41
ssozonoff 0:5b09476278da 42 template<class TYPE> inline TYPE BIT(const TYPE & x) {
ssozonoff 0:5b09476278da 43 return TYPE(1) << x;
ssozonoff 0:5b09476278da 44 }
ssozonoff 0:5b09476278da 45
ssozonoff 0:5b09476278da 46 template<class TYPE> inline bool IsBitSet(const TYPE & x, const TYPE & y) {
ssozonoff 0:5b09476278da 47 return 0 != (x & y);
ssozonoff 0:5b09476278da 48 }
ssozonoff 0:5b09476278da 49
ssozonoff 0:5b09476278da 50 HMC6343::HMC6343(PinName sda, PinName scl) {
ssozonoff 0:5b09476278da 51
ssozonoff 0:5b09476278da 52 i2c_ = new I2C(sda, scl);
ssozonoff 0:5b09476278da 53 //100KHz, as specified by the datasheet.
ssozonoff 0:5b09476278da 54 i2c_->frequency(100000);
ssozonoff 0:5b09476278da 55
ssozonoff 0:5b09476278da 56 operationMode_ = getOpMode();
ssozonoff 0:5b09476278da 57
ssozonoff 0:5b09476278da 58 }
ssozonoff 0:5b09476278da 59
ssozonoff 0:5b09476278da 60 double HMC6343::sampleHeading(void) {
ssozonoff 0:5b09476278da 61
ssozonoff 0:5b09476278da 62 char tx[1];
ssozonoff 0:5b09476278da 63 char rx[6];
ssozonoff 0:5b09476278da 64
ssozonoff 0:5b09476278da 65 tx[0] = HMC6343_GET_HEADING_DATA;
ssozonoff 0:5b09476278da 66 i2c_->write((HMC6343_I2C_ADDRESS << 1) & 0xFE, tx, 1);
ssozonoff 0:5b09476278da 67 wait_ms(1);
ssozonoff 0:5b09476278da 68
ssozonoff 0:5b09476278da 69 i2c_->read((HMC6343_I2C_ADDRESS << 1) | 0x01, rx, 6);
ssozonoff 0:5b09476278da 70
ssozonoff 0:5b09476278da 71 return ((double)((((int)rx[0] << 8) | (int)rx[1])) / 10);
ssozonoff 0:5b09476278da 72 }
ssozonoff 0:5b09476278da 73
ssozonoff 0:5b09476278da 74
ssozonoff 0:5b09476278da 75 void HMC6343::setReset(void) {
ssozonoff 0:5b09476278da 76 char tx[1];
ssozonoff 0:5b09476278da 77 tx[0] = HMC6343_RESET;
ssozonoff 0:5b09476278da 78 i2c_->write((HMC6343_I2C_ADDRESS << 1) & 0xFE, tx, 1);
ssozonoff 0:5b09476278da 79 wait_ms(7);
ssozonoff 0:5b09476278da 80 }
ssozonoff 0:5b09476278da 81
ssozonoff 0:5b09476278da 82 void HMC6343::setCalibrationMode(int exitOrEnter) {
ssozonoff 0:5b09476278da 83 char tx[1];
ssozonoff 0:5b09476278da 84 int delay = 0;
ssozonoff 0:5b09476278da 85
ssozonoff 0:5b09476278da 86 tx[0] = exitOrEnter;
ssozonoff 0:5b09476278da 87
ssozonoff 0:5b09476278da 88 if (exitOrEnter == HMC6343_EXIT_CALIB) {
ssozonoff 0:5b09476278da 89 delay = 50;
ssozonoff 0:5b09476278da 90 } else if (exitOrEnter == HMC6343_ENTER_CALIB) {
ssozonoff 0:5b09476278da 91 delay = 1;
ssozonoff 0:5b09476278da 92 }
ssozonoff 0:5b09476278da 93
ssozonoff 0:5b09476278da 94 i2c_->write((HMC6343_I2C_ADDRESS << 1) & 0xFE, tx, 1);
ssozonoff 0:5b09476278da 95 wait_ms(delay);
ssozonoff 0:5b09476278da 96 }
ssozonoff 0:5b09476278da 97
ssozonoff 0:5b09476278da 98
ssozonoff 0:5b09476278da 99 int HMC6343::getSlaveAddress(void) {
ssozonoff 0:5b09476278da 100 return read(HMC6343_SLAVE_ADDR);
ssozonoff 0:5b09476278da 101 }
ssozonoff 0:5b09476278da 102
ssozonoff 0:5b09476278da 103 int HMC6343::getOffset(int axis) {
ssozonoff 0:5b09476278da 104
ssozonoff 0:5b09476278da 105 char rx[2] = {0x00, 0x00};
ssozonoff 0:5b09476278da 106
ssozonoff 0:5b09476278da 107 if (axis == HMC6343_X_AXIS) {
ssozonoff 0:5b09476278da 108 rx[0] = read(HMC6343_XOFFSET_MSB);
ssozonoff 0:5b09476278da 109 rx[1] = read(HMC6343_XOFFSET_LSB);
ssozonoff 0:5b09476278da 110
ssozonoff 0:5b09476278da 111 } else if (axis == HMC6343_Y_AXIS) {
ssozonoff 0:5b09476278da 112 rx[0] = read(HMC6343_YOFFSET_MSB);
ssozonoff 0:5b09476278da 113 rx[1] = read(HMC6343_YOFFSET_LSB);
ssozonoff 0:5b09476278da 114
ssozonoff 0:5b09476278da 115 } else {
ssozonoff 0:5b09476278da 116 rx[0] = read(HMC6343_ZOFFSET_MSB);
ssozonoff 0:5b09476278da 117 rx[1] = read(HMC6343_ZOFFSET_LSB);
ssozonoff 0:5b09476278da 118 }
ssozonoff 0:5b09476278da 119
ssozonoff 0:5b09476278da 120 return ((rx[0] << 8) | (rx[1]));
ssozonoff 0:5b09476278da 121
ssozonoff 0:5b09476278da 122 }
ssozonoff 0:5b09476278da 123
ssozonoff 0:5b09476278da 124
ssozonoff 0:5b09476278da 125 int HMC6343::getSoftwareVersion(void) {
ssozonoff 0:5b09476278da 126
ssozonoff 0:5b09476278da 127 return read(HMC6343_SOFT_VER);
ssozonoff 0:5b09476278da 128
ssozonoff 0:5b09476278da 129 }
ssozonoff 0:5b09476278da 130
ssozonoff 0:5b09476278da 131 int HMC6343::getOpMode(void) {
ssozonoff 0:5b09476278da 132
ssozonoff 0:5b09476278da 133 char tx[1];
ssozonoff 0:5b09476278da 134 tx[0] = HMC6343_GET_OPMODE;
ssozonoff 0:5b09476278da 135
ssozonoff 0:5b09476278da 136 char rx[2];
ssozonoff 0:5b09476278da 137
ssozonoff 0:5b09476278da 138 i2c_->write((HMC6343_I2C_ADDRESS << 1) & 0xFE, tx, 1);
ssozonoff 0:5b09476278da 139 wait_ms(1);
ssozonoff 0:5b09476278da 140 i2c_->read((HMC6343_I2C_ADDRESS << 1) | 0x01, rx, 2);
ssozonoff 0:5b09476278da 141
ssozonoff 0:5b09476278da 142 operationMode_ = (rx[1] << 8) | (rx[0]);
ssozonoff 0:5b09476278da 143
ssozonoff 0:5b09476278da 144 return operationMode_;
ssozonoff 0:5b09476278da 145
ssozonoff 0:5b09476278da 146 }
ssozonoff 0:5b09476278da 147
ssozonoff 0:5b09476278da 148 void HMC6343::setOpMode(int mode, int periodicSetReset, int measurementRate) {
ssozonoff 0:5b09476278da 149
ssozonoff 0:5b09476278da 150 }
ssozonoff 0:5b09476278da 151
ssozonoff 0:5b09476278da 152 void HMC6343::writeFloat(int lsb_address, float data) {
ssozonoff 0:5b09476278da 153 int i = (int)(data * 100);
ssozonoff 0:5b09476278da 154 if (i <= 1800 && i >= -1800) {
ssozonoff 0:5b09476278da 155 write(lsb_address, (int)(i & 0x000000FF));
ssozonoff 0:5b09476278da 156 write(lsb_address + 1, (int)(i >> 8));
ssozonoff 0:5b09476278da 157 }
ssozonoff 0:5b09476278da 158 }
ssozonoff 0:5b09476278da 159
ssozonoff 0:5b09476278da 160 float HMC6343::readFloat(int lsb_eprom_address) {
ssozonoff 0:5b09476278da 161 return ((float)(read(lsb_eprom_address + 1) << 8 | read(lsb_eprom_address)) / 100);
ssozonoff 0:5b09476278da 162 }
ssozonoff 0:5b09476278da 163
ssozonoff 0:5b09476278da 164
ssozonoff 0:5b09476278da 165 void HMC6343::setMagneticDeviation(float data) {
ssozonoff 0:5b09476278da 166 writeFloat(HMC6343_DEV_LSB, data);
ssozonoff 0:5b09476278da 167 }
ssozonoff 0:5b09476278da 168
ssozonoff 0:5b09476278da 169 float HMC6343::getMagneticDeviation() {
ssozonoff 0:5b09476278da 170 return readFloat(HMC6343_DEV_LSB);
ssozonoff 0:5b09476278da 171 }
ssozonoff 0:5b09476278da 172
ssozonoff 0:5b09476278da 173 void HMC6343::setMagneticVariation(float data) {
ssozonoff 0:5b09476278da 174 writeFloat(HMC6343_VAR_LSB, data);
ssozonoff 0:5b09476278da 175 }
ssozonoff 0:5b09476278da 176
ssozonoff 0:5b09476278da 177 float HMC6343::getMagneticVariation() {
ssozonoff 0:5b09476278da 178 return readFloat(HMC6343_VAR_LSB);
ssozonoff 0:5b09476278da 179 }
ssozonoff 0:5b09476278da 180
ssozonoff 0:5b09476278da 181
ssozonoff 0:5b09476278da 182
ssozonoff 0:5b09476278da 183 void HMC6343::write(int address, int data) {
ssozonoff 0:5b09476278da 184
ssozonoff 0:5b09476278da 185 char tx[3];
ssozonoff 0:5b09476278da 186
ssozonoff 0:5b09476278da 187 tx[0] = HMC6343_EEPROM_WRITE;
ssozonoff 0:5b09476278da 188 tx[1] = address;
ssozonoff 0:5b09476278da 189 tx[2] = data;
ssozonoff 0:5b09476278da 190
ssozonoff 0:5b09476278da 191 i2c_->write((HMC6343_I2C_ADDRESS << 1) & 0xFE, tx, 3);
ssozonoff 0:5b09476278da 192 wait_ms(1);
ssozonoff 0:5b09476278da 193
ssozonoff 0:5b09476278da 194 }
ssozonoff 0:5b09476278da 195
ssozonoff 0:5b09476278da 196 int HMC6343::read(int address) {
ssozonoff 0:5b09476278da 197
ssozonoff 0:5b09476278da 198 char tx[2];
ssozonoff 0:5b09476278da 199 char rx[1];
ssozonoff 0:5b09476278da 200
ssozonoff 0:5b09476278da 201 tx[0] = HMC6343_EEPROM_READ;
ssozonoff 0:5b09476278da 202 tx[1] = address;
ssozonoff 0:5b09476278da 203
ssozonoff 0:5b09476278da 204 i2c_->write((HMC6343_I2C_ADDRESS << 1) & 0xFE, tx, 2);
ssozonoff 0:5b09476278da 205 wait_ms(1);
ssozonoff 0:5b09476278da 206 i2c_->read((HMC6343_I2C_ADDRESS << 1) | 0x01, rx, 1);
ssozonoff 0:5b09476278da 207 wait_ms(1);
ssozonoff 0:5b09476278da 208
ssozonoff 0:5b09476278da 209 return (rx[0]);
ssozonoff 0:5b09476278da 210
ssozonoff 0:5b09476278da 211 }