Driver for KX134-1211 Accelerometer

Dependents:   KX134-1211 Examples

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?

UserRevisionLine numberNew 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 }