Driver for KX134-1211 Accelerometer

Dependents:   KX134-1211 Examples

Committer:
Jasper Swallen
Date:
Tue Sep 22 19:36:06 2020 -0400
Revision:
0:01d5616ba355
Child:
1:c6e2a348da09
move code from github to mercurial

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 0:01d5616ba355 6 char defaultBuffer[2] = {0}; // allows calling writeRegisterOneByte
Jasper Swallen 0:01d5616ba355 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 0:01d5616ba355 12 char *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 0:01d5616ba355 24 drdyeStatus = 0; // Data Ready Engine disabled
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 0:01d5616ba355 81 void KX134::readRegister(Register addr, char *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 0:01d5616ba355 95 void KX134::writeRegister(Register addr, uint8_t *data, char *rx_buf, int size)
Jasper Swallen 0:01d5616ba355 96 {
Jasper Swallen 0:01d5616ba355 97 select();
Jasper Swallen 0:01d5616ba355 98
Jasper Swallen 0:01d5616ba355 99 _spi.write((uint8_t)addr); // select register
Jasper Swallen 0:01d5616ba355 100 for(int i = 0; i < size; ++i)
Jasper Swallen 0:01d5616ba355 101 {
Jasper Swallen 0:01d5616ba355 102 rx_buf[i] = _spi.write(data[i]);
Jasper Swallen 0:01d5616ba355 103 }
Jasper Swallen 0:01d5616ba355 104
Jasper Swallen 0:01d5616ba355 105 deselect();
Jasper Swallen 0:01d5616ba355 106 }
Jasper Swallen 0:01d5616ba355 107
Jasper Swallen 0:01d5616ba355 108 /* Returns a 16 bit signed integer representation of a 2 address read
Jasper Swallen 0:01d5616ba355 109 * Assumes 2s Complement
Jasper Swallen 0:01d5616ba355 110 */
Jasper Swallen 0:01d5616ba355 111 int16_t KX134::read16BitValue(Register lowAddr, Register highAddr)
Jasper Swallen 0:01d5616ba355 112 {
Jasper Swallen 0:01d5616ba355 113 // get contents of register
Jasper Swallen 0:01d5616ba355 114 char lowWord[2], highWord[2];
Jasper Swallen 0:01d5616ba355 115 readRegister(lowAddr, lowWord);
Jasper Swallen 0:01d5616ba355 116 readRegister(highAddr, highWord);
Jasper Swallen 0:01d5616ba355 117
Jasper Swallen 0:01d5616ba355 118 // combine low & high words
Jasper Swallen 0:01d5616ba355 119 uint16_t val2sComplement =
Jasper Swallen 0:01d5616ba355 120 (static_cast<uint16_t>(highWord[1] << 8)) | lowWord[1];
Jasper Swallen 0:01d5616ba355 121 int16_t value = static_cast<int16_t>(val2sComplement);
Jasper Swallen 0:01d5616ba355 122
Jasper Swallen 0:01d5616ba355 123 return value;
Jasper Swallen 0:01d5616ba355 124 }
Jasper Swallen 0:01d5616ba355 125
Jasper Swallen 0:01d5616ba355 126 float KX134::convertRawToGravs(int16_t lsbValue)
Jasper Swallen 0:01d5616ba355 127 {
Jasper Swallen 0:01d5616ba355 128 if(gsel1Status && gsel0Status)
Jasper Swallen 0:01d5616ba355 129 {
Jasper Swallen 0:01d5616ba355 130 // +-64g
Jasper Swallen 0:01d5616ba355 131 return (float)lsbValue * 0.00195f;
Jasper Swallen 0:01d5616ba355 132 }
Jasper Swallen 0:01d5616ba355 133 else if(gsel1Status && !gsel0Status)
Jasper Swallen 0:01d5616ba355 134 {
Jasper Swallen 0:01d5616ba355 135 // +-32g
Jasper Swallen 0:01d5616ba355 136 return (float)lsbValue * 0.00098f;
Jasper Swallen 0:01d5616ba355 137 }
Jasper Swallen 0:01d5616ba355 138 else if(!gsel1Status && gsel0Status)
Jasper Swallen 0:01d5616ba355 139 {
Jasper Swallen 0:01d5616ba355 140 // +-16g
Jasper Swallen 0:01d5616ba355 141 return (float)lsbValue * 0.00049f;
Jasper Swallen 0:01d5616ba355 142 }
Jasper Swallen 0:01d5616ba355 143 else if(!gsel1Status && !gsel0Status)
Jasper Swallen 0:01d5616ba355 144 {
Jasper Swallen 0:01d5616ba355 145 // +-8g
Jasper Swallen 0:01d5616ba355 146 return (float)lsbValue * 0.00024f;
Jasper Swallen 0:01d5616ba355 147 }
Jasper Swallen 0:01d5616ba355 148 else
Jasper Swallen 0:01d5616ba355 149 {
Jasper Swallen 0:01d5616ba355 150 return 0;
Jasper Swallen 0:01d5616ba355 151 }
Jasper Swallen 0:01d5616ba355 152 }
Jasper Swallen 0:01d5616ba355 153
Jasper Swallen 0:01d5616ba355 154 void KX134::getAccelerations(int16_t *output)
Jasper Swallen 0:01d5616ba355 155 {
Jasper Swallen 0:01d5616ba355 156 // read X, Y, and Z
Jasper Swallen 0:01d5616ba355 157 output[0] = read16BitValue(Register::XOUT_L, Register::XOUT_H);
Jasper Swallen 0:01d5616ba355 158 output[1] = read16BitValue(Register::YOUT_L, Register::YOUT_H);
Jasper Swallen 0:01d5616ba355 159 output[2] = read16BitValue(Register::ZOUT_L, Register::ZOUT_H);
Jasper Swallen 0:01d5616ba355 160 }
Jasper Swallen 0:01d5616ba355 161
Jasper Swallen 0:01d5616ba355 162 bool KX134::checkExistence()
Jasper Swallen 0:01d5616ba355 163 {
Jasper Swallen 0:01d5616ba355 164 // verify WHO_I_AM
Jasper Swallen 0:01d5616ba355 165 char whoami[5];
Jasper Swallen 0:01d5616ba355 166 readRegister(Register::WHO_AM_I, whoami);
Jasper Swallen 0:01d5616ba355 167
Jasper Swallen 0:01d5616ba355 168 if(whoami[1] != 0x46)
Jasper Swallen 0:01d5616ba355 169 {
Jasper Swallen 0:01d5616ba355 170 return false; // WHO_AM_I is incorrect
Jasper Swallen 0:01d5616ba355 171 }
Jasper Swallen 0:01d5616ba355 172
Jasper Swallen 0:01d5616ba355 173 // verify COTR
Jasper Swallen 0:01d5616ba355 174 char cotr[2];
Jasper Swallen 0:01d5616ba355 175 readRegister(Register::COTR, cotr);
Jasper Swallen 0:01d5616ba355 176 if(cotr[1] != 0x55)
Jasper Swallen 0:01d5616ba355 177 {
Jasper Swallen 0:01d5616ba355 178 return false; // COTR is incorrect
Jasper Swallen 0:01d5616ba355 179 }
Jasper Swallen 0:01d5616ba355 180
Jasper Swallen 0:01d5616ba355 181 return true;
Jasper Swallen 0:01d5616ba355 182 }
Jasper Swallen 0:01d5616ba355 183
Jasper Swallen 0:01d5616ba355 184 void KX134::setAccelRange(Range range)
Jasper Swallen 0:01d5616ba355 185 {
Jasper Swallen 0:01d5616ba355 186 gsel0Status = (uint8_t)range & 0b01;
Jasper Swallen 0:01d5616ba355 187 gsel1Status = (uint8_t)range & 0b10;
Jasper Swallen 0:01d5616ba355 188
Jasper Swallen 0:01d5616ba355 189 uint8_t writeByte = (1 << 7) | (resStatus << 6) | (drdyeStatus << 5) |
Jasper Swallen 0:01d5616ba355 190 (gsel1Status << 4) | (gsel0Status << 3) |
Jasper Swallen 0:01d5616ba355 191 (tdteStatus << 2) | (tpeStatus);
Jasper Swallen 0:01d5616ba355 192 // reserved bit 1, PC1 bit must be enabled
Jasper Swallen 0:01d5616ba355 193
Jasper Swallen 0:01d5616ba355 194 writeRegisterOneByte(Register::CNTL1, writeByte);
Jasper Swallen 0:01d5616ba355 195
Jasper Swallen 0:01d5616ba355 196 registerWritingEnabled = 0;
Jasper Swallen 0:01d5616ba355 197 }
Jasper Swallen 0:01d5616ba355 198
Jasper Swallen 0:01d5616ba355 199 void KX134::setOutputDataRateBytes(uint8_t byteHz)
Jasper Swallen 0:01d5616ba355 200 {
Jasper Swallen 0:01d5616ba355 201 if(!registerWritingEnabled)
Jasper Swallen 0:01d5616ba355 202 {
Jasper Swallen 0:01d5616ba355 203 return;
Jasper Swallen 0:01d5616ba355 204 }
Jasper Swallen 0:01d5616ba355 205
Jasper Swallen 0:01d5616ba355 206 osa0 = byteHz & 0b0001;
Jasper Swallen 0:01d5616ba355 207 osa1 = byteHz & 0b0010;
Jasper Swallen 0:01d5616ba355 208 osa2 = byteHz & 0b0100;
Jasper Swallen 0:01d5616ba355 209 osa3 = byteHz & 0b1000;
Jasper Swallen 0:01d5616ba355 210
Jasper Swallen 0:01d5616ba355 211 uint8_t writeByte = (iirBypass << 7) | (lpro << 6) | (fstup << 5) |
Jasper Swallen 0:01d5616ba355 212 (osa3 << 3) | (osa2 << 2) | (osa1 << 1) | osa0;
Jasper Swallen 0:01d5616ba355 213 // reserved bit 4
Jasper Swallen 0:01d5616ba355 214
Jasper Swallen 0:01d5616ba355 215 writeRegisterOneByte(Register::ODCNTL, writeByte);
Jasper Swallen 0:01d5616ba355 216 }
Jasper Swallen 0:01d5616ba355 217
Jasper Swallen 0:01d5616ba355 218 void KX134::setOutputDataRateHz(uint32_t hz)
Jasper Swallen 0:01d5616ba355 219 {
Jasper Swallen 0:01d5616ba355 220 // calculate byte representation from new polling rate
Jasper Swallen 0:01d5616ba355 221 // bytes = log2(32*rate/25)
Jasper Swallen 0:01d5616ba355 222
Jasper Swallen 0:01d5616ba355 223 double new_rate = (double)hz;
Jasper Swallen 0:01d5616ba355 224
Jasper Swallen 0:01d5616ba355 225 double bytes_double = log2((32.f / 25.f) * new_rate);
Jasper Swallen 0:01d5616ba355 226 uint8_t bytes_int = (uint8_t)ceil(bytes_double);
Jasper Swallen 0:01d5616ba355 227
Jasper Swallen 0:01d5616ba355 228 setOutputDataRateBytes(bytes_int);
Jasper Swallen 0:01d5616ba355 229 }
Jasper Swallen 0:01d5616ba355 230
Jasper Swallen 0:01d5616ba355 231 void KX134::enableRegisterWriting()
Jasper Swallen 0:01d5616ba355 232 {
Jasper Swallen 0:01d5616ba355 233 writeRegisterOneByte(Register::CNTL1, 0x00);
Jasper Swallen 0:01d5616ba355 234 registerWritingEnabled = 1;
Jasper Swallen 0:01d5616ba355 235 }
Jasper Swallen 0:01d5616ba355 236
Jasper Swallen 0:01d5616ba355 237 void KX134::disableRegisterWriting()
Jasper Swallen 0:01d5616ba355 238 {
Jasper Swallen 0:01d5616ba355 239 if(!registerWritingEnabled)
Jasper Swallen 0:01d5616ba355 240 {
Jasper Swallen 0:01d5616ba355 241 return;
Jasper Swallen 0:01d5616ba355 242 }
Jasper Swallen 0:01d5616ba355 243
Jasper Swallen 0:01d5616ba355 244 uint8_t writeByte = (0 << 7) | (resStatus << 6) | (drdyeStatus << 5) |
Jasper Swallen 0:01d5616ba355 245 (gsel1Status << 4) | (gsel0Status << 3) |
Jasper Swallen 0:01d5616ba355 246 (tdteStatus << 2) | (tpeStatus);
Jasper Swallen 0:01d5616ba355 247 // reserved bit 1, PC1 bit must be enabled
Jasper Swallen 0:01d5616ba355 248
Jasper Swallen 0:01d5616ba355 249 writeRegisterOneByte(Register::CNTL1, writeByte);
Jasper Swallen 0:01d5616ba355 250
Jasper Swallen 0:01d5616ba355 251 registerWritingEnabled = 0;
Jasper Swallen 0:01d5616ba355 252 }