Driver for KX134-1211 Accelerometer
Dependents: KX134-1211 Examples
KX134.cpp@1:c6e2a348da09, 2020-10-25 (annotated)
- Committer:
- Jasper Swallen
- Date:
- Sun Oct 25 15:47:36 2020 -0400
- Revision:
- 1:c6e2a348da09
- Parent:
- 0:01d5616ba355
make synchronous & read all accel data at once
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jasper Swallen |
0:01d5616ba355 | 1 | #include "KX134.h" |
Jasper Swallen |
0:01d5616ba355 | 2 | #include "math.h" |
Jasper Swallen |
0:01d5616ba355 | 3 | |
Jasper Swallen |
0:01d5616ba355 | 4 | #define SPI_FREQ 100000 |
Jasper Swallen |
0:01d5616ba355 | 5 | |
Jasper Swallen |
1:c6e2a348da09 | 6 | static uint8_t defaultBuffer[2] = {0}; // allows calling writeRegisterOneByte |
Jasper Swallen |
1:c6e2a348da09 | 7 | // without buf argument |
Jasper Swallen |
0:01d5616ba355 | 8 | |
Jasper Swallen |
0:01d5616ba355 | 9 | /* Writes one byte to a register |
Jasper Swallen |
0:01d5616ba355 | 10 | */ |
Jasper Swallen |
0:01d5616ba355 | 11 | void KX134::writeRegisterOneByte(Register addr, uint8_t data, |
Jasper Swallen |
1:c6e2a348da09 | 12 | uint8_t *buf = defaultBuffer) |
Jasper Swallen |
0:01d5616ba355 | 13 | { |
Jasper Swallen |
0:01d5616ba355 | 14 | uint8_t _data[1] = {data}; |
Jasper Swallen |
0:01d5616ba355 | 15 | writeRegister(addr, _data, buf); |
Jasper Swallen |
0:01d5616ba355 | 16 | } |
Jasper Swallen |
0:01d5616ba355 | 17 | |
Jasper Swallen |
0:01d5616ba355 | 18 | KX134::KX134(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName int1, |
Jasper Swallen |
0:01d5616ba355 | 19 | PinName int2, PinName rst) |
Jasper Swallen |
0:01d5616ba355 | 20 | : _spi(mosi, miso, sclk), _int1(int1), _int2(int2), _cs(cs), _rst(rst) |
Jasper Swallen |
0:01d5616ba355 | 21 | { |
Jasper Swallen |
0:01d5616ba355 | 22 | // set default values for settings variables |
Jasper Swallen |
0:01d5616ba355 | 23 | resStatus = 1; // high performance mode |
Jasper Swallen |
1:c6e2a348da09 | 24 | drdyeStatus = 1; // Data Ready Engine enabled |
Jasper Swallen |
0:01d5616ba355 | 25 | gsel1Status = 0; // +-8g bit 1 |
Jasper Swallen |
0:01d5616ba355 | 26 | gsel0Status = 0; // +-8g bit 0 |
Jasper Swallen |
0:01d5616ba355 | 27 | tdteStatus = 0; // Tap/Double-Tap engine disabled |
Jasper Swallen |
0:01d5616ba355 | 28 | tpeStatus = 0; // Tilt Position Engine disabled |
Jasper Swallen |
0:01d5616ba355 | 29 | |
Jasper Swallen |
0:01d5616ba355 | 30 | iirBypass = 0; // IIR filter is not bypassed, i.e. filtering is applied |
Jasper Swallen |
0:01d5616ba355 | 31 | lpro = 0; // IIR filter corner frequency set to ODR/9 |
Jasper Swallen |
0:01d5616ba355 | 32 | fstup = 0; // Fast Start is disabled |
Jasper Swallen |
0:01d5616ba355 | 33 | osa3 = 0; // Output Data Rate bits |
Jasper Swallen |
0:01d5616ba355 | 34 | osa2 = 1; // default is 50hz |
Jasper Swallen |
0:01d5616ba355 | 35 | osa1 = 1; |
Jasper Swallen |
0:01d5616ba355 | 36 | osa0 = 0; |
Jasper Swallen |
0:01d5616ba355 | 37 | |
Jasper Swallen |
0:01d5616ba355 | 38 | registerWritingEnabled = 0; |
Jasper Swallen |
0:01d5616ba355 | 39 | |
Jasper Swallen |
0:01d5616ba355 | 40 | deselect(); |
Jasper Swallen |
0:01d5616ba355 | 41 | } |
Jasper Swallen |
0:01d5616ba355 | 42 | |
Jasper Swallen |
0:01d5616ba355 | 43 | bool KX134::init() |
Jasper Swallen |
0:01d5616ba355 | 44 | { |
Jasper Swallen |
0:01d5616ba355 | 45 | deselect(); |
Jasper Swallen |
0:01d5616ba355 | 46 | |
Jasper Swallen |
0:01d5616ba355 | 47 | _spi.frequency(SPI_FREQ); |
Jasper Swallen |
0:01d5616ba355 | 48 | _spi.format(8, 1); |
Jasper Swallen |
0:01d5616ba355 | 49 | |
Jasper Swallen |
0:01d5616ba355 | 50 | return reset(); |
Jasper Swallen |
0:01d5616ba355 | 51 | } |
Jasper Swallen |
0:01d5616ba355 | 52 | |
Jasper Swallen |
0:01d5616ba355 | 53 | bool KX134::reset() |
Jasper Swallen |
0:01d5616ba355 | 54 | { |
Jasper Swallen |
0:01d5616ba355 | 55 | // write registers to start reset |
Jasper Swallen |
0:01d5616ba355 | 56 | writeRegisterOneByte(Register::INTERNAL_0X7F, 0x00); |
Jasper Swallen |
0:01d5616ba355 | 57 | writeRegisterOneByte(Register::CNTL2, 0x00); |
Jasper Swallen |
0:01d5616ba355 | 58 | writeRegisterOneByte(Register::CNTL2, 0x80); |
Jasper Swallen |
0:01d5616ba355 | 59 | |
Jasper Swallen |
0:01d5616ba355 | 60 | // software reset time |
Jasper Swallen |
0:01d5616ba355 | 61 | wait_us(2000); |
Jasper Swallen |
0:01d5616ba355 | 62 | |
Jasper Swallen |
0:01d5616ba355 | 63 | // check existence |
Jasper Swallen |
0:01d5616ba355 | 64 | return checkExistence(); |
Jasper Swallen |
0:01d5616ba355 | 65 | } |
Jasper Swallen |
0:01d5616ba355 | 66 | |
Jasper Swallen |
0:01d5616ba355 | 67 | /* Helper Functions |
Jasper Swallen |
0:01d5616ba355 | 68 | * ==================================================== |
Jasper Swallen |
0:01d5616ba355 | 69 | */ |
Jasper Swallen |
0:01d5616ba355 | 70 | |
Jasper Swallen |
0:01d5616ba355 | 71 | void KX134::deselect() |
Jasper Swallen |
0:01d5616ba355 | 72 | { |
Jasper Swallen |
0:01d5616ba355 | 73 | _cs.write(1); |
Jasper Swallen |
0:01d5616ba355 | 74 | } |
Jasper Swallen |
0:01d5616ba355 | 75 | |
Jasper Swallen |
0:01d5616ba355 | 76 | void KX134::select() |
Jasper Swallen |
0:01d5616ba355 | 77 | { |
Jasper Swallen |
0:01d5616ba355 | 78 | _cs.write(0); |
Jasper Swallen |
0:01d5616ba355 | 79 | } |
Jasper Swallen |
0:01d5616ba355 | 80 | |
Jasper Swallen |
1:c6e2a348da09 | 81 | void KX134::readRegister(Register addr, uint8_t *rx_buf, int size) |
Jasper Swallen |
0:01d5616ba355 | 82 | { |
Jasper Swallen |
0:01d5616ba355 | 83 | select(); |
Jasper Swallen |
0:01d5616ba355 | 84 | |
Jasper Swallen |
0:01d5616ba355 | 85 | rx_buf[0] = _spi.write((uint8_t)addr | (1 << 7)); |
Jasper Swallen |
0:01d5616ba355 | 86 | |
Jasper Swallen |
0:01d5616ba355 | 87 | for(int i = 1; i < size; ++i) |
Jasper Swallen |
0:01d5616ba355 | 88 | { |
Jasper Swallen |
0:01d5616ba355 | 89 | rx_buf[i] = _spi.write(0x00); |
Jasper Swallen |
0:01d5616ba355 | 90 | } |
Jasper Swallen |
0:01d5616ba355 | 91 | |
Jasper Swallen |
0:01d5616ba355 | 92 | deselect(); |
Jasper Swallen |
0:01d5616ba355 | 93 | } |
Jasper Swallen |
0:01d5616ba355 | 94 | |
Jasper Swallen |
1:c6e2a348da09 | 95 | void KX134::writeRegister(Register addr, uint8_t *data, uint8_t *rx_buf, |
Jasper Swallen |
1:c6e2a348da09 | 96 | int size) |
Jasper Swallen |
0:01d5616ba355 | 97 | { |
Jasper Swallen |
0:01d5616ba355 | 98 | select(); |
Jasper Swallen |
0:01d5616ba355 | 99 | |
Jasper Swallen |
0:01d5616ba355 | 100 | _spi.write((uint8_t)addr); // select register |
Jasper Swallen |
0:01d5616ba355 | 101 | for(int i = 0; i < size; ++i) |
Jasper Swallen |
0:01d5616ba355 | 102 | { |
Jasper Swallen |
0:01d5616ba355 | 103 | rx_buf[i] = _spi.write(data[i]); |
Jasper Swallen |
0:01d5616ba355 | 104 | } |
Jasper Swallen |
0:01d5616ba355 | 105 | |
Jasper Swallen |
0:01d5616ba355 | 106 | deselect(); |
Jasper Swallen |
0:01d5616ba355 | 107 | } |
Jasper Swallen |
0:01d5616ba355 | 108 | |
Jasper Swallen |
0:01d5616ba355 | 109 | int16_t KX134::read16BitValue(Register lowAddr, Register highAddr) |
Jasper Swallen |
0:01d5616ba355 | 110 | { |
Jasper Swallen |
0:01d5616ba355 | 111 | // get contents of register |
Jasper Swallen |
1:c6e2a348da09 | 112 | uint8_t lowWord[2], highWord[2]; |
Jasper Swallen |
0:01d5616ba355 | 113 | readRegister(lowAddr, lowWord); |
Jasper Swallen |
0:01d5616ba355 | 114 | readRegister(highAddr, highWord); |
Jasper Swallen |
0:01d5616ba355 | 115 | |
Jasper Swallen |
1:c6e2a348da09 | 116 | return convertTo16BitValue(lowWord[1], highWord[1]); |
Jasper Swallen |
1:c6e2a348da09 | 117 | } |
Jasper Swallen |
1:c6e2a348da09 | 118 | |
Jasper Swallen |
1:c6e2a348da09 | 119 | int16_t KX134::convertTo16BitValue(uint8_t low, uint8_t high) |
Jasper Swallen |
1:c6e2a348da09 | 120 | { |
Jasper Swallen |
0:01d5616ba355 | 121 | // combine low & high words |
Jasper Swallen |
1:c6e2a348da09 | 122 | uint16_t val2sComplement = (static_cast<uint16_t>(high << 8)) | low; |
Jasper Swallen |
0:01d5616ba355 | 123 | int16_t value = static_cast<int16_t>(val2sComplement); |
Jasper Swallen |
0:01d5616ba355 | 124 | |
Jasper Swallen |
0:01d5616ba355 | 125 | return value; |
Jasper Swallen |
0:01d5616ba355 | 126 | } |
Jasper Swallen |
0:01d5616ba355 | 127 | |
Jasper Swallen |
0:01d5616ba355 | 128 | float KX134::convertRawToGravs(int16_t lsbValue) |
Jasper Swallen |
0:01d5616ba355 | 129 | { |
Jasper Swallen |
0:01d5616ba355 | 130 | if(gsel1Status && gsel0Status) |
Jasper Swallen |
0:01d5616ba355 | 131 | { |
Jasper Swallen |
0:01d5616ba355 | 132 | // +-64g |
Jasper Swallen |
0:01d5616ba355 | 133 | return (float)lsbValue * 0.00195f; |
Jasper Swallen |
0:01d5616ba355 | 134 | } |
Jasper Swallen |
0:01d5616ba355 | 135 | else if(gsel1Status && !gsel0Status) |
Jasper Swallen |
0:01d5616ba355 | 136 | { |
Jasper Swallen |
0:01d5616ba355 | 137 | // +-32g |
Jasper Swallen |
0:01d5616ba355 | 138 | return (float)lsbValue * 0.00098f; |
Jasper Swallen |
0:01d5616ba355 | 139 | } |
Jasper Swallen |
0:01d5616ba355 | 140 | else if(!gsel1Status && gsel0Status) |
Jasper Swallen |
0:01d5616ba355 | 141 | { |
Jasper Swallen |
0:01d5616ba355 | 142 | // +-16g |
Jasper Swallen |
0:01d5616ba355 | 143 | return (float)lsbValue * 0.00049f; |
Jasper Swallen |
0:01d5616ba355 | 144 | } |
Jasper Swallen |
0:01d5616ba355 | 145 | else if(!gsel1Status && !gsel0Status) |
Jasper Swallen |
0:01d5616ba355 | 146 | { |
Jasper Swallen |
0:01d5616ba355 | 147 | // +-8g |
Jasper Swallen |
0:01d5616ba355 | 148 | return (float)lsbValue * 0.00024f; |
Jasper Swallen |
0:01d5616ba355 | 149 | } |
Jasper Swallen |
0:01d5616ba355 | 150 | else |
Jasper Swallen |
0:01d5616ba355 | 151 | { |
Jasper Swallen |
0:01d5616ba355 | 152 | return 0; |
Jasper Swallen |
0:01d5616ba355 | 153 | } |
Jasper Swallen |
0:01d5616ba355 | 154 | } |
Jasper Swallen |
0:01d5616ba355 | 155 | |
Jasper Swallen |
0:01d5616ba355 | 156 | void KX134::getAccelerations(int16_t *output) |
Jasper Swallen |
0:01d5616ba355 | 157 | { |
Jasper Swallen |
1:c6e2a348da09 | 158 | uint8_t words[7]; |
Jasper Swallen |
1:c6e2a348da09 | 159 | |
Jasper Swallen |
1:c6e2a348da09 | 160 | // this was the recommended method by Kionix |
Jasper Swallen |
1:c6e2a348da09 | 161 | // for some reason, this has *significantly* less noise than reading |
Jasper Swallen |
1:c6e2a348da09 | 162 | // one-by-one |
Jasper Swallen |
1:c6e2a348da09 | 163 | readRegister(Register::XOUT_L, words, 7); |
Jasper Swallen |
1:c6e2a348da09 | 164 | |
Jasper Swallen |
1:c6e2a348da09 | 165 | output[0] = convertTo16BitValue(words[1], words[2]); |
Jasper Swallen |
1:c6e2a348da09 | 166 | output[1] = convertTo16BitValue(words[3], words[4]); |
Jasper Swallen |
1:c6e2a348da09 | 167 | output[2] = convertTo16BitValue(words[5], words[6]); |
Jasper Swallen |
0:01d5616ba355 | 168 | } |
Jasper Swallen |
0:01d5616ba355 | 169 | |
Jasper Swallen |
0:01d5616ba355 | 170 | bool KX134::checkExistence() |
Jasper Swallen |
0:01d5616ba355 | 171 | { |
Jasper Swallen |
0:01d5616ba355 | 172 | // verify WHO_I_AM |
Jasper Swallen |
1:c6e2a348da09 | 173 | uint8_t whoami[2]; |
Jasper Swallen |
0:01d5616ba355 | 174 | readRegister(Register::WHO_AM_I, whoami); |
Jasper Swallen |
0:01d5616ba355 | 175 | |
Jasper Swallen |
0:01d5616ba355 | 176 | if(whoami[1] != 0x46) |
Jasper Swallen |
0:01d5616ba355 | 177 | { |
Jasper Swallen |
0:01d5616ba355 | 178 | return false; // WHO_AM_I is incorrect |
Jasper Swallen |
0:01d5616ba355 | 179 | } |
Jasper Swallen |
0:01d5616ba355 | 180 | |
Jasper Swallen |
0:01d5616ba355 | 181 | // verify COTR |
Jasper Swallen |
1:c6e2a348da09 | 182 | uint8_t cotr[2]; |
Jasper Swallen |
0:01d5616ba355 | 183 | readRegister(Register::COTR, cotr); |
Jasper Swallen |
0:01d5616ba355 | 184 | if(cotr[1] != 0x55) |
Jasper Swallen |
0:01d5616ba355 | 185 | { |
Jasper Swallen |
0:01d5616ba355 | 186 | return false; // COTR is incorrect |
Jasper Swallen |
0:01d5616ba355 | 187 | } |
Jasper Swallen |
0:01d5616ba355 | 188 | |
Jasper Swallen |
0:01d5616ba355 | 189 | return true; |
Jasper Swallen |
0:01d5616ba355 | 190 | } |
Jasper Swallen |
0:01d5616ba355 | 191 | |
Jasper Swallen |
0:01d5616ba355 | 192 | void KX134::setAccelRange(Range range) |
Jasper Swallen |
0:01d5616ba355 | 193 | { |
Jasper Swallen |
0:01d5616ba355 | 194 | gsel0Status = (uint8_t)range & 0b01; |
Jasper Swallen |
0:01d5616ba355 | 195 | gsel1Status = (uint8_t)range & 0b10; |
Jasper Swallen |
0:01d5616ba355 | 196 | |
Jasper Swallen |
0:01d5616ba355 | 197 | uint8_t writeByte = (1 << 7) | (resStatus << 6) | (drdyeStatus << 5) | |
Jasper Swallen |
0:01d5616ba355 | 198 | (gsel1Status << 4) | (gsel0Status << 3) | |
Jasper Swallen |
0:01d5616ba355 | 199 | (tdteStatus << 2) | (tpeStatus); |
Jasper Swallen |
0:01d5616ba355 | 200 | // reserved bit 1, PC1 bit must be enabled |
Jasper Swallen |
0:01d5616ba355 | 201 | |
Jasper Swallen |
0:01d5616ba355 | 202 | writeRegisterOneByte(Register::CNTL1, writeByte); |
Jasper Swallen |
0:01d5616ba355 | 203 | |
Jasper Swallen |
0:01d5616ba355 | 204 | registerWritingEnabled = 0; |
Jasper Swallen |
0:01d5616ba355 | 205 | } |
Jasper Swallen |
0:01d5616ba355 | 206 | |
Jasper Swallen |
0:01d5616ba355 | 207 | void KX134::setOutputDataRateBytes(uint8_t byteHz) |
Jasper Swallen |
0:01d5616ba355 | 208 | { |
Jasper Swallen |
0:01d5616ba355 | 209 | if(!registerWritingEnabled) |
Jasper Swallen |
0:01d5616ba355 | 210 | { |
Jasper Swallen |
0:01d5616ba355 | 211 | return; |
Jasper Swallen |
0:01d5616ba355 | 212 | } |
Jasper Swallen |
0:01d5616ba355 | 213 | |
Jasper Swallen |
0:01d5616ba355 | 214 | osa0 = byteHz & 0b0001; |
Jasper Swallen |
0:01d5616ba355 | 215 | osa1 = byteHz & 0b0010; |
Jasper Swallen |
0:01d5616ba355 | 216 | osa2 = byteHz & 0b0100; |
Jasper Swallen |
0:01d5616ba355 | 217 | osa3 = byteHz & 0b1000; |
Jasper Swallen |
0:01d5616ba355 | 218 | |
Jasper Swallen |
0:01d5616ba355 | 219 | uint8_t writeByte = (iirBypass << 7) | (lpro << 6) | (fstup << 5) | |
Jasper Swallen |
0:01d5616ba355 | 220 | (osa3 << 3) | (osa2 << 2) | (osa1 << 1) | osa0; |
Jasper Swallen |
0:01d5616ba355 | 221 | // reserved bit 4 |
Jasper Swallen |
0:01d5616ba355 | 222 | |
Jasper Swallen |
0:01d5616ba355 | 223 | writeRegisterOneByte(Register::ODCNTL, writeByte); |
Jasper Swallen |
0:01d5616ba355 | 224 | } |
Jasper Swallen |
0:01d5616ba355 | 225 | |
Jasper Swallen |
0:01d5616ba355 | 226 | void KX134::setOutputDataRateHz(uint32_t hz) |
Jasper Swallen |
0:01d5616ba355 | 227 | { |
Jasper Swallen |
0:01d5616ba355 | 228 | // calculate byte representation from new polling rate |
Jasper Swallen |
0:01d5616ba355 | 229 | // bytes = log2(32*rate/25) |
Jasper Swallen |
0:01d5616ba355 | 230 | |
Jasper Swallen |
0:01d5616ba355 | 231 | double new_rate = (double)hz; |
Jasper Swallen |
0:01d5616ba355 | 232 | |
Jasper Swallen |
0:01d5616ba355 | 233 | double bytes_double = log2((32.f / 25.f) * new_rate); |
Jasper Swallen |
0:01d5616ba355 | 234 | uint8_t bytes_int = (uint8_t)ceil(bytes_double); |
Jasper Swallen |
0:01d5616ba355 | 235 | |
Jasper Swallen |
0:01d5616ba355 | 236 | setOutputDataRateBytes(bytes_int); |
Jasper Swallen |
0:01d5616ba355 | 237 | } |
Jasper Swallen |
0:01d5616ba355 | 238 | |
Jasper Swallen |
0:01d5616ba355 | 239 | void KX134::enableRegisterWriting() |
Jasper Swallen |
0:01d5616ba355 | 240 | { |
Jasper Swallen |
0:01d5616ba355 | 241 | writeRegisterOneByte(Register::CNTL1, 0x00); |
Jasper Swallen |
0:01d5616ba355 | 242 | registerWritingEnabled = 1; |
Jasper Swallen |
0:01d5616ba355 | 243 | } |
Jasper Swallen |
0:01d5616ba355 | 244 | |
Jasper Swallen |
0:01d5616ba355 | 245 | void KX134::disableRegisterWriting() |
Jasper Swallen |
0:01d5616ba355 | 246 | { |
Jasper Swallen |
0:01d5616ba355 | 247 | if(!registerWritingEnabled) |
Jasper Swallen |
0:01d5616ba355 | 248 | { |
Jasper Swallen |
0:01d5616ba355 | 249 | return; |
Jasper Swallen |
0:01d5616ba355 | 250 | } |
Jasper Swallen |
0:01d5616ba355 | 251 | |
Jasper Swallen |
0:01d5616ba355 | 252 | uint8_t writeByte = (0 << 7) | (resStatus << 6) | (drdyeStatus << 5) | |
Jasper Swallen |
0:01d5616ba355 | 253 | (gsel1Status << 4) | (gsel0Status << 3) | |
Jasper Swallen |
0:01d5616ba355 | 254 | (tdteStatus << 2) | (tpeStatus); |
Jasper Swallen |
0:01d5616ba355 | 255 | // reserved bit 1, PC1 bit must be enabled |
Jasper Swallen |
0:01d5616ba355 | 256 | |
Jasper Swallen |
0:01d5616ba355 | 257 | writeRegisterOneByte(Register::CNTL1, writeByte); |
Jasper Swallen |
0:01d5616ba355 | 258 | |
Jasper Swallen |
0:01d5616ba355 | 259 | registerWritingEnabled = 0; |
Jasper Swallen |
0:01d5616ba355 | 260 | } |
Jasper Swallen |
1:c6e2a348da09 | 261 | |
Jasper Swallen |
1:c6e2a348da09 | 262 | bool KX134::dataReady() |
Jasper Swallen |
1:c6e2a348da09 | 263 | { |
Jasper Swallen |
1:c6e2a348da09 | 264 | uint8_t buf[2]; |
Jasper Swallen |
1:c6e2a348da09 | 265 | readRegister(Register::INS2, buf); |
Jasper Swallen |
1:c6e2a348da09 | 266 | |
Jasper Swallen |
1:c6e2a348da09 | 267 | return (buf[1] == 0x10); |
Jasper Swallen |
1:c6e2a348da09 | 268 | } |