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

kx123.cpp

Committer:
MikkoZ
Date:
2016-09-30
Revision:
1:f328083fb80b
Parent:
0:a3f43eb92f86
Child:
2:62891556d47b

File content as of revision 1:f328083fb80b:

/*   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.h"

/**
* Create a KX123 instance for communication through pre-instantiated
* RegisterWriter (I2C) -object.
*
* @param i2c_obj pre-instantiated RegisterWriter (I2C) -object reference
* @param sad slave address of sensor.
* @param wai who_am_i value (i.e. sensor type/model)
*/
KX123::KX123(RegisterWriter &i2c_obj, uint8_t sad, uint8_t wai) : i2c_rw(i2c_obj) {
    _sad = sad;
    _wai = wai;        
}

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.
**/
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;
}


/**
* Get raw uint16_t XYZ-values from sensor
* @param *buf to uint16_t[3] for results
* @return 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;
}


/**
* Get gravity scaled float XYZ-values from sensor
* @param *buf to float[3] for results
* @return true on error, false on read ok.
**/
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;
}