Driver for the HSCDTD008A Geomagnetic Sensor.

Dependents:   HSCDTD008A_Hello

Committer:
hudakz
Date:
Sun Jun 20 14:18:02 2021 +0000
Revision:
1:b90695c17177
Parent:
0:ccf912737de7
Driver for the HSCDTD008A Geomagnetic Sensor.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:ccf912737de7 1 /*
hudakz 0:ccf912737de7 2 * Copyright (c) 2020 Zoltan Hudak <hudakz@outlook.com>
hudakz 0:ccf912737de7 3 * All rights reserved.
hudakz 0:ccf912737de7 4 *
hudakz 0:ccf912737de7 5 * This program is free software: you can redistribute it and/or modify
hudakz 0:ccf912737de7 6 * it under the terms of the GNU General Public License as published by
hudakz 0:ccf912737de7 7 * the Free Software Foundation, either version 3 of the License, or
hudakz 0:ccf912737de7 8 * (at your option) any later version.
hudakz 0:ccf912737de7 9 *
hudakz 0:ccf912737de7 10 * This program is distributed in the hope that it will be useful,
hudakz 0:ccf912737de7 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 0:ccf912737de7 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 0:ccf912737de7 13 * GNU General Public License for more details.
hudakz 0:ccf912737de7 14 *
hudakz 0:ccf912737de7 15 * You should have received a copy of the GNU General Public License
hudakz 0:ccf912737de7 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 0:ccf912737de7 17 */
hudakz 0:ccf912737de7 18
hudakz 0:ccf912737de7 19 #include "mbed.h"
hudakz 0:ccf912737de7 20 #include "HSCDTD008A.h"
hudakz 0:ccf912737de7 21
hudakz 0:ccf912737de7 22 /*$off*/
hudakz 0:ccf912737de7 23 const char STB = 0x0C; // Self test response
hudakz 0:ccf912737de7 24 const char INFO1 = 0x0D; // More info version
hudakz 0:ccf912737de7 25 const char INFO2 = 0x0E; // More info ALPS
hudakz 0:ccf912737de7 26 const char WIA = 0x0F; // Who I am
hudakz 0:ccf912737de7 27 const char OUTX_LSB = 0x10; // Output X LSB
hudakz 0:ccf912737de7 28 const char OUTX_MSB = 0x11; // Output X MSB
hudakz 0:ccf912737de7 29 const char OUTY_LSB = 0x12; // Output Y LSB
hudakz 0:ccf912737de7 30 const char OUTY_MSB = 0x13; // Output Y MSB
hudakz 0:ccf912737de7 31 const char OUTZ_LSB = 0x14; // Output Z LSB
hudakz 0:ccf912737de7 32 const char OUTZ_MSB = 0x15; // Output Z MSB
hudakz 0:ccf912737de7 33 const char STAT = 0x18; // Status
hudakz 0:ccf912737de7 34 const char FFPT = 0x19; // FIFO Pointer Status
hudakz 0:ccf912737de7 35 const char CTRL1 = 0x1B; // Control1
hudakz 0:ccf912737de7 36 const char CTRL2 = 0x1C; // Control2
hudakz 0:ccf912737de7 37 const char CTRL3 = 0x1D; // Control3
hudakz 0:ccf912737de7 38 const char CTRL4 = 0x1E; // Control4
hudakz 0:ccf912737de7 39 const char OFFX_LSB = 0x20; // Offset X LSB
hudakz 0:ccf912737de7 40 const char OFFX_MSB = 0x21; // Offset X MSB
hudakz 0:ccf912737de7 41 const char OFFY_LSB = 0x22; // Offset Y LSB
hudakz 0:ccf912737de7 42 const char OFFY_MSB = 0x23; // Offset Y MSB
hudakz 0:ccf912737de7 43 const char OFFZ_LSB = 0x24; // Offset Z LSB
hudakz 0:ccf912737de7 44 const char OFFZ_MSB = 0x25; // Offset Z MSB
hudakz 0:ccf912737de7 45 const char ITHR_LSB = 0x26; // Interrupt Threshold LSB. Comparison value.Note: Enabled if CTRL2.FCO
hudakz 0:ccf912737de7 46 const char ITHR_MSB = 0x27; // Interrupt Threshold MSB. Not Used (Read Only)
hudakz 0:ccf912737de7 47 const char TEMP = 0x31; // Temperature Data, Signed Integer. LSB = 1°C, 1000 0000 = -128°C, 0000 0000 = 0°C, 0111 1111 = 127°C
hudakz 0:ccf912737de7 48 //
hudakz 0:ccf912737de7 49 /**
hudakz 0:ccf912737de7 50 * @brief
hudakz 0:ccf912737de7 51 * @note
hudakz 0:ccf912737de7 52 * @param
hudakz 0:ccf912737de7 53 * @retval
hudakz 0:ccf912737de7 54 */
hudakz 0:ccf912737de7 55 void printBinary(uint8_t val)
hudakz 0:ccf912737de7 56 {
hudakz 0:ccf912737de7 57 for (int i = 7; i >= 0; i--) {
hudakz 0:ccf912737de7 58 if (val & (1<< i))
hudakz 0:ccf912737de7 59 putc('1', stdout);
hudakz 0:ccf912737de7 60 else
hudakz 0:ccf912737de7 61 putc('0', stdout);
hudakz 0:ccf912737de7 62 }
hudakz 0:ccf912737de7 63 }
hudakz 0:ccf912737de7 64 /*$on*/
hudakz 0:ccf912737de7 65
hudakz 0:ccf912737de7 66 /**
hudakz 0:ccf912737de7 67 * @brief Constructor
hudakz 0:ccf912737de7 68 * @note
hudakz 0:ccf912737de7 69 * @param
hudakz 0:ccf912737de7 70 * @retval
hudakz 0:ccf912737de7 71 */
hudakz 1:b90695c17177 72 HSCDTD008A::HSCDTD008A(PinName sda, PinName scl, uint8_t addr /*= 0x0C*/ ) :
hudakz 0:ccf912737de7 73 _i2c(new I2C(sda, scl)),
hudakz 0:ccf912737de7 74 _addr(addr << 1), // convert to 8bit address
hudakz 0:ccf912737de7 75 _x(0),
hudakz 0:ccf912737de7 76 _y(0),
hudakz 0:ccf912737de7 77 _z(0)
hudakz 0:ccf912737de7 78 {
hudakz 0:ccf912737de7 79 _i2c->frequency(400000); // select 400kHz clock
hudakz 0:ccf912737de7 80 }
hudakz 0:ccf912737de7 81
hudakz 0:ccf912737de7 82 /**
hudakz 0:ccf912737de7 83 * @brief
hudakz 0:ccf912737de7 84 * @note
hudakz 0:ccf912737de7 85 * @param
hudakz 0:ccf912737de7 86 * @retval
hudakz 0:ccf912737de7 87 */
hudakz 0:ccf912737de7 88 int16_t HSCDTD008A::toInt16(uint16_t word)
hudakz 0:ccf912737de7 89 {
hudakz 0:ccf912737de7 90 if (word & (1 << 7))
hudakz 0:ccf912737de7 91 return(-(uint16_t(~word + 1)));
hudakz 0:ccf912737de7 92 else
hudakz 0:ccf912737de7 93 return(word);
hudakz 0:ccf912737de7 94 }
hudakz 0:ccf912737de7 95
hudakz 0:ccf912737de7 96 /**
hudakz 0:ccf912737de7 97 * @brief
hudakz 0:ccf912737de7 98 * @note
hudakz 0:ccf912737de7 99 * @param
hudakz 0:ccf912737de7 100 * @retval
hudakz 0:ccf912737de7 101 */
hudakz 0:ccf912737de7 102 void HSCDTD008A::softReset()
hudakz 0:ccf912737de7 103 {
hudakz 0:ccf912737de7 104 const char soft_reset[] = { CTRL3, (1 << SRST) };
hudakz 0:ccf912737de7 105 char ret;
hudakz 0:ccf912737de7 106
hudakz 0:ccf912737de7 107 _i2c->write(_addr, soft_reset, 2);
hudakz 0:ccf912737de7 108
hudakz 0:ccf912737de7 109 while (true) {
hudakz 0:ccf912737de7 110 ThisThread::sleep_for(1ms);
hudakz 0:ccf912737de7 111
hudakz 0:ccf912737de7 112 // read CTRL3 register
hudakz 0:ccf912737de7 113 _i2c->write(_addr, &CTRL3, 1);
hudakz 0:ccf912737de7 114 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 115
hudakz 0:ccf912737de7 116 if (ret & (1 << SRST) == 0) {
hudakz 0:ccf912737de7 117 break; // done
hudakz 0:ccf912737de7 118 }
hudakz 0:ccf912737de7 119 }
hudakz 0:ccf912737de7 120 }
hudakz 0:ccf912737de7 121
hudakz 0:ccf912737de7 122 /**
hudakz 0:ccf912737de7 123 * @brief
hudakz 0:ccf912737de7 124 * @note
hudakz 0:ccf912737de7 125 * @param
hudakz 0:ccf912737de7 126 * @retval
hudakz 0:ccf912737de7 127 */
hudakz 1:b90695c17177 128 uint8_t HSCDTD008A::selfTest()
hudakz 0:ccf912737de7 129 {
hudakz 0:ccf912737de7 130 const char start_selftest[] = { CTRL3, (1 << STC) };
hudakz 0:ccf912737de7 131 char ret;
hudakz 0:ccf912737de7 132
hudakz 0:ccf912737de7 133 _i2c->write(_addr, start_selftest, 2);
hudakz 0:ccf912737de7 134
hudakz 0:ccf912737de7 135 // read Status register
hudakz 0:ccf912737de7 136 _i2c->write(_addr, &STB, 1);
hudakz 0:ccf912737de7 137 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 138
hudakz 0:ccf912737de7 139 if (ret == 0xAA) {
hudakz 0:ccf912737de7 140 ThisThread::sleep_for(1ms);
hudakz 0:ccf912737de7 141
hudakz 0:ccf912737de7 142 // read Status register
hudakz 0:ccf912737de7 143 _i2c->write(_addr, &STB, 1);
hudakz 0:ccf912737de7 144 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 145 if (ret == 0x55) {
hudakz 0:ccf912737de7 146 return OK;
hudakz 0:ccf912737de7 147 }
hudakz 0:ccf912737de7 148 }
hudakz 0:ccf912737de7 149
hudakz 0:ccf912737de7 150 return ERROR;
hudakz 0:ccf912737de7 151 }
hudakz 0:ccf912737de7 152
hudakz 0:ccf912737de7 153 /**
hudakz 0:ccf912737de7 154 * @brief
hudakz 0:ccf912737de7 155 * @note
hudakz 0:ccf912737de7 156 * @param
hudakz 0:ccf912737de7 157 * @retval
hudakz 0:ccf912737de7 158 */
hudakz 0:ccf912737de7 159 void HSCDTD008A::calibrateOffsets()
hudakz 0:ccf912737de7 160 {
hudakz 0:ccf912737de7 161 const char start_calibration[] = { CTRL3, (1 << OCL) };
hudakz 0:ccf912737de7 162 char ret;
hudakz 0:ccf912737de7 163
hudakz 0:ccf912737de7 164 _i2c->write(_addr, start_calibration, 2);
hudakz 0:ccf912737de7 165
hudakz 0:ccf912737de7 166 while (true) {
hudakz 0:ccf912737de7 167 ThisThread::sleep_for(1ms);
hudakz 0:ccf912737de7 168
hudakz 0:ccf912737de7 169 // read Control3 register
hudakz 0:ccf912737de7 170 _i2c->write(_addr, &CTRL3, 1);
hudakz 0:ccf912737de7 171 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 172
hudakz 0:ccf912737de7 173 if ((ret & (1 << OCL)) == 0) {
hudakz 0:ccf912737de7 174 break; // done
hudakz 0:ccf912737de7 175 }
hudakz 0:ccf912737de7 176 }
hudakz 0:ccf912737de7 177 }
hudakz 0:ccf912737de7 178
hudakz 0:ccf912737de7 179 /**
hudakz 0:ccf912737de7 180 * @brief
hudakz 0:ccf912737de7 181 * @note
hudakz 0:ccf912737de7 182 * @param
hudakz 0:ccf912737de7 183 * @retval
hudakz 0:ccf912737de7 184 */
hudakz 0:ccf912737de7 185 void HSCDTD008A::setDriftOffsetX(uint16_t val)
hudakz 0:ccf912737de7 186 {
hudakz 0:ccf912737de7 187 const char set_offx_lsb[] = { OFFX_LSB, (char)(val & 0xFF) };
hudakz 0:ccf912737de7 188 const char set_offx_msb[] = { OFFX_MSB, (char)((val >> 8) & 0xFF) };
hudakz 0:ccf912737de7 189
hudakz 0:ccf912737de7 190 _i2c->write(_addr, set_offx_lsb, 2);
hudakz 0:ccf912737de7 191 _i2c->write(_addr, set_offx_msb, 2);
hudakz 0:ccf912737de7 192 }
hudakz 0:ccf912737de7 193
hudakz 0:ccf912737de7 194 /**
hudakz 0:ccf912737de7 195 * @brief
hudakz 0:ccf912737de7 196 * @note
hudakz 0:ccf912737de7 197 * @param
hudakz 0:ccf912737de7 198 * @retval
hudakz 0:ccf912737de7 199 */
hudakz 0:ccf912737de7 200 void HSCDTD008A::setDriftOffsetY(uint16_t val)
hudakz 0:ccf912737de7 201 {
hudakz 0:ccf912737de7 202 const char set_offy_lsb[] = { OFFY_LSB, (char)(val & 0xFF) };
hudakz 0:ccf912737de7 203 const char set_offy_msb[] = { OFFY_MSB, (char)((val >> 8) & 0xFF) };
hudakz 0:ccf912737de7 204
hudakz 0:ccf912737de7 205 _i2c->write(_addr, set_offy_lsb, 2);
hudakz 0:ccf912737de7 206 _i2c->write(_addr, set_offy_msb, 2);
hudakz 0:ccf912737de7 207 }
hudakz 0:ccf912737de7 208
hudakz 0:ccf912737de7 209 /**
hudakz 0:ccf912737de7 210 * @brief
hudakz 0:ccf912737de7 211 * @note
hudakz 0:ccf912737de7 212 * @param
hudakz 0:ccf912737de7 213 * @retval
hudakz 0:ccf912737de7 214 */
hudakz 0:ccf912737de7 215 void HSCDTD008A::setDriftOffsetZ(uint16_t val)
hudakz 0:ccf912737de7 216 {
hudakz 0:ccf912737de7 217 const char set_offz_lsb[] = { OFFZ_LSB, (char)(val & 0xFF) };
hudakz 0:ccf912737de7 218 const char set_offz_msb[] = { OFFZ_MSB, (char)((val >> 8) & 0xFF) };
hudakz 0:ccf912737de7 219
hudakz 0:ccf912737de7 220 _i2c->write(_addr, set_offz_lsb, 2);
hudakz 0:ccf912737de7 221 _i2c->write(_addr, set_offz_msb, 2);
hudakz 0:ccf912737de7 222 }
hudakz 0:ccf912737de7 223
hudakz 0:ccf912737de7 224 /**
hudakz 0:ccf912737de7 225 * @brief
hudakz 0:ccf912737de7 226 * @note
hudakz 0:ccf912737de7 227 * @param
hudakz 0:ccf912737de7 228 * @retval
hudakz 0:ccf912737de7 229 */
hudakz 0:ccf912737de7 230 void HSCDTD008A::compensateTemp()
hudakz 0:ccf912737de7 231 {
hudakz 0:ccf912737de7 232 const char measure_temperature[] = { CTRL3, (1 << TCS) };
hudakz 0:ccf912737de7 233 char ret;
hudakz 0:ccf912737de7 234
hudakz 0:ccf912737de7 235 forcedMode();
hudakz 0:ccf912737de7 236 _i2c->write(_addr, measure_temperature, 2);
hudakz 0:ccf912737de7 237
hudakz 0:ccf912737de7 238 while (true) {
hudakz 0:ccf912737de7 239 ThisThread::sleep_for(1ms);
hudakz 0:ccf912737de7 240
hudakz 1:b90695c17177 241 // read Status register
hudakz 0:ccf912737de7 242 _i2c->write(_addr, &STAT, 1);
hudakz 0:ccf912737de7 243 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 244
hudakz 0:ccf912737de7 245 if (ret & (1 << TRDY)) {
hudakz 0:ccf912737de7 246 break; // done
hudakz 0:ccf912737de7 247 }
hudakz 0:ccf912737de7 248 }
hudakz 0:ccf912737de7 249
hudakz 0:ccf912737de7 250 standbyMode();
hudakz 0:ccf912737de7 251 }
hudakz 0:ccf912737de7 252
hudakz 0:ccf912737de7 253 /**
hudakz 0:ccf912737de7 254 * @brief
hudakz 0:ccf912737de7 255 * @note
hudakz 0:ccf912737de7 256 * @param
hudakz 0:ccf912737de7 257 * @retval
hudakz 0:ccf912737de7 258 */
hudakz 0:ccf912737de7 259 void HSCDTD008A::enableFifo()
hudakz 0:ccf912737de7 260 {
hudakz 0:ccf912737de7 261 const char enable_fifo[] = { CTRL2, (1 << FF) };
hudakz 0:ccf912737de7 262
hudakz 0:ccf912737de7 263 _i2c->write(_addr, enable_fifo, 2);
hudakz 0:ccf912737de7 264 }
hudakz 0:ccf912737de7 265
hudakz 0:ccf912737de7 266 /**
hudakz 0:ccf912737de7 267 * @brief
hudakz 0:ccf912737de7 268 * @note
hudakz 0:ccf912737de7 269 * @param
hudakz 0:ccf912737de7 270 * @retval
hudakz 0:ccf912737de7 271 */
hudakz 0:ccf912737de7 272 void HSCDTD008A::disableFifo()
hudakz 0:ccf912737de7 273 {
hudakz 0:ccf912737de7 274 const char enable_fifo[] = { CTRL2, (0 << FF) };
hudakz 0:ccf912737de7 275
hudakz 0:ccf912737de7 276 _i2c->write(_addr, enable_fifo, 2);
hudakz 0:ccf912737de7 277 }
hudakz 0:ccf912737de7 278
hudakz 0:ccf912737de7 279 /**
hudakz 0:ccf912737de7 280 * @brief
hudakz 0:ccf912737de7 281 * @note
hudakz 0:ccf912737de7 282 * @param
hudakz 0:ccf912737de7 283 * @retval
hudakz 0:ccf912737de7 284 */
hudakz 0:ccf912737de7 285 uint8_t HSCDTD008A::getFifoPointer()
hudakz 0:ccf912737de7 286 {
hudakz 0:ccf912737de7 287 char ret;
hudakz 0:ccf912737de7 288
hudakz 1:b90695c17177 289 // read FIFO pointer register
hudakz 0:ccf912737de7 290 _i2c->write(_addr, &FFPT, 1);
hudakz 0:ccf912737de7 291 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 292
hudakz 0:ccf912737de7 293 return(ret & FP);
hudakz 0:ccf912737de7 294 }
hudakz 0:ccf912737de7 295
hudakz 0:ccf912737de7 296 /**
hudakz 0:ccf912737de7 297 * @brief
hudakz 0:ccf912737de7 298 * @note
hudakz 0:ccf912737de7 299 * @param
hudakz 0:ccf912737de7 300 * @retval
hudakz 0:ccf912737de7 301 */
hudakz 0:ccf912737de7 302 bool HSCDTD008A::isFifoFull()
hudakz 0:ccf912737de7 303 {
hudakz 0:ccf912737de7 304 char ret;
hudakz 0:ccf912737de7 305
hudakz 0:ccf912737de7 306 // read Status register
hudakz 0:ccf912737de7 307 _i2c->write(_addr, &STAT, 1);
hudakz 0:ccf912737de7 308 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 309
hudakz 0:ccf912737de7 310 if (ret & (1 << FFU))
hudakz 0:ccf912737de7 311 return true;
hudakz 0:ccf912737de7 312 else
hudakz 0:ccf912737de7 313 return false;
hudakz 0:ccf912737de7 314 }
hudakz 0:ccf912737de7 315
hudakz 0:ccf912737de7 316 /**
hudakz 0:ccf912737de7 317 * @brief
hudakz 0:ccf912737de7 318 * @note
hudakz 0:ccf912737de7 319 * @param
hudakz 0:ccf912737de7 320 * @retval
hudakz 0:ccf912737de7 321 */
hudakz 0:ccf912737de7 322 bool HSCDTD008A::isFifoOverrun()
hudakz 0:ccf912737de7 323 {
hudakz 0:ccf912737de7 324 char ret;
hudakz 0:ccf912737de7 325
hudakz 0:ccf912737de7 326 // read Status register
hudakz 0:ccf912737de7 327 _i2c->write(_addr, &STAT, 1);
hudakz 0:ccf912737de7 328 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 329
hudakz 0:ccf912737de7 330 if (ret & ((1 << FFU) | (1 << DOR)))
hudakz 0:ccf912737de7 331 return true;
hudakz 0:ccf912737de7 332 else
hudakz 0:ccf912737de7 333 return false;
hudakz 0:ccf912737de7 334 }
hudakz 0:ccf912737de7 335
hudakz 0:ccf912737de7 336 /**
hudakz 0:ccf912737de7 337 * @brief
hudakz 0:ccf912737de7 338 * @note
hudakz 0:ccf912737de7 339 * @param
hudakz 0:ccf912737de7 340 * @retval
hudakz 0:ccf912737de7 341 */
hudakz 0:ccf912737de7 342 bool HSCDTD008A::isDataReady()
hudakz 0:ccf912737de7 343 {
hudakz 0:ccf912737de7 344 char ret;
hudakz 0:ccf912737de7 345
hudakz 0:ccf912737de7 346 // read Status register
hudakz 0:ccf912737de7 347 _i2c->write(_addr, &STAT, 1);
hudakz 0:ccf912737de7 348 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 349
hudakz 0:ccf912737de7 350 if (ret & (1 << DRDY) == 0)
hudakz 0:ccf912737de7 351 return true;
hudakz 0:ccf912737de7 352 else
hudakz 0:ccf912737de7 353 return false;
hudakz 0:ccf912737de7 354 }
hudakz 0:ccf912737de7 355
hudakz 0:ccf912737de7 356 /**
hudakz 0:ccf912737de7 357 * @brief
hudakz 0:ccf912737de7 358 * @note
hudakz 0:ccf912737de7 359 * @param
hudakz 0:ccf912737de7 360 * @retval
hudakz 0:ccf912737de7 361 */
hudakz 0:ccf912737de7 362 void HSCDTD008A::standbyMode()
hudakz 0:ccf912737de7 363 {
hudakz 0:ccf912737de7 364 const char select_standby_mode[] = { CTRL1, (0 << PC) };
hudakz 0:ccf912737de7 365
hudakz 0:ccf912737de7 366 _i2c->write(_addr, select_standby_mode, 2);
hudakz 0:ccf912737de7 367 }
hudakz 0:ccf912737de7 368
hudakz 0:ccf912737de7 369 /**
hudakz 0:ccf912737de7 370 * @brief
hudakz 0:ccf912737de7 371 * @note
hudakz 0:ccf912737de7 372 * @param
hudakz 0:ccf912737de7 373 * @retval
hudakz 0:ccf912737de7 374 */
hudakz 0:ccf912737de7 375 void HSCDTD008A::normalMode(uint8_t odr /*= 0b01*/, bool enableDataReady /*= false*/ )
hudakz 0:ccf912737de7 376 {
hudakz 0:ccf912737de7 377 const char enable_data_ready[] = { CTRL2, (1 << DEN) | (0 << DRP) }; // enable Data Ready with ACTIVE LOW control
hudakz 0:ccf912737de7 378 const char select_normal_mode[] = { CTRL1, (1 << PC) | (0b11 << ODR) | (0 << FS) }; // set active mode to normal
hudakz 0:ccf912737de7 379
hudakz 0:ccf912737de7 380 if (enableDataReady)
hudakz 0:ccf912737de7 381 _i2c->write(_addr, enable_data_ready, 2);
hudakz 0:ccf912737de7 382
hudakz 0:ccf912737de7 383 _i2c->write(_addr, select_normal_mode, 2);
hudakz 0:ccf912737de7 384 }
hudakz 0:ccf912737de7 385
hudakz 0:ccf912737de7 386 /**
hudakz 0:ccf912737de7 387 * @brief
hudakz 0:ccf912737de7 388 * @note
hudakz 0:ccf912737de7 389 * @param
hudakz 0:ccf912737de7 390 * @retval
hudakz 0:ccf912737de7 391 */
hudakz 0:ccf912737de7 392 void HSCDTD008A::forcedMode()
hudakz 0:ccf912737de7 393 {
hudakz 0:ccf912737de7 394 const char select_forced_mode[] = { CTRL1, (1 << PC) | (1 << FS) };
hudakz 0:ccf912737de7 395
hudakz 0:ccf912737de7 396 _i2c->write(_addr, select_forced_mode, 2);
hudakz 0:ccf912737de7 397 }
hudakz 0:ccf912737de7 398
hudakz 0:ccf912737de7 399 /**
hudakz 0:ccf912737de7 400 * @brief
hudakz 0:ccf912737de7 401 * @note
hudakz 0:ccf912737de7 402 * @param
hudakz 0:ccf912737de7 403 * @retval
hudakz 0:ccf912737de7 404 */
hudakz 0:ccf912737de7 405 bool HSCDTD008A::getResolution()
hudakz 0:ccf912737de7 406 {
hudakz 0:ccf912737de7 407 char ret;
hudakz 0:ccf912737de7 408
hudakz 0:ccf912737de7 409 // read CTRL4 register
hudakz 0:ccf912737de7 410 _i2c->write(_addr, &CTRL4, 1);
hudakz 0:ccf912737de7 411 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 412
hudakz 0:ccf912737de7 413 // check RS bit
hudakz 0:ccf912737de7 414 if (ret & (1 << RS))
hudakz 0:ccf912737de7 415 return true; // 15bit output resolution
hudakz 0:ccf912737de7 416 else
hudakz 0:ccf912737de7 417 return false; // 14bit output resolution
hudakz 0:ccf912737de7 418 }
hudakz 0:ccf912737de7 419
hudakz 0:ccf912737de7 420 /**
hudakz 0:ccf912737de7 421 * @brief
hudakz 0:ccf912737de7 422 * @note
hudakz 0:ccf912737de7 423 * @param
hudakz 0:ccf912737de7 424 * @retval
hudakz 0:ccf912737de7 425 */
hudakz 0:ccf912737de7 426 void HSCDTD008A::setResolution(bool fifteen_bits)
hudakz 0:ccf912737de7 427 {
hudakz 0:ccf912737de7 428 char ret;
hudakz 0:ccf912737de7 429 char cmd[2] = { CTRL4, 0 };
hudakz 0:ccf912737de7 430
hudakz 0:ccf912737de7 431 // read CTRL4 register
hudakz 0:ccf912737de7 432 _i2c->write(_addr, &CTRL4, 1);
hudakz 0:ccf912737de7 433 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 434
hudakz 0:ccf912737de7 435 if (fifteen_bits)
hudakz 0:ccf912737de7 436 ret |= (1 << RS); // set RS bit
hudakz 0:ccf912737de7 437 else
hudakz 0:ccf912737de7 438 ret &= ~(0 << RS); // clear RS bit
hudakz 0:ccf912737de7 439 cmd[1] = RS; // set output resolution
hudakz 0:ccf912737de7 440 _i2c->write(_addr, cmd, 2);
hudakz 0:ccf912737de7 441 }
hudakz 0:ccf912737de7 442
hudakz 0:ccf912737de7 443 /**
hudakz 0:ccf912737de7 444 * @brief
hudakz 0:ccf912737de7 445 * @note Shall be called in forced mode
hudakz 0:ccf912737de7 446 * @param
hudakz 0:ccf912737de7 447 * @retval
hudakz 0:ccf912737de7 448 */
hudakz 0:ccf912737de7 449 uint8_t HSCDTD008A::measure()
hudakz 0:ccf912737de7 450 {
hudakz 0:ccf912737de7 451 const char start_measurement[] = { CTRL3, (1 << FRC) }; // Start measurement in force mode (returns to 0 when finished)
hudakz 0:ccf912737de7 452 char ret;
hudakz 0:ccf912737de7 453 char data[6];
hudakz 0:ccf912737de7 454
hudakz 0:ccf912737de7 455 // Start measurement in forced mode
hudakz 0:ccf912737de7 456 _i2c->write(_addr, &STAT, 1);
hudakz 0:ccf912737de7 457 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 458 if (!(ret & (1 << DRDY))) {
hudakz 0:ccf912737de7 459 _i2c->write(_addr, start_measurement, 2);
hudakz 0:ccf912737de7 460 }
hudakz 0:ccf912737de7 461
hudakz 0:ccf912737de7 462 // Read Status register
hudakz 0:ccf912737de7 463 _i2c->write(_addr, &STAT, 1);
hudakz 0:ccf912737de7 464 _i2c->read(_addr, &ret, 1);
hudakz 0:ccf912737de7 465
hudakz 0:ccf912737de7 466 // Is data ready?
hudakz 0:ccf912737de7 467 if (ret & (1 << DRDY)) {
hudakz 0:ccf912737de7 468 readData();
hudakz 0:ccf912737de7 469
hudakz 0:ccf912737de7 470 return OK;
hudakz 0:ccf912737de7 471 }
hudakz 0:ccf912737de7 472
hudakz 0:ccf912737de7 473 return ERROR;
hudakz 0:ccf912737de7 474 }
hudakz 0:ccf912737de7 475
hudakz 0:ccf912737de7 476 /**
hudakz 0:ccf912737de7 477 * @brief
hudakz 0:ccf912737de7 478 * @note
hudakz 0:ccf912737de7 479 * @param
hudakz 0:ccf912737de7 480 * @retval
hudakz 0:ccf912737de7 481 */
hudakz 0:ccf912737de7 482 void HSCDTD008A::readData()
hudakz 0:ccf912737de7 483 {
hudakz 0:ccf912737de7 484 char data[6];
hudakz 0:ccf912737de7 485
hudakz 0:ccf912737de7 486 _i2c->write(_addr, &OUTX_LSB, 1);
hudakz 0:ccf912737de7 487 _i2c->read(_addr, data, 6);
hudakz 0:ccf912737de7 488
hudakz 0:ccf912737de7 489 _x = *((uint16_t*) &data[0]); // two bytes, LSB first
hudakz 0:ccf912737de7 490 _y = *((uint16_t*) &data[2]); // two bytes, LSB first
hudakz 0:ccf912737de7 491 _z = *((uint16_t*) &data[4]); // two bytes, LSB first
hudakz 0:ccf912737de7 492
hudakz 0:ccf912737de7 493 // Debug print
hudakz 0:ccf912737de7 494 //printf("x = ");
hudakz 0:ccf912737de7 495 //printBinary(data[1]);
hudakz 0:ccf912737de7 496 //putc(' ', stdout);
hudakz 0:ccf912737de7 497 //printBinary(data[0]);
hudakz 0:ccf912737de7 498 //printf(" = %d \t= %f mT\r\n", _x, x());
hudakz 0:ccf912737de7 499 //printf("y = ");
hudakz 0:ccf912737de7 500 //printBinary(data[3]);
hudakz 0:ccf912737de7 501 //putc(' ', stdout);
hudakz 0:ccf912737de7 502 //printBinary(data[2]);
hudakz 0:ccf912737de7 503 //printf(" = %d \t= %f mT\r\n", _y, y());
hudakz 0:ccf912737de7 504 //printf("z = ");
hudakz 0:ccf912737de7 505 //printBinary(data[5]);
hudakz 0:ccf912737de7 506 //putc(' ', stdout);
hudakz 0:ccf912737de7 507 //printBinary(data[4]);
hudakz 0:ccf912737de7 508 //printf(" = %d \t= %f mT\r\n", _z, z());
hudakz 0:ccf912737de7 509 }
hudakz 0:ccf912737de7 510
hudakz 0:ccf912737de7 511 /**
hudakz 0:ccf912737de7 512 * @brief
hudakz 0:ccf912737de7 513 * @note
hudakz 0:ccf912737de7 514 * @param
hudakz 0:ccf912737de7 515 * @retval
hudakz 0:ccf912737de7 516 */
hudakz 0:ccf912737de7 517 float HSCDTD008A::x()
hudakz 0:ccf912737de7 518 {
hudakz 0:ccf912737de7 519 return toInt16(_x) * RANGE / RESOL; // mT
hudakz 0:ccf912737de7 520 }
hudakz 0:ccf912737de7 521
hudakz 0:ccf912737de7 522 /**
hudakz 0:ccf912737de7 523 * @brief
hudakz 0:ccf912737de7 524 * @note
hudakz 0:ccf912737de7 525 * @param
hudakz 0:ccf912737de7 526 * @retval
hudakz 0:ccf912737de7 527 */
hudakz 0:ccf912737de7 528 float HSCDTD008A::y()
hudakz 0:ccf912737de7 529 {
hudakz 0:ccf912737de7 530 return toInt16(_y) * RANGE / RESOL; // mT
hudakz 0:ccf912737de7 531 }
hudakz 0:ccf912737de7 532
hudakz 0:ccf912737de7 533 /**
hudakz 0:ccf912737de7 534 * @brief
hudakz 0:ccf912737de7 535 * @note
hudakz 0:ccf912737de7 536 * @param
hudakz 0:ccf912737de7 537 * @retval
hudakz 0:ccf912737de7 538 */
hudakz 0:ccf912737de7 539 float HSCDTD008A::z()
hudakz 0:ccf912737de7 540 {
hudakz 0:ccf912737de7 541 return toInt16(_z) * RANGE / RESOL; // mT
hudakz 0:ccf912737de7 542 }