315 lines
11 KiB
C
Executable File
315 lines
11 KiB
C
Executable File
/* --------------------------------------------------------------------------------------------------------
|
|
* Copyright(C), 2010-2011, Fuzhou Rockchip Co. ,Ltd. All Rights Reserved.
|
|
*
|
|
* File: Acc_mma8452.c
|
|
*
|
|
* Desc: 实现 akmd8975 要求的 accelerometer sensor 的功能接口 : 开启, 关闭, 获取数据等.
|
|
*
|
|
* -----------------------------------------------------------------------------------
|
|
* < 习语 和 缩略语 > :
|
|
*
|
|
* acc : accelerometer sensor, "g sensor" 的 别名.
|
|
*
|
|
* -----------------------------------------------------------------------------------
|
|
* < 内部模块 or 对象的层次结构 > :
|
|
*
|
|
* -----------------------------------------------------------------------------------
|
|
* < 功能实现的基本流程 > :
|
|
*
|
|
* -----------------------------------------------------------------------------------
|
|
* < 关键标识符 > :
|
|
*
|
|
* -----------------------------------------------------------------------------------
|
|
* < 本模块实现依赖的外部模块 > :
|
|
* ...
|
|
* -----------------------------------------------------------------------------------
|
|
* Note:
|
|
*
|
|
* Author: ChenZhen
|
|
*
|
|
* --------------------------------------------------------------------------------------------------------
|
|
* Version:
|
|
* v1.0 : init version
|
|
* --------------------------------------------------------------------------------------------------------
|
|
* Log:
|
|
----Wed Jan 19 18:55:55 2011 v1.0
|
|
*
|
|
* --------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Include Files
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <signal.h>
|
|
#include <pthread.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
#include "mma8452_kernel.h"
|
|
|
|
#include "AKCommon.h"
|
|
#include "AK8975Driver.h"
|
|
#include "Acc_mma8452.h"
|
|
|
|
//#define ENABLE_DEBUG_LOG
|
|
#include "custom_log.h"
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Local Macros
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/** path to accelerometer control device. */
|
|
#define ASENSOR_PATH "/dev/mma8452_daemon"
|
|
|
|
/** 表征相同的 加速度物理量的时, "Android 上层使用的 数值" 和 "sensor 数据设备送出的 数值" 之间的比值. */
|
|
#define ACCELERATION_RATIO_ANDROID_TO_HW (9.80665f / 1000000)
|
|
|
|
/** "sDisableAccTimer" 在本 app 模块 scope 中的标识 ID. */
|
|
#define APP_TIME_ID__DISABLE_ACC (1)
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Local Typedefs
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
typedef char bool;
|
|
|
|
#undef TRUE
|
|
#define TRUE 1
|
|
|
|
#undef FALSE
|
|
#define FALSE 0
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* External Function Prototypes (referenced in other file)
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Local Function Prototypes
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
void onTimeOut(sigval_t v);
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Local Variables
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/** acc(g sensor) 控制设备(ASENSOR_PATH) 的 FD. */
|
|
static int sAccFd = -1;
|
|
|
|
/** timer, 用于定时超时之后 disable acc. 这里是 "系统 timer ID", 动态创建. */
|
|
static timer_t sDisableAccTimer = NULL;
|
|
/** 若在 ENABLE_TIME_OUT 秒内, akmd8975 没有再次读取 acc 数据, 则 disable acc 设备. */
|
|
static const int ENABLE_TIME_OUT = 5;
|
|
|
|
/** 标识当前模块是否 使能了 acc 设备(要求其采集 g sensor 数据). */
|
|
static bool sHasEnabledAcc = FALSE;
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Global Variables
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Global Functions Implementation
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* Open device driver.
|
|
* This function opens device driver of acceleration sensor.
|
|
* Additionally, measurement range is set to +/- 2G mode, bandwidth is set to 25Hz.
|
|
* @return
|
|
* If this function succeeds, the return value is #AKD_SUCCESS.
|
|
* Otherwise the return value is #AKD_FAIL.
|
|
*/
|
|
int16_t Acc_InitDevice(void)
|
|
{
|
|
D("Entered.");
|
|
int16_t result = AKD_SUCCESS;
|
|
struct sigevent se; /* 将用来定义对 timer 超时事件的定制处理方式. */
|
|
struct itimerspec ts; /* 将用于定义超时时间. */
|
|
|
|
/* 尝试打开 acc 控制设备文件. */
|
|
if ( 0 > (sAccFd = open(ASENSOR_PATH, O_RDONLY ) ) )
|
|
{
|
|
E("failed to open acc file '%s', error is '%s'", ASENSOR_PATH, strerror(errno));
|
|
result = AKD_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
/* < 创建 sDisableAccTimer. > */
|
|
memset(&se, 0, sizeof(se) );
|
|
se.sigev_notify = SIGEV_THREAD; /* "A notification function will be called to perform notification". */
|
|
se.sigev_notify_function = onTimeOut; /* 通知回调函数. */
|
|
se.sigev_value.sival_int = APP_TIME_ID__DISABLE_ACC; /* sigev_value : sigev_notify_function 的回调实参. */
|
|
if ( timer_create (CLOCK_REALTIME, &se, &sDisableAccTimer) < 0 )
|
|
{
|
|
E("failed create 'sDisableAccTimer'; error is '%s'.", strerror(errno));
|
|
result = AKD_FAIL;
|
|
goto EXIT;
|
|
}
|
|
// sDisableAccTimer 将在 Acc_GetAccelerationData() 中启动.
|
|
|
|
sHasEnabledAcc = FALSE; // 显式初始化.
|
|
|
|
EXIT:
|
|
if ( AKD_SUCCESS != result )
|
|
{
|
|
if ( NULL != sDisableAccTimer )
|
|
{
|
|
timer_delete(sDisableAccTimer);
|
|
sDisableAccTimer = NULL;
|
|
}
|
|
if ( -1 != sAccFd )
|
|
{
|
|
close(sAccFd);
|
|
sAccFd = -1;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Close device driver.
|
|
* This function closes device drivers of acceleration sensor.
|
|
*/
|
|
void Acc_DeinitDevice(void)
|
|
{
|
|
D("Entered.");
|
|
|
|
timer_delete(sDisableAccTimer);
|
|
sDisableAccTimer = NULL;
|
|
|
|
/* 若 acc 设备已经被启动, 则... */
|
|
if ( sHasEnabledAcc )
|
|
{
|
|
D("to call 'GSENSOR_IOCTL_CLOSE'.");
|
|
if ( ioctl(sAccFd, GSENSOR_IOCTL_CLOSE) < 0 )
|
|
{
|
|
E("failed to disable acc device.");
|
|
}
|
|
sHasEnabledAcc = FALSE;
|
|
}
|
|
|
|
close(sAccFd);
|
|
sAccFd = -1;
|
|
}
|
|
|
|
/**
|
|
* Acquire acceleration data from acceleration sensor and convert it to Android coordinate system.
|
|
* .! : 目前设计为 尽量不阻塞的形式.
|
|
* @param[out] fData
|
|
* A acceleration data array.
|
|
* The coordinate system of the acquired data follows the definition of Android.
|
|
* @return
|
|
* If this function succeeds, the return value is #AKD_SUCCESS.
|
|
* Otherwise the return value is #AKD_FAIL.
|
|
*
|
|
*/
|
|
int16_t Acc_GetAccelerationData(float fData[3])
|
|
{
|
|
int16_t result = AKD_SUCCESS;
|
|
struct itimerspec ts; /* 将用于定义超时时间. */
|
|
|
|
struct sensor_axis accData = {0, 0, 0};
|
|
|
|
/* 若尚未使能 acc, 则... */
|
|
if ( !sHasEnabledAcc )
|
|
{
|
|
/* 使能 acc. */
|
|
if ( 0 > ioctl(sAccFd, GSENSOR_IOCTL_START) )
|
|
{
|
|
E("failed to START acc device; error is '%s'.", strerror(errno));
|
|
result = AKD_FAIL;
|
|
goto EXIT;
|
|
}
|
|
/* 设置采样率. */
|
|
int sample_rate = MMA8452_RATE_12P5; // .! : 暂时先使用 12.5 Hz.
|
|
if ( 0 > ioctl(sAccFd, GSENSOR_IOCTL_APP_SET_RATE, &sample_rate) )
|
|
{
|
|
E("failed to set sample rete of acc device; error is '%s'.", strerror(errno));
|
|
result = AKD_FAIL;
|
|
goto EXIT;
|
|
}
|
|
/* 置位标识. */
|
|
sHasEnabledAcc = TRUE;
|
|
}
|
|
|
|
/* 获取 acc sensor 数据. */ // .! : 尽量不阻塞.
|
|
if ( 0 > ioctl(sAccFd, GSENSOR_IOCTL_GETDATA, &accData) )
|
|
{
|
|
E("failed to GET acc data, error is '%s.'", strerror(errno));
|
|
result = AKD_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
/* 重置 sDisableAccTimer. */
|
|
// D("to reset 'sDisableAccTimer'.");
|
|
memset(&ts, 0, sizeof(ts) );
|
|
ts.it_value.tv_sec = ENABLE_TIME_OUT;
|
|
if ( timer_settime(sDisableAccTimer, 0, &ts, NULL) < 0 )
|
|
{
|
|
E("failed start 'sDisableAccTimer'; error is '%s'.", strerror(errno));
|
|
result = AKD_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
/* 转化为 Android 定义的格式, 待返回. */ // .! : 和 HAL 的 MmaSensor.cpp 中一致, 使用 默认横屏坐标定义 g sensor 数据.
|
|
fData[0] = ( (accData.x) * ACCELERATION_RATIO_ANDROID_TO_HW);
|
|
fData[1] = ( (accData.y) * ACCELERATION_RATIO_ANDROID_TO_HW);
|
|
fData[2] = ( (accData.z) * ACCELERATION_RATIO_ANDROID_TO_HW);
|
|
D_WHEN_REPEAT(100, "got acc sensor data : x = %f, y = %f, z = %f.", fData[0], fData[1], fData[2] );
|
|
|
|
EXIT:
|
|
return result;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------------------------------
|
|
* Local Functions Implementation
|
|
* ---------------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
/**
|
|
* sDisableAccTimer 超时的通知回调.
|
|
*/
|
|
void onTimeOut(sigval_t v)
|
|
{
|
|
int appTimerId = v.sival_int;
|
|
I("'sDisableAccTimer' timers out, appTimerId = %d.", appTimerId);
|
|
switch ( appTimerId )
|
|
{
|
|
case APP_TIME_ID__DISABLE_ACC:
|
|
D("to disable acc device.");
|
|
if ( sHasEnabledAcc )
|
|
{
|
|
D("to call 'GSENSOR_IOCTL_CLOSE'.");
|
|
if ( ioctl(sAccFd, GSENSOR_IOCTL_CLOSE) < 0 )
|
|
{
|
|
E("failed to disable acc device.");
|
|
}
|
|
sHasEnabledAcc = FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
E("unknow app timer ID.");
|
|
return;
|
|
}
|
|
}
|
|
|