Driver for the HSCDTD008A Geomagnetic Sensor.
HSCDTD008A.cpp@1:b90695c17177, 2021-06-20 (annotated)
- 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?
User | Revision | Line number | New 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 | } |