Kionix KX123 accelerometer C++ driver. Can be used for some extend also with kx022, kx023, kx122, etc. when used features are present in sensor.

Dependents:   kionix-kx123-hello

Committer:
MikkoZ
Date:
Thu Oct 06 13:02:55 2016 +0000
Revision:
3:4fd5361ed180
Parent:
2:62891556d47b
Bugfix: get_results_highpass; ; Changed parameter from uint16_t to int16_t as it should be.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikkoZ 0:a3f43eb92f86 1 /* Copyright 2016 Rohm Semiconductor
MikkoZ 0:a3f43eb92f86 2
MikkoZ 0:a3f43eb92f86 3 Licensed under the Apache License, Version 2.0 (the "License");
MikkoZ 0:a3f43eb92f86 4 you may not use this file except in compliance with the License.
MikkoZ 0:a3f43eb92f86 5 You may obtain a copy of the License at
MikkoZ 0:a3f43eb92f86 6
MikkoZ 0:a3f43eb92f86 7 http://www.apache.org/licenses/LICENSE-2.0
MikkoZ 0:a3f43eb92f86 8
MikkoZ 0:a3f43eb92f86 9 Unless required by applicable law or agreed to in writing, software
MikkoZ 0:a3f43eb92f86 10 distributed under the License is distributed on an "AS IS" BASIS,
MikkoZ 0:a3f43eb92f86 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MikkoZ 0:a3f43eb92f86 12 See the License for the specific language governing permissions and
MikkoZ 0:a3f43eb92f86 13 limitations under the License.
MikkoZ 0:a3f43eb92f86 14 */
MikkoZ 0:a3f43eb92f86 15 #include "RegisterWriter/RegisterWriter/rohm_hal2.h"
MikkoZ 0:a3f43eb92f86 16 #include "RegisterWriter/RegisterWriter/RegisterWriter.h"
MikkoZ 0:a3f43eb92f86 17
MikkoZ 0:a3f43eb92f86 18 #include "kx123.h"
MikkoZ 0:a3f43eb92f86 19
MikkoZ 0:a3f43eb92f86 20 /**
MikkoZ 1:f328083fb80b 21 * Create a KX123 instance for communication through pre-instantiated
MikkoZ 1:f328083fb80b 22 * RegisterWriter (I2C) -object.
MikkoZ 0:a3f43eb92f86 23 *
MikkoZ 1:f328083fb80b 24 * @param i2c_obj pre-instantiated RegisterWriter (I2C) -object reference
MikkoZ 0:a3f43eb92f86 25 * @param sad slave address of sensor.
MikkoZ 0:a3f43eb92f86 26 * @param wai who_am_i value (i.e. sensor type/model)
MikkoZ 0:a3f43eb92f86 27 */
MikkoZ 1:f328083fb80b 28 KX123::KX123(RegisterWriter &i2c_obj, uint8_t sad, uint8_t wai) : i2c_rw(i2c_obj) {
MikkoZ 1:f328083fb80b 29 _sad = sad;
MikkoZ 1:f328083fb80b 30 _wai = wai;
MikkoZ 2:62891556d47b 31 setup_mode_on = false;
MikkoZ 0:a3f43eb92f86 32 }
MikkoZ 0:a3f43eb92f86 33
MikkoZ 0:a3f43eb92f86 34 KX123::~KX123(){
MikkoZ 0:a3f43eb92f86 35 }
MikkoZ 0:a3f43eb92f86 36
MikkoZ 0:a3f43eb92f86 37 /**
MikkoZ 2:62891556d47b 38 * Start setup/stand-by mode and shut off measurements.
MikkoZ 2:62891556d47b 39 * @return true on error, false on ok
MikkoZ 2:62891556d47b 40 */
MikkoZ 2:62891556d47b 41 bool KX123::start_setup_mode(void){
MikkoZ 2:62891556d47b 42 setup_mode_on = true;
MikkoZ 2:62891556d47b 43 return i2c_rw.change_bits(_sad, KX122_CNTL1, KX122_CNTL1_PC1, KX122_CNTL1_PC1);
MikkoZ 2:62891556d47b 44 }
MikkoZ 2:62891556d47b 45
MikkoZ 2:62891556d47b 46 /**
MikkoZ 2:62891556d47b 47 * Start operating/measurement mode. Setup is not allowed while in this mode.
MikkoZ 2:62891556d47b 48 * @return true on error, false on ok
MikkoZ 2:62891556d47b 49 */
MikkoZ 2:62891556d47b 50 bool KX123::start_measurement_mode(void){
MikkoZ 2:62891556d47b 51 setup_mode_on = false;
MikkoZ 2:62891556d47b 52 return i2c_rw.change_bits(_sad, KX122_CNTL1, KX122_CNTL1_PC1, 0);
MikkoZ 2:62891556d47b 53 }
MikkoZ 2:62891556d47b 54
MikkoZ 2:62891556d47b 55 /**
MikkoZ 0:a3f43eb92f86 56 * Check if sensor is connected, setup defaults to sensor and start measuring.
MikkoZ 0:a3f43eb92f86 57 * @return true on error, false on ok
MikkoZ 0:a3f43eb92f86 58 */
MikkoZ 0:a3f43eb92f86 59 bool KX123::set_defaults()
MikkoZ 0:a3f43eb92f86 60 {
MikkoZ 0:a3f43eb92f86 61 unsigned char buf;
MikkoZ 0:a3f43eb92f86 62
MikkoZ 0:a3f43eb92f86 63 DEBUG_print("\n\r");
MikkoZ 0:a3f43eb92f86 64 DEBUG_print("KX123 init started\n\r");
MikkoZ 1:f328083fb80b 65 i2c_rw.read_register(_sad, KX122_WHO_AM_I, &buf, 1);
MikkoZ 0:a3f43eb92f86 66 if (buf == KX123_WHO_AM_I_WAI_ID) {
MikkoZ 0:a3f43eb92f86 67 DEBUG_print("KX123 found. (WAI %d) ", buf);
MikkoZ 0:a3f43eb92f86 68 } else {
MikkoZ 0:a3f43eb92f86 69 DEBUG_print("KX123 not found (WAI %d, not %d). ", buf, KX123_WHO_AM_I_WAI_ID);
MikkoZ 0:a3f43eb92f86 70 switch(buf){
MikkoZ 0:a3f43eb92f86 71 case KX012_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 72 DEBUG_print("Found KX012");
MikkoZ 0:a3f43eb92f86 73 break;
MikkoZ 0:a3f43eb92f86 74 case KX022_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 75 DEBUG_print("Found KX022");
MikkoZ 0:a3f43eb92f86 76 break;
MikkoZ 0:a3f43eb92f86 77 case KX023_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 78 DEBUG_print("Found KX023");
MikkoZ 0:a3f43eb92f86 79 break;
MikkoZ 0:a3f43eb92f86 80 case KX23H_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 81 DEBUG_print("Found KX23H");
MikkoZ 0:a3f43eb92f86 82 break;
MikkoZ 0:a3f43eb92f86 83 case KX112_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 84 DEBUG_print("Found KX112");
MikkoZ 0:a3f43eb92f86 85 break;
MikkoZ 0:a3f43eb92f86 86 case KX122_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 87 DEBUG_print("Found KX122");
MikkoZ 0:a3f43eb92f86 88 break;
MikkoZ 0:a3f43eb92f86 89 case KX124_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 90 DEBUG_print("Found KX124");
MikkoZ 0:a3f43eb92f86 91 break;
MikkoZ 0:a3f43eb92f86 92 case KX222_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 93 DEBUG_print("Found KX222");
MikkoZ 0:a3f43eb92f86 94 break;
MikkoZ 0:a3f43eb92f86 95 case KX224_WHO_AM_I_WAI_ID:
MikkoZ 0:a3f43eb92f86 96 DEBUG_print("Found KX224");
MikkoZ 0:a3f43eb92f86 97 break;
MikkoZ 0:a3f43eb92f86 98 default:
MikkoZ 0:a3f43eb92f86 99 DEBUG_print("Not even other sensor found from same family.\n\r");
MikkoZ 0:a3f43eb92f86 100 return true;
MikkoZ 0:a3f43eb92f86 101 }
MikkoZ 0:a3f43eb92f86 102 DEBUG_print(" though, trying to use that.\n\r");
MikkoZ 0:a3f43eb92f86 103 }
MikkoZ 0:a3f43eb92f86 104
MikkoZ 0:a3f43eb92f86 105 //First set CNTL1 PC1-bit to stand-by mode, after that setup can be made
MikkoZ 1:f328083fb80b 106 i2c_rw.write_register(_sad, KX122_CNTL1, 0 );
MikkoZ 2:62891556d47b 107 setup_mode_on = true;
MikkoZ 0:a3f43eb92f86 108
MikkoZ 0:a3f43eb92f86 109 //set_tilt_position_defaults();
MikkoZ 0:a3f43eb92f86 110
MikkoZ 0:a3f43eb92f86 111 //ODCNTL: Output Data Rate control (ODR)
MikkoZ 1:f328083fb80b 112 i2c_rw.write_register(_sad, KX122_ODCNTL, KX122_ODCNTL_OSA_25600);
MikkoZ 0:a3f43eb92f86 113 //Setup G-range and 8/16-bit resolution + set CNTL1 PC1-bit to operating mode (also WUF_EN, TP_EN and DT_EN)
MikkoZ 1:f328083fb80b 114 i2c_rw.write_register(_sad, KX122_CNTL1, ( KX122_CNTL1_PC1 | KX122_CNTL1_GSEL_8G | KX122_CNTL1_RES ) );
MikkoZ 2:62891556d47b 115 setup_mode_on = false;
MikkoZ 0:a3f43eb92f86 116
MikkoZ 0:a3f43eb92f86 117 //resolution_divider = 32768/2; //KX122_CNTL1_GSEL_2G
MikkoZ 0:a3f43eb92f86 118 //resolution_divider = 32768/4; //KX122_CNTL1_GSEL_4G
MikkoZ 0:a3f43eb92f86 119 resolution_divider = 32768/8; //KX122_CNTL1_GSEL_8G
MikkoZ 0:a3f43eb92f86 120
MikkoZ 0:a3f43eb92f86 121 return false;
MikkoZ 0:a3f43eb92f86 122 }
MikkoZ 0:a3f43eb92f86 123
MikkoZ 0:a3f43eb92f86 124
MikkoZ 0:a3f43eb92f86 125 /**
MikkoZ 2:62891556d47b 126 * Setup default settings for a tilt position
MikkoZ 0:a3f43eb92f86 127 **/
MikkoZ 0:a3f43eb92f86 128 void KX123::set_tilt_position_defaults(){
MikkoZ 2:62891556d47b 129 if (setup_mode_on == false) return;
MikkoZ 0:a3f43eb92f86 130 //CNTL3: Tilt position control, directional tap control and motion wakeup control
MikkoZ 1:f328083fb80b 131 i2c_rw.write_register(_sad, KX122_CNTL3, ( KX122_CNTL3_OTP_50 | KX122_CNTL3_OTDT_400 ) );
MikkoZ 0:a3f43eb92f86 132 //TILT_TIMER: Setup tilt position timer (~=filter)
MikkoZ 1:f328083fb80b 133 i2c_rw.write_register(_sad, KX122_TILT_TIMER, 0x01);
MikkoZ 0:a3f43eb92f86 134 return;
MikkoZ 0:a3f43eb92f86 135 }
MikkoZ 0:a3f43eb92f86 136
MikkoZ 0:a3f43eb92f86 137
MikkoZ 0:a3f43eb92f86 138 /**
MikkoZ 2:62891556d47b 139 * Get filtered uint16_t XYZ-values from sensor
MikkoZ 2:62891556d47b 140 * @param *buf to uint16_t[3] for results
MikkoZ 2:62891556d47b 141 * @return true on error, false on read ok.
MikkoZ 2:62891556d47b 142 **/
MikkoZ 3:4fd5361ed180 143 bool KX123::getresults_highpass(int16_t* buf) {
MikkoZ 2:62891556d47b 144 #define RESULTS_LEN 6
MikkoZ 2:62891556d47b 145 uint8_t tmp[RESULTS_LEN]; //XYZ (lhlhlh)
MikkoZ 2:62891556d47b 146 uint8_t read_bytes;
MikkoZ 2:62891556d47b 147
MikkoZ 2:62891556d47b 148 read_bytes = i2c_rw.read_register(_sad, KX122_XHP_L, &tmp[0], sizeof(tmp));
MikkoZ 2:62891556d47b 149 if (read_bytes != RESULTS_LEN){
MikkoZ 2:62891556d47b 150 return true;
MikkoZ 2:62891556d47b 151 }
MikkoZ 2:62891556d47b 152 buf[0] = ( tmp[1] << 8 ) | tmp[0]; //X
MikkoZ 2:62891556d47b 153 buf[1] = ( tmp[3] << 8 ) | tmp[2]; //Y
MikkoZ 2:62891556d47b 154 buf[2] = ( tmp[5] << 8 ) | tmp[4]; //Z
MikkoZ 2:62891556d47b 155 return false;
MikkoZ 2:62891556d47b 156 }
MikkoZ 2:62891556d47b 157
MikkoZ 2:62891556d47b 158 /**
MikkoZ 1:f328083fb80b 159 * Get raw uint16_t XYZ-values from sensor
MikkoZ 1:f328083fb80b 160 * @param *buf to uint16_t[3] for results
MikkoZ 1:f328083fb80b 161 * @return true on error, false on read ok.
MikkoZ 0:a3f43eb92f86 162 **/
MikkoZ 0:a3f43eb92f86 163 bool KX123::getresults_raw(int16_t* buf){
MikkoZ 0:a3f43eb92f86 164 #define RESULTS_LEN 6
MikkoZ 0:a3f43eb92f86 165 uint8_t tmp[RESULTS_LEN]; //XYZ (lhlhlh)
MikkoZ 0:a3f43eb92f86 166 uint8_t read_bytes;
MikkoZ 0:a3f43eb92f86 167
MikkoZ 1:f328083fb80b 168 read_bytes = i2c_rw.read_register(_sad, KX122_XOUT_L, &tmp[0], sizeof(tmp));
MikkoZ 0:a3f43eb92f86 169 if (read_bytes != RESULTS_LEN){
MikkoZ 0:a3f43eb92f86 170 return true;
MikkoZ 0:a3f43eb92f86 171 }
MikkoZ 0:a3f43eb92f86 172 buf[0] = ( tmp[1] << 8 ) | tmp[0]; //X
MikkoZ 0:a3f43eb92f86 173 buf[1] = ( tmp[3] << 8 ) | tmp[2]; //Y
MikkoZ 0:a3f43eb92f86 174 buf[2] = ( tmp[5] << 8 ) | tmp[4]; //Z
MikkoZ 0:a3f43eb92f86 175 return false;
MikkoZ 0:a3f43eb92f86 176 }
MikkoZ 0:a3f43eb92f86 177
MikkoZ 0:a3f43eb92f86 178
MikkoZ 1:f328083fb80b 179 /**
MikkoZ 1:f328083fb80b 180 * Get gravity scaled float XYZ-values from sensor
MikkoZ 1:f328083fb80b 181 * @param *buf to float[3] for results
MikkoZ 1:f328083fb80b 182 * @return true on error, false on read ok.
MikkoZ 1:f328083fb80b 183 **/
MikkoZ 0:a3f43eb92f86 184 bool KX123::getresults_g(float* buf){
MikkoZ 0:a3f43eb92f86 185 int16_t raw[3];
MikkoZ 0:a3f43eb92f86 186 int read_error;
MikkoZ 0:a3f43eb92f86 187
MikkoZ 0:a3f43eb92f86 188 read_error = getresults_raw(&raw[0]);
MikkoZ 0:a3f43eb92f86 189 if (read_error){
MikkoZ 0:a3f43eb92f86 190 return read_error;
MikkoZ 0:a3f43eb92f86 191 }
MikkoZ 0:a3f43eb92f86 192
MikkoZ 0:a3f43eb92f86 193 //Scale raw values to G-scale
MikkoZ 0:a3f43eb92f86 194 buf[0] = ((float)raw[0]) / resolution_divider;
MikkoZ 0:a3f43eb92f86 195 buf[1] = ((float)raw[1]) / resolution_divider;
MikkoZ 0:a3f43eb92f86 196 buf[2] = ((float)raw[2]) / resolution_divider;
MikkoZ 0:a3f43eb92f86 197 return false;
MikkoZ 0:a3f43eb92f86 198 }
MikkoZ 0:a3f43eb92f86 199
MikkoZ 2:62891556d47b 200 /**
MikkoZ 3:4fd5361ed180 201 * Get gravity scaled float XYZ-values from highpass filtered sensor values
MikkoZ 3:4fd5361ed180 202 * @param *buf to float[3] for results
MikkoZ 3:4fd5361ed180 203 * @return true on error, false on read ok.
MikkoZ 3:4fd5361ed180 204 **/
MikkoZ 3:4fd5361ed180 205 bool KX123::getresults_highpass_g(float* buf){
MikkoZ 3:4fd5361ed180 206 int16_t raw[3];
MikkoZ 3:4fd5361ed180 207 int read_error;
MikkoZ 3:4fd5361ed180 208
MikkoZ 3:4fd5361ed180 209 read_error = getresults_highpass(&raw[0]);
MikkoZ 3:4fd5361ed180 210 if (read_error){
MikkoZ 3:4fd5361ed180 211 return read_error;
MikkoZ 3:4fd5361ed180 212 }
MikkoZ 3:4fd5361ed180 213
MikkoZ 3:4fd5361ed180 214 //Scale raw values to G-scale
MikkoZ 3:4fd5361ed180 215 buf[0] = ((float)raw[0]) / resolution_divider;
MikkoZ 3:4fd5361ed180 216 buf[1] = ((float)raw[1]) / resolution_divider;
MikkoZ 3:4fd5361ed180 217 buf[2] = ((float)raw[2]) / resolution_divider;
MikkoZ 3:4fd5361ed180 218 return false;
MikkoZ 3:4fd5361ed180 219 }
MikkoZ 3:4fd5361ed180 220
MikkoZ 3:4fd5361ed180 221 /**
MikkoZ 2:62891556d47b 222 * Get axes of current tilt and previous tilt
MikkoZ 2:62891556d47b 223 * @param *current_previous space for storing 2 (uint8_t) values
MikkoZ 2:62891556d47b 224 * @return true on error
MikkoZ 2:62891556d47b 225 */
MikkoZ 2:62891556d47b 226 bool KX123::get_tilt(enum e_axis* current_previous){
MikkoZ 2:62891556d47b 227 #define GET_TILT_READ_LEN 2
MikkoZ 2:62891556d47b 228 uint8_t read_bytes;
MikkoZ 0:a3f43eb92f86 229
MikkoZ 2:62891556d47b 230 read_bytes = i2c_rw.read_register(_sad, KX122_TSCP, (uint8_t*)current_previous, GET_TILT_READ_LEN);
MikkoZ 2:62891556d47b 231
MikkoZ 2:62891556d47b 232 return (read_bytes != GET_TILT_READ_LEN);
MikkoZ 2:62891556d47b 233 }
MikkoZ 2:62891556d47b 234
MikkoZ 2:62891556d47b 235 /**
MikkoZ 2:62891556d47b 236 * Get axis of triggered tap/double tap interrupt from INS1
MikkoZ 2:62891556d47b 237 * @param *axis space for storing 1 (uint8_t) value in e_axis format
MikkoZ 2:62891556d47b 238 * @return true on error
MikkoZ 2:62891556d47b 239 */
MikkoZ 2:62891556d47b 240 bool KX123::get_tap_interrupt_axis(enum e_axis* axis){
MikkoZ 2:62891556d47b 241 #define GET_TAP_READ_LEN 1
MikkoZ 2:62891556d47b 242 uint8_t read_bytes;
MikkoZ 2:62891556d47b 243
MikkoZ 2:62891556d47b 244 read_bytes = i2c_rw.read_register(_sad, KX122_INS1, (uint8_t*)axis, GET_TAP_READ_LEN);
MikkoZ 2:62891556d47b 245
MikkoZ 2:62891556d47b 246 return (read_bytes != GET_TAP_READ_LEN);
MikkoZ 2:62891556d47b 247 }
MikkoZ 2:62891556d47b 248
MikkoZ 2:62891556d47b 249 /**
MikkoZ 2:62891556d47b 250 * Get axis of triggered motion detect interrupt from INS3
MikkoZ 2:62891556d47b 251 * @param *axis space for storing 1 (uint8_t) value in e_axis format
MikkoZ 2:62891556d47b 252 * @return true on error
MikkoZ 2:62891556d47b 253 */
MikkoZ 2:62891556d47b 254 bool KX123::get_detected_motion_axis(enum e_axis* axis){
MikkoZ 2:62891556d47b 255 #define GET_MOTION_READ_LEN 1
MikkoZ 2:62891556d47b 256 uint8_t read_bytes;
MikkoZ 2:62891556d47b 257
MikkoZ 2:62891556d47b 258 read_bytes = i2c_rw.read_register(_sad, KX122_INS3, (uint8_t*)axis, GET_MOTION_READ_LEN);
MikkoZ 2:62891556d47b 259
MikkoZ 2:62891556d47b 260 return (read_bytes != GET_MOTION_READ_LEN);
MikkoZ 2:62891556d47b 261 }
MikkoZ 2:62891556d47b 262
MikkoZ 2:62891556d47b 263 /**
MikkoZ 2:62891556d47b 264 * Set axis of triggered motion detect interrupt from CNTL2
MikkoZ 2:62891556d47b 265 * @param cnltl2_tilt_mask Orred e_axis values for axes directions to cause interrupt
MikkoZ 2:62891556d47b 266 * @return true on error or setup mode off
MikkoZ 2:62891556d47b 267 */
MikkoZ 2:62891556d47b 268 bool KX123::set_tilt_axis_mask(uint8_t cnltl2_tilt_mask){
MikkoZ 2:62891556d47b 269 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 270 //MSb 00 == no_action
MikkoZ 2:62891556d47b 271 return i2c_rw.write_register(_sad, KX122_CNTL2, (cnltl2_tilt_mask & KX123_AXIS_MASK) );
MikkoZ 2:62891556d47b 272 }
MikkoZ 2:62891556d47b 273
MikkoZ 2:62891556d47b 274 /**
MikkoZ 2:62891556d47b 275 * get cause of interrupt trigger from INS2
MikkoZ 2:62891556d47b 276 * @param *int_reason space for storing 1 (uint8_t) value in e_interrupt_reason format
MikkoZ 2:62891556d47b 277 * @return true on error
MikkoZ 2:62891556d47b 278 */
MikkoZ 2:62891556d47b 279 bool KX123::get_interrupt_reason(enum e_interrupt_reason* int_reason){
MikkoZ 2:62891556d47b 280 #define INT_REASON_LEN 1
MikkoZ 2:62891556d47b 281 uint8_t read_bytes;
MikkoZ 2:62891556d47b 282
MikkoZ 2:62891556d47b 283 read_bytes = i2c_rw.read_register(_sad, KX122_INS2, (uint8_t*)int_reason, INT_REASON_LEN);
MikkoZ 2:62891556d47b 284
MikkoZ 2:62891556d47b 285 return (read_bytes != INT_REASON_LEN);
MikkoZ 2:62891556d47b 286 }
MikkoZ 2:62891556d47b 287
MikkoZ 2:62891556d47b 288 /**
MikkoZ 2:62891556d47b 289 * Check from sensor register if interrupt has occured. Usable feature when
MikkoZ 2:62891556d47b 290 * multiple sensor interrupts are connected to same interrupt pin.
MikkoZ 2:62891556d47b 291 * @return true when interrupt has occured. False on read fail and no interrupt.
MikkoZ 2:62891556d47b 292 */
MikkoZ 2:62891556d47b 293 bool KX123::has_interrupt_occured(){
MikkoZ 2:62891556d47b 294 uint8_t status_reg;
MikkoZ 2:62891556d47b 295 uint8_t read_bytes;
MikkoZ 2:62891556d47b 296
MikkoZ 2:62891556d47b 297 read_bytes = i2c_rw.read_register(_sad, KX122_INS2, &status_reg, 1);
MikkoZ 2:62891556d47b 298 return ((read_bytes == 1) && (status_reg & KX122_STATUS_REG_INT));
MikkoZ 2:62891556d47b 299 }
MikkoZ 2:62891556d47b 300
MikkoZ 2:62891556d47b 301 /**
MikkoZ 2:62891556d47b 302 * Clear interrupt flag when latched. (==Interrupt release) Doesn't work for FIFO
MikkoZ 2:62891556d47b 303 * Buffer Full or FIFO Watermark -interrupts.
MikkoZ 2:62891556d47b 304 */
MikkoZ 2:62891556d47b 305 void KX123::clear_interrupt(){
MikkoZ 2:62891556d47b 306 uint8_t value_discarded;
MikkoZ 2:62891556d47b 307
MikkoZ 2:62891556d47b 308 i2c_rw.read_register(_sad, KX122_INT_REL, &value_discarded, 1);
MikkoZ 2:62891556d47b 309
MikkoZ 2:62891556d47b 310 return;
MikkoZ 2:62891556d47b 311 }
MikkoZ 2:62891556d47b 312
MikkoZ 2:62891556d47b 313 /**
MikkoZ 2:62891556d47b 314 * Initiate software reset and RAM reboot routine and wait untill finished.
MikkoZ 2:62891556d47b 315 */
MikkoZ 2:62891556d47b 316 void KX123::soft_reset(){
MikkoZ 2:62891556d47b 317 uint8_t reset_ongoing;
MikkoZ 2:62891556d47b 318
MikkoZ 2:62891556d47b 319 i2c_rw.change_bits(_sad, KX122_CNTL2, KX122_CNTL2_SRST, KX122_CNTL2_SRST );
MikkoZ 2:62891556d47b 320 do{
MikkoZ 2:62891556d47b 321 uint8_t cntl2, read_bytes;
MikkoZ 2:62891556d47b 322
MikkoZ 2:62891556d47b 323 read_bytes = i2c_rw.read_register(_sad, KX122_CNTL2, &cntl2, 1);
MikkoZ 2:62891556d47b 324 reset_ongoing = ((read_bytes == 0) || (cntl2 & KX122_CNTL2_SRST));
MikkoZ 2:62891556d47b 325 } while (reset_ongoing);
MikkoZ 2:62891556d47b 326
MikkoZ 2:62891556d47b 327 return;
MikkoZ 2:62891556d47b 328 }
MikkoZ 2:62891556d47b 329
MikkoZ 2:62891556d47b 330 /**
MikkoZ 2:62891556d47b 331 * Verify proper integrated circuit functionality
MikkoZ 2:62891556d47b 332 * @return true on test fail or setup mode off, false on test ok.
MikkoZ 2:62891556d47b 333 **/
MikkoZ 2:62891556d47b 334 bool KX123::self_test(){
MikkoZ 2:62891556d47b 335 uint8_t cotr_value;
MikkoZ 2:62891556d47b 336 bool read_ok;
MikkoZ 2:62891556d47b 337
MikkoZ 2:62891556d47b 338 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 339 //first read to make sure COTR is in default value
MikkoZ 2:62891556d47b 340 read_ok = i2c_rw.read_register(_sad, KX122_COTR, &cotr_value, 1);
MikkoZ 2:62891556d47b 341 read_ok = i2c_rw.read_register(_sad, KX122_COTR, &cotr_value, 1);
MikkoZ 2:62891556d47b 342 if ((cotr_value != 0x55) || (!read_ok) ){
MikkoZ 2:62891556d47b 343 return true;
MikkoZ 2:62891556d47b 344 }
MikkoZ 2:62891556d47b 345 i2c_rw.change_bits(_sad, KX122_CNTL2, KX122_CNTL2_COTC, KX122_CNTL2_COTC );
MikkoZ 2:62891556d47b 346 read_ok = i2c_rw.read_register(_sad, KX122_COTR, &cotr_value, 1);
MikkoZ 2:62891556d47b 347 if ((cotr_value != 0xAA) || (!read_ok) ){
MikkoZ 2:62891556d47b 348 return true;
MikkoZ 2:62891556d47b 349 }
MikkoZ 2:62891556d47b 350 return false;
MikkoZ 2:62891556d47b 351 }
MikkoZ 2:62891556d47b 352
MikkoZ 2:62891556d47b 353 /**
MikkoZ 2:62891556d47b 354 * Setup ODR values for Tilt Position, Directional Tap and Motion Detect.
MikkoZ 2:62891556d47b 355 * @param tilt_position_odr KX122_CNTL3_OTP_* -value or 0xff to skip.
MikkoZ 2:62891556d47b 356 * @param directional_tap_odr KX122_CNTL3_OTDT_* -value or 0xff to skip.
MikkoZ 3:4fd5361ed180 357 * @param motion_wuf_odr motion detect/high-pass odr (KX122_CNTL3_OWUF_* -value) or 0xff to skip.
MikkoZ 2:62891556d47b 358 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 359 **/
MikkoZ 2:62891556d47b 360 bool KX123::set_cntl3_odrs(uint8_t tilt_position_odr, uint8_t directional_tap_odr, uint8_t motion_wuf_odr){
MikkoZ 2:62891556d47b 361 uint8_t cntl3;
MikkoZ 2:62891556d47b 362 bool read_ok;
MikkoZ 2:62891556d47b 363
MikkoZ 2:62891556d47b 364 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 365
MikkoZ 2:62891556d47b 366 read_ok = i2c_rw.read_register(_sad, KX122_CNTL3, &cntl3, 1);
MikkoZ 2:62891556d47b 367 if(!read_ok) return true;
MikkoZ 2:62891556d47b 368
MikkoZ 2:62891556d47b 369 if (tilt_position_odr != 0xff){
MikkoZ 2:62891556d47b 370 cntl3 = (cntl3 & ~KX122_CNTL3_OTP_MASK) | (tilt_position_odr & KX122_CNTL3_OTP_MASK);
MikkoZ 2:62891556d47b 371 }
MikkoZ 2:62891556d47b 372 if (directional_tap_odr != 0xff){
MikkoZ 2:62891556d47b 373 cntl3 = (cntl3 & ~KX122_CNTL3_OTDT_MASK) | (directional_tap_odr & KX122_CNTL3_OTDT_MASK);
MikkoZ 2:62891556d47b 374 }
MikkoZ 2:62891556d47b 375 if (motion_wuf_odr != 0xff){
MikkoZ 2:62891556d47b 376 cntl3 = (cntl3 & ~KX122_CNTL3_OWUF_MASK) | (motion_wuf_odr & KX122_CNTL3_OWUF_MASK);
MikkoZ 2:62891556d47b 377 }
MikkoZ 2:62891556d47b 378 return i2c_rw.write_register(_sad, KX122_CNTL3, cntl3);
MikkoZ 2:62891556d47b 379 }
MikkoZ 2:62891556d47b 380
MikkoZ 2:62891556d47b 381 /**
MikkoZ 2:62891556d47b 382 * Setup ODR value, IIR-filter on/off and lowpass filter corner frequency.
MikkoZ 2:62891556d47b 383 * @param iir_filter_off False to filter ON or true to filter OFF.
MikkoZ 2:62891556d47b 384 * @param lowpass_filter_freq_half Filter corner frequency setup. False to ODR/9. True to ODR/2.
MikkoZ 2:62891556d47b 385 * @param odr Output Data Rate using KX122_ODCNTL_OSA_* -definitions.
MikkoZ 2:62891556d47b 386 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 387 **/
MikkoZ 2:62891556d47b 388 bool KX123::set_odcntl(bool iir_filter_off, uint8_t lowpass_filter_freq_half, uint8_t odr){
MikkoZ 2:62891556d47b 389 uint8_t odcntl;
MikkoZ 2:62891556d47b 390
MikkoZ 2:62891556d47b 391 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 392
MikkoZ 2:62891556d47b 393 odcntl = (odr & KX122_ODCNTL_OSA_MASK);
MikkoZ 2:62891556d47b 394 if (iir_filter_off){
MikkoZ 2:62891556d47b 395 odcntl = (odcntl | KX122_ODCNTL_IIR_BYPASS);
MikkoZ 2:62891556d47b 396 }
MikkoZ 2:62891556d47b 397 if (lowpass_filter_freq_half){
MikkoZ 2:62891556d47b 398 odcntl = (odcntl | KX122_ODCNTL_LPRO);
MikkoZ 2:62891556d47b 399 }
MikkoZ 2:62891556d47b 400
MikkoZ 2:62891556d47b 401 return i2c_rw.write_register(_sad, KX122_ODCNTL, odcntl);
MikkoZ 2:62891556d47b 402 }
MikkoZ 2:62891556d47b 403
MikkoZ 2:62891556d47b 404 /**
MikkoZ 2:62891556d47b 405 * Setup physical int1 pin, selftest polarity and SPI 3-wire on/off.
MikkoZ 2:62891556d47b 406 * @param pwsel Pulse width configuration in KX122_INC1_PWSEL1_* values
MikkoZ 2:62891556d47b 407 * @param physical_int_pin_enabled
MikkoZ 2:62891556d47b 408 * @param physical_int_pin_active_high (default true)
MikkoZ 2:62891556d47b 409 * @param physical_int_pin_latch_disabled
MikkoZ 2:62891556d47b 410 * @param self_test_polarity_positive
MikkoZ 2:62891556d47b 411 * @param spi3wire_enabled Use 3 wires instead of 4.
MikkoZ 2:62891556d47b 412 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 413 **/
MikkoZ 2:62891556d47b 414 bool KX123::int1_setup(uint8_t pwsel,
MikkoZ 2:62891556d47b 415 bool physical_int_pin_enabled,
MikkoZ 2:62891556d47b 416 bool physical_int_pin_active_high,
MikkoZ 2:62891556d47b 417 bool physical_int_pin_latch_disabled,
MikkoZ 2:62891556d47b 418 bool self_test_polarity_positive,
MikkoZ 2:62891556d47b 419 bool spi3wire_enabled){
MikkoZ 2:62891556d47b 420
MikkoZ 2:62891556d47b 421 uint8_t inc1;
MikkoZ 2:62891556d47b 422
MikkoZ 2:62891556d47b 423 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 424
MikkoZ 2:62891556d47b 425 inc1 = (pwsel & KX122_INC1_PWSEL1_MASK);
MikkoZ 2:62891556d47b 426 if (physical_int_pin_enabled){
MikkoZ 2:62891556d47b 427 inc1 = (inc1 | KX122_INC1_IEN1);
MikkoZ 2:62891556d47b 428 }
MikkoZ 2:62891556d47b 429 if (physical_int_pin_active_high){
MikkoZ 2:62891556d47b 430 inc1 = (inc1 | KX122_INC1_IEA1);
MikkoZ 2:62891556d47b 431 }
MikkoZ 2:62891556d47b 432 if (physical_int_pin_latch_disabled){
MikkoZ 2:62891556d47b 433 inc1 = (inc1 | KX122_INC1_IEL1);
MikkoZ 2:62891556d47b 434 }
MikkoZ 2:62891556d47b 435 if (self_test_polarity_positive){
MikkoZ 2:62891556d47b 436 inc1 = (inc1 | KX122_INC1_STPOL);
MikkoZ 2:62891556d47b 437 }
MikkoZ 2:62891556d47b 438 if (spi3wire_enabled){
MikkoZ 2:62891556d47b 439 inc1 = (inc1 | KX122_INC1_SPI3E);
MikkoZ 2:62891556d47b 440 }
MikkoZ 2:62891556d47b 441 return i2c_rw.write_register(_sad, KX122_INC1, inc1);
MikkoZ 2:62891556d47b 442 }
MikkoZ 2:62891556d47b 443
MikkoZ 2:62891556d47b 444
MikkoZ 2:62891556d47b 445 /**
MikkoZ 2:62891556d47b 446 * Setup physical int2 pin and int1/2 autoclear.
MikkoZ 2:62891556d47b 447 * @param pwsel Pulse width configuration in KX122_INC1_PWSEL1_* values
MikkoZ 2:62891556d47b 448 * @param physical_int_pin_enabled
MikkoZ 2:62891556d47b 449 * @param physical_int_pin_active_high (default true)
MikkoZ 2:62891556d47b 450 * @param physical_int_pin_latch_disabled
MikkoZ 2:62891556d47b 451 * @param aclr2_enabled
MikkoZ 2:62891556d47b 452 * @param aclr1_enabled
MikkoZ 2:62891556d47b 453 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 454 **/
MikkoZ 2:62891556d47b 455 bool KX123::int2_setup(uint8_t pwsel,
MikkoZ 2:62891556d47b 456 bool physical_int_pin_enabled,
MikkoZ 2:62891556d47b 457 bool physical_int_pin_active_high,
MikkoZ 2:62891556d47b 458 bool physical_int_pin_latch_disabled,
MikkoZ 2:62891556d47b 459 bool aclr2_enabled,
MikkoZ 2:62891556d47b 460 bool aclr1_enabled){
MikkoZ 2:62891556d47b 461
MikkoZ 2:62891556d47b 462 uint8_t inc5;
MikkoZ 2:62891556d47b 463
MikkoZ 2:62891556d47b 464 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 465
MikkoZ 2:62891556d47b 466 inc5 = (pwsel & KX122_INC5_PWSEL2_MASK);
MikkoZ 2:62891556d47b 467 if (physical_int_pin_enabled){
MikkoZ 2:62891556d47b 468 inc5 = (inc5 | KX122_INC5_IEN2);
MikkoZ 2:62891556d47b 469 }
MikkoZ 2:62891556d47b 470 if (physical_int_pin_active_high){
MikkoZ 2:62891556d47b 471 inc5 = (inc5 | KX122_INC5_IEA2);
MikkoZ 2:62891556d47b 472 }
MikkoZ 2:62891556d47b 473 if (physical_int_pin_latch_disabled){
MikkoZ 2:62891556d47b 474 inc5 = (inc5 | KX122_INC5_IEL2);
MikkoZ 2:62891556d47b 475 }
MikkoZ 2:62891556d47b 476 if (aclr2_enabled){
MikkoZ 2:62891556d47b 477 inc5 = (inc5 | KX122_INC5_ACLR2);
MikkoZ 2:62891556d47b 478 }
MikkoZ 2:62891556d47b 479 if (aclr1_enabled){
MikkoZ 2:62891556d47b 480 inc5 = (inc5 | KX122_INC5_ACLR1);
MikkoZ 2:62891556d47b 481 }
MikkoZ 2:62891556d47b 482 return i2c_rw.write_register(_sad, KX122_INC5, inc5);
MikkoZ 2:62891556d47b 483 }
MikkoZ 2:62891556d47b 484
MikkoZ 2:62891556d47b 485 /**
MikkoZ 2:62891556d47b 486 * Select interrupt reasons that can trigger interrupt for int1.
MikkoZ 2:62891556d47b 487 * @param interrupt_reason One or more e_interrupt_reason -values except doubletap.
MikkoZ 2:62891556d47b 488 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 489 **/
MikkoZ 2:62891556d47b 490 bool KX123::set_int1_interrupt_reason(uint8_t interrupt_reason){
MikkoZ 2:62891556d47b 491 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 492 return i2c_rw.write_register(_sad, KX122_INC4, interrupt_reason);
MikkoZ 2:62891556d47b 493 }
MikkoZ 2:62891556d47b 494
MikkoZ 2:62891556d47b 495 /**
MikkoZ 2:62891556d47b 496 * Select interrupt reasons that can trigger interrupt for int2.
MikkoZ 2:62891556d47b 497 * @param interrupt_reason One or more e_interrupt_reason -values except doubletap.
MikkoZ 2:62891556d47b 498 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 499 **/
MikkoZ 2:62891556d47b 500 bool KX123::set_int2_interrupt_reason(uint8_t interrupt_reason){
MikkoZ 2:62891556d47b 501 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 502 return i2c_rw.write_register(_sad, KX122_INC6, interrupt_reason);
MikkoZ 2:62891556d47b 503 }
MikkoZ 2:62891556d47b 504
MikkoZ 2:62891556d47b 505 /**
MikkoZ 2:62891556d47b 506 * Select axis that are monitored for motion detect interrupt.
MikkoZ 2:62891556d47b 507 * @param xxyyzz combination of e_axis -values for enabling axis
MikkoZ 2:62891556d47b 508 * @param axis_and_combination_enabled true for AND or false for OR
MikkoZ 2:62891556d47b 509 *
MikkoZ 2:62891556d47b 510 * true for AND configuration = (XN || XP) && (YN || YP) && (ZN || ZP)
MikkoZ 2:62891556d47b 511 *
MikkoZ 2:62891556d47b 512 * false for OR configuration = (XN || XP || YN || TP || ZN || ZP)
MikkoZ 2:62891556d47b 513 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 514 **/
MikkoZ 2:62891556d47b 515 bool KX123::set_motion_detect_axis(uint8_t xxyyzz, bool axis_and_combination_enabled){
MikkoZ 2:62891556d47b 516 uint8_t inc2;
MikkoZ 2:62891556d47b 517
MikkoZ 2:62891556d47b 518 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 519
MikkoZ 2:62891556d47b 520 inc2 = (xxyyzz & KX122_INC2_WUE_MASK);
MikkoZ 2:62891556d47b 521 if (axis_and_combination_enabled){
MikkoZ 2:62891556d47b 522 inc2 = (inc2 | KX122_INC2_AOI_AND);
MikkoZ 2:62891556d47b 523 }
MikkoZ 2:62891556d47b 524 return i2c_rw.write_register(_sad, KX122_INC2, inc2);
MikkoZ 2:62891556d47b 525 }
MikkoZ 2:62891556d47b 526
MikkoZ 2:62891556d47b 527 /**
MikkoZ 2:62891556d47b 528 * Select axis that are monitored for tap/doubletap interrupt.
MikkoZ 2:62891556d47b 529 * @param xxyyzz combination of e_axis -values for enabling axis
MikkoZ 2:62891556d47b 530 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 531 **/
MikkoZ 2:62891556d47b 532 bool KX123::set_tap_axis(uint8_t xxyyzz){
MikkoZ 2:62891556d47b 533 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 534 return i2c_rw.write_register(_sad, KX122_INC3, xxyyzz);
MikkoZ 2:62891556d47b 535 }
MikkoZ 2:62891556d47b 536