aboutsummaryrefslogtreecommitdiff
path: root/modules/libjoy/caanoo
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libjoy/caanoo')
-rw-r--r--modules/libjoy/caanoo/i2c-dev.h342
-rw-r--r--modules/libjoy/caanoo/te9_tf9_hybrid_driver.c3301
-rw-r--r--modules/libjoy/caanoo/te9_tf9_hybrid_driver.h466
3 files changed, 4109 insertions, 0 deletions
diff --git a/modules/libjoy/caanoo/i2c-dev.h b/modules/libjoy/caanoo/i2c-dev.h
new file mode 100644
index 0000000..91bd001
--- /dev/null
+++ b/modules/libjoy/caanoo/i2c-dev.h
@@ -0,0 +1,342 @@
+/*
+ i2c-dev.h - i2c-bus driver, char device interface
+
+ Copyright (C) 1995-97 Simon G. Vogl
+ Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+/* $Id: i2c-dev.h 5164 2008-03-26 13:48:21Z khali $ */
+
+#ifndef LIB_I2CDEV_H
+#define LIB_I2CDEV_H
+
+#include <linux/types.h>
+#include <sys/ioctl.h>
+
+
+/* -- i2c.h -- */
+
+
+/*
+ * I2C Message - used for pure i2c transaction, also from /dev interface
+ */
+#if 1
+struct i2c_msg {
+ __u16 addr; /* slave address */
+ unsigned short flags;
+#define I2C_M_TEN 0x10 /* we have a ten bit chip address */
+#define I2C_M_RD 0x01
+#define I2C_M_NOSTART 0x4000
+#define I2C_M_REV_DIR_ADDR 0x2000
+#define I2C_M_IGNORE_NAK 0x1000
+#define I2C_M_NO_RD_ACK 0x0800
+ short len; /* msg length */
+ char *buf; /* pointer to msg data */
+};
+#endif
+
+/* To determine what functionality is present */
+
+#define I2C_FUNC_I2C 0x00000001
+#define I2C_FUNC_10BIT_ADDR 0x00000002
+#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
+#define I2C_FUNC_SMBUS_PEC 0x00000008
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_QUICK 0x00010000
+#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000
+#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000
+#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000
+#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */
+
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
+ I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2)
+
+/* Old name, for compatibility */
+#define I2C_FUNC_SMBUS_HWPEC_CALC I2C_FUNC_SMBUS_PEC
+
+/*
+ * Data for SMBus Messages
+ */
+#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
+#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */
+#if 1
+union i2c_smbus_data {
+ __u8 byte;
+ __u16 word;
+ __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+ /* and one more for PEC */
+};
+#endif
+
+/* smbus_access read or write markers */
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE 0
+
+/* SMBus transaction types (size parameter in the above functions)
+ Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
+#define I2C_SMBUS_QUICK 0
+#define I2C_SMBUS_BYTE 1
+#define I2C_SMBUS_BYTE_DATA 2
+#define I2C_SMBUS_WORD_DATA 3
+#define I2C_SMBUS_PROC_CALL 4
+#define I2C_SMBUS_BLOCK_DATA 5
+#define I2C_SMBUS_I2C_BLOCK_BROKEN 6
+#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+#define I2C_SMBUS_I2C_BLOCK_DATA 8
+
+
+/* ----- commands for the ioctl like i2c_command call:
+ * note that additional calls are defined in the algorithm and hw
+ * dependent layers - these can be listed here, or see the
+ * corresponding header files.
+ */
+ /* -> bit-adapter specific ioctls */
+#define I2C_RETRIES 0x0701 /* number of times a device address */
+ /* should be polled when not */
+ /* acknowledging */
+#define I2C_TIMEOUT 0x0702 /* set timeout - call with int */
+
+
+/* this is for i2c-dev.c */
+#define I2C_SLAVE 0x0703 /* Change slave address */
+ /* Attn.: Slave address is 7 or 10 bits */
+#define I2C_SLAVE_FORCE 0x0706 /* Change slave address */
+ /* Attn.: Slave address is 7 or 10 bits */
+ /* This changes the address, even if it */
+ /* is already taken! */
+#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
+
+#define I2C_FUNCS 0x0705 /* Get the adapter functionality */
+#define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
+#define I2C_PEC 0x0708 /* != 0 for SMBus PEC */
+
+#define I2C_SMBUS 0x0720 /* SMBus-level access */
+
+/* -- i2c.h -- */
+
+
+/* Note: 10-bit addresses are NOT supported! */
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+ char read_write;
+ __u8 command;
+ int size;
+ union i2c_smbus_data *data;
+};
+
+/* This is the structure as used in the I2C_RDWR ioctl call */
+struct i2c_rdwr_ioctl_data {
+ struct i2c_msg *msgs; /* pointers to i2c_msgs */
+ int nmsgs; /* number of i2c_msgs */
+};
+
+
+static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
+ int size, union i2c_smbus_data *data)
+{
+ struct i2c_smbus_ioctl_data args;
+
+ args.read_write = read_write;
+ args.command = command;
+ args.size = size;
+ args.data = data;
+ return ioctl(file,I2C_SMBUS,&args);
+}
+
+
+static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
+{
+ return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
+}
+
+static inline __s32 i2c_smbus_read_byte(int file)
+{
+ union i2c_smbus_data data;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
+ return -1;
+ else
+ return 0x0FF & data.byte;
+}
+
+static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
+{
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
+ I2C_SMBUS_BYTE,NULL);
+}
+
+static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
+{
+ union i2c_smbus_data data;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_BYTE_DATA,&data))
+ return -1;
+ else
+ return 0x0FF & data.byte;
+}
+
+static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
+ __u8 value)
+{
+ union i2c_smbus_data data;
+ data.byte = value;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BYTE_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
+{
+ union i2c_smbus_data data;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_WORD_DATA,&data))
+ return -1;
+ else
+ return 0x0FFFF & data.word;
+}
+
+static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
+ __u16 value)
+{
+ union i2c_smbus_data data;
+ data.word = value;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_WORD_DATA, &data);
+}
+
+static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
+{
+ union i2c_smbus_data data;
+ data.word = value;
+ if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_PROC_CALL,&data))
+ return -1;
+ else
+ return 0x0FFFF & data.word;
+}
+
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
+ __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ I2C_SMBUS_BLOCK_DATA,&data))
+ return -1;
+ else {
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > 32)
+ length = 32;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BLOCK_DATA, &data);
+}
+
+/* Returns the number of read bytes */
+/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
+ ask for less than 32 bytes, your code will only work with kernels
+ 2.6.23 and later. */
+static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+
+ if (length > 32)
+ length = 32;
+ data.block[0] = length;
+ if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
+ length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
+ I2C_SMBUS_I2C_BLOCK_DATA,&data))
+ return -1;
+ else {
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+ }
+}
+
+static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > 32)
+ length = 32;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
+}
+
+/* Returns the number of read bytes */
+static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
+ __u8 length, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > 32)
+ length = 32;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
+ I2C_SMBUS_BLOCK_PROC_CALL,&data))
+ return -1;
+ else {
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+ }
+}
+
+
+#endif /* LIB_I2CDEV_H */
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<length; i++)
+ Rd24C080((U32)KIONIX_ACCEL_I2C_SLV_ADDR, (U32)reg+i, &data[i]);
+ #elif defined(USE_I2C_POLL)
+ for(i=0; i<length; i++)
+ _Rd24C080((U32)KIONIX_ACCEL_I2C_SLV_ADDR, (U32)reg+i, &data[i]);
+ #endif
+#endif
+ KIONIX_LeaveCriticalSection(&tf9_crit_sect);
+ return 0;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_write_byte
+DESCRIPTION: This function writes a byte of data to the Kionix accelerometer.
+ARGUMENTS PASSED: register address, data variable
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: None
+IMPORTANT NOTES: Using the i2c_smbus_write_byte_data function requires the inclusion of
+ the i2c-dev.h file available in the lm-sensors package.
+==================================================================================================*/
+int KIONIX_ACCEL_write_byte(int reg, int data)
+{
+ int res=0;
+ KIONIX_EnterCriticalSection(&tf9_crit_sect);
+
+#ifdef KX_PLATFORM_LINUX
+ res = i2c_smbus_write_byte_data(fd, reg, data);
+
+#elif defined(KX_PLATFORM_WIN32) || defined(KX_PLATFORM_WINCE)
+
+#elif defined(KX_PLATFORM_REX)
+ res = accel_i2c_write(KIONIX_ACCEL_I2C_SLV_ADDR, reg, &data, 1);
+
+#elif defined(KX_PLATFORM_FIRMWARE)
+ #ifdef USE_I2C_GPIO
+ {
+ unsigned char wb[2], rb[2];
+ wb[0] = reg; wb[1] = data;
+ i2c_write(KIONIX_ACCEL_I2C_SLV_ADDR, wb, 2);
+ }
+ #elif defined(USE_I2C_INT)
+ Wr24C080((U32)KIONIX_ACCEL_I2C_SLV_ADDR, (U32)reg, data);
+ #elif defined(USE_I2C_POLL)
+ _Wr24C080((U32)KIONIX_ACCEL_I2C_SLV_ADDR, (U32)reg, data);
+ #endif
+#endif
+ if(res < 0){
+ //printf("Write failed on register 0x%02x with data 0x%02x\n", reg, data);
+ KIONIX_LeaveCriticalSection(&tf9_crit_sect);
+ return 1;
+ }
+ KIONIX_LeaveCriticalSection(&tf9_crit_sect);
+ return res;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_get_device_type
+DESCRIPTION: This function return the Kionix accelerometer device type
+ARGUMENTS PASSED: None
+RETURN VALUE: -1 = fail; 0: TE9; 1: TF9; 2: SD9
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: None
+IMPORTANT NOTES:
+==================================================================================================*/
+int KIONIX_ACCEL_get_device_type(void)
+{
+ return device;
+}
+
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_deinit
+DESCRIPTION: This function de-initializes the Kionix accelerometer.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: None
+POST-CONDITIONS: Acceleration data outputs are disabled
+==================================================================================================*/
+int KIONIX_ACCEL_deinit(void)
+{
+ int res=0;
+
+ res = KIONIX_ACCEL_disable_outputs();
+ KIONIX_ACCEL_disable_interrupt();
+ res |= KIONIX_ACCEL_disable_all();
+ res |= KIONIX_ACCEL_sleep();
+ KIONIX_DeleteCriticalSection(&tf9_crit_sect);
+
+ return res;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_init
+DESCRIPTION: This function initializes the Kionix accelerometer.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: None
+POST-CONDITIONS: Acceleration data outputs are enabled
+==================================================================================================*/
+int KIONIX_ACCEL_init(void)
+{
+ int ctlreg_1 = 0;
+ int ctlreg_3 = 0;
+ int status = 0;
+ char who_am_i = 0;
+ long funcs = 0;
+#ifdef KX_PLATFORM_LINUX
+ //open i2c adapter; included checks for adapters 1, 2, and 3, but could be 0-255
+#if 0
+ fd = open("/dev/i2c-2", O_RDWR);
+ if (fd == -1){
+ fd = open("/dev/i2c-1", O_RDWR);
+ if (fd == -1){
+ fd = open("/dev/i2c-3", O_RDWR);
+ if (fd == -1){
+ printf("Error opening adapter\n");
+ exit(1);
+ }
+ }
+ }
+#else
+ fd = open("/dev/i2c-0", O_RDWR);
+ if (fd == -1){
+ printf("Error opening adapter\n");
+ return 1;
+ }
+#endif
+ //set slave address for i2c adapter
+ if (ioctl(fd, I2C_SLAVE, KIONIX_ACCEL_I2C_SLV_ADDR) < 0){
+ printf("Failed to set slave address\n");
+ exit(1);
+ }
+ printf("set slave address success...\n");
+
+ //i2c block functionality check
+ if (ioctl(fd, I2C_FUNCS, &funcs) < 0){
+ printf("I2C adapter failed functionality check\n");
+ }
+ printf("check functionality... ok\n");
+
+ if (! (funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)){
+ printf("I2C block read function not available; using byte reads\n");
+ block = 0;
+ }
+ else {
+ printf("I2C Block read function success... using block reads\n");
+ block = 1;
+ }
+ fflush(stdout);
+#endif // #if defined(KX_PLATFORM_LINUX)
+ KxMSleep(50); //wait 50ms
+ KIONIX_InitializeCriticalSection(&tf9_crit_sect);
+
+ //determine what hardware is included by reading the WHO_AM_I register
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_WHO_AM_I, &who_am_i, 1) == 0){
+ switch(who_am_i){
+ //KXTF9 initialization
+ case 0x01:
+ case 0x4E:
+ KxPrint("[%d] found Device ID to(0x%x) \n", __LINE__, who_am_i );
+ KxPrint("Initializing device: KXTF9\n");
+ device = 1;
+
+ status |= KXTF9_set_G_range(2);
+ status |= KXTF9_set_resolution(12);
+ status |= KXTF9_set_odr_tap(400);
+ status |= KXTF9_set_odr_tilt(12);
+ status |= KIONIX_ACCEL_set_odr_motion(50);
+ status |= KIONIX_ACCEL_int_activeh();
+ status |= KIONIX_ACCEL_int_latch();
+ status |= KIONIX_ACCEL_disable_all();
+
+ break;
+
+ //KXTE9 initialization
+ case 0x00:
+ KxPrint("[%d] found Device ID to(0x%x) \n", __LINE__, who_am_i );
+ KxPrint("Initializing device: KXTE9\n" );
+ device = 0;
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_PC1); /* disable accelerometer outputs */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRA); /* set ODR to 40 Hz */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRB);
+
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_TPE); /* disable the tilt position function */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_WUFE);/* disable wake up function */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_B2SE);/* disable back to sleep function */
+ KIONIX_ACCEL_write_byte(0x3E, 0xCA); /* allow write access to threshold registers */
+ /* this correction has been made in R1V6 ASIC */
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1) == 0){
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB); /* set ODR to 40 Hz for B2S and WUF engines*/
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SA);
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3) == 0){
+ if (KIONIX_ACCEL_tilt_timer(20) == 0){
+ if (KIONIX_ACCEL_wuf_timer(4) == 0){
+ if (KXTE9_b2s_timer(3) == 0){
+ if (KIONIX_ACCEL_wuf_thresh(16) == 0){
+ status = 0;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ KIONIX_ACCEL_write_byte(0x3E, 0x00); /* block write access to threshold registers */
+ break;
+ default:
+ KxPrint("[%d] found Device ID to(0x%x) \n", __LINE__, who_am_i );
+ status = 1;
+ break;
+ }
+ }
+ else {
+ KxPrint("-E- can't reading the WHO_AM_I register\n");
+ status = 1;
+ }
+
+ return status;
+#if 0
+
+ int ctlreg_1 = 0;
+ int ctlreg_3 = 0;
+ int status = 0;
+ char who_am_i = 0;
+ long funcs = 0;
+ //open i2c adapter; included checks for adapters 1, 2, and 3, but could be 0-255
+ fd = open("/dev/i2c-2", O_RDWR);
+ if (fd == -1){
+ fd = open("/dev/i2c-1", O_RDWR);
+ if (fd == -1){
+ fd = open("/dev/i2c-3", O_RDWR);
+ if (fd == -1){
+ printf("Error opening adapter\n");
+ exit(1);
+ }
+ }
+ }
+ //set slave address for i2c adapter
+ if (ioctl(fd, I2C_SLAVE, KIONIX_ACCEL_I2C_SLV_ADDR) < 0){
+ printf("Failed to set slave address\n");
+ exit(1);
+ }
+ //i2c block functionality check
+ if (ioctl(fd, I2C_FUNCS, &funcs) < 0){
+ printf("I2C adapter failed functionality check\n");
+ }
+ if (! (funcs & I2C_FUNC_SMBUS_READ_I2C_BLOCK)){
+ printf("I2C block read function not available; using byte reads\n");
+ block = 0;
+ }
+ else block = 1;
+
+ //determine what hardware is included by reading the WHO_AM_I register
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_WHO_AM_I, &who_am_i, 1) == 0){
+ switch(who_am_i){
+ //KXTF9 initialization
+ case 0x4E:
+ printf("Initializing device: KXTF9\n");
+ device = 1;
+
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_PC1); /* disable accelerometer outputs */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_RES); /* place accelerometer in 8-bit mode */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_DRDYE); /* disable the availability of new acceleration data */
+ /* to be reflected on the interrupt pin*/
+ //set the sensor to +/-2g range
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL1); /* bit for setting g range */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_GSEL0); /* bit for setting g range */
+
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_TPE); /* disable the tilt position function */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_WUFE); /* disable wake up function */
+
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1) == 0){
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTA); /* set ODR to 400 Hz for tap double tap function */
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OTDTB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OTPA); /* set ODR to 12.5 Hz for tilt position function */
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OTPB);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA); /* set ODR for general motion detection function */
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB); /* and high pass filtered outputs to 50 Hz */
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3) == 0){
+ //write Kionix recommended values for best performance
+ if (KIONIX_ACCEL_tilt_timer(6) == 0){
+ if (KIONIX_ACCEL_wuf_timer(4) == 0){
+
+ status = 0;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+
+ break;
+
+ //KXTE9 initialization
+ case 0x00:
+ printf("Initializing device: KXTE9\n");
+ device = 0;
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_PC1); /* disable accelerometer outputs */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRA); /* set ODR to 40 Hz */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRB);
+
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_TPE); /* disable the tilt position function */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_WUFE);/* disable wake up function */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_B2SE);/* disable back to sleep function */
+ KIONIX_ACCEL_write_byte(0x3E, 0xCA); /* allow write access to threshold registers */
+ /* this correction has been made in R1V6 ASIC */
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1) == 0){
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB); /* set ODR to 40 Hz for B2S and WUF engines*/
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SA);
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3) == 0){
+ if (KIONIX_ACCEL_tilt_timer(20) == 0){
+ if (KIONIX_ACCEL_wuf_timer(4) == 0){
+ if (KXTE9_b2s_timer(3) == 0){
+ if (KIONIX_ACCEL_wuf_thresh(16) == 0){
+ status = 0;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ }
+ else status = 1;
+ KIONIX_ACCEL_write_byte(0x3E, 0x00); /* block write access to threshold registers */
+ break;
+ default:
+ status = 1;
+ break;
+ }
+ }
+ else status = 1;
+ KIONIX_ACCEL_enable_outputs(); /* enable acceleration data output */
+ return status;
+#endif
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_isr
+DESCRIPTION: This function is the interrupt service routine for the accelerometer.
+ARGUMENTS PASSED: None
+RETURN VALUE: None
+PRE-CONDITIONS: None
+POST-CONDITIONS: None
+IMPORTANT NOTES: Called from interrupt context, so do NOT do any i2c operations!
+==================================================================================================*/
+void KIONIX_ACCEL_isr(void)
+{
+#ifdef KX_PLATFORM_REX
+ #if 0
+ extern SU_TASK_HANDLE accel_task_handle;
+ // disable accelerometer interrupt first
+ KIONIX_ACCEL_disable_interrupt();
+ // Set event to handle interrupt
+ suSetEventMask(accel_task_handle, ACCEL_EVENT_INTERRUPT, NULL);
+ // enable accelerometer interrupt again
+ KIONIX_ACCEL_enable_interrupt();
+ #else
+ // disable accelerometer interrupt first
+ KIONIX_ACCEL_disable_interrupt();
+ // Set event to handle interrupt
+ rex_set_sigs( &accel_tcb, SKY_ACCEL_ISR_SIG ); /* Signal a queue event */
+ // TODO : Interrupt enable in SKY_ACCEL_ISR_SIG signal routine after process interrupt.
+ #endif
+#endif
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_enable_interrupt
+DESCRIPTION: This function enables the interrupt for the accelerometer.
+ARGUMENTS PASSED: None
+RETURN VALUE: None
+PRE-CONDITIONS: None
+POST-CONDITIONS: None
+IMPORTANT NOTES: Called from interrupt context, so do NOT do any i2c operations!
+==================================================================================================*/
+void KIONIX_ACCEL_enable_interrupt(void)
+{
+ // set up interrupt for rising edge detection
+#ifdef KX_PLATFORM_REX
+ // set up interrupt for rising edge detection
+// gpio_int_set_detect((gpio_int_type)ACCEL_GPIO_INT, DETECT_EDGE);
+// gpio_int_set_handler(ACCEL_GPIO_INT, ACTIVE_HIGH, (gpio_int_handler_type)KIONIX_ACCEL_isr);
+ gpio_int_set_detect(BIO_ACC_INT, DETECT_EDGE);
+ gpio_int_set_handler((gpio_int_type)BIO_ACC_INT, ACTIVE_HIGH, KIONIX_ACCEL_isr);
+#endif
+ KIONIX_ACCEL_enable_int();
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_disable_interrupt
+DESCRIPTION: This function disables the interrupt for the accelerometer.
+ARGUMENTS PASSED: None
+RETURN VALUE: None
+PRE-CONDITIONS: None
+POST-CONDITIONS: None
+IMPORTANT NOTES: Called from interrupt context, so do NOT do any i2c operations!
+==================================================================================================*/
+void KIONIX_ACCEL_disable_interrupt(void)
+{
+ KX_INTLOCK();
+
+ KIONIX_ACCEL_disable_int();
+
+#ifdef KX_PLATFORM_REX
+// gpio_int_set_handler(ACCEL_GPIO_INT, ACTIVE_HIGH, (gpio_int_handler_type)NULL);
+ gpio_int_set_handler((gpio_int_type)BIO_ACC_INT, ACTIVE_HIGH, NULL);
+#endif
+
+ KX_INTFREE();
+}
+
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_enable_outputs
+DESCRIPTION: This function enables accelerometer outputs.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Accelerometer outputs enabled
+==================================================================================================*/
+int KIONIX_ACCEL_enable_outputs(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_PC1); /* sets PC1 bit to be in power up state */
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_disable_outputs
+DESCRIPTION: This function disables accelerometer outputs.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Accelerometer outputs disabled
+==================================================================================================*/
+int KIONIX_ACCEL_disable_outputs(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_PC1); /* sets PC1 bit to be in power up state */
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_enable_tilt_function
+DESCRIPTION: This function enables the tilt position function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Tilt position function is enabled
+==================================================================================================*/
+int KIONIX_ACCEL_enable_tilt_function(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_TPE); /* sets TPE bit to enable tilt position function*/
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_disable_tilt_function
+DESCRIPTION: This function disables the tilt position function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Tilt position function is disabled
+==================================================================================================*/
+int KIONIX_ACCEL_disable_tilt_function(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_TPE); /* unset TPE bit to disable tilt position function */
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_enable_wake_up_function
+DESCRIPTION: This function enables the wake up function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Wake up function is enabled
+==================================================================================================*/
+int KIONIX_ACCEL_enable_wake_up_function(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_WUFE); /* set WUFE bit to enable the wake up function */
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_disable_wake_up_function
+DESCRIPTION: This function disables the wake up function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Wake up function is disabled
+==================================================================================================*/
+int KIONIX_ACCEL_disable_wake_up_function(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_WUFE); /* unset the WUFE bit to disable the wake up function */
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_enable_all
+DESCRIPTION: This function enables all engines.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: All engines enabled
+==================================================================================================*/
+int KIONIX_ACCEL_enable_all(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_PC1); /* set PC1 to enable the accelerometer outputs */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_TPE); /* set TPE bit to enable the tilt function */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_WUFE); /* set WUFE to enable the wake up function */
+ if (device == 0){ //KXTE9
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_B2SE); /* set B2SE to enable back to sleep function on KXTE9 */
+ }
+ else if (device == 1){ //KXTF9
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_TDTE); /* set TDTE to enable tap function on KXTF9 */
+ }
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_disable_all
+DESCRIPTION: This function disables all engines.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: All engines disabled
+==================================================================================================*/
+int KIONIX_ACCEL_disable_all(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_PC1); /* unset the PC1 bit to disable the accelerometer outputs */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_TPE); /* unset the TPE bit to disable the tilt function */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_WUFE); /* unset WUFE to disable wake up function */
+ if (device == 0){ //KXTE9
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_B2SE); /* set B2SE to enable back to sleep function on KXTE9 */
+ }
+ else if (device == 1){ //KXTF9
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_TDTE); /* set TDTE to enable tap function on KXTF9 */
+ }
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_sleep
+DESCRIPTION: This function places the accelerometer into a standby state while retaining
+ current register values.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Device is in sleep mode
+==================================================================================================*/
+int KIONIX_ACCEL_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_PC1); /* unset the PC1 bit to disable the accelerometer */
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_read_interrupt_status
+DESCRIPTION: This function reads the physical pin interrupt status.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = interrupt active; 1 = interrupt inactive
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: None
+==================================================================================================*/
+int KIONIX_ACCEL_read_interrupt_status(void)
+{
+ int interrupt_status;
+ char status_reg;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_STATUS_REG, &status_reg, 1) == 0){
+ if ((status_reg & 0x10) == 0x00){
+ interrupt_status = 1;
+ }
+ else interrupt_status = 0;
+ }
+ else interrupt_status = 1;
+ return interrupt_status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_read_interrupt_source
+DESCRIPTION: This function reads the Interrupt Source 2 register.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = interrupt active; 1 = interrupt inactive
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: interrupt_source contains the byte read from Interrupt Source Register 2
+==================================================================================================*/
+int KIONIX_ACCEL_read_interrupt_source(char* interrupt_source)
+{
+ int interrupt_status;
+ if (device == 0){ //KXTE9
+ if (KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG2, interrupt_source, 1) == 0){
+ if (interrupt_source != 0x00){
+ interrupt_status = 0;
+ }
+ else interrupt_status = 1;
+ }
+ }
+ else if (device == 1){ //KXTF9
+ if (KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, interrupt_source, 1) == 0){
+ if (interrupt_source != 0x00){
+ interrupt_status = 0;
+ }
+ else interrupt_status = 1;
+ }
+ }
+ else interrupt_status = 1;
+ return interrupt_status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_read_previous_position
+DESCRIPTION: This function reads the previous tilt position register.
+ARGUMENTS PASSED: previous_position pointer
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: previous_position is assigned
+==================================================================================================*/
+int KIONIX_ACCEL_read_previous_position(char* previous_position)
+{
+ int status;
+ status = KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_TILT_POS_PRE, previous_position, 1);
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_read_current_position
+DESCRIPTION: This function reads the current tilt position register.
+ARGUMENTS PASSED: current_position pointer
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: current_position is assigned
+==================================================================================================*/
+int KIONIX_ACCEL_read_current_position(char* current_position)
+{
+ int status;
+ status = KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_TILT_POS_CUR, current_position, 1);
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_reset
+DESCRIPTION: This function issues a software reset to the Kionix accelerometer.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Accelerometer is reset (will have to re-initialize)
+==================================================================================================*/
+int KIONIX_ACCEL_reset(void)
+{
+ char ctrl_reg3 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctrl_reg3, 1) == 0){
+ SET_REG_BIT(ctrl_reg3, CTRL_REG3_SRST);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctrl_reg3);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_tilt_timer
+DESCRIPTION: This function sets the number of tilt debounce samples.
+ARGUMENTS PASSED: tilt_timer; 0-255
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Tile debounce set according to tilt_timer
+==================================================================================================*/
+int KIONIX_ACCEL_tilt_timer(int tilt_timer)
+{
+ int status;
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_TILT_TIMER, tilt_timer) == 0){
+ status = 0;
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_wuf_timer
+DESCRIPTION: This function sets the number of wake-up debounce samples.
+ARGUMENTS PASSED: wuf_timer; 0-255
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Wake-up-function debounce set according to wuf_timer
+==================================================================================================*/
+int KIONIX_ACCEL_wuf_timer(int wuf_timer)
+{
+ int status;
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_WUF_TIMER, wuf_timer) == 0){
+ status = 0;
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_wuf_thresh
+DESCRIPTION: This function defines the threshold for general motion detection.
+ARGUMENTS PASSED: wuf_thresh; 0-255
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Wake up function threshold set according to wuf_thresh
+IMPORTANT NOTES: Default: 0.5g (0x20h)
+==================================================================================================*/
+int KIONIX_ACCEL_wuf_thresh(int wuf_thresh)
+{
+ int status;
+ if (KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_WUF_THRESH, wuf_thresh) == 0){
+ status = 0;
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_z
+DESCRIPTION: This function masks Z-axis from the activity engine.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Z-axis masked
+==================================================================================================*/
+int KIONIX_ACCEL_motion_mask_z(void)
+{
+ char int_ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_CTRL_REG2, &int_ctrl_reg2, 1) == 0){
+ SET_REG_BIT(int_ctrl_reg2, INT_CTRL_REG2_ZBW);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_INT_CTRL_REG2, int_ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_z
+DESCRIPTION: This function unmasks Z-axis from the activity engine.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Z-axis unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_motion_unmask_z(void)
+{
+ char int_ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_CTRL_REG2, &int_ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(int_ctrl_reg2, INT_CTRL_REG2_ZBW);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_INT_CTRL_REG2, int_ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_y
+DESCRIPTION: This function masks Y-axis from the activity engine.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Y-axis masked
+==================================================================================================*/
+int KIONIX_ACCEL_motion_mask_y(void)
+{
+ char int_ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_CTRL_REG2, &int_ctrl_reg2, 1) == 0){
+ SET_REG_BIT(int_ctrl_reg2, INT_CTRL_REG2_YBW);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_INT_CTRL_REG2, int_ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_y
+DESCRIPTION: This function unmasks Y-axis from the activity engine.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Y-axis unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_motion_unmask_y(void)
+{
+ char int_ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_CTRL_REG2, &int_ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(int_ctrl_reg2, INT_CTRL_REG2_YBW);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_INT_CTRL_REG2, int_ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_x
+DESCRIPTION: This function masks X-axis from the activity engine.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: X-axis masked
+==================================================================================================*/
+int KIONIX_ACCEL_motion_mask_x(void)
+{
+ char int_ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_CTRL_REG2, &int_ctrl_reg2, 1) == 0){
+ SET_REG_BIT(int_ctrl_reg2, INT_CTRL_REG2_XBW);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_INT_CTRL_REG2, int_ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_x
+DESCRIPTION: This function unmasks X-axis from the activity engine.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: X-axis unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_motion_unmask_x(void)
+{
+ char int_ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_INT_CTRL_REG2, &int_ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(int_ctrl_reg2, INT_CTRL_REG2_XBW);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_INT_CTRL_REG2, int_ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_fu
+DESCRIPTION: This function masks face-up state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Face up state masked
+==================================================================================================*/
+int KIONIX_ACCEL_position_mask_fu(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ SET_REG_BIT(ctrl_reg2, CTRL_REG2_FUM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_fd
+DESCRIPTION: This function masks face-down state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Face down state masked
+==================================================================================================*/
+int KIONIX_ACCEL_position_mask_fd(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ SET_REG_BIT(ctrl_reg2, CTRL_REG2_FDM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_up
+DESCRIPTION: This function masks up state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Up state masked
+==================================================================================================*/
+int KIONIX_ACCEL_position_mask_up(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ SET_REG_BIT(ctrl_reg2, CTRL_REG2_UPM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_do
+DESCRIPTION: This function masks down state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Down state masked
+==================================================================================================*/
+int KIONIX_ACCEL_position_mask_do(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ SET_REG_BIT(ctrl_reg2, CTRL_REG2_DOM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_ri
+DESCRIPTION: This function masks right state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Right state masked
+==================================================================================================*/
+int KIONIX_ACCEL_position_mask_ri(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ SET_REG_BIT(ctrl_reg2, CTRL_REG2_RIM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_mask_le
+DESCRIPTION: This function masks left state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Left state masked
+==================================================================================================*/
+int KIONIX_ACCEL_position_mask_le(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ SET_REG_BIT(ctrl_reg2, CTRL_REG2_LEM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_fu
+DESCRIPTION: This function unmasks face-up state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Face up state unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_position_unmask_fu(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(ctrl_reg2, CTRL_REG2_FUM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_fd
+DESCRIPTION: This function unmasks face-down state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Face down state unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_position_unmask_fd(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(ctrl_reg2, CTRL_REG2_FDM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_up
+DESCRIPTION: This function unmasks up state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Up state unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_position_unmask_up(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(ctrl_reg2, CTRL_REG2_UPM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_do
+DESCRIPTION: This function unmasks down state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Down state unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_position_unmask_do(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(ctrl_reg2, CTRL_REG2_DOM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_ri
+DESCRIPTION: This function unmasks right state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Right state unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_position_unmask_ri(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(ctrl_reg2, CTRL_REG2_RIM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_position_unmask_le
+DESCRIPTION: This function unmasks left state in the screen rotation function.
+ARGUMENTS PASSED: None
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: Left state unmasked
+==================================================================================================*/
+int KIONIX_ACCEL_position_unmask_le(void)
+{
+ char ctrl_reg2 = 0;
+ int status = 0;
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG2, &ctrl_reg2, 1) == 0){
+ UNSET_REG_BIT(ctrl_reg2, CTRL_REG2_LEM);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG2, ctrl_reg2);
+ }
+ else status = 1;
+ return status;
+}
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_set_odr_motion
+DESCRIPTION: This function sets the ODR frequency.
+ARGUMENTS PASSED: frequency variable; 1, 3, 10, or 40 for KXTE9; 25, 50, 100, or 200 for KXTF9
+RETURN VALUE: 0 = pass; 1 = fail
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: ODR is set according to frequency
+==================================================================================================*/
+int KIONIX_ACCEL_set_odr_motion(int frequency)
+{
+ char ctlreg_1 = 0;
+ char ctlreg_3 = 0;
+ if (device == 0){ //KXTE9
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG1, &ctlreg_1, 1) != 0){
+ 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 1Hz */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_ODRA);
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_ODRB);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SA);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SB);
+ break;
+ case 3: /* set all ODR's to 3Hz */
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_ODRA);
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRB);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SB);
+ break;
+ case 10: /* set all ODR's to 10Hz */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRA);
+ UNSET_REG_BIT(ctlreg_1, CTRL_REG1_ODRB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SA);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SB);
+ break;
+ case 40: /* set all ODR's to 40Hz */
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRA);
+ SET_REG_BIT(ctlreg_1, CTRL_REG1_ODRB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OB2SB);
+ break;
+ default:
+ return 1;
+ }
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG1, ctlreg_1);
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3);
+ }
+ else if (device == 1){ //KXTF9
+ if (KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_CTRL_REG3, &ctlreg_3, 1) != 0){
+ return 1;
+ }
+ switch (frequency){
+ case 25: /* set ODR to 25Hz */
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ break;
+ case 50: /* set ODR t0 50 Hz */
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ break;
+ case 100: /* set ODR to 100 Hz */
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ UNSET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ break;
+ case 200: /* set ODR to 200 Hz */
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFA);
+ SET_REG_BIT(ctlreg_3, CTRL_REG3_OWUFB);
+ break;
+ default:
+ return 1;
+ }
+ KIONIX_ACCEL_write_byte(KIONIX_ACCEL_I2C_CTRL_REG3, ctlreg_3);
+ }
+ return 0;
+}
+
+void KIONIX_ACCEL_process_directional_tap(char tap_mode, char tap_direction)
+{
+ switch(tap_direction)
+ {
+ case INT_CTRL_REG3_TFUM : // Z+
+ KxPrint("Z+, (%d) Back \n", tap_mode);
+ break;
+ case INT_CTRL_REG3_TFDM : // Z-
+ KxPrint("Z-, (%d) Front \n", tap_mode);
+ break;
+ case INT_CTRL_REG3_TUPM : // Y+
+ KxPrint("Y+, (%d) Down \n", tap_mode);
+ break;
+ case INT_CTRL_REG3_TDOM : // Y-
+ KxPrint("Y-, (%d) Up \n", tap_mode);
+ break;
+ case INT_CTRL_REG3_TRIM : // X+
+ KxPrint("X+, (%d) Left \n", tap_mode);
+ break;
+ case INT_CTRL_REG3_TLEM : // X-
+ KxPrint("X-, (%d) Right \n", tap_mode);
+ break;
+ }
+ return;
+}
+
+void KIONIX_ACCEL_process_screen_rotation(char tilt_pos_pre, char tilt_pos_cur)
+{
+ if(tilt_pos_pre == tilt_pos_cur) {
+ KxPrint("Tilt State is prev(0x%02x) == curr(0x%02x) \n", tilt_pos_pre, tilt_pos_cur);
+ return;
+ }
+
+ switch(tilt_pos_cur)
+ {
+ case CTRL_REG2_RIM : // X+
+ KxPrint("X+, Landscape LEFT \n");
+ break;
+ case CTRL_REG2_LEM : // X-
+ KxPrint("X-, Landscape RIGHT \n");
+ break;
+ case CTRL_REG2_UPM : // Y+
+ KxPrint("Y+, Potrait UP \n");
+ break;
+ case CTRL_REG2_DOM : // Y-
+ KxPrint("Y-, Potrait DOWN \n");
+ break;
+ case CTRL_REG2_FUM : // Z+
+ KxPrint("Z+, Face UP \n");
+ break;
+ case CTRL_REG2_FDM : // Z-
+ KxPrint("Z-, Face DOWN \n");
+ break;
+ }
+
+ return;
+}
+
+void KIONIX_ACCEL_process_motion_detection(char int_src_reg1, char int_src_reg2)
+{
+ switch(device)
+ {
+ case 0 : //KXTE9
+ if(int_src_reg1 & 0x4) KxPrint("0x%02x, activity state has changed to Inactive \n", int_src_reg2); // B2SS
+ if(int_src_reg1 & 0x2) KxPrint("0x%02x, activity state has changed to Active \n", int_src_reg2); // WUFS
+ break;
+ case 1 : // KXTF9
+ KxPrint("TODO: TF9 motion detection process \n");
+ break;
+ case 2 : // KXSD9
+ break;
+ }
+
+ return;
+}
+
+/*==================================================================================================
+FUNCTION: KIONIX_ACCEL_service_interrupt
+DESCRIPTION: This function clears the interrupt request status.
+ARGUMENTS PASSED: source_of_interrupt pointer
+RETURN VALUE: 0 = interrupt was pending; 1 = interrupt was not pending
+PRE-CONDITIONS: KIONIX_ACCEL_init() has been called
+POST-CONDITIONS: source_of_interrupt is assigned
+ Interrupt pending bit (MOTI in REGA) will be cleared
+IMPORTANT NOTES: Do not call this from interrupt context since it accesses i2c.
+==================================================================================================*/
+//int KIONIX_ACCEL_service_interrupt(int* source_of_interrupt)
+int KIONIX_ACCEL_service_interrupt(void)
+{
+ char status_reg=0, int_rel=0, value=0;
+ char int_src_reg1, int_src_reg2;
+ char tilt_pos_cur, tilt_pos_pre;
+ int res=0;
+
+ KX_INTLOCK( );
+
+ // disable accelerometer interrupt first
+ KIONIX_ACCEL_disable_interrupt();
+
+ KIONIX_ACCEL_read_bytes(KIONIX_ACCEL_I2C_STATUS_REG, &status_reg, 1);
+ KxPrint("-W- status_reg (0x%02x) \n", status_reg);
+ if( !(status_reg & BIT(4)) ) {
+ KxPrint("-W- no interrupt event (0x%02x) \n", status_reg);
+ goto RELEASE_INT;
+ }
+
+ switch(device)
+ {
+ case 0: // KXTE9
+ KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG1, &int_src_reg1, 1);
+ KIONIX_ACCEL_read_bytes(KXTE9_I2C_INT_SRC_REG2, &int_src_reg2, 1);
+ if( (int_src_reg1 & 0x4) || (int_src_reg1 & 0x2) ) { // B2SS or WUFS
+ KIONIX_ACCEL_process_motion_detection(int_src_reg1, int_src_reg2);
+ }
+ if(int_src_reg1 & 0x1) { // 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);
+ // TODO:
+ KIONIX_ACCEL_process_screen_rotation(tilt_pos_pre, tilt_pos_cur);
+ }
+ break;
+ case 1: // KXTF9
+ KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG1, &int_src_reg1, 1);
+ KIONIX_ACCEL_read_bytes(KXTF9_I2C_INT_SRC_REG2, &int_src_reg2, 1);
+ if(int_src_reg2 & (0x3<<2) ) { // Direction tap
+ unsigned char tap_mode ;
+ tap_mode = ((int_src_reg2&(0x3<<2))>>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
diff --git a/modules/libjoy/caanoo/te9_tf9_hybrid_driver.h b/modules/libjoy/caanoo/te9_tf9_hybrid_driver.h
new file mode 100644
index 0000000..5cad296
--- /dev/null
+++ b/modules/libjoy/caanoo/te9_tf9_hybrid_driver.h
@@ -0,0 +1,466 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KIONIX_DRV_VERSION "091130_1.0.0"
+
+#define KX_PLATFORM_LINUX
+//#define KX_PLATFORM_WIN32
+//#define KX_PLATFORM_WINCE
+//#define KX_PLATFORM_REX
+//#define KX_PLATFORM_FIRMWARE
+
+
+/*==================================================================================================
+ Module Name: te9_tf9_hybrid_driver
+
+ General Description: this file contains function calls to control Kionix KXTE9 and KXTF9 via I2C.
+====================================================================================================
+Revision History:
+ Modification Tracking
+Author Date Number Description of Changes
+------------------------- ------------ ---------- -------------------------------------------
+Chris Hudson 03/26/2009 Cleaned up
+Chris Hudson 03/23/2009 Added more differentiation between E9 and F9 functions
+Chris Hudson 02/04/2009 Modified driver for use in a Linux environment
+Izudin Cemer/Ken Foust 01/02/2009 Unified the driver for TE9 and TF9 product series
+Izudin Cemer/Ken Foust 10/08/2008 Cleaned up code for initial release
+Izudin Cemer/Ken Foust 08/27/2008 Initial support
+====================================================================================================
+ INCLUDE FILES
+==================================================================================================*/
+
+// TODO:
+#ifdef KX_PLATFORM_LINUX
+
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <stdint.h>
+ #include <sys/ioctl.h>
+ #include <errno.h>
+// #include "i2c-dev.h"
+
+#elif defined(KX_PLATFORM_WIN32)
+ #include <windows.h>
+
+#elif defined(KX_PLATFORM_WINCE)
+ #include <windows.h>
+
+#elif defined(KX_PLATFORM_REX)
+ #include "task.h"
+
+ #include "sleep.h"
+ #include "dog.h"
+ #include "bio.h"
+ #include "gpio_int.h"
+ #include "pm.h"
+ #include "i2c.h"
+ #include "accel_task.h"
+ #include "accel_types.h"
+ #include "ui.h"
+ #include "i2c.h"
+ #include <math.h>
+ #include "KxCriticalSection.h"
+#elif defined(KX_PLATFORM_FIRMWARE)
+
+ #include <string.h>
+ #include "def.h"
+ #include "option.h"
+ #include "2440addr.h"
+ #include "2440lib.h"
+ #include "2440slib.h"
+
+ #include "IIC.h"
+ #include "eint.h"
+
+#endif
+
+/*==================================================================================================
+ LOCAL CONSTANTS
+==================================================================================================*/
+#ifdef KX_PLATFORM_LINUX
+ //#define ACCEL_GPIO_INT (GPIO_INT_85) /* KIONIX_ACCEL interrupt pin is connected to GPIO 85 on Blaze */
+ //#define ACCEL_GPIO_INT (GPIO_INT_19) /* KIONIX_ACCEL interrupt pin is connected to GPIO 19 on Halo */
+ #define I2C_BUS_HW_CTRL 1
+ #define I2C_REG_DEV 1
+ #define I2C_STOP_START_BEFORE_READ 1
+ #define ACCEL_EVENT_INTERRUPT 1
+ #define DETECT_EDGE 1
+ #define ACTIVE_HIGH 1
+ #define GPIO_INT_85 1
+
+#elif defined(KX_PLATFORM_WIN32)
+
+#elif defined(KX_PLATFORM_WINCE)
+
+#elif defined(KX_PLATFORM_REX)
+
+#elif defined(KX_PLATFORM_FIRMWARE)
+
+#endif
+
+typedef struct
+{
+ int x;
+ int y;
+ int z;
+} ACCEL_XYZ;
+
+//added by lars - 20100308
+#define DEVICE_TYPE_KIONIX_KXTE9 0
+#define DEVICE_TYPE_KIONIX_KXTF9 1
+#define DEVICE_TYPE_KIONIX_KXSD9 2
+
+
+/*==================================================================================================
+ MACROS
+==================================================================================================*/
+#ifdef KX_PLATFORM_LINUX
+ #define KxPrint printf
+
+ #define KxMSleep(v) usleep((v)*1000)
+ #define KxUSleep(v) usleep(v)
+
+ #define KIONIX_InitializeCriticalSection(x)
+ #define KIONIX_EnterCriticalSection(x)
+ #define KIONIX_LeaveCriticalSection(x)
+ #define KIONIX_DeleteCriticalSection(x)
+
+ #define KX_INTLOCK()
+ #define KX_INTFREE()
+
+#elif defined(KX_PLATFORM_WIN32) || defined(KX_PLATFORM_WINCE)
+ #define KxPrint printf
+
+ #define KxMSleep(v) Sleep(v)
+ #define KxUSleep(v) Sleep(v/1000)
+
+ #define KIONIX_InitializeCriticalSection(x)
+ #define KIONIX_EnterCriticalSection(x)
+ #define KIONIX_LeaveCriticalSection(x)
+ #define KIONIX_DeleteCriticalSection(x)
+
+ #define KX_INTLOCK()
+ #define KX_INTFREE()
+
+#elif defined(KX_PLATFORM_REX)
+ #define KxPrint printf
+
+ #define KxMSleep(v) rex_sleep(v)
+ #define KxUSleep(v) rex_sleep(v/1000)
+
+ #define KIONIX_InitializeCriticalSection(x) rex_init_crit_sect(x)
+ #define KIONIX_EnterCriticalSection(x) rex_enter_crit_sect(x)
+ #define KIONIX_LeaveCriticalSection(x) rex_leave_crit_sect(x)
+ #define KIONIX_DeleteCriticalSection(x)
+
+ #define KX_INTLOCK() REX_INTLOCK()
+ #define KX_INTFREE() REX_INTFREE()
+
+#elif defined(KX_PLATFORM_FIRMWARE)
+ #define KxPrint Uart_Printf
+
+ #define KxMSleep(v) Delay(v) // ms, // rex_sleep(x)
+ #define KxUSleep(v) Delay(v/1000)
+
+ #define KIONIX_InitializeCriticalSection(x)
+ #define KIONIX_EnterCriticalSection(x)
+ #define KIONIX_LeaveCriticalSection(x)
+ #define KIONIX_DeleteCriticalSection(x)
+
+ #define KX_INTLOCK()
+ #define KX_INTFREE()
+
+ //#define USE_I2C_INT
+ //#define USE_I2C_POLL
+ #define USE_I2C_GPIO
+#endif
+
+#define BIT(x) (1<<x)
+#define SET_REG_BIT(r,b) r |= b
+#define UNSET_REG_BIT(r,b) r &= ~b
+/*==================================================================================================
+ KIONIX ACCEL REGISTER MAP
+==================================================================================================*/
+#ifdef KX_PLATFORM_FIRMWARE
+//#define KIONIX_ACCEL_I2C_SLV_ADDR (0x30) // KXSD9
+#define KIONIX_ACCEL_I2C_SLV_ADDR (0x1E) // KXTE9, KXTF9
+#else
+//#define KIONIX_ACCEL_I2C_SLV_ADDR (0x30>>1) // KXSD9
+#define KIONIX_ACCEL_I2C_SLV_ADDR (0x1E>>1) // KXTE9, KXTF9
+#endif
+/*==================================================================================================
+ COMMON REGISTERS
+==================================================================================================*/
+#define KIONIX_ACCEL_I2C_ST_RESP 0x0C
+#define KIONIX_ACCEL_I2C_WHO_AM_I 0x0F
+#define KIONIX_ACCEL_I2C_TILT_POS_CUR 0x10
+#define KIONIX_ACCEL_I2C_TILT_POS_PRE 0x11
+#define KIONIX_ACCEL_I2C_STATUS_REG 0x18
+#define KIONIX_ACCEL_I2C_INT_REL 0x1A
+#define KIONIX_ACCEL_I2C_CTRL_REG1 0x1B
+#define KIONIX_ACCEL_I2C_CTRL_REG2 0x1C
+#define KIONIX_ACCEL_I2C_CTRL_REG3 0x1D
+#define KIONIX_ACCEL_I2C_INT_CTRL_REG2 0x1F
+#define KIONIX_ACCEL_I2C_TILT_TIMER 0x28
+#define KIONIX_ACCEL_I2C_WUF_TIMER 0x29
+#define KIONIX_ACCEL_I2C_WUF_THRESH 0x5A
+/*==================================================================================================
+ KXTE9-SPECIFIC REGISTERS
+==================================================================================================*/
+#define KXTE9_I2C_XOUT 0x12
+#define KXTE9_I2C_YOUT 0x13
+#define KXTE9_I2C_ZOUT 0x14
+#define KXTE9_I2C_INT_SRC_REG1 0x16
+#define KXTE9_I2C_INT_SRC_REG2 0x17
+#define KXTE9_I2C_INT_CTRL_REG1 0x1E
+#define KXTE9_I2C_B2S_TIMER 0x2A
+#define KXTE9_I2C_B2S_THRESH 0x5B
+/*==================================================================================================
+ KXTF9-SPECIFIC REGISTERS
+==================================================================================================*/
+#define KXTF9_I2C_XOUT_HPF_L 0x00
+#define KXTF9_I2C_XOUT_HPF_H 0x01
+#define KXTF9_I2C_YOUT_HPF_L 0x02
+#define KXTF9_I2C_YOUT_HPF_H 0x03
+#define KXTF9_I2C_ZOUT_HPF_L 0x04
+#define KXTF9_I2C_ZOUT_HPF_H 0x05
+#define KXTF9_I2C_XOUT_L 0x06
+#define KXTF9_I2C_XOUT_H 0x07
+#define KXTF9_I2C_YOUT_L 0x08
+#define KXTF9_I2C_YOUT_H 0x09
+#define KXTF9_I2C_ZOUT_L 0x0A
+#define KXTF9_I2C_ZOUT_H 0x0B
+#define KXTF9_I2C_INT_SRC_REG1 0x15
+#define KXTF9_I2C_INT_SRC_REG2 0x16
+#define KXTF9_I2C_INT_CTRL_REG1 0x1E
+#define KXTF9_I2C_INT_CTRL_REG3 0x20
+#define KXTF9_I2C_DATA_CTRL_REG 0x21
+#define KXTF9_I2C_TDT_TIMER 0x2B
+#define KXTF9_I2C_TDT_H_THRESH 0x2C
+#define KXTF9_I2C_TDT_L_THRESH 0x2D
+#define KXTF9_I2C_TDT_TAP_TIMER 0x2E
+#define KXTF9_I2C_TDT_TOTAL_TIMER 0x2F
+#define KXTF9_I2C_TDT_LATENCY_TIMER 0x30
+#define KXTF9_I2C_TDT_WINDOW_TIMER 0x31
+/*==================================================================================================
+ KIONIX ACCEL CONTROL BIT DEFINITION
+==================================================================================================*/
+/*==================================================================================================
+ COMMON CONTROL BITS
+==================================================================================================*/
+#define CTRL_REG1_TPE 0x01 /* enables tilt position function */
+#define CTRL_REG1_WUFE 0x02 /* enables wake up function */
+#define CTRL_REG1_PC1 0x80 /* operating mode 1 = full power mode; 0 = stand by mode */
+#define CTRL_REG2_FUM 0x01 /* face up state mask */
+#define CTRL_REG2_FDM 0x02 /* face down state mask */
+#define CTRL_REG2_UPM 0x04 /* up state mask */
+#define CTRL_REG2_DOM 0x08 /* down state mask */
+#define CTRL_REG2_RIM 0x10 /* right state mask */
+#define CTRL_REG2_LEM 0x20 /* left state mask */
+#define CTRL_REG3_OWUFB 0x01 /* active mode output data rate */
+#define CTRL_REG3_OWUFA 0x02 /* active mode output data rate */
+#define CTRL_REG3_STC 0x10 /* initiates self-test function */
+#define CTRL_REG3_OTPB 0x20 /* sets output data rate for tilt position function */
+#define CTRL_REG3_OTPA 0x40 /* sets output data rate for tilt position function */
+#define CTRL_REG3_SRST 0x80 /* software reset */
+#define INT_CTRL_REG2_XBW 0x80 /* X-axis motion mask */
+#define INT_CTRL_REG2_YBW 0x40 /* Y-axis motion mask */
+#define INT_CTRL_REG2_ZBW 0x20 /* Z-axis motion mask */
+/*==================================================================================================
+ KXTE9-SPECIFIC CONTROL BITS
+==================================================================================================*/
+#define CTRL_REG1_B2SE 0x04 /* enables back to sleep function on KXTE9 */
+#define CTRL_REG1_ODRB 0x08 /* bit0 for selecting the output data rate on KXTE9 */
+#define CTRL_REG1_ODRA 0x10 /* bit1 for selecting the output data rate on KXTE9 */
+#define CTRL_REG3_OB2SB 0x04 /* sets output data rate when in inactive mode (KXTE9) */
+#define CTRL_REG3_OB2SA 0x08 /* sets output data rate when in incative mode (KXTE9) */
+#define KXTE9_INT_CTRL_REG1_IEL 0x04 /* sets response of physical interrupt pin */
+#define KXTE9_INT_CTRL_REG1_IEA 0x08 /* sets polarity of the physical interrupt pin*/
+#define KXTE9_INT_CTRL_REG1_IEN 0x10 /* enables/disables the physical interrupt pin; 1=enable; 0=disable */
+#define FULL_SCALE_RANGE_2_G 2000 /* indicates full scale g-range of the KIONIX_ACCEL */
+#define BIT_SENSITIVITY_2_G 16 /* indicates sensitivity of the KIONIX_ACCEL ((2^6)/4) */
+#define ZERO_G_OFFSET 32 /* indicates 0g offset of the KIONIX_ACCEL ((2^6)/2) */
+/*==================================================================================================
+ KXTF9-SPECIFIC CONTROL BITS
+==================================================================================================*/
+#define CTRL_REG1_TDTE 0x04 /* enables tap/double tap function on KXTF9 */
+#define CTRL_REG1_GSEL0 0x08 /* bit0 used for selecting the g range */
+#define CTRL_REG1_GSEL1 0x10 /* bit1 used for selecting the g range */
+#define CTRL_REG1_DRDYE 0x20 /* enables physical interrupt when new accel data is available on KXTF9 */
+#define CTRL_REG1_RES 0x40 /* performance mode on KXTF9 */
+#define CTRL_REG3_OTDTB 0x04 /* sets output data rate for tap double tap function */
+#define CTRL_REG3_OTDTA 0x08 /* sets output data rate for tap double tap function */
+#define INT_CTRL_REG3_TFUM 0x01 /* Z positive tap detection mask */
+#define INT_CTRL_REG3_TFDM 0x02 /* Z negative tap detection mask */
+#define INT_CTRL_REG3_TUPM 0x04 /* Y positive tap detection mask */
+#define INT_CTRL_REG3_TDOM 0x08 /* Y negative tap detection mask */
+#define INT_CTRL_REG3_TRIM 0x10 /* X positive tap detection mask */
+#define INT_CTRL_REG3_TLEM 0x20 /* X negative tap detection mask */
+#define KXTF9_INT_CTRL_REG1_STPOL 0x02 /* ST (self test) polarity bit */
+#define KXTF9_INT_CTRL_REG1_ULMB 0x04 /* unlatched mode for WUF 1=unlatche; 0=latched */
+#define KXTF9_INT_CTRL_REG1_IEL 0x08 /* sets response of physical interrupt pin */
+#define KXTF9_INT_CTRL_REG1_IEA 0x10 /* sets polarity of the physical interrupt pin*/
+#define KXTF9_INT_CTRL_REG1_IEN 0x20 /* enables/disables the physical interrupt pin; 1=enable; 0=disable */
+#define DATA_CTRL_REG_OSAC 0x01 /* sets LPF Acceleration output data rates */
+#define DATA_CTRL_REG_OSAB 0x02 /* sets LPF Acceleration output data rates */
+#define DATA_CTRL_REG_OSAA 0x04 /* sets LPF Acceleration output data rates */
+#define DATA_CTRL_REG_HPFROB 0x10 /* sets HPF roll-off frequency */
+#define DATA_CTRL_REG_HPFROA 0x20 /* sets HPF roll-off frequency */
+/*==================================================================================================
+ GLOBAL VARIABLES
+==================================================================================================*/
+static int KIONIX_ACCEL_g_range = 2000; /* KIONIX_ACCEL factory default G range in milli g */
+/*==================================================================================================
+ COMMON FUNCTIONS
+==================================================================================================*/
+int KIONIX_ACCEL_read_bytes(int reg, char* data, int length);
+int KIONIX_ACCEL_write_byte(int reg, int data);
+int KIONIX_ACCEL_get_device_type(void);
+int KIONIX_ACCEL_deinit(void);
+int KIONIX_ACCEL_init(void);
+void KIONIX_ACCEL_isr(void);
+void KIONIX_ACCEL_enable_interrupt(void);
+void KIONIX_ACCEL_disable_interrupt(void);
+int KIONIX_ACCEL_enable_outputs(void);
+int KIONIX_ACCEL_disable_outputs(void);
+int KIONIX_ACCEL_enable_tilt_function(void);
+int KIONIX_ACCEL_disable_tilt_function(void);
+int KIONIX_ACCEL_enable_wake_up_function(void);
+int KIONIX_ACCEL_disable_wake_up_function(void);
+int KIONIX_ACCEL_enable_all(void);
+int KIONIX_ACCEL_disable_all(void);
+int KIONIX_ACCEL_sleep(void);
+int KIONIX_ACCEL_read_interrupt_status(void);
+int KIONIX_ACCEL_read_interrupt_source(char* interrupt_source);
+int KIONIX_ACCEL_read_previous_position(char* previous_position);
+int KIONIX_ACCEL_read_current_position(char* current_position);
+int KIONIX_ACCEL_reset(void);
+int KIONIX_ACCEL_tilt_timer(int tilt_timer);
+int KIONIX_ACCEL_wuf_timer(int wuf_timer);
+int KIONIX_ACCEL_wuf_thresh(int wuf_thresh);
+int KIONIX_ACCEL_motion_mask_z(void);
+int KIONIX_ACCEL_motion_unmask_z(void);
+int KIONIX_ACCEL_motion_mask_y(void);
+int KIONIX_ACCEL_motion_unmask_y(void);
+int KIONIX_ACCEL_motion_mask_x(void);
+int KIONIX_ACCEL_motion_unmask_x(void);
+int KIONIX_ACCEL_position_mask_fu(void);
+int KIONIX_ACCEL_position_mask_fd(void);
+int KIONIX_ACCEL_position_mask_up(void);
+int KIONIX_ACCEL_position_mask_do(void);
+int KIONIX_ACCEL_position_mask_ri(void);
+int KIONIX_ACCEL_position_mask_le(void);
+int KIONIX_ACCEL_position_unmask_fu(void);
+int KIONIX_ACCEL_position_unmask_fd(void);
+int KIONIX_ACCEL_position_unmask_up(void);
+int KIONIX_ACCEL_position_unmask_do(void);
+int KIONIX_ACCEL_position_unmask_ri(void);
+int KIONIX_ACCEL_position_unmask_le(void);
+int KIONIX_ACCEL_set_odr_motion(int frequency);
+//int KIONIX_ACCEL_service_interrupt(int* source_of_interrupt);
+int KIONIX_ACCEL_service_interrupt(void);
+int KIONIX_ACCEL_read_LPF_cnt(int* x, int* y, int* z);
+int KIONIX_ACCEL_read_LPF_g(int* gx, int* gy, int* gz);
+int KIONIX_ACCEL_read_current_odr_motion(double* ODR_rate_motion);
+int KIONIX_ACCEL_read_position_status(void);
+int KIONIX_ACCEL_read_wuf_status(void);
+int KIONIX_ACCEL_enable_int(void);
+int KIONIX_ACCEL_disable_int(void);
+int KIONIX_ACCEL_int_activeh(void);
+int KIONIX_ACCEL_int_activel(void);
+int KIONIX_ACCEL_int_latch(void);
+int KIONIX_ACCEL_int_pulse(void);
+/*==================================================================================================
+ KXTE9-SPECIFIC FUNCTIONS
+==================================================================================================*/
+int KIONIX_ACCEL_enable_back_to_sleep(void);
+int KIONIX_ACCEL_disable_back_to_sleep(void);
+int KXTE9_read_b2s_status(void);
+int KXTE9_b2s_timer(int b2s_timer);
+int KXTE9_b2s_thresh(int b2s_thresh);
+/*==================================================================================================
+ KXTF9-SPECIFIC FUNCTIONS
+==================================================================================================*/
+int KXTF9_enable_tap_detection(void);
+int KXTF9_disable_tap_detection(void);
+int KXTF9_read_single_tap_status(void);
+int KXTF9_read_double_tap_status(void);
+int KXTF9_set_odr_tilt(int frequency);
+int KXTF9_set_G_range(int range);
+int KXTF9_read_HPF_cnt(int* x, int* y, int* z);
+int KXTF9_read_HPF_g(int* gx, int* gy, int* gz);
+int KXTF9_read_current_odr_tilt(double* ODR_rate_tilt);
+int KXTF9_read_current_odr_tap(double* ODR_rate_tap);
+int KXTF9_read_tap_direction(char* int_src_reg1);
+int KXTF9_int_alt_disable(void);
+int KXTF9_int_alt_enable(void);
+int KXTF9_tdt_timer(int tdt_timer);
+int KXTF9_tdt_h_thresh(int tdt_h_thresh);
+int KXTF9_tdt_l_thresh(int tdt_l_thresh);
+int KXTF9_tdt_tap_timer(int tdt_tap_timer);
+int KXTF9_tdt_total_timer(int tdt_total_timer);
+int KXTF9_tdt_latency_timer(int tdt_latency_timer);
+int KXTF9_tdt_window_timer(int tdt_window_timer);
+int KXTF9_tap_mask_TFU(void);
+int KXTF9_tap_unmask_TFU(void);
+int KXTF9_tap_mask_TFD(void);
+int KXTF9_tap_unmask_TFD(void);
+int KXTF9_tap_mask_TUP(void);
+int KXTF9_tap_unmask_TUP(void);
+int KXTF9_tap_mask_TDO(void);
+int KXTF9_tap_unmask_TDO(void);
+int KXTF9_tap_mask_TRI(void);
+int KXTF9_tap_unmask_TRI(void);
+int KXTF9_tap_mask_TLE(void);
+int KXTF9_tap_unmask_TLE(void);
+int KXTF9_tap_mask_all_direction(void);
+int KXTF9_tap_unmask_all_direction(void);
+int KXTF9_set_odr_tap(int alpha);
+int KXTF9_set_lpf_odr(int frequency);
+int KXTF9_set_resolution(int resolution);
+
+enum {
+ PROCESS_NONE=0,
+ PROCESS_INTERRUPT,
+ PROCESS_SHAKEPOLL,
+ PROCESS_OTHER,
+};
+
+//*************************************************************
+// Name : shake.h
+// Author : Kionix, Inc.
+// Version : 1.0
+// Copyright :
+// Description : shake detection
+//*************************************************************
+
+#define CONFIG_RATE 50 // data rate (hz)
+#define CONFIG_DURATION 180 // max length of a shake (ms)
+#define CONFIG_DELAY 0 // min seperation between shakes (ms)
+#define CONFIG_TIMEOUT 580 //280 // max seperation between shakes (ms)
+#define CONFIG_THRESHOLD 3000 //20000 // min shake threshold ((x^2 + y^2 + z^2) / 1000)
+
+typedef struct
+{
+ long cntShake; // valid shake count
+ long cntInvalid; // invalid shake count
+
+ long cntDuration; // duration timer
+ long cntDelay; // delay timer
+ long cntTimeout; // timeout timer
+
+ long maxDuration; // duration threshold
+ long maxDelay; // delay threshold
+ long maxTimeout; // timeout threshold
+
+} shake_data;
+
+void KIONIX_SHAKE_Init(shake_data* data);
+long KIONIX_SHAKE_Update(shake_data* data, long val);
+
+#ifdef __cplusplus
+}
+#endif