OSDN Git Service

Ignore avail freqs when the hrtimer trigger is selected
[android-x86/hardware-intel-libsensors.git] / transform.c
1 /*
2  * Copyright (C) 2014-2015 Intel Corporation.
3  */
4
5 #include <stdlib.h>
6 #include <math.h>
7 #include <utils/Log.h>
8 #include <cutils/properties.h>
9 #include <hardware/sensors.h>
10 #include "calibration.h"
11 #include "common.h"
12 #include "description.h"
13 #include "transform.h"
14 #include "utils.h"
15 #include "filtering.h"
16 #include "enumeration.h"
17
18 #define GYRO_MIN_SAMPLES 5 /* Drop first few gyro samples after enable */
19
20
21 /*----------------------------------------------------------------------------*/
22
23
24 /* Macros related to Intel Sensor Hub */
25
26 #define GRAVITY         9.80665
27
28 /* 720 LSG = 1G */
29 #define LSG             1024.0
30 #define NUMOFACCDATA    8.0
31
32 /* Conversion of acceleration data to SI units (m/s^2) */
33 #define CONVERT_A       (GRAVITY_EARTH / LSG / NUMOFACCDATA)
34 #define CONVERT_A_X(x)  ((float(x) / 1000) * (GRAVITY * -1.0))
35 #define CONVERT_A_Y(x)  ((float(x) / 1000) * (GRAVITY * 1.0))
36 #define CONVERT_A_Z(x)  ((float(x) / 1000) * (GRAVITY * 1.0))
37
38 /* Conversion of magnetic data to uT units */
39 #define CONVERT_M       (1.0 / 6.6)
40 #define CONVERT_M_X     (-CONVERT_M)
41 #define CONVERT_M_Y     (-CONVERT_M)
42 #define CONVERT_M_Z     (CONVERT_M)
43
44 /* Conversion of orientation data to degree units */
45 #define CONVERT_O       (1.0 / 64)
46 #define CONVERT_O_A     (CONVERT_O)
47 #define CONVERT_O_P     (CONVERT_O)
48 #define CONVERT_O_R     (-CONVERT_O)
49
50 /* Conversion of gyro data to SI units (radian/sec) */
51 #define CONVERT_GYRO    (2000.0 / 32767 * M_PI / 180)
52 #define CONVERT_GYRO_X  (-CONVERT_GYRO)
53 #define CONVERT_GYRO_Y  (-CONVERT_GYRO)
54 #define CONVERT_GYRO_Z  (CONVERT_GYRO)
55
56 #define BIT(x) (1 << (x))
57
58 #define PROXIMITY_THRESHOLD 1
59
60 inline unsigned int set_bit_range (int start, int end)
61 {
62         int i;
63         unsigned int value = 0;
64
65         for (i = start; i < end; ++i)
66                 value |= BIT(i);
67
68         return value;
69 }
70
71 inline float convert_from_vtf_format (int size, int exponent, unsigned int value)
72 {
73         int divider = 1;
74         int i;
75         float sample;
76         float mul = 1.0;
77
78         value = value & set_bit_range(0, size * 8);
79
80         if (value & BIT(size*8-1)) {
81                 value =  ((1LL << (size * 8)) - value);
82                 mul = -1.0;
83         }
84
85         sample = value * 1.0;
86
87         if (exponent < 0) {
88                 exponent = abs(exponent);
89                 for (i = 0; i < exponent; ++i)
90                         divider = divider * 10;
91
92                 return mul * sample/divider;
93         }
94
95         return mul * sample * pow(10.0, exponent);
96 }
97
98 /* Platform sensor orientation */
99 #define DEF_ORIENT_ACCEL_X      -1
100 #define DEF_ORIENT_ACCEL_Y      -1
101 #define DEF_ORIENT_ACCEL_Z      -1
102
103 #define DEF_ORIENT_GYRO_X       1
104 #define DEF_ORIENT_GYRO_Y       1
105 #define DEF_ORIENT_GYRO_Z       1
106
107 /* G to m/s^2 */
108 #define CONVERT_FROM_VTF16(s,d,x)      convert_from_vtf_format(s,d,x)
109 #define CONVERT_A_G_VTF16E14_X(s,d,x)  (DEF_ORIENT_ACCEL_X * convert_from_vtf_format(s,d,x) * GRAVITY)
110 #define CONVERT_A_G_VTF16E14_Y(s,d,x)  (DEF_ORIENT_ACCEL_Y * convert_from_vtf_format(s,d,x) * GRAVITY)
111 #define CONVERT_A_G_VTF16E14_Z(s,d,x)  (DEF_ORIENT_ACCEL_Z * convert_from_vtf_format(s,d,x) * GRAVITY)
112
113 /* Degree/sec to radian/sec */
114 #define CONVERT_G_D_VTF16E14_X(s,d,x)  (DEF_ORIENT_GYRO_X * convert_from_vtf_format(s,d,x) * M_PI / 180)
115 #define CONVERT_G_D_VTF16E14_Y(s,d,x)  (DEF_ORIENT_GYRO_Y * convert_from_vtf_format(s,d,x) * M_PI / 180)
116 #define CONVERT_G_D_VTF16E14_Z(s,d,x)  (DEF_ORIENT_GYRO_Z * convert_from_vtf_format(s,d,x) * M_PI / 180)
117
118 /* Milli gauss to micro tesla */
119 #define CONVERT_M_MG_VTF16E14_X(s,d,x) (convert_from_vtf_format(s,d,x) / 10)
120 #define CONVERT_M_MG_VTF16E14_Y(s,d,x) (convert_from_vtf_format(s,d,x) / 10)
121 #define CONVERT_M_MG_VTF16E14_Z(s,d,x) (convert_from_vtf_format(s,d,x) / 10)
122
123
124 static int64_t sample_as_int64 (unsigned char* sample, datum_info_t* type)
125 {
126         uint64_t u64;
127         int i;
128         int zeroed_bits = type->storagebits - type->realbits;
129         uint64_t sign_mask;
130         uint64_t value_mask;
131
132         u64 = 0;
133
134         if (type->endianness == 'b')
135                 for (i=0; i<type->storagebits/8; i++)
136                         u64 = (u64 << 8) | sample[i];
137         else
138                 for (i=type->storagebits/8 - 1; i>=0; i--)
139                         u64 = (u64 << 8) | sample[i];
140
141         u64 = (u64 >> type->shift) & (~0ULL >> zeroed_bits);
142
143         if (type->sign == 'u')
144                 return (int64_t) u64; /* We don't handle unsigned 64 bits int */
145
146         /* Signed integer */
147
148         switch (type->realbits) {
149                 case 0 ... 1:
150                         return 0;
151
152                 case 8:
153                         return (int64_t) (int8_t) u64;
154
155                 case 16:
156                         return (int64_t) (int16_t) u64;
157
158                 case 32:
159                         return (int64_t) (int32_t) u64;
160
161                 case 64:
162                         return (int64_t) u64;
163
164                 default:
165                         sign_mask = 1 << (type->realbits-1);
166                         value_mask = sign_mask - 1;
167
168                         if (u64 & sign_mask)
169                                 return - ((~u64 & value_mask) + 1);     /* Negative value: return 2-complement */
170                         else
171                                 return (int64_t) u64;                   /* Positive value */
172         }
173 }
174
175
176 static void reorder_fields (float* data, unsigned char map[MAX_CHANNELS])
177 {
178         int i;
179         float temp[MAX_CHANNELS];
180
181         for (i=0; i<MAX_CHANNELS; i++)
182                 temp[i] = data[map[i]];
183
184         for (i=0; i<MAX_CHANNELS; i++)
185                 data[i] = temp[i];
186 }
187
188 static void mount_correction (float* data, float mm[9])
189 {
190         int i;
191         float temp[3];
192
193         for (i=0; i<3; i++)
194                 temp[i] = data[0] * mm[i * 3] + data[1] * mm[i * 3 + 1] + data[2] * mm[i * 3 + 2];
195
196         for (i=0; i<3; i++)
197                 data[i] = temp[i];
198 }
199
200 static void clamp_gyro_readings_to_zero (int s, sensors_event_t* data)
201 {
202         float x, y, z;
203         float near_zero;
204
205         x = data->data[0];
206         y = data->data[1];
207         z = data->data[2];
208
209         /* If we're calibrated, don't filter out as much */
210         if (sensor[s].cal_level > 0)
211                 near_zero = 0.02; /* rad/s */
212         else
213                 near_zero = 0.1;
214
215         /* If motion on all axes is small enough */
216         if (fabs(x) < near_zero && fabs(y) < near_zero && fabs(z) < near_zero) {
217
218                 /*
219                  * Report that we're not moving at all... but not exactly zero as composite sensors (orientation, rotation vector) don't
220                  * seem to react very well to it.
221                  */
222
223                 data->data[0] *= 0.000001;
224                 data->data[1] *= 0.000001;
225                 data->data[2] *= 0.000001;
226         }
227 }
228
229
230 static void process_event_gyro_uncal (int s, int i, sensors_event_t* data)
231 {
232         gyro_cal_t* gyro_data;
233
234         if (sensor[s].type == SENSOR_TYPE_GYROSCOPE) {
235                 gyro_data = (gyro_cal_t*) sensor[s].cal_data;
236
237                 memcpy(&sensor[i].sample, data, sizeof(sensors_event_t));
238
239                 sensor[i].sample.type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
240                 sensor[i].sample.sensor = s;
241
242                 sensor[i].sample.data[0] = data->data[0] + gyro_data->bias_x;
243                 sensor[i].sample.data[1] = data->data[1] + gyro_data->bias_y;
244                 sensor[i].sample.data[2] = data->data[2] + gyro_data->bias_z;
245
246                 sensor[i].sample.uncalibrated_gyro.bias[0] = gyro_data->bias_x;
247                 sensor[i].sample.uncalibrated_gyro.bias[1] = gyro_data->bias_y;
248                 sensor[i].sample.uncalibrated_gyro.bias[2] = gyro_data->bias_z;
249
250                 sensor[i].report_pending = 1;
251         }
252 }
253
254 static void process_event_magn_uncal (int s, int i, sensors_event_t* data)
255 {
256         compass_cal_t* magn_data;
257
258         if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD) {
259                 magn_data = (compass_cal_t*) sensor[s].cal_data;
260
261                 memcpy(&sensor[i].sample, data, sizeof(sensors_event_t));
262
263                 sensor[i].sample.type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
264                 sensor[i].sample.sensor = s;
265
266                 sensor[i].sample.data[0] = data->data[0] + magn_data->offset[0][0];
267                 sensor[i].sample.data[1] = data->data[1] + magn_data->offset[1][0];
268                 sensor[i].sample.data[2] = data->data[2] + magn_data->offset[2][0];
269
270                 sensor[i].sample.uncalibrated_magnetic.bias[0] = magn_data->offset[0][0];
271                 sensor[i].sample.uncalibrated_magnetic.bias[1] = magn_data->offset[1][0];
272                 sensor[i].sample.uncalibrated_magnetic.bias[2] = magn_data->offset[2][0];
273
274                 sensor[i].report_pending = 1;
275         }
276 }
277
278 static void process_event (int s, sensors_event_t* data)
279 {
280         /*
281          * This gets the real event (post process - calibration, filtering & co.) and makes it into a virtual one.
282          * The specific processing function for each sensor will populate the necessary fields and set up the report pending flag.
283          */
284
285          int i;
286
287          /* Go through out virtual sensors and check if we can use this event */
288          for (i = 0; i < sensor_count; i++)
289                 switch (sensor[i].type) {
290                         case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
291                                 process_event_gyro_uncal(s, i, data);
292                                 break;
293                         case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
294                                 process_event_magn_uncal(s, i, data);
295                                 break;
296                         default:
297                                 break;
298                 }
299 }
300
301
302 static int finalize_sample_default (int s, sensors_event_t* data)
303 {
304         /* Swap fields if we have a custom channel ordering on this sensor */
305         if (sensor[s].quirks & QUIRK_FIELD_ORDERING)
306                 reorder_fields(data->data, sensor[s].order);
307         if (sensor[s].quirks & QUIRK_MOUNTING_MATRIX)
308                 mount_correction(data->data, sensor[s].mounting_matrix);
309
310         sensor[s].event_count++;
311
312         switch (sensor[s].type) {
313                 case SENSOR_TYPE_ACCELEROMETER:
314                         /* Always consider the accelerometer accurate */
315                         data->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
316                         if (sensor[s].quirks & QUIRK_BIASED)
317                                 calibrate_accel(s, data);
318                         denoise(s, data);
319                         break;
320
321                 case SENSOR_TYPE_MAGNETIC_FIELD:
322                         calibrate_compass (s, data);
323                         denoise(s, data);
324                         break;
325
326                 case SENSOR_TYPE_GYROSCOPE:
327
328                         /* Report medium accuracy by default ; higher accuracy levels will be reported once, and if, we achieve  calibration. */
329                         data->gyro.status = SENSOR_STATUS_ACCURACY_MEDIUM;
330
331                         /*
332                          * We're only trying to calibrate data from continuously firing gyroscope drivers, as motion based ones use
333                          * movement thresholds that may lead us to incorrectly estimate bias.
334                          */
335                         if (sensor[s].selected_trigger !=
336                                 sensor[s].motion_trigger_name)
337                                         calibrate_gyro(s, data);
338
339                         /*
340                          * For noisy sensors drop a few samples to make sure we have at least GYRO_MIN_SAMPLES events in the
341                          * filtering queue. This improves mean and std dev.
342                          */
343                         if (sensor[s].filter_type) {
344                                 if (sensor[s].selected_trigger !=
345                                     sensor[s].motion_trigger_name &&
346                                     sensor[s].event_count < GYRO_MIN_SAMPLES)
347                                                 return 0;
348
349                                 denoise(s, data);
350                         }
351
352                         /* Clamp near zero moves to (0,0,0) if appropriate */
353                         clamp_gyro_readings_to_zero(s, data);
354                         break;
355
356                 case SENSOR_TYPE_PROXIMITY:
357                         /*
358                          * See iio spec for in_proximity* - depending on the device
359                          * this value is either in meters either unit-less and cannot
360                          * be translated to SI units. Where the translation is not possible
361                          * lower values indicate something is close and higher ones indicate distance.
362                          */
363                         if (data->data[0] > PROXIMITY_THRESHOLD)
364                                 data->data[0] = PROXIMITY_THRESHOLD;
365
366                         /* ... fall through ... */
367                 case SENSOR_TYPE_LIGHT:
368                 case SENSOR_TYPE_AMBIENT_TEMPERATURE:
369                 case SENSOR_TYPE_TEMPERATURE:
370                 case SENSOR_TYPE_INTERNAL_ILLUMINANCE:
371                 case SENSOR_TYPE_INTERNAL_INTENSITY:
372                         /* Only keep two decimals for these readings */
373                         data->data[0] = 0.01 * ((int) (data->data[0] * 100));
374
375                         /* These are on change sensors ; drop the sample if it has the same value as the previously reported one. */
376                         if (data->data[0] == sensor[s].prev_val.data)
377                                 return 0;
378
379                         sensor[s].prev_val.data = data->data[0];
380                         break;
381                 case SENSOR_TYPE_STEP_COUNTER:
382                         if (data->u64.step_counter == sensor[s].prev_val.data64)
383                                 return 0;
384                         sensor[s].prev_val.data64 = data->u64.data[0];
385                         break;
386
387         }
388
389         /* If there are active virtual sensors depending on this one - process the event */
390         if (sensor[s].ref_count)
391                 process_event(s, data);
392
393
394         return 1; /* Return sample to Android */
395 }
396
397
398 static float transform_sample_default (int s, int c, unsigned char* sample_data)
399 {
400         datum_info_t* sample_type = &sensor[s].channel[c].type_info;
401         int64_t s64 = sample_as_int64(sample_data, sample_type);
402         float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale;
403
404         /* In case correction has been requested using properties, apply it */
405         float correction = sensor[s].channel[c].opt_scale;
406
407         /* Correlated with "acquire_immediate_value" method */
408         if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
409                 return CONVERT_GAUSS_TO_MICROTESLA((sensor[s].offset + s64) * scale) * correction;
410
411         /* Apply default scaling rules */
412         return (sensor[s].offset + s64) * scale * correction;
413 }
414
415
416 static int finalize_sample_ISH (int s, sensors_event_t* data)
417 {
418         float pitch, roll, yaw;
419
420         /* Swap fields if we have a custom channel ordering on this sensor */
421         if (sensor[s].quirks & QUIRK_FIELD_ORDERING)
422                 reorder_fields(data->data, sensor[s].order);
423
424         if (sensor[s].type == SENSOR_TYPE_ORIENTATION) {
425
426                 pitch = data->data[0];
427                 roll = data->data[1];
428                 yaw = data->data[2];
429
430                 data->data[0] = 360.0 - yaw;
431                 data->data[1] = -pitch;
432                 data->data[2] = -roll;
433         }
434
435         /* Add this event to our global records, for filtering purposes */
436         record_sample(s, data);
437
438         return 1; /* Return sample to Android */
439 }
440
441
442 static float transform_sample_ISH (int s, int c, unsigned char* sample_data)
443 {
444         datum_info_t* sample_type = &sensor[s].channel[c].type_info;
445         int val         = (int) sample_as_int64(sample_data, sample_type);
446         float correction;
447         int data_bytes  = (sample_type->realbits)/8;
448         int exponent    = sensor[s].offset;
449
450         /* In case correction has been requested using properties, apply it */
451         correction = sensor[s].channel[c].opt_scale;
452
453         switch (sensor_desc[s].type) {
454                 case SENSOR_TYPE_ACCELEROMETER:
455                         switch (c) {
456                                 case 0:
457                                         return correction * CONVERT_A_G_VTF16E14_X(data_bytes, exponent, val);
458
459                                 case 1:
460                                         return correction * CONVERT_A_G_VTF16E14_Y(data_bytes, exponent, val);
461
462                                 case 2:
463                                         return  correction * CONVERT_A_G_VTF16E14_Z(data_bytes, exponent, val);
464                         }
465                         break;
466
467                 case SENSOR_TYPE_GYROSCOPE:
468                         switch (c) {
469                                 case 0:
470                                         return correction * CONVERT_G_D_VTF16E14_X(data_bytes, exponent, val);
471
472                                 case 1:
473                                         return correction * CONVERT_G_D_VTF16E14_Y(data_bytes, exponent, val);
474
475                                 case 2:
476                                         return  correction * CONVERT_G_D_VTF16E14_Z(data_bytes, exponent, val);
477                         }
478                         break;
479
480                 case SENSOR_TYPE_MAGNETIC_FIELD:
481                         switch (c) {
482                                 case 0:
483                                         return correction * CONVERT_M_MG_VTF16E14_X(data_bytes, exponent, val);
484
485                                 case 1:
486                                         return correction * CONVERT_M_MG_VTF16E14_Y(data_bytes, exponent, val);
487
488                                 case 2:
489                                         return correction * CONVERT_M_MG_VTF16E14_Z(data_bytes, exponent, val);
490                         }
491                         break;
492
493                 case SENSOR_TYPE_LIGHT:
494                         return (float) val;
495
496                 case SENSOR_TYPE_ORIENTATION:
497                         return correction * convert_from_vtf_format(data_bytes, exponent, val);
498
499                 case SENSOR_TYPE_ROTATION_VECTOR:
500                         return correction * convert_from_vtf_format(data_bytes, exponent, val);
501         }
502
503         return 0;
504 }
505
506
507 void select_transform (int s)
508 {
509         char prop_name[PROP_NAME_MAX];
510         char prop_val[PROP_VALUE_MAX];
511         int i                   = sensor[s].catalog_index;
512         const char *prefix      = sensor_catalog[i].tag;
513
514         sprintf(prop_name, PROP_BASE, prefix, "transform");
515
516         if (property_get(prop_name, prop_val, ""))
517                 if (!strcmp(prop_val, "ISH")) {
518                         ALOGI(  "Using Intel Sensor Hub semantics on %s\n", sensor[s].friendly_name);
519
520                         sensor[s].ops.transform = transform_sample_ISH;
521                         sensor[s].ops.finalize = finalize_sample_ISH;
522                         return;
523                 }
524
525         sensor[s].ops.transform = transform_sample_default;
526         sensor[s].ops.finalize = finalize_sample_default;
527 }
528
529
530 float acquire_immediate_float_value (int s, int c)
531 {
532         char sysfs_path[PATH_MAX];
533         float val;
534         int ret;
535         int dev_num = sensor[s].dev_num;
536         int i = sensor[s].catalog_index;
537         const char* raw_path = sensor_catalog[i].channel[c].raw_path;
538         const char* input_path = sensor_catalog[i].channel[c].input_path;
539         float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale;
540         float offset = sensor[s].offset;
541         float correction;
542
543         /* In case correction has been requested using properties, apply it */
544         correction = sensor[s].channel[c].opt_scale;
545
546         /* Acquire a sample value for sensor s / channel c through sysfs */
547
548         if (sensor[s].channel[c].input_path_present) {
549                 sprintf(sysfs_path, BASE_PATH "%s", dev_num, input_path);
550                 ret = sysfs_read_float(sysfs_path, &val);
551
552                 if (!ret) {
553                         if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
554                                 return CONVERT_GAUSS_TO_MICROTESLA (val * correction);
555                         return val * correction;
556                 }
557         }
558
559         if (!sensor[s].channel[c].raw_path_present)
560                 return 0;
561
562         sprintf(sysfs_path, BASE_PATH "%s", dev_num, raw_path);
563         ret = sysfs_read_float(sysfs_path, &val);
564
565         if (ret == -1)
566                 return 0;
567
568         /*
569          * There is no transform ops defined yet for raw sysfs values.
570          * Use this function to perform transformation as well.
571          */
572         if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD)
573                 return CONVERT_GAUSS_TO_MICROTESLA ((val + offset) * scale) * correction;
574
575         return (val + offset) * scale * correction;
576 }
577
578 uint64_t acquire_immediate_uint64_value (int s, int c)
579 {
580         char sysfs_path[PATH_MAX];
581         uint64_t val;
582         int ret;
583         int dev_num = sensor[s].dev_num;
584         int i = sensor[s].catalog_index;
585         const char* raw_path = sensor_catalog[i].channel[c].raw_path;
586         const char* input_path = sensor_catalog[i].channel[c].input_path;
587         float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale;
588         float offset = sensor[s].offset;
589         int sensor_type = sensor_catalog[i].type;
590         float correction;
591
592         /* In case correction has been requested using properties, apply it */
593         correction = sensor[s].channel[c].opt_scale;
594
595         /* Acquire a sample value for sensor s / channel c through sysfs */
596
597         if (sensor[s].channel[c].input_path_present) {
598                 sprintf(sysfs_path, BASE_PATH "%s", dev_num, input_path);
599                 ret = sysfs_read_uint64(sysfs_path, &val);
600
601                 if (!ret)
602                         return val * correction;
603         };
604
605         if (!sensor[s].channel[c].raw_path_present)
606                 return 0;
607
608         sprintf(sysfs_path, BASE_PATH "%s", dev_num, raw_path);
609         ret = sysfs_read_uint64(sysfs_path, &val);
610
611         if (ret == -1)
612                 return 0;
613
614         return (val + offset) * scale * correction;
615 }