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 Rohm

Committer:
MikkoZ
Date:
Thu Oct 06 10:23:48 2016 +0000
Revision:
2:62891556d47b
Parent:
1:f328083fb80b
Child:
3:4fd5361ed180
Added many features for setting up and reading the sensor registers via driver functions.

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 2:62891556d47b 143 bool KX123::getresults_highpass(uint16_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 2:62891556d47b 201 * Get axes of current tilt and previous tilt
MikkoZ 2:62891556d47b 202 * @param *current_previous space for storing 2 (uint8_t) values
MikkoZ 2:62891556d47b 203 * @return true on error
MikkoZ 2:62891556d47b 204 */
MikkoZ 2:62891556d47b 205 bool KX123::get_tilt(enum e_axis* current_previous){
MikkoZ 2:62891556d47b 206 #define GET_TILT_READ_LEN 2
MikkoZ 2:62891556d47b 207 uint8_t read_bytes;
MikkoZ 0:a3f43eb92f86 208
MikkoZ 2:62891556d47b 209 read_bytes = i2c_rw.read_register(_sad, KX122_TSCP, (uint8_t*)current_previous, GET_TILT_READ_LEN);
MikkoZ 2:62891556d47b 210
MikkoZ 2:62891556d47b 211 return (read_bytes != GET_TILT_READ_LEN);
MikkoZ 2:62891556d47b 212 }
MikkoZ 2:62891556d47b 213
MikkoZ 2:62891556d47b 214 /**
MikkoZ 2:62891556d47b 215 * Get axis of triggered tap/double tap interrupt from INS1
MikkoZ 2:62891556d47b 216 * @param *axis space for storing 1 (uint8_t) value in e_axis format
MikkoZ 2:62891556d47b 217 * @return true on error
MikkoZ 2:62891556d47b 218 */
MikkoZ 2:62891556d47b 219 bool KX123::get_tap_interrupt_axis(enum e_axis* axis){
MikkoZ 2:62891556d47b 220 #define GET_TAP_READ_LEN 1
MikkoZ 2:62891556d47b 221 uint8_t read_bytes;
MikkoZ 2:62891556d47b 222
MikkoZ 2:62891556d47b 223 read_bytes = i2c_rw.read_register(_sad, KX122_INS1, (uint8_t*)axis, GET_TAP_READ_LEN);
MikkoZ 2:62891556d47b 224
MikkoZ 2:62891556d47b 225 return (read_bytes != GET_TAP_READ_LEN);
MikkoZ 2:62891556d47b 226 }
MikkoZ 2:62891556d47b 227
MikkoZ 2:62891556d47b 228 /**
MikkoZ 2:62891556d47b 229 * Get axis of triggered motion detect interrupt from INS3
MikkoZ 2:62891556d47b 230 * @param *axis space for storing 1 (uint8_t) value in e_axis format
MikkoZ 2:62891556d47b 231 * @return true on error
MikkoZ 2:62891556d47b 232 */
MikkoZ 2:62891556d47b 233 bool KX123::get_detected_motion_axis(enum e_axis* axis){
MikkoZ 2:62891556d47b 234 #define GET_MOTION_READ_LEN 1
MikkoZ 2:62891556d47b 235 uint8_t read_bytes;
MikkoZ 2:62891556d47b 236
MikkoZ 2:62891556d47b 237 read_bytes = i2c_rw.read_register(_sad, KX122_INS3, (uint8_t*)axis, GET_MOTION_READ_LEN);
MikkoZ 2:62891556d47b 238
MikkoZ 2:62891556d47b 239 return (read_bytes != GET_MOTION_READ_LEN);
MikkoZ 2:62891556d47b 240 }
MikkoZ 2:62891556d47b 241
MikkoZ 2:62891556d47b 242 /**
MikkoZ 2:62891556d47b 243 * Set axis of triggered motion detect interrupt from CNTL2
MikkoZ 2:62891556d47b 244 * @param cnltl2_tilt_mask Orred e_axis values for axes directions to cause interrupt
MikkoZ 2:62891556d47b 245 * @return true on error or setup mode off
MikkoZ 2:62891556d47b 246 */
MikkoZ 2:62891556d47b 247 bool KX123::set_tilt_axis_mask(uint8_t cnltl2_tilt_mask){
MikkoZ 2:62891556d47b 248 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 249 //MSb 00 == no_action
MikkoZ 2:62891556d47b 250 return i2c_rw.write_register(_sad, KX122_CNTL2, (cnltl2_tilt_mask & KX123_AXIS_MASK) );
MikkoZ 2:62891556d47b 251 }
MikkoZ 2:62891556d47b 252
MikkoZ 2:62891556d47b 253 /**
MikkoZ 2:62891556d47b 254 * get cause of interrupt trigger from INS2
MikkoZ 2:62891556d47b 255 * @param *int_reason space for storing 1 (uint8_t) value in e_interrupt_reason format
MikkoZ 2:62891556d47b 256 * @return true on error
MikkoZ 2:62891556d47b 257 */
MikkoZ 2:62891556d47b 258 bool KX123::get_interrupt_reason(enum e_interrupt_reason* int_reason){
MikkoZ 2:62891556d47b 259 #define INT_REASON_LEN 1
MikkoZ 2:62891556d47b 260 uint8_t read_bytes;
MikkoZ 2:62891556d47b 261
MikkoZ 2:62891556d47b 262 read_bytes = i2c_rw.read_register(_sad, KX122_INS2, (uint8_t*)int_reason, INT_REASON_LEN);
MikkoZ 2:62891556d47b 263
MikkoZ 2:62891556d47b 264 return (read_bytes != INT_REASON_LEN);
MikkoZ 2:62891556d47b 265 }
MikkoZ 2:62891556d47b 266
MikkoZ 2:62891556d47b 267 /**
MikkoZ 2:62891556d47b 268 * Check from sensor register if interrupt has occured. Usable feature when
MikkoZ 2:62891556d47b 269 * multiple sensor interrupts are connected to same interrupt pin.
MikkoZ 2:62891556d47b 270 * @return true when interrupt has occured. False on read fail and no interrupt.
MikkoZ 2:62891556d47b 271 */
MikkoZ 2:62891556d47b 272 bool KX123::has_interrupt_occured(){
MikkoZ 2:62891556d47b 273 uint8_t status_reg;
MikkoZ 2:62891556d47b 274 uint8_t read_bytes;
MikkoZ 2:62891556d47b 275
MikkoZ 2:62891556d47b 276 read_bytes = i2c_rw.read_register(_sad, KX122_INS2, &status_reg, 1);
MikkoZ 2:62891556d47b 277 return ((read_bytes == 1) && (status_reg & KX122_STATUS_REG_INT));
MikkoZ 2:62891556d47b 278 }
MikkoZ 2:62891556d47b 279
MikkoZ 2:62891556d47b 280 /**
MikkoZ 2:62891556d47b 281 * Clear interrupt flag when latched. (==Interrupt release) Doesn't work for FIFO
MikkoZ 2:62891556d47b 282 * Buffer Full or FIFO Watermark -interrupts.
MikkoZ 2:62891556d47b 283 */
MikkoZ 2:62891556d47b 284 void KX123::clear_interrupt(){
MikkoZ 2:62891556d47b 285 uint8_t value_discarded;
MikkoZ 2:62891556d47b 286
MikkoZ 2:62891556d47b 287 i2c_rw.read_register(_sad, KX122_INT_REL, &value_discarded, 1);
MikkoZ 2:62891556d47b 288
MikkoZ 2:62891556d47b 289 return;
MikkoZ 2:62891556d47b 290 }
MikkoZ 2:62891556d47b 291
MikkoZ 2:62891556d47b 292 /**
MikkoZ 2:62891556d47b 293 * Initiate software reset and RAM reboot routine and wait untill finished.
MikkoZ 2:62891556d47b 294 */
MikkoZ 2:62891556d47b 295 void KX123::soft_reset(){
MikkoZ 2:62891556d47b 296 uint8_t reset_ongoing;
MikkoZ 2:62891556d47b 297
MikkoZ 2:62891556d47b 298 i2c_rw.change_bits(_sad, KX122_CNTL2, KX122_CNTL2_SRST, KX122_CNTL2_SRST );
MikkoZ 2:62891556d47b 299 do{
MikkoZ 2:62891556d47b 300 uint8_t cntl2, read_bytes;
MikkoZ 2:62891556d47b 301
MikkoZ 2:62891556d47b 302 read_bytes = i2c_rw.read_register(_sad, KX122_CNTL2, &cntl2, 1);
MikkoZ 2:62891556d47b 303 reset_ongoing = ((read_bytes == 0) || (cntl2 & KX122_CNTL2_SRST));
MikkoZ 2:62891556d47b 304 } while (reset_ongoing);
MikkoZ 2:62891556d47b 305
MikkoZ 2:62891556d47b 306 return;
MikkoZ 2:62891556d47b 307 }
MikkoZ 2:62891556d47b 308
MikkoZ 2:62891556d47b 309 /**
MikkoZ 2:62891556d47b 310 * Verify proper integrated circuit functionality
MikkoZ 2:62891556d47b 311 * @return true on test fail or setup mode off, false on test ok.
MikkoZ 2:62891556d47b 312 **/
MikkoZ 2:62891556d47b 313 bool KX123::self_test(){
MikkoZ 2:62891556d47b 314 uint8_t cotr_value;
MikkoZ 2:62891556d47b 315 bool read_ok;
MikkoZ 2:62891556d47b 316
MikkoZ 2:62891556d47b 317 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 318 //first read to make sure COTR is in default value
MikkoZ 2:62891556d47b 319 read_ok = i2c_rw.read_register(_sad, KX122_COTR, &cotr_value, 1);
MikkoZ 2:62891556d47b 320 read_ok = i2c_rw.read_register(_sad, KX122_COTR, &cotr_value, 1);
MikkoZ 2:62891556d47b 321 if ((cotr_value != 0x55) || (!read_ok) ){
MikkoZ 2:62891556d47b 322 return true;
MikkoZ 2:62891556d47b 323 }
MikkoZ 2:62891556d47b 324 i2c_rw.change_bits(_sad, KX122_CNTL2, KX122_CNTL2_COTC, KX122_CNTL2_COTC );
MikkoZ 2:62891556d47b 325 read_ok = i2c_rw.read_register(_sad, KX122_COTR, &cotr_value, 1);
MikkoZ 2:62891556d47b 326 if ((cotr_value != 0xAA) || (!read_ok) ){
MikkoZ 2:62891556d47b 327 return true;
MikkoZ 2:62891556d47b 328 }
MikkoZ 2:62891556d47b 329 return false;
MikkoZ 2:62891556d47b 330 }
MikkoZ 2:62891556d47b 331
MikkoZ 2:62891556d47b 332 /**
MikkoZ 2:62891556d47b 333 * Setup ODR values for Tilt Position, Directional Tap and Motion Detect.
MikkoZ 2:62891556d47b 334 * @param tilt_position_odr KX122_CNTL3_OTP_* -value or 0xff to skip.
MikkoZ 2:62891556d47b 335 * @param directional_tap_odr KX122_CNTL3_OTDT_* -value or 0xff to skip.
MikkoZ 2:62891556d47b 336 * @param motion_wuf_odr KX122_CNTL3_OWUF_* -value or 0xff to skip.
MikkoZ 2:62891556d47b 337 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 338 **/
MikkoZ 2:62891556d47b 339 bool KX123::set_cntl3_odrs(uint8_t tilt_position_odr, uint8_t directional_tap_odr, uint8_t motion_wuf_odr){
MikkoZ 2:62891556d47b 340 uint8_t cntl3;
MikkoZ 2:62891556d47b 341 bool read_ok;
MikkoZ 2:62891556d47b 342
MikkoZ 2:62891556d47b 343 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 344
MikkoZ 2:62891556d47b 345 read_ok = i2c_rw.read_register(_sad, KX122_CNTL3, &cntl3, 1);
MikkoZ 2:62891556d47b 346 if(!read_ok) return true;
MikkoZ 2:62891556d47b 347
MikkoZ 2:62891556d47b 348 if (tilt_position_odr != 0xff){
MikkoZ 2:62891556d47b 349 cntl3 = (cntl3 & ~KX122_CNTL3_OTP_MASK) | (tilt_position_odr & KX122_CNTL3_OTP_MASK);
MikkoZ 2:62891556d47b 350 }
MikkoZ 2:62891556d47b 351 if (directional_tap_odr != 0xff){
MikkoZ 2:62891556d47b 352 cntl3 = (cntl3 & ~KX122_CNTL3_OTDT_MASK) | (directional_tap_odr & KX122_CNTL3_OTDT_MASK);
MikkoZ 2:62891556d47b 353 }
MikkoZ 2:62891556d47b 354 if (motion_wuf_odr != 0xff){
MikkoZ 2:62891556d47b 355 cntl3 = (cntl3 & ~KX122_CNTL3_OWUF_MASK) | (motion_wuf_odr & KX122_CNTL3_OWUF_MASK);
MikkoZ 2:62891556d47b 356 }
MikkoZ 2:62891556d47b 357 return i2c_rw.write_register(_sad, KX122_CNTL3, cntl3);
MikkoZ 2:62891556d47b 358 }
MikkoZ 2:62891556d47b 359
MikkoZ 2:62891556d47b 360 /**
MikkoZ 2:62891556d47b 361 * Setup ODR value, IIR-filter on/off and lowpass filter corner frequency.
MikkoZ 2:62891556d47b 362 * @param iir_filter_off False to filter ON or true to filter OFF.
MikkoZ 2:62891556d47b 363 * @param lowpass_filter_freq_half Filter corner frequency setup. False to ODR/9. True to ODR/2.
MikkoZ 2:62891556d47b 364 * @param odr Output Data Rate using KX122_ODCNTL_OSA_* -definitions.
MikkoZ 2:62891556d47b 365 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 366 **/
MikkoZ 2:62891556d47b 367 bool KX123::set_odcntl(bool iir_filter_off, uint8_t lowpass_filter_freq_half, uint8_t odr){
MikkoZ 2:62891556d47b 368 uint8_t odcntl;
MikkoZ 2:62891556d47b 369
MikkoZ 2:62891556d47b 370 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 371
MikkoZ 2:62891556d47b 372 odcntl = (odr & KX122_ODCNTL_OSA_MASK);
MikkoZ 2:62891556d47b 373 if (iir_filter_off){
MikkoZ 2:62891556d47b 374 odcntl = (odcntl | KX122_ODCNTL_IIR_BYPASS);
MikkoZ 2:62891556d47b 375 }
MikkoZ 2:62891556d47b 376 if (lowpass_filter_freq_half){
MikkoZ 2:62891556d47b 377 odcntl = (odcntl | KX122_ODCNTL_LPRO);
MikkoZ 2:62891556d47b 378 }
MikkoZ 2:62891556d47b 379
MikkoZ 2:62891556d47b 380 return i2c_rw.write_register(_sad, KX122_ODCNTL, odcntl);
MikkoZ 2:62891556d47b 381 }
MikkoZ 2:62891556d47b 382
MikkoZ 2:62891556d47b 383 /**
MikkoZ 2:62891556d47b 384 * Setup physical int1 pin, selftest polarity and SPI 3-wire on/off.
MikkoZ 2:62891556d47b 385 * @param pwsel Pulse width configuration in KX122_INC1_PWSEL1_* values
MikkoZ 2:62891556d47b 386 * @param physical_int_pin_enabled
MikkoZ 2:62891556d47b 387 * @param physical_int_pin_active_high (default true)
MikkoZ 2:62891556d47b 388 * @param physical_int_pin_latch_disabled
MikkoZ 2:62891556d47b 389 * @param self_test_polarity_positive
MikkoZ 2:62891556d47b 390 * @param spi3wire_enabled Use 3 wires instead of 4.
MikkoZ 2:62891556d47b 391 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 392 **/
MikkoZ 2:62891556d47b 393 bool KX123::int1_setup(uint8_t pwsel,
MikkoZ 2:62891556d47b 394 bool physical_int_pin_enabled,
MikkoZ 2:62891556d47b 395 bool physical_int_pin_active_high,
MikkoZ 2:62891556d47b 396 bool physical_int_pin_latch_disabled,
MikkoZ 2:62891556d47b 397 bool self_test_polarity_positive,
MikkoZ 2:62891556d47b 398 bool spi3wire_enabled){
MikkoZ 2:62891556d47b 399
MikkoZ 2:62891556d47b 400 uint8_t inc1;
MikkoZ 2:62891556d47b 401
MikkoZ 2:62891556d47b 402 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 403
MikkoZ 2:62891556d47b 404 inc1 = (pwsel & KX122_INC1_PWSEL1_MASK);
MikkoZ 2:62891556d47b 405 if (physical_int_pin_enabled){
MikkoZ 2:62891556d47b 406 inc1 = (inc1 | KX122_INC1_IEN1);
MikkoZ 2:62891556d47b 407 }
MikkoZ 2:62891556d47b 408 if (physical_int_pin_active_high){
MikkoZ 2:62891556d47b 409 inc1 = (inc1 | KX122_INC1_IEA1);
MikkoZ 2:62891556d47b 410 }
MikkoZ 2:62891556d47b 411 if (physical_int_pin_latch_disabled){
MikkoZ 2:62891556d47b 412 inc1 = (inc1 | KX122_INC1_IEL1);
MikkoZ 2:62891556d47b 413 }
MikkoZ 2:62891556d47b 414 if (self_test_polarity_positive){
MikkoZ 2:62891556d47b 415 inc1 = (inc1 | KX122_INC1_STPOL);
MikkoZ 2:62891556d47b 416 }
MikkoZ 2:62891556d47b 417 if (spi3wire_enabled){
MikkoZ 2:62891556d47b 418 inc1 = (inc1 | KX122_INC1_SPI3E);
MikkoZ 2:62891556d47b 419 }
MikkoZ 2:62891556d47b 420 return i2c_rw.write_register(_sad, KX122_INC1, inc1);
MikkoZ 2:62891556d47b 421 }
MikkoZ 2:62891556d47b 422
MikkoZ 2:62891556d47b 423
MikkoZ 2:62891556d47b 424 /**
MikkoZ 2:62891556d47b 425 * Setup physical int2 pin and int1/2 autoclear.
MikkoZ 2:62891556d47b 426 * @param pwsel Pulse width configuration in KX122_INC1_PWSEL1_* values
MikkoZ 2:62891556d47b 427 * @param physical_int_pin_enabled
MikkoZ 2:62891556d47b 428 * @param physical_int_pin_active_high (default true)
MikkoZ 2:62891556d47b 429 * @param physical_int_pin_latch_disabled
MikkoZ 2:62891556d47b 430 * @param aclr2_enabled
MikkoZ 2:62891556d47b 431 * @param aclr1_enabled
MikkoZ 2:62891556d47b 432 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 433 **/
MikkoZ 2:62891556d47b 434 bool KX123::int2_setup(uint8_t pwsel,
MikkoZ 2:62891556d47b 435 bool physical_int_pin_enabled,
MikkoZ 2:62891556d47b 436 bool physical_int_pin_active_high,
MikkoZ 2:62891556d47b 437 bool physical_int_pin_latch_disabled,
MikkoZ 2:62891556d47b 438 bool aclr2_enabled,
MikkoZ 2:62891556d47b 439 bool aclr1_enabled){
MikkoZ 2:62891556d47b 440
MikkoZ 2:62891556d47b 441 uint8_t inc5;
MikkoZ 2:62891556d47b 442
MikkoZ 2:62891556d47b 443 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 444
MikkoZ 2:62891556d47b 445 inc5 = (pwsel & KX122_INC5_PWSEL2_MASK);
MikkoZ 2:62891556d47b 446 if (physical_int_pin_enabled){
MikkoZ 2:62891556d47b 447 inc5 = (inc5 | KX122_INC5_IEN2);
MikkoZ 2:62891556d47b 448 }
MikkoZ 2:62891556d47b 449 if (physical_int_pin_active_high){
MikkoZ 2:62891556d47b 450 inc5 = (inc5 | KX122_INC5_IEA2);
MikkoZ 2:62891556d47b 451 }
MikkoZ 2:62891556d47b 452 if (physical_int_pin_latch_disabled){
MikkoZ 2:62891556d47b 453 inc5 = (inc5 | KX122_INC5_IEL2);
MikkoZ 2:62891556d47b 454 }
MikkoZ 2:62891556d47b 455 if (aclr2_enabled){
MikkoZ 2:62891556d47b 456 inc5 = (inc5 | KX122_INC5_ACLR2);
MikkoZ 2:62891556d47b 457 }
MikkoZ 2:62891556d47b 458 if (aclr1_enabled){
MikkoZ 2:62891556d47b 459 inc5 = (inc5 | KX122_INC5_ACLR1);
MikkoZ 2:62891556d47b 460 }
MikkoZ 2:62891556d47b 461 return i2c_rw.write_register(_sad, KX122_INC5, inc5);
MikkoZ 2:62891556d47b 462 }
MikkoZ 2:62891556d47b 463
MikkoZ 2:62891556d47b 464 /**
MikkoZ 2:62891556d47b 465 * Select interrupt reasons that can trigger interrupt for int1.
MikkoZ 2:62891556d47b 466 * @param interrupt_reason One or more e_interrupt_reason -values except doubletap.
MikkoZ 2:62891556d47b 467 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 468 **/
MikkoZ 2:62891556d47b 469 bool KX123::set_int1_interrupt_reason(uint8_t interrupt_reason){
MikkoZ 2:62891556d47b 470 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 471 return i2c_rw.write_register(_sad, KX122_INC4, interrupt_reason);
MikkoZ 2:62891556d47b 472 }
MikkoZ 2:62891556d47b 473
MikkoZ 2:62891556d47b 474 /**
MikkoZ 2:62891556d47b 475 * Select interrupt reasons that can trigger interrupt for int2.
MikkoZ 2:62891556d47b 476 * @param interrupt_reason One or more e_interrupt_reason -values except doubletap.
MikkoZ 2:62891556d47b 477 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 478 **/
MikkoZ 2:62891556d47b 479 bool KX123::set_int2_interrupt_reason(uint8_t interrupt_reason){
MikkoZ 2:62891556d47b 480 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 481 return i2c_rw.write_register(_sad, KX122_INC6, interrupt_reason);
MikkoZ 2:62891556d47b 482 }
MikkoZ 2:62891556d47b 483
MikkoZ 2:62891556d47b 484 /**
MikkoZ 2:62891556d47b 485 * Select axis that are monitored for motion detect interrupt.
MikkoZ 2:62891556d47b 486 * @param xxyyzz combination of e_axis -values for enabling axis
MikkoZ 2:62891556d47b 487 * @param axis_and_combination_enabled true for AND or false for OR
MikkoZ 2:62891556d47b 488 *
MikkoZ 2:62891556d47b 489 * true for AND configuration = (XN || XP) && (YN || YP) && (ZN || ZP)
MikkoZ 2:62891556d47b 490 *
MikkoZ 2:62891556d47b 491 * false for OR configuration = (XN || XP || YN || TP || ZN || ZP)
MikkoZ 2:62891556d47b 492 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 493 **/
MikkoZ 2:62891556d47b 494 bool KX123::set_motion_detect_axis(uint8_t xxyyzz, bool axis_and_combination_enabled){
MikkoZ 2:62891556d47b 495 uint8_t inc2;
MikkoZ 2:62891556d47b 496
MikkoZ 2:62891556d47b 497 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 498
MikkoZ 2:62891556d47b 499 inc2 = (xxyyzz & KX122_INC2_WUE_MASK);
MikkoZ 2:62891556d47b 500 if (axis_and_combination_enabled){
MikkoZ 2:62891556d47b 501 inc2 = (inc2 | KX122_INC2_AOI_AND);
MikkoZ 2:62891556d47b 502 }
MikkoZ 2:62891556d47b 503 return i2c_rw.write_register(_sad, KX122_INC2, inc2);
MikkoZ 2:62891556d47b 504 }
MikkoZ 2:62891556d47b 505
MikkoZ 2:62891556d47b 506 /**
MikkoZ 2:62891556d47b 507 * Select axis that are monitored for tap/doubletap interrupt.
MikkoZ 2:62891556d47b 508 * @param xxyyzz combination of e_axis -values for enabling axis
MikkoZ 2:62891556d47b 509 * @return true on error or setup mode off, false on setup ok.
MikkoZ 2:62891556d47b 510 **/
MikkoZ 2:62891556d47b 511 bool KX123::set_tap_axis(uint8_t xxyyzz){
MikkoZ 2:62891556d47b 512 if (setup_mode_on == false) return true;
MikkoZ 2:62891556d47b 513 return i2c_rw.write_register(_sad, KX122_INC3, xxyyzz);
MikkoZ 2:62891556d47b 514 }
MikkoZ 2:62891556d47b 515