Kionix KX123 accelerometer C++ driver. Can be used for some extend also with kx022, kx023, kx122, etc. when used features are present in sensor.
Fork of kionix-kx123-driver by
Diff: kx123.cpp
- Revision:
- 0:a3f43eb92f86
- Child:
- 1:f328083fb80b
diff -r 000000000000 -r a3f43eb92f86 kx123.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kx123.cpp Thu Sep 29 15:05:08 2016 +0000 @@ -0,0 +1,157 @@ +/* Copyright 2016 Rohm Semiconductor + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +#include "RegisterWriter/RegisterWriter/rohm_hal2.h" +#include "RegisterWriter/RegisterWriter/RegisterWriter.h" + +#include "kx123_registers.h" +#include "kx123.h" + +/** +* KX123 accelerometer driver +*/ +/** +* Create a KX123 instance which is connected to pre-instantiated I2C object. +* +* @param sad slave address of sensor. +* @param wai who_am_i value (i.e. sensor type/model) +*/ +KX123::KX123(RegisterWriter &i2c_obj, uint8_t newsad, uint8_t newwai) : i2c_rw(i2c_obj) { + sad = newsad; + wai = newwai; +} + +/** +* KX123 destructor +*/ +KX123::~KX123(){ +} + +/** +* Check if sensor is connected, setup defaults to sensor and start measuring. +* @return true on error, false on ok +*/ +bool KX123::set_defaults() +{ + unsigned char buf; + + DEBUG_print("\n\r"); + DEBUG_print("KX123 init started\n\r"); + i2c_rw.read_register(sad, KX122_WHO_AM_I, &buf, 1); + if (buf == KX123_WHO_AM_I_WAI_ID) { + DEBUG_print("KX123 found. (WAI %d) ", buf); + } else { + DEBUG_print("KX123 not found (WAI %d, not %d). ", buf, KX123_WHO_AM_I_WAI_ID); + switch(buf){ + case KX012_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX012"); + break; + case KX022_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX022"); + break; + case KX023_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX023"); + break; + case KX23H_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX23H"); + break; + case KX112_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX112"); + break; + case KX122_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX122"); + break; + case KX124_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX124"); + break; + case KX222_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX222"); + break; + case KX224_WHO_AM_I_WAI_ID: + DEBUG_print("Found KX224"); + break; + default: + DEBUG_print("Not even other sensor found from same family.\n\r"); + return true; + } + DEBUG_print(" though, trying to use that.\n\r"); + } + + //First set CNTL1 PC1-bit to stand-by mode, after that setup can be made + i2c_rw.write_register(sad, KX122_CNTL1, 0 ); + + //set_tilt_position_defaults(); + + //ODCNTL: Output Data Rate control (ODR) + i2c_rw.write_register(sad, KX122_ODCNTL, KX122_ODCNTL_OSA_25600); + //Setup G-range and 8/16-bit resolution + set CNTL1 PC1-bit to operating mode (also WUF_EN, TP_EN and DT_EN) + i2c_rw.write_register(sad, KX122_CNTL1, ( KX122_CNTL1_PC1 | KX122_CNTL1_GSEL_8G | KX122_CNTL1_RES ) ); + + //resolution_divider = 32768/2; //KX122_CNTL1_GSEL_2G + //resolution_divider = 32768/4; //KX122_CNTL1_GSEL_4G + resolution_divider = 32768/8; //KX122_CNTL1_GSEL_8G + + return false; +} + + +/** +CNTL PC1-bit has to be set to stand-by before this command. +return true on error +**/ +void KX123::set_tilt_position_defaults(){ + //CNTL3: Tilt position control, directional tap control and motion wakeup control + i2c_rw.write_register(sad, KX122_CNTL3, ( KX122_CNTL3_OTP_50 | KX122_CNTL3_OTDT_400 ) ); + //TILT_TIMER: Setup tilt position timer (~=filter) + i2c_rw.write_register(sad, KX122_TILT_TIMER, 0x01); + return; +} + + +/** +return read_error, true on error, false on read ok. +**/ +bool KX123::getresults_raw(int16_t* buf){ + #define RESULTS_LEN 6 + uint8_t tmp[RESULTS_LEN]; //XYZ (lhlhlh) + uint8_t read_bytes; + + read_bytes = i2c_rw.read_register(sad, KX122_XOUT_L, &tmp[0], sizeof(tmp)); + if (read_bytes != RESULTS_LEN){ + return true; + } + buf[0] = ( tmp[1] << 8 ) | tmp[0]; //X + buf[1] = ( tmp[3] << 8 ) | tmp[2]; //Y + buf[2] = ( tmp[5] << 8 ) | tmp[4]; //Z + return false; +} + + +bool KX123::getresults_g(float* buf){ + int16_t raw[3]; + int read_error; + + read_error = getresults_raw(&raw[0]); + if (read_error){ + return read_error; + } + + //Scale raw values to G-scale + buf[0] = ((float)raw[0]) / resolution_divider; + buf[1] = ((float)raw[1]) / resolution_divider; + buf[2] = ((float)raw[2]) / resolution_divider; + return false; +} + +