From ea1947ffcc606d757357398b24e74a3f4ecefa07 Mon Sep 17 00:00:00 2001 From: neonloop Date: Wed, 20 Oct 2021 14:54:27 +0000 Subject: Initial commit from steward-fu release --- modules/libjoy/caanoo/te9_tf9_hybrid_driver.c | 3301 +++++++++++++++++++++++++ 1 file changed, 3301 insertions(+) create mode 100644 modules/libjoy/caanoo/te9_tf9_hybrid_driver.c (limited to 'modules/libjoy/caanoo/te9_tf9_hybrid_driver.c') diff --git a/modules/libjoy/caanoo/te9_tf9_hybrid_driver.c b/modules/libjoy/caanoo/te9_tf9_hybrid_driver.c new file mode 100644 index 0000000..851f679 --- /dev/null +++ b/modules/libjoy/caanoo/te9_tf9_hybrid_driver.c @@ -0,0 +1,3301 @@ +//Cleaned up 3/26 CMH + +#ifdef __cplusplus +extern "C" { +#endif +/*================================================================================================== + INCLUDE FILES +==================================================================================================*/ +#include "te9_tf9_hybrid_driver.h" +#include "i2c-dev.h" +/*================================================================================================== + LOCAL VARIABLES +==================================================================================================*/ +#ifdef KX_PLATFORM_LINUX +static int fd = 0; //local file descriptor for the /dev/i2c interface +static int block = 0; //flag for block read functionality (1=block, 0=no block) +#endif +static int device = 0; //flag to indicate device KXTE9=0, KXTF9=1 +#ifdef KX_PLATFORM_REX + LOCAL rex_crit_sect_type tf9_crit_sect; +#else + int tf9_crit_sect; +#endif +unsigned char gpio_int_type; +/*================================================================================================== + COMMON FUNCTIONS +==================================================================================================*/ +// TODO: +#ifdef KX_PLATFORM_REX + extern sky_accel_mode_type sky_accel_current_mode; + extern i2c_status_type accel_i2c_write(unsigned char dev_addr, unsigned char addr, unsigned char *data, unsigned char length); + extern i2c_status_type accel_i2c_read(unsigned char dev_addr, unsigned char addr, unsigned char *data, unsigned char length); + extern void accel_process_landscape(unsigned char tilt_pos_pre, unsigned char tilt_pos_cur); + extern void accel_process_updown(unsigned char tilt_pos_pre, unsigned char tilt_pos_cur); + extern void accel_process_tap(unsigned char tap_mode, unsigned char tap_direction); + +#elif defined(KX_PLATFORM_FIRMWARE) + void Wr24C080(U32 slvAddr,U32 addr,U8 data); + void Rd24C080(U32 slvAddr,U32 addr,U8 *data); + + void _Wr24C080(U32 slvAddr,U32 addr,U8 data); + void _Rd24C080(U32 slvAddr,U32 addr,U8 *data); +#endif + + +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_read_bytes +DESCRIPTION: This function reads data from the Kionix accelerometer in bytes. +ARGUMENTS PASSED: register address, data pointer, length in number of bytes +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: None +IMPORTANT NOTES: Using the i2c_smbus functions requires the inclusion of the i2c-dev.h file + available in the lm-sensors package. +==================================================================================================*/ +int KIONIX_ACCEL_read_bytes(int reg, char* data, int length) +{ + int status = 0; + int ret = 0; + int i; + KIONIX_EnterCriticalSection(&tf9_crit_sect); +#ifdef KX_PLATFORM_LINUX + if (block == 1){ + status = i2c_smbus_read_i2c_block_data(fd, reg, length, (__u8*)data); + if(status < 0){ //status will be number of bytes read, negative if read failed + //printf("Read failed on register 0x%02x\n", reg); + KIONIX_LeaveCriticalSection(&tf9_crit_sect); + return 1; + } + } + else if (block == 0){ + for (i = 0; i < length; i++){ + ret = i2c_smbus_read_byte_data(fd, reg + i); + if (ret < 0){ //status will be the data retrieved in the byte read + //printf("Read failed on register 0x%02x\n", (reg + i)); + return 1; + } + else data[i] = (char)ret; + } + } + else { + KIONIX_LeaveCriticalSection(&tf9_crit_sect); + return 1; + } +#elif defined(KX_PLATFORM_WIN32) || defined(KX_PLATFORM_WINCE) + +#elif defined(KX_PLATFORM_REX) + status = accel_i2c_read(KIONIX_ACCEL_I2C_SLV_ADDR, reg, &data[0], length); + +#elif defined(KX_PLATFORM_FIRMWARE) + #ifdef USE_I2C_GPIO + { + unsigned char wb[2], rb[2]; + wb[0] = reg; + i2c_read(KIONIX_ACCEL_I2C_SLV_ADDR, &wb[0], 1, &data[0], length); + } + #elif defined(USE_I2C_INT) + for(i=0; i>2); + KIONIX_ACCEL_process_directional_tap(tap_mode, int_src_reg1); // tap_mode(single/dobule), tap_direction + } + if(int_src_reg2 & BIT(0) ) { // TPS + KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_TILT_POS_CUR, &tilt_pos_cur, 1); + KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_TILT_POS_PRE, &tilt_pos_pre, 1); + KIONIX_ACCEL_process_screen_rotation(tilt_pos_pre, tilt_pos_cur); + } + if(int_src_reg2 & BIT(1)) { // WUFS + KIONIX_ACCEL_process_motion_detection(int_src_reg1, int_src_reg2); + } + break; + case 2: // KXSD9 + break; + } + + +RELEASE_INT: + KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_REL, &int_rel, 1); + // enable accelerometer interrupt again + KIONIX_ACCEL_enable_interrupt(); + + KX_INTFREE( ); + +#if 0 + int return_status = 1; + char dummy = 0; + if (device == 0){ //KXTE9 + // read the interrupt source register + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG2, (char *)source_of_interrupt, 1) == 0){ + // clear the interrupt source information along with interrupt pin + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_REL, &dummy, 1) == 0){ + return_status = 0; + } + else return_status = 1; + } + else return_status = 1; + } + else if (device == 1){ //KXTF9 + // read the interrupt source register + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, (char *)source_of_interrupt, 1) == 0){ + // clear the interrupt source information along with interrupt pin + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_REL, &dummy, 1) == 0){ + return_status = 0; + } + else return_status = 1; + } + else return_status = 1; + } + else return_status = 1; + return return_status; +#endif // end of #if 0 +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_read_LPF_cnt +DESCRIPTION: This function reads the number of counts on the X, Y, and Z axes. +ARGUMENTS PASSED: x, y, and z pointers +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: x, y, and z are assigned +==================================================================================================*/ +int KIONIX_ACCEL_read_LPF_cnt(int* x, int* y, int* z) +{ + int status, x_sign, y_sign, z_sign; + char Res, x_char; + char ret[3] = {0, 0, 0}; + char xyz[6] = {0, 0, 0, 0, 0, 0}; + if (device == 0){ //KXTE9 + status = KIONIX_ACCEL_read_bytes(KXTE9_I2C_XOUT, ret, 3); + if(status == 0){ + *x = (int)(ret[0]) >> 2; + *y = (int)(ret[1]) >> 2; + *z = (int)(ret[2]) >> 2; + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &Res, 1) == 0){ + Res = Res & 0x40; + switch(Res){ + case 0x00: //low-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_L, xyz, 6)) == 0){ + *x = ((int)xyz[1]); + x_sign = *x >> 7; //1 = negative; 0 = positive + if (x_sign == 1){ + *x = ((~(*x) + 0x01) & 0x0FF); + *x = -(*x); + } + *y = ((int)xyz[3]); + y_sign = *y >> 7; //1 = negative; 0 = positive + if (y_sign == 1){ + *y = ((~(*y) + 0x01) & 0x0FF); //2's complement + *y = -(*y); + } + *z = ((int)xyz[5]); + z_sign = *z >> 7; //1 = negative; 0 = positive + if (z_sign == 1){ + *z = ((~(*z) + 0x01) & 0x0FF); //2's complement + *z = -(*z); + } + } + break; + case 0x40: //high-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_L, xyz, 6)) == 0){ + *x = ((int)xyz[0]) >> 4; + *x = *x + (((int)xyz[1]) << 4); + x_sign = *x >> 11; //1 = negative; 0 = positive + if (x_sign == 1){ + *x = ((~(*x) + 0x01) & 0x0FFF); //2's complement + *x = -(*x); + } + *y = ((int)xyz[2]) >> 4; + *y = *y + (((int)xyz[3]) << 4); + y_sign = *y >> 11; //1 = negative; 0 = positive + if (y_sign == 1){ + *y = ((~(*y) + 0x01) & 0x0FFF); //2's complement + *y = -(*y); + } + *z = ((int)xyz[4]) >> 4; + *z = *z + (((int)xyz[5]) << 4); + z_sign = *z >> 11; //1 = negative; 0 = positive + if (z_sign == 1){ + *z = ((~(*z) + 0x01) & 0x0FFF); //2's complement + *z = -(*z); + } + } + break; + } + } + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_read_LPF_g +DESCRIPTION: This function reads the G(gravity force) values on the X, Y, and Z axes. + The units used are milli-g's, or 1/1000*G. +ARGUMENTS PASSED: gx, gy, and gz pointers +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: gx, gy, and gz are assigned +==================================================================================================*/ +int KIONIX_ACCEL_read_LPF_g(int* gx, int* gy, int* gz) +{ + int status, sensitivity; + int x = 0; + int y = 0; + int z = 0; + int x_sign, y_sign, z_sign; + char xyz[6] = {0, 0, 0, 0, 0, 0}; + char Res = 0; + char G_range = 0; + int range = 0; + if (device == 0){ //KXTE9 + sensitivity = BIT_SENSITIVITY_2_G; + if ((status = KIONIX_ACCEL_read_LPF_cnt(&x, &y, &z)) == 0){ + /* calculate milli-G's */ + *gx = 1000 * (x - ZERO_G_OFFSET) / sensitivity; + *gy = 1000 * (y - ZERO_G_OFFSET) / sensitivity; + *gz = 1000 * (z - ZERO_G_OFFSET) / sensitivity; + } + else status = 1; + } + else if (device == 1){ //KXTF9 + //determine if in the low resolution or high resolution state + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &Res, 1) == 0){ + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &G_range, 1) == 0){ + G_range = G_range & 0x18; + G_range = G_range >> 3; + switch(G_range){ + case 0: + range = 2; + break; + case 1: + range = 4; + break; + case 2: + range = 8; + break; + default: + break; + } + Res = Res & 0x40; + switch(Res){ + case 0x00: //low-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_L, xyz, 6)) == 0){ + x = ((int)xyz[1]); + x_sign = x >> 7; //1 = negative; 0 = positive + if (x_sign == 1){ + x = ((~(x) + 0x01) & 0x0FF); + x = -(x); + } + y = ((int)xyz[3]); + y_sign = y >> 7; //1 = negative; 0 = positive + if (y_sign == 1){ + y = ((~(y) + 0x01) & 0x0FF); //2's complement + y = -(y); + } + z = ((int)xyz[5]); + z_sign = z >> 7; //1 = negative; 0 = positive + if (z_sign == 1){ + z = ((~(z) + 0x01) & 0x0FF); //2's complement + z = -(z); + } + sensitivity = (256)/(2*range); + /* calculate milli-G's */ + *gx = 1000 * (x) / sensitivity; + *gy = 1000 * (y) / sensitivity; + *gz = 1000 * (z) / sensitivity; + } + break; + case 0x40: //high-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_L, xyz, 6)) == 0){ + x = ((int)xyz[0]) >> 4; + x = x + (((int)xyz[1]) << 4); + x_sign = x >> 11; //1 = negative; 0 = positive + if (x_sign == 1){ + x = ((~(x) + 0x01) & 0x0FFF); //2's complement + x = -(x); + } + y = ((int)xyz[2]) >> 4; + y = y + (((int)xyz[3]) << 4); + y_sign = y >> 11; //1 = negative; 0 = positive + if (y_sign == 1){ + y = ((~(y) + 0x01) & 0x0FFF); //2's complement + y = -(y); + } + z = ((int)xyz[4]) >> 4; + z = z + (((int)xyz[5]) << 4); + z_sign = z >> 11; //1 = negative; 0 = positive + if (z_sign == 1){ + z = ((~(z) + 0x01) & 0x0FFF); //2's complement + z = -(z); + } + sensitivity = (4096)/(2*range); + /* calculate milli-G's */ + *gx = 1000 * (x) / sensitivity; + *gy = 1000 * (y) / sensitivity; + *gz = 1000 * (z) / sensitivity; + } + break; + default: + break; + } + } + else status = 1; + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_read_current_odr_motion +DESCRIPTION: This function reads the current ODR of the general motion function. +ARGUMENTS PASSED: ODR_rate_motion pointer +RETURN VALUE: 0 = ODR set correctly; 1 = ODR invalid +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: ODR_rate_motion is assigned +==================================================================================================*/ +int KIONIX_ACCEL_read_current_odr_motion(double* ODR_rate_motion) +{ + int status; + char status_reg, ctrl_reg; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_STATUS_REG, &status_reg, 1) == 0){ + status_reg &= 0x0C; + status_reg >>= 2; + switch (status_reg){ + case 0: + *ODR_rate_motion = 1; + status = 0; + break; + case 1: + *ODR_rate_motion = 3; + status = 0; + break; + case 2: + *ODR_rate_motion = 10; + status = 0; + break; + case 3: + *ODR_rate_motion = 40; + status = 0; + break; + default: + status = 1; + break; + } + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctrl_reg, 1) == 0){ + ctrl_reg &= 0x03; + ctrl_reg >>= 2; + switch (ctrl_reg){ + case 0: + *ODR_rate_motion = 25; + status = 0; + break; + case 1: + *ODR_rate_motion = 50; + status = 0; + break; + case 2: + *ODR_rate_motion = 100; + status = 0; + break; + case 3: + *ODR_rate_motion = 200; + status = 0; + break; + default: + status = 1; + break; + } + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_read_position_status +DESCRIPTION: This function reads INT_SRC_REG to determine if there was a change in tilt. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = tilt occurred; 1 = no tilt occurred +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: None +==================================================================================================*/ +int KIONIX_ACCEL_read_position_status(void) +{ + int position_status; + char src_reg1, src_reg2; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG1, &src_reg1, 1) == 0){ + if((src_reg1 & 0x01) == 1){ + position_status = 0; + } + else position_status = 1; + } + else position_status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, &src_reg2, 1) == 0){ + if((src_reg2 & 0x01) == 1){ + position_status = 0; + } + else position_status = 1; + } + else position_status = 1; + } + else position_status = 1; + return position_status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_read_wuf_status +DESCRIPTION: This function reads INT_SRC_REG1 to determine if wake up occurred. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = wake up occurred; 1 = no wake up occurred +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: None +==================================================================================================*/ +int KIONIX_ACCEL_read_wuf_status(void) +{ + int wuf_status; + char src_reg1, src_reg2; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG1, &src_reg1, 1) == 0){ + if((src_reg1 & 0x02) == 0x02){ + wuf_status = 0; + } + else wuf_status = 1; + } + else wuf_status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, &src_reg2, 1) == 0){ + if((src_reg2 & 0x02) == 0x02){ + wuf_status = 0; + } + else wuf_status = 1; + } + else wuf_status = 1; + } + else wuf_status = 1; + return wuf_status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_enable_int +DESCRIPTION: This function enables the physical interrupt. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Physical interrupt enabled +==================================================================================================*/ +int KIONIX_ACCEL_enable_int(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTE9_INT_CTRL_REG1_IEN); + KIONIX_ACCEL_write_byte(KXTE9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_IEN); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_disable_int +DESCRIPTION: This function disables the physical interrupt. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Physical interrupt disabled +==================================================================================================*/ +int KIONIX_ACCEL_disable_int(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTE9_INT_CTRL_REG1_IEN); + KIONIX_ACCEL_write_byte(KXTE9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_IEN); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_int_activeh +DESCRIPTION: This function sets the polarity of physical interrupt pin to active high. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Physical interrupt set to active high +==================================================================================================*/ +int KIONIX_ACCEL_int_activeh(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTE9_INT_CTRL_REG1_IEA); + KIONIX_ACCEL_write_byte(KXTE9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_IEA); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_int_activel +DESCRIPTION: This function sets the polarity of physical interrupt pin to active low. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Physical interrupt set to active low +==================================================================================================*/ +int KIONIX_ACCEL_int_activel(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTE9_INT_CTRL_REG1_IEA); + KIONIX_ACCEL_write_byte(KXTE9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_IEA); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_int_latch +DESCRIPTION: This function sets the physical interrupt to a latch state. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Physical interrupt set to latched response +==================================================================================================*/ +int KIONIX_ACCEL_int_latch(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTE9_INT_CTRL_REG1_IEL); + KIONIX_ACCEL_write_byte(KXTE9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_IEL); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_int_pulse +DESCRIPTION: This function sets the physical interrupt to a pulse state. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Physical interrupt set to pulse response +==================================================================================================*/ +int KIONIX_ACCEL_int_pulse(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTE9_INT_CTRL_REG1_IEL); + KIONIX_ACCEL_write_byte(KXTE9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else if (device == 1){ //KXTF9 + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_IEL); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== + KXTE9-SPECIFIC FUNCTIONS +==================================================================================================*/ +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_enable_back_to_sleep +DESCRIPTION: This function enables the back to sleep function. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Back to sleep is enabled +==================================================================================================*/ +int KIONIX_ACCEL_enable_back_to_sleep(void) +{ + char ctlreg_1 = 0; + int status = 0; + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctlreg_1, 1) == 0){ + SET_REG_BIT(ctlreg_1, CTRL_REG1_B2SE); /* set the B2SE bit to enable back to sleep function */ + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KIONIX_ACCEL_disable_back_to_sleep +DESCRIPTION: This function disables the back to sleep function. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Back to sleep is disabled +==================================================================================================*/ +int KIONIX_ACCEL_disable_back_to_sleep(void) +{ + char ctlreg_1 = 0; + int status = 0; + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctlreg_1, 1) == 0){ + UNSET_REG_BIT(ctlreg_1, CTRL_REG1_B2SE); /* unset the B2SE bit to disable back to sleep function */ + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTE9_read_b2s_status +DESCRIPTION: This function reads INT_SRC_REG1 to determine if back to sleep occurred. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = back to sleep occurred; 1 = back to sleep did not occur +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: None +==================================================================================================*/ +int KXTE9_read_b2s_status(void) +{ + int wuf_status; + char src_reg1; + if (device == 1){ //KXTF9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG1, &src_reg1, 1) == 0){ + if((src_reg1 & 0x04) == 0x04){ + wuf_status = 0; + } + else wuf_status = 1; + } + else wuf_status = 1; + return wuf_status; +} +/*================================================================================================== +FUNCTION: KXTE9_b2s_timer +DESCRIPTION: This function sets the number of back-to-sleep debounce samples. +ARGUMENTS PASSED: b2s_timer; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Back-to-sleep debounce set according to b2s_timer +==================================================================================================*/ +int KXTE9_b2s_timer(int b2s_timer) +{ + int status; + if (device == 1){ //KXTF9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTE9_I2C_B2S_TIMER, b2s_timer) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTE9_b2s_thresh +DESCRIPTION: This function defines the threshold for back-to-sleep detection. +ARGUMENTS PASSED: b2s_thresh ; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Back-to-sleep function threshold set according to b2s_thresh +IMPORTANT NOTES: Default: 1.5g (0x60h) +==================================================================================================*/ +int KXTE9_b2s_thresh(int b2s_thresh) +{ + int status; + if (device == 1){ //KXTF9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTE9_I2C_B2S_THRESH, b2s_thresh) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== + KXTF9-SPECIFIC FUNCTIONS +==================================================================================================*/ +/*================================================================================================== +FUNCTION: KXTF9_enable_tap_detection +DESCRIPTION: This function enables the tap detection function. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Tap detection is enabled +==================================================================================================*/ +int KXTF9_enable_tap_detection(void) +{ + char ctlreg_1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctlreg_1, 1) == 0){ + SET_REG_BIT(ctlreg_1, CTRL_REG1_TDTE); /* set TDTE bit to enable tap function */ + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_disable_tap_detection +DESCRIPTION: This function disables the tap detection function. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Tap detection is disabled +==================================================================================================*/ +int KXTF9_disable_tap_detection(void) +{ + char ctlreg_1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctlreg_1, 1) == 0){ + UNSET_REG_BIT(ctlreg_1, CTRL_REG1_TDTE); /* unset the TDTE bit to disable tap function */ + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_read_single_tap_status +DESCRIPTION: This function reads INT_SRC_REG2 to determine whether a single tap event + occurred. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = single tap occurred; 1 = single tap did not occur +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: None +==================================================================================================*/ +int KXTF9_read_single_tap_status(void) +{ + int single_tap; + char src_reg2; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, &src_reg2, 1) == 0){ + if((src_reg2 & 0x0C) == 0x04){ + single_tap = 0; + } + else single_tap = 1; + } + else single_tap = 1; + return single_tap; +} +/*================================================================================================== +FUNCTION: KXTF9_read_double_tap_status +DESCRIPTION: This function reads INT_SRC_REG2 to determine whether a double tap event + occurred. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = double tap occurred; 1 = double tap did not occur +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: None +==================================================================================================*/ +int KXTF9_read_double_tap_status(void) +{ + int double_tap; + char src_reg2; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, &src_reg2, 1) == 0){ + if((src_reg2 & 0x0C) == 0x08){ + double_tap = 0; + } + else double_tap = 1; + } + else double_tap = 1; + return double_tap; +} +/*================================================================================================== +FUNCTION: KXTF9_set_odr_tilt +DESCRIPTION: This function sets the ODR frequency for the tilt position function. +ARGUMENTS PASSED: frequency variable; 1, 6, 12, or 50 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: ODR is set for tilt function according to frequency +==================================================================================================*/ +int KXTF9_set_odr_tilt(int frequency) +{ + char ctlreg_3 = 0; + if (device == 0){ //KXTE9 + // CTRL_REG1's initial output data rate ??? + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctlreg_3, 1) != 0){ + return 1; + } + switch (frequency){ + case 1: /* set all ODR's to 1.6Hz */ + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTPA); + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTPB); + break; + case 6: /* set all ODR's to 6.3Hz */ + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTPA); + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTPB); + break; + case 12: /* set all ODR's to 12.5Hz */ + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTPA); + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTPB); + break; + case 50: /* set all ODR's to 50Hz */ + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTPA); + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTPB); + break; + default: + return 1; + } + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3); + return 0; +} +/*================================================================================================== +FUNCTION: KXTF9_set_G_range +DESCRIPTION: This function sets the accelerometer G range. +ARGUMENTS PASSED: range variable; 2, 4, or 8 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: G range is set according to range +==================================================================================================*/ +int KXTF9_set_G_range(int range) +{ + char ctlreg_1 = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctlreg_1, 1) != 0){ + return 1; + } + switch (range){ + case 2: /* set G-range to 2g */ + UNSET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL1); + UNSET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL0); + break; + case 4: /* set G-range to 4g */ + UNSET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL1); + SET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL0); + break; + case 8: /* set G-range to 8g */ + SET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL1); + UNSET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL0); + break; + default: + return 1; + } + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1); + return 0; +} +/*================================================================================================== +FUNCTION: KXTF9_read_HPF_cnt +DESCRIPTION: This function reads the high pass filtered number of counts on the X, Y, + and Z axes. +ARGUMENTS PASSED: x, y, and z pointers +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: x, y, and z are assigned +==================================================================================================*/ +int KXTF9_read_HPF_cnt(int* x, int* y, int* z) +{ + int status, x_sign, y_sign, z_sign; + char Res = 0; + char xyz[6] = {0, 0, 0, 0, 0, 0}; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &Res, 1) == 0){ + Res = Res & 0x40; + switch(Res){ + case 0x00: //low-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_HPF_L, xyz, 6)) == 0){ + *x = ((int)xyz[1]); + x_sign = *x >> 7; //1 = negative; 0 = positive + if (x_sign == 1){ + *x = ((~(*x) + 0x01) & 0x0FF); + *x = -(*x); + } + *y = ((int)xyz[3]); + y_sign = *y >> 7; //1 = negative; 0 = positive + if (y_sign == 1){ + *y = ((~(*y) + 0x01) & 0x0FF); //2's complement + *y = -(*y); + } + *z = ((int)xyz[5]); + z_sign = *z >> 7; //1 = negative; 0 = positive + if (z_sign == 1){ + *z = ((~(*z) + 0x01) & 0x0FF); //2's complement + *z = -(*z); + } + } + break; + case 0x40: //high-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_HPF_L, xyz, 6)) == 0){ + *x = ((int)xyz[0]) >> 4; + *x = *x + (((int)xyz[1]) << 4); + x_sign = *x >> 11; //1 = negative; 0 = positive + if (x_sign == 1){ + *x = ((~(*x) + 0x01) & 0x0FFF); //2's complement + *x = -(*x); + } + *y = ((int)xyz[2]) >> 4; + *y = *y + (((int)xyz[3]) << 4); + y_sign = *y >> 11; //1 = negative; 0 = positive + if (y_sign == 1){ + *y = ((~(*y) + 0x01) & 0x0FFF); //2's complement + *y = -(*y); + } + *z = ((int)xyz[4]) >> 4; + *z = *z + (((int)xyz[5]) << 4); + z_sign = *z >> 11; //1 = negative; 0 = positive + if (z_sign == 1){ + *z = ((~(*z) + 0x01) & 0x0FFF); //2's complement + *z = -(*z); + } + } + break; + } + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_read_HPF_g +DESCRIPTION: This function reads the G(gravity force) values on the X, Y, and Z axes. + The units used are milli-g's, or 1/1000*G. +ARGUMENTS PASSED: gx, gy, and gz pointers +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: gx, gy, and gz are assigned +==================================================================================================*/ +int KXTF9_read_HPF_g(int* gx, int* gy, int* gz) +{ + int status; + int x,y,z; + int x_sign, y_sign, z_sign; + int sensitivity; + char xyz[6] = {0, 0, 0, 0, 0, 0}; + char Res = 0; + char G_range = 0; + int range = 0; + if (device == 0){ //KXTE9 + return 1; + } + //determine if in the low resolution or high resolution state + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &Res, 1) == 0){ + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &G_range, 1) == 0){ + G_range = G_range & 0x18; + G_range = G_range >> 3; + switch(G_range){ + case 0: + range = 2; + break; + case 1: + range = 4; + break; + case 2: + range = 8; + break; + default: + break; + } + Res = Res & 0x40; + switch(Res){ + case 0x00: //low-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_HPF_L, xyz, 6)) == 0){ + x = ((int)xyz[1]); + x_sign = x >> 7; //1 = negative; 0 = positive + if (x_sign == 1){ + x = ((~(x) + 0x01) & 0x0FF); + x = -(x); + } + y = ((int)xyz[3]); + y_sign = y >> 7; //1 = negative; 0 = positive + if (y_sign == 1){ + y = ((~(y) + 0x01) & 0x0FF); //2's complement + y = -(y); + } + z = ((int)xyz[5]); + z_sign = z >> 7; //1 = negative; 0 = positive + if (z_sign == 1){ + z = ((~(z) + 0x01) & 0x0FF); //2's complement + z = -(z); + } + sensitivity = (256)/(2*range); + /* calculate milli-G's */ + *gx = 1000 * (x) / sensitivity; + *gy = 1000 * (y) / sensitivity; + *gz = 1000 * (z) / sensitivity; + } + break; + case 0x40: //high-resolution state + if ((status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_XOUT_HPF_L, xyz, 6)) == 0){ + x = ((int)xyz[0]) >> 4; + x = x + (((int)xyz[1]) << 4); + x_sign = x >> 11; //1 = negative; 0 = positive + if (x_sign == 1){ + x = ((~(x) + 0x01) & 0x0FFF); //2's complement + x = -(x); + } + y = ((int)xyz[2]) >> 4; + y = y + (((int)xyz[3]) << 4); + y_sign = y >> 11; //1 = negative; 0 = positive + if (y_sign == 1){ + y = ((~(y) + 0x01) & 0x0FFF); //2's complement + y = -(y); + } + z = ((int)xyz[4]) >> 4; + z = z + (((int)xyz[5]) << 4); + z_sign = z >> 11; //1 = negative; 0 = positive + if (z_sign == 1){ + z = ((~(z) + 0x01) & 0x0FFF); //2's complement + z = -(z); + } + sensitivity = (4096)/(2*range); + /* calculate milli-G's */ + *gx = 1000 * (x) / sensitivity; + *gy = 1000 * (y) / sensitivity; + *gz = 1000 * (z) / sensitivity; + } + break; + default: + break; + } + } + else status = 1; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_read_current_odr_tilt +DESCRIPTION: This function reads the current ODR of the tilt function. +ARGUMENTS PASSED: ODR_rate_tilt pointer +RETURN VALUE: 0 = ODR set correctly; 1 = ODR invalid +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: ODR_rate_tilt is assigned +==================================================================================================*/ +int KXTF9_read_current_odr_tilt(double* ODR_rate_tilt) +{ + int status; + char ctrl_reg; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctrl_reg, 1) == 0){ + ctrl_reg &= 0x60; + ctrl_reg >>= 5; + switch (ctrl_reg){ + case 0: + *ODR_rate_tilt = 1.6; + status = 0; + break; + case 1: + *ODR_rate_tilt = 6.3; + status = 0; + break; + case 2: + *ODR_rate_tilt = 12.5; + status = 0; + break; + case 3: + *ODR_rate_tilt = 50; + status = 0; + break; + default: + status = 1; + break; + } + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_read_current_odr_tap +DESCRIPTION: This function reads the current ODR of the tap double tap function. +ARGUMENTS PASSED: ODR_rate_tap pointer +RETURN VALUE: 0 = ODR set correctly; 1 = ODR invalid +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: ODR_rate_tap is assigned +==================================================================================================*/ +int KXTF9_read_current_odr_tap(double* ODR_rate_tap) +{ + int status; + char ctrl_reg; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctrl_reg, 1) == 0){ + ctrl_reg &= 0x0C; + ctrl_reg >>= 2; + switch (ctrl_reg){ + case 0: + *ODR_rate_tap = 50; + status = 0; + break; + case 1: + *ODR_rate_tap = 100; + status = 0; + break; + case 2: + *ODR_rate_tap = 200; + status = 0; + break; + case 3: + *ODR_rate_tap = 400; + status = 0; + break; + default: + status = 1; + break; + } + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_read_tap_direction +DESCRIPTION: This function reads INT_SRC_REG1 to determine which axis and in which direction + a tap or double tap event occurred. +ARGUMENTS PASSED: int_src_reg1 pointer +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: int_src_reg1 is assigned +==================================================================================================*/ +int KXTF9_read_tap_direction(char* int_src_reg1) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + status = KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG1, int_src_reg1, 1); + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_int_alt_disable +DESCRIPTION: This function disables the alternate unlatched response for the physical + interrupt pin. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Alternate unlatched response for physical interrupt disabled +==================================================================================================*/ +int KXTF9_int_alt_disable(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + UNSET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_ULMB); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_int_alt_enable +DESCRIPTION: This function enables the alternate unlatched response for the physical + interrupt pin. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Alternate unlatched response for physical interrupt enabled +==================================================================================================*/ +int KXTF9_int_alt_enable(void) +{ + char int_ctrl_reg1 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG1, &int_ctrl_reg1, 1) == 0){ + SET_REG_BIT(int_ctrl_reg1, KXTF9_INT_CTRL_REG1_ULMB); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG1, int_ctrl_reg1); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_timer +DESCRIPTION: This function defines the minimum separation between the first and second + taps in a double tap event. +ARGUMENTS PASSED: tdt_timer; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Double tap minimum separation set according to tdt_timer +IMPORTANT NOTES: Default: 0.3s (0x78h) +==================================================================================================*/ +int KXTF9_tdt_timer(int tdt_timer) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_TIMER, tdt_timer) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_h_thresh +DESCRIPTION: This function defines the upper limit for the jerk threshold. +ARGUMENTS PASSED: tdt_h_thresh; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Upper tap threshold set according to tdt_h_thresh +IMPORTANT NOTES: Default: 14j (0xB6h) +==================================================================================================*/ +int KXTF9_tdt_h_thresh(int tdt_h_thresh) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_H_THRESH, tdt_h_thresh) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_l_thresh +DESCRIPTION: This function defines the lower limit for the jerk threshold. +ARGUMENTS PASSED: tdt_l_thresh; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Lower tap threshold set according to tdt_l_thresh +IMPORTANT NOTES: Default: 1j (0x1Ah) +==================================================================================================*/ +int KXTF9_tdt_l_thresh(int tdt_l_thresh) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_L_THRESH, tdt_l_thresh) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_tap_timer +DESCRIPTION: This function defines the minimum and maximum pulse width for the tap event. +ARGUMENTS PASSED: tdt_tap_timer; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Tap timer set according to tdt_tap_timer +IMPORTANT NOTES: Default: 0.005s lower limit, 0.05s upper limit (0xA2h) +==================================================================================================*/ +int KXTF9_tdt_tap_timer(int tdt_tap_timer) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_TAP_TIMER, tdt_tap_timer) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_total_timer +DESCRIPTION: This function defines the amount of time that two taps in a double tap event + can be avove the PI threshold. +ARGUMENTS PASSED: tdt_total_timer; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Total timer set according to tdt_total_timer +IMPORTANT NOTES: Default: 0.09s (0x24h) +==================================================================================================*/ +int KXTF9_tdt_total_timer(int tdt_total_timer) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_TOTAL_TIMER, tdt_total_timer) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_latency_timer +DESCRIPTION: This function defines the total amount of time that the tap algorithm will + count samples that are above the PI threshold. +ARGUMENTS PASSED: tdt_latency_timer; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Latency timer set according to tdt_latency_timer +IMPORTANT NOTES: Default: 0.1s (0x28h) +==================================================================================================*/ +int KXTF9_tdt_latency_timer(int tdt_latency_timer) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_LATENCY_TIMER, tdt_latency_timer) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tdt_window_timer +DESCRIPTION: This function defines the time window for the entire tap event, + single or double, to occur. +ARGUMENTS PASSED: tdt_window_timer; 0-255 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Window timer set according to tdt_window_timer +IMPORTANT NOTES: Default: 0.4s (0xA0h) +==================================================================================================*/ +int KXTF9_tdt_window_timer(int tdt_window_timer) +{ + int status; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_write_byte(KXTF9_I2C_TDT_WINDOW_TIMER, tdt_window_timer) == 0){ + status = 0; + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_TFU +DESCRIPTION: This function masks Z+ (face up) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Z+ tap masked +==================================================================================================*/ +int KXTF9_tap_mask_TFU(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + SET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TFUM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_TFU +DESCRIPTION: This function unmasks Z+ (face up) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Z+ tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_TFU(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + UNSET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TFUM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_TFD +DESCRIPTION: This function masks Z- (face down) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Z- tap masked +==================================================================================================*/ +int KXTF9_tap_mask_TFD(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + SET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TFDM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_TFD +DESCRIPTION: This function unmasks Z- (face down) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Z- tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_TFD(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + UNSET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TFDM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_TUP +DESCRIPTION: This function masks Y+ (up) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Y+ tap masked +==================================================================================================*/ +int KXTF9_tap_mask_TUP(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + SET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TUPM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_TUP +DESCRIPTION: This function unmasks Y+ (up) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Y+ tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_TUP(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + UNSET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TUPM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_TDO +DESCRIPTION: This function masks Y- (down) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Y- tap masked +==================================================================================================*/ +int KXTF9_tap_mask_TDO(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + SET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TDOM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_TDO +DESCRIPTION: This function unmasks Y- (down) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Y- tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_TDO(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + UNSET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TDOM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_TRI +DESCRIPTION: This function masks X+ (right) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: X+ tap masked +==================================================================================================*/ +int KXTF9_tap_mask_TRI(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + SET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TRIM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_TRI +DESCRIPTION: This function unmasks X+ (right) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: X+ tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_TRI(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + UNSET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TRIM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_TLE +DESCRIPTION: This function masks X- (left) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: X- tap masked +==================================================================================================*/ +int KXTF9_tap_mask_TLE(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + SET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TLEM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_TLE +DESCRIPTION: This function unmasks X- (left) tap. +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: X- tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_TLE(void) +{ + char ctrl_reg3 = 0; + int status = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_CTRL_REG3, &ctrl_reg3, 1) == 0){ + UNSET_REG_BIT(ctrl_reg3, INT_CTRL_REG3_TLEM); + KIONIX_ACCEL_write_byte(KXTF9_I2C_INT_CTRL_REG3, ctrl_reg3); + } + else status = 1; + return status; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_mask_all_direction +DESCRIPTION: +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: All direction tap masked +==================================================================================================*/ +int KXTF9_tap_mask_all_direction(void) +{ + int res=0; + + res |= KXTF9_tap_mask_TFU(); // Z+ + res |= KXTF9_tap_mask_TFD(); // Z- + res |= KXTF9_tap_mask_TUP(); // Y+ + res |= KXTF9_tap_mask_TDO(); // Y- + res |= KXTF9_tap_mask_TRI(); // X+ + res |= KXTF9_tap_mask_TLE(); // X- + + return res; +} +/*================================================================================================== +FUNCTION: KXTF9_tap_unmask_all_direction +DESCRIPTION: +ARGUMENTS PASSED: None +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: All direction tap unmasked +==================================================================================================*/ +int KXTF9_tap_unmask_all_direction(void) +{ + int res=0; + + res |= KXTF9_tap_unmask_TFU(); // Z+ + res |= KXTF9_tap_unmask_TFD(); // Z- + res |= KXTF9_tap_unmask_TUP(); // Y+ + res |= KXTF9_tap_unmask_TDO(); // Y- + res |= KXTF9_tap_unmask_TRI(); // X+ + res |= KXTF9_tap_unmask_TLE(); // X- + + return res; +} +/*================================================================================================== +FUNCTION: KXTF9_set_odr_tap +DESCRIPTION: This function sets the ODR frequency for the Direction Tap function. +ARGUMENTS PASSED: frequency variable; 50, 100, 200 or 400 +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: ODR is set for Direction Tap function according to frequency +==================================================================================================*/ +int KXTF9_set_odr_tap(int frequency) +{ + char ctlreg_3 = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctlreg_3, 1) != 0){ + return 1; + } + switch (frequency){ + case 50: /* set all ODR's to 50Hz */ + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTA); + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTB); + break; + case 100: /* set all ODR's to 100Hz */ + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTA); + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTB); + break; + case 200: /* set all ODR's to 200Hz */ + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTA); + UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTB); + break; + case 400: /* set all ODR's to 400Hz */ + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTA); + SET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTB); + break; + default: + return 1; + } + KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3); + return 0; +} + +/*================================================================================================== +FUNCTION: KXTF9_set_hpf_odr +DESCRIPTION: This function sets the high pass filter roll off frequency for the accelerometer outputs. +ARGUMENTS PASSED: frequency, where roll_off_frequency = ODR/alpha; alpha = (50, 100, 200, 400) +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: High pass filter roll off is set according to frequency +==================================================================================================*/ +int KXTF9_set_hpf_odr(int frequency) +{ + char data_ctrl_reg = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_DATA_CTRL_REG, &data_ctrl_reg, 1) != 0){ + return 1; + } + switch (frequency){ + case 50: /* set tap ODR to 50Hz */ + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROA); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROB); + break; + case 100: /* set tap ODR to 100 Hz */ + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROA); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROB); + break; + case 200: /* set tap ODR to 200 Hz */ + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROA); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROB); + break; + case 400: /* set tap ODR to 400 Hz */ + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROA); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_HPFROB); + break; + default: + return 1; + } + KIONIX_ACCEL_write_byte(KXTF9_I2C_DATA_CTRL_REG, data_ctrl_reg); + return 0; +} +/*================================================================================================== +FUNCTION: KXTF9_set_lpf_odr +DESCRIPTION: This function sets the low pass filter roll off for the accelerometer outputs. +ARGUMENTS PASSED: roll off frequency (6, 12, 25, 50, 100, 200, 400) +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Low pass filter roll off is set according to frequency +==================================================================================================*/ +int KXTF9_set_lpf_odr(int frequency) +{ + char data_ctrl_reg = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_DATA_CTRL_REG, &data_ctrl_reg, 1) != 0){ + return 1; + } + switch (frequency){ + case 6: /* set LPF rolloff to 6.25Hz */ + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + case 12: /* set LPF rolloff to 12.5Hz */ + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + case 25: /* set LPF rolloff to 25Hz */ + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + case 50: /* set LPF rolloff to 50Hz */ + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + case 100: /* set LPF rolloff to 100Hz */ + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + case 200: /* set LPF rolloff to 200 Hz */ + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + case 400: /* set LPF rolloff to 400 Hz */ + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAA); + SET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAB); + UNSET_REG_BIT(data_ctrl_reg, DATA_CTRL_REG_OSAC); + break; + default: + return 1; + } + KIONIX_ACCEL_write_byte(KXTF9_I2C_DATA_CTRL_REG, data_ctrl_reg); + return 0; +} +/*================================================================================================== +FUNCTION: KXTF9_set_resolution +DESCRIPTION: This function sets the resolution of the accelerometer outputs. +ARGUMENTS PASSED: resolution (8-bit or 12-bit) +RETURN VALUE: 0 = pass; 1 = fail +PRE-CONDITIONS: KIONIX_ACCEL_init() has been called +POST-CONDITIONS: Accelerometer resolution is set according to resolution +==================================================================================================*/ +int KXTF9_set_resolution(int resolution) +{ + char ctrl_reg1 = 0; + if (device == 0){ //KXTE9 + return 1; + } + if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctrl_reg1, 1) != 0){ + return 1; + } + switch (resolution){ + case 8: /* set resolution to 8 bits */ + UNSET_REG_BIT(ctrl_reg1, CTRL_REG1_RES); + break; + case 12: /* set resolution to 12 bits */ + SET_REG_BIT(ctrl_reg1, CTRL_REG1_RES); + break; + default: + return 1; + } + return 0; +} + + + +//************************************************************* +// KIONIX_SHAKE_Init +// - initializes the shake detection engine +// params +// - shake_data* data = engine data +// return +// - none +//************************************************************* +void KIONIX_SHAKE_Init(shake_data* data) +{ + // init thresholds (convert ms to counts) + data->maxDuration = CONFIG_DURATION / (1000 / CONFIG_RATE); + data->maxDelay = CONFIG_DELAY / (1000 / CONFIG_RATE); + data->maxTimeout = CONFIG_TIMEOUT / (1000 / CONFIG_RATE); + + // init timers + data->cntDuration = 0; + data->cntDelay = 0; + data->cntTimeout = 0; + + // init counters + data->cntShake = 0; + data->cntInvalid = 0; +} + + +//************************************************************* +// KIONIX_SHAKE_Update +// - updates the shake detection engine +// - maintains current shake count +// - NOTE: must be called at a fixed interval +// params +// - shake_data* data = engine data +// - long val = (x^2 + y^2 + z^2) / 1000 +// return +// - long = current shake count +//************************************************************* +long KIONIX_SHAKE_Update(shake_data* data, long val) +{ + // possible shake... + if (val > CONFIG_THRESHOLD) + { + // if the delay timer has started & + // not yet expired -> flag invalid + if (data->cntDelay > 0) + data->cntInvalid = 1; + + // inc duration + data->cntDuration += 1; + + // reset delay & timeout + data->cntDelay = data->maxDelay; + data->cntTimeout = data->maxTimeout; + + return 0; + } + + // shake detected... + if ((data->cntDuration >= 2) && + (data->cntDuration <= data->maxDuration)) + { + // add valid shakes to the count + if (data->cntInvalid == 0) + data->cntShake += 1; + } + + // flag valid & reset duration + data->cntInvalid = 0; + data->cntDuration = 0; + + // dec delay & timeout (if necessary) + data->cntDelay -= (data->cntDelay > 0 ? 1 : 0); + data->cntTimeout -= (data->cntTimeout > 0 ? 1 : 0); + + // reset shake count after timeout + if (data->cntTimeout <= 0) + { + data->cntShake = 0; + data->cntDelay = 0; + data->cntTimeout = 0; + } + + return data->cntShake; +} + + +#ifdef __cplusplus +} +#endif -- cgit v1.2.3