diff options
author | neonloop | 2021-10-20 14:54:27 +0000 |
---|---|---|
committer | neonloop | 2021-10-20 14:54:27 +0000 |
commit | ea1947ffcc606d757357398b24e74a3f4ecefa07 (patch) | |
tree | 2031b8d4fc4c61063c710a7148378f57e662efbd /modules/libjoy/caanoo | |
download | bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.tar.gz bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.tar.bz2 bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.zip |
Initial commit from steward-fu releasemain
Diffstat (limited to 'modules/libjoy/caanoo')
-rw-r--r-- | modules/libjoy/caanoo/i2c-dev.h | 342 | ||||
-rw-r--r-- | modules/libjoy/caanoo/te9_tf9_hybrid_driver.c | 3301 | ||||
-rw-r--r-- | modules/libjoy/caanoo/te9_tf9_hybrid_driver.h | 466 |
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 |