260 lines
5.9 KiB
C
Executable File
260 lines
5.9 KiB
C
Executable File
/******************************************************************************
|
|
*
|
|
* $Id: misc.c 303 2011-08-12 04:22:45Z kihara.gb $
|
|
*
|
|
* -- Copyright Notice --
|
|
*
|
|
* Copyright (c) 2004 Asahi Kasei Microdevices Corporation, Japan
|
|
* All Rights Reserved.
|
|
*
|
|
* This software program is proprietary program of Asahi Kasei Microdevices
|
|
* Corporation("AKM") licensed to authorized Licensee under Software License
|
|
* Agreement (SLA) executed between the Licensee and AKM.
|
|
*
|
|
* Use of the software by unauthorized third party, or use of the software
|
|
* beyond the scope of the SLA is strictly prohibited.
|
|
*
|
|
* -- End Asahi Kasei Microdevices Copyright Notice --
|
|
*
|
|
******************************************************************************/
|
|
#include "misc.h"
|
|
#include "AKCommon.h"
|
|
#include <fcntl.h>
|
|
#include <linux/input.h>
|
|
/*#include <linux/time.h>*//* ns_to_timespec() */
|
|
|
|
static int s_fdForm = -1; /*!< FD to formation detect device */
|
|
|
|
struct AKMD_INTERVAL {
|
|
long interval; /*!< Measurement interval, 32-bit is enough for HDOE */
|
|
int16 decimator; /*!< HDOE decimator */
|
|
};
|
|
|
|
static struct AKMD_INTERVAL s_interval[] = {
|
|
{ 10000000, 10 }, /* 100Hz */
|
|
{ 16666667, 6 }, /* 60Hz SENSOR_DELAY_FASTEST */
|
|
{ 20000000, 5 }, /* 50Hz SENSOR_DELAY_GAME */
|
|
{ 25000000, 4 }, /* 40Hz */
|
|
{ 50000000, 2 }, /* 20Hz */
|
|
{ 62500000, 2 }, /* 16Hz SENSOR_DELAY_UI */
|
|
{ 100000000, 1 }, /* 10Hz */
|
|
{ 125000000, 1 } /* 8Hz SENSOR_DELAY_NORMAL */
|
|
};
|
|
|
|
/*!
|
|
Sleep function in millisecond.
|
|
@param[in] msec Suspend time in millisecond.
|
|
*/
|
|
inline void msleep(signed int msec)
|
|
{
|
|
usleep(1000 * msec);
|
|
}
|
|
|
|
/*!
|
|
Open device driver which detects current formation. This is just a stab of
|
|
interface. Therefore, this function do nothing.
|
|
@return If function succeeds, the return value is 1. Otherwise, the return
|
|
value is 0.
|
|
*/
|
|
int16 misc_openForm(void)
|
|
{
|
|
if (s_fdForm < 0) {
|
|
s_fdForm = 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*!
|
|
Close device driver
|
|
*/
|
|
void misc_closeForm(void)
|
|
{
|
|
if (s_fdForm != -1) {
|
|
s_fdForm = -1;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
Get current formation This is just a stab of interface. Therefore, this
|
|
function do nothing.
|
|
@return The number represents current form.
|
|
*/
|
|
int16 misc_checkForm(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*!
|
|
Convert from int64_t value to timespec structure
|
|
@return timespec value
|
|
@param[in] val int64_t value
|
|
*/
|
|
struct timespec int64_to_timespec(int64_t val)
|
|
{
|
|
struct timespec ret;
|
|
ret.tv_sec = (long) (val / 1000000000);
|
|
ret.tv_nsec = val - ret.tv_sec;
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*!
|
|
Convert from timespec structure to int64_t value
|
|
@return int64_t value
|
|
@param[in] val timespec value
|
|
*/
|
|
int64_t timespec_to_int64(struct timespec* val)
|
|
{
|
|
return ((int64_t)(val->tv_sec * 1000000000) + (int64_t)val->tv_nsec);
|
|
}
|
|
|
|
/*!
|
|
Calculate the difference between two timespec structure.
|
|
\a begin should be later than \a end.
|
|
@return the difference in int64_t type value.
|
|
@param[in] begin
|
|
@param[in] end
|
|
*/
|
|
int64_t CalcDuration(struct timespec* begin, struct timespec* end)
|
|
{
|
|
struct timespec diff;
|
|
|
|
diff.tv_sec = begin->tv_sec - end->tv_sec;
|
|
|
|
if ((diff.tv_nsec = begin->tv_nsec - end->tv_nsec) < 0) {
|
|
diff.tv_nsec += 1000000000;
|
|
diff.tv_sec -= 1;
|
|
}
|
|
|
|
if (diff.tv_sec < 0) {
|
|
return 0; /* Minimum nanosec */
|
|
}
|
|
|
|
return timespec_to_int64(&diff);
|
|
}
|
|
|
|
/*!
|
|
Search and open an input event file by name. This function search the
|
|
directory "/dev/input/".
|
|
@return When this function succeeds, the return value is a file descriptor
|
|
to the found event file. If fails, the return value is -1.
|
|
@param[in] name The name of input device to be searched.
|
|
*/
|
|
int openInputDevice(const char* name)
|
|
{
|
|
const int NUM_EVENT = 16;
|
|
const int BUFSIZE = 32;
|
|
const int NAMESIZE = 128;
|
|
char buf[BUFSIZE];
|
|
char evName[NAMESIZE];
|
|
int i;
|
|
int fd;
|
|
for (i = 0; i < NUM_EVENT; i++) {
|
|
if (snprintf(buf, BUFSIZE, "/dev/input/event%d", i) < 0) {
|
|
break;
|
|
}
|
|
fd = open(buf, O_RDONLY | O_NONBLOCK);
|
|
if (fd >= 0) {
|
|
if (ioctl(fd, EVIOCGNAME(NAMESIZE - 1), &evName) >= 1) {
|
|
AKMDEBUG(DBG_LEVEL2, "event%d(%d): %s\n", i, fd, evName);
|
|
if (!strncmp(name, evName, strlen(name))) {
|
|
break;
|
|
}
|
|
}
|
|
close(fd);
|
|
}
|
|
fd = -1;
|
|
}
|
|
|
|
AKMDEBUG(DBG_LEVEL2, "openInput(%s): fd=%d\n", name, fd);
|
|
return fd;
|
|
}
|
|
|
|
/*!
|
|
Get valid measurement interval and HDOE decimator.
|
|
@return If this function succeeds, the return value is 1. Otherwise 0.
|
|
@param[in,out] time Input a requirement of sensor measurement interval.
|
|
The closest interval will be returned as output.
|
|
@param[out] hdoe_interval When the output interval value is set to looper,
|
|
this decimation value should be used to decimate the HDOE.
|
|
*/
|
|
int16 GetHDOEDecimator(int64_t* time, int16* hdoe_interval)
|
|
{
|
|
const int n = (sizeof(s_interval) / sizeof(s_interval[0]));
|
|
int i;
|
|
int64_t org;
|
|
|
|
org = *time;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
*time = s_interval[i].interval;
|
|
*hdoe_interval = s_interval[i].decimator;
|
|
if (org <= *time) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
AKMDEBUG(DBG_LEVEL3, "HDOEDecimator:%lld,%lld\n", org, *time);
|
|
return 1;
|
|
}
|
|
|
|
/*!
|
|
This function convert coordinate system.
|
|
@retval 1 Conversion succeeds.
|
|
@retval 0 Conversion failed.
|
|
@param[in] pat Conversion pattern number.
|
|
@param[in,out] Original vector as input, converted data as output.
|
|
*/
|
|
int16 ConvertCoordinate(
|
|
const AKMD_PATNO pat,
|
|
int16vec* vec)
|
|
{
|
|
int16 tmp;
|
|
switch(pat){
|
|
// Obverse
|
|
case PAT1:
|
|
// This is Android default
|
|
break;
|
|
case PAT2:
|
|
tmp = vec->u.x;
|
|
vec->u.x = vec->u.y;
|
|
vec->u.y = -tmp;
|
|
break;
|
|
case PAT3:
|
|
vec->u.x = -(vec->u.x);
|
|
vec->u.y = -(vec->u.y);
|
|
break;
|
|
case PAT4:
|
|
tmp = vec->u.x;
|
|
vec->u.x = -(vec->u.y);
|
|
vec->u.y = tmp;
|
|
break;
|
|
// Reverse
|
|
case PAT5:
|
|
vec->u.x = -(vec->u.x);
|
|
vec->u.z = -(vec->u.z);
|
|
break;
|
|
case PAT6:
|
|
tmp = vec->u.x;
|
|
vec->u.x = vec->u.y;
|
|
vec->u.y = tmp;
|
|
vec->u.z = -(vec->u.z);
|
|
break;
|
|
case PAT7:
|
|
vec->u.y = -(vec->u.y);
|
|
vec->u.z = -(vec->u.z);
|
|
break;
|
|
case PAT8:
|
|
tmp = vec->u.x;
|
|
vec->u.x = -(vec->u.y);
|
|
vec->u.y = -tmp;
|
|
vec->u.z = -(vec->u.z);
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|