1 /* Medfield sensor plugins
2 * Copyright (C) 2013 Intel Corporation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; version 2.1.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301USA
19 #include "accelprocessor.h"
20 #include <sensor_accel.h>
24 static const float XY_THRESHOLD = 2;
26 static const float RADIAN_MULTIPLIER = 180/M_PI;
28 static const int ROTATION_THD = 45;
30 static const int ROTATION_0 = 0;
31 static const int ROTATION_90 = 90;
32 static const int ROTATION_180 = 180;
33 static const int ROTATION_360 = 360;
35 static const char *ROTATION_KEY = DEFAULT_SENSOR_KEY_PREFIX"10001";
37 AccelProcessor::AccelProcessor():
45 find_input_device_by_name("accel");
46 BaseProcessor::find_device_from_udev("accel");
47 mSysfsPath.append("/lis3dh");
50 mSupportedEvents.push_back(ACCELEROMETER_EVENT_ROTATION_CHECK);
51 mSupportedEvents.push_back(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
52 mSupportedEvents.push_back(ACCELEROMETER_EVENT_ORIENTATION_DATA_REPORT_ON_TIME);
55 bool AccelProcessor::fill_values(unsigned int type, int &count,
56 data_unit_idx_t &unit, data_accuracy &accuracy)
59 if (type == ACCELEROMETER_BASE_DATA_SET) {
63 DbgPrint("Returning ACCELEROMETER_BASE_DATA_SET -mX, mY, mZ");
65 unit = IDX_UNIT_METRE_PER_SECOND_SQUARED;
66 accuracy = ACCURACY_GOOD;
71 if (type == ACCELEROMETER_ORIENTATION_DATA_SET) {
76 unit = IDX_UNIT_DEGREE;
77 accuracy = ACCURACY_NORMAL;
84 int AccelProcessor::get_property(unsigned int property_level, base_property_struct &result)
86 strcpy(result.sensor_name, "lis3dh");
87 strcpy(result.sensor_vendor, "st");
89 if (property_level == ACCELEROMETER_BASE_DATA_SET) {
90 result.sensor_unit_idx = IDX_UNIT_METRE_PER_SECOND_SQUARED;
91 result.sensor_min_range = -20;
92 result.sensor_max_range = 20;
93 result.sensor_resolution = 0.0002;
94 } else if (property_level == ACCELEROMETER_ORIENTATION_DATA_SET) {
95 result.sensor_unit_idx = IDX_UNIT_DEGREE;
96 result.sensor_min_range = ROTATION_0;
97 result.sensor_max_range = ROTATION_360;
98 result.sensor_resolution = 0.0002;
106 void AccelProcessor::calculateOrientation()
108 double absx = mX < 0 ? -mX : mX;
109 double absy = mY < 0 ? -mY : mY;
111 double atan_value = 0;
112 if (mZ == 0 && mX == 0)
115 atan_value = atan2(mZ,mX);
117 //Todo: Check if calculations could be avoided here
118 int angle = ((int) (atan_value * (RADIAN_MULTIPLIER)));
121 if (angle > 0 && angle <= 180) {
122 mGamma = (angle-ROTATION_90);
125 else if (angle <= 0 && angle >= -ROTATION_180) {
126 mGamma = -(ROTATION_90+(angle));
129 DbgPrint("Angle is %d and gamma %d\n",angle,mGamma);
131 double normZ = mZ / 9.8;
134 } else if ( normZ < -1.0 ) {
138 DbgPrint("Normalized zeta is %f\n",normZ);
140 mBeta = (int)( acos(normZ) *(RADIAN_MULTIPLIER));
144 if (absx < XY_THRESHOLD && absy < XY_THRESHOLD ) {
145 DbgPrint("absx %f absy %f\n",absx,absy);
149 angle = (int) (atan2(mY,mX)*RADIAN_MULTIPLIER);
150 DbgPrint("Angle between y and x is is %d",angle);
151 int section = (angle+ROTATION_180)/45;
152 DbgPrint("\n\nSection is %d\n\n",section);
154 /**************************
155 * ->>>>> Read clockwise, number presents power button
164 if(section == 6 || section == 5) {
165 DbgPrint("Power button up");
166 mRotation.rotation = ROTATION_EVENT_0;
167 mRotation.rm[0] = ROTATION_PORTRAIT_TOP;
168 mRotation.rm[1] = ROTATION_LANDSCAPE_LEFT;
171 else if(section == 4 || section == 3) {
172 DbgPrint("Power button right");
173 mRotation.rotation = ROTATION_EVENT_270;
174 mRotation.rm[0] = ROTATION_LANDSCAPE_RIGHT;
175 mRotation.rm[1] = ROTATION_PORTRAIT_TOP;
178 else if (section == 2 || section == 1) {
179 DbgPrint("Power button down");
180 mRotation.rotation = ROTATION_EVENT_180;
181 mRotation.rm[0] = ROTATION_PORTRAIT_BTM;
182 mRotation.rm[1] = ROTATION_LANDSCAPE_LEFT;
186 DbgPrint("Power button left");
187 mRotation.rotation = ROTATION_EVENT_90;
188 mRotation.rm[0] = ROTATION_LANDSCAPE_LEFT;
189 mRotation.rm[1] = ROTATION_PORTRAIT_BTM;
193 void AccelProcessor::process_input_events(const std::vector <input_event *> &events)
200 BaseProcessor::process_input_events(events);
202 //Sensors input z and y value in negative from value
203 //expected from sensor framework
204 //and all values as integer (multiplied by 100)
205 mX = mValues[0] /= 100.0;
206 mY = mValues[1] /= -100.0;
207 mZ = mValues[2] /= -100.0;
209 accelerometer_rotate_state oldRotation = mRotation.rotation;
210 calculateOrientation();
211 if (oldRotation != mRotation.rotation) {
212 vconf_set_int(ROTATION_KEY, mRotation.rotation);