X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fhardware-intel-libsensors.git;a=blobdiff_plain;f=transform.c;h=7aee50d2c59042489b576ac5b10fbba8e120babf;hp=be4a8f122e19007921b50276583869219cfbef5c;hb=3531d198cfa2bba5cdd7ad9863ecfbf7fdb95a18;hpb=85c42117b76d73d435cea6980ca03228129439dd diff --git a/transform.c b/transform.c index be4a8f1..7aee50d 100644 --- a/transform.c +++ b/transform.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Intel Corporation. + * Copyright (C) 2014-2015 Intel Corporation. */ #include @@ -12,117 +12,118 @@ #include "description.h" #include "transform.h" #include "utils.h" +#include "filtering.h" +#include "enumeration.h" + +#define GYRO_MIN_SAMPLES 5 /* Drop first few gyro samples after enable */ + /*----------------------------------------------------------------------------*/ + /* Macros related to Intel Sensor Hub */ -#define GRAVITY 9.80665f +#define GRAVITY 9.80665 /* 720 LSG = 1G */ -#define LSG (1024.0f) -#define NUMOFACCDATA (8.0f) - -/* conversion of acceleration data to SI units (m/s^2) */ -#define CONVERT_A (GRAVITY_EARTH / LSG / NUMOFACCDATA) -#define CONVERT_A_X(x) ((float(x)/1000) * (GRAVITY * -1.0)) -#define CONVERT_A_Y(x) ((float(x)/1000) * (GRAVITY * 1.0)) -#define CONVERT_A_Z(x) ((float(x)/1000) * (GRAVITY * 1.0)) - -/* conversion of magnetic data to uT units */ -#define CONVERT_M (1.0f/6.6f) -#define CONVERT_M_X (-CONVERT_M) -#define CONVERT_M_Y (-CONVERT_M) -#define CONVERT_M_Z (CONVERT_M) - -#define CONVERT_GAUSS_TO_MICROTESLA(x) ( (x) * 100 ) - -/* conversion of orientation data to degree units */ -#define CONVERT_O (1.0f/64.0f) -#define CONVERT_O_A (CONVERT_O) -#define CONVERT_O_P (CONVERT_O) -#define CONVERT_O_R (-CONVERT_O) - -/*conversion of gyro data to SI units (radian/sec) */ -#define CONVERT_GYRO ((2000.0f/32767.0f)*((float)M_PI / 180.0f)) -#define CONVERT_GYRO_X (-CONVERT_GYRO) -#define CONVERT_GYRO_Y (-CONVERT_GYRO) -#define CONVERT_GYRO_Z (CONVERT_GYRO) +#define LSG 1024.0 +#define NUMOFACCDATA 8.0 + +/* Conversion of acceleration data to SI units (m/s^2) */ +#define CONVERT_A (GRAVITY_EARTH / LSG / NUMOFACCDATA) +#define CONVERT_A_X(x) ((float(x) / 1000) * (GRAVITY * -1.0)) +#define CONVERT_A_Y(x) ((float(x) / 1000) * (GRAVITY * 1.0)) +#define CONVERT_A_Z(x) ((float(x) / 1000) * (GRAVITY * 1.0)) + +/* Conversion of magnetic data to uT units */ +#define CONVERT_M (1.0 / 6.6) +#define CONVERT_M_X (-CONVERT_M) +#define CONVERT_M_Y (-CONVERT_M) +#define CONVERT_M_Z (CONVERT_M) + +#define CONVERT_GAUSS_TO_MICROTESLA(x) ((x) * 100) + +/* Conversion of orientation data to degree units */ +#define CONVERT_O (1.0 / 64) +#define CONVERT_O_A (CONVERT_O) +#define CONVERT_O_P (CONVERT_O) +#define CONVERT_O_R (-CONVERT_O) + +/* Conversion of gyro data to SI units (radian/sec) */ +#define CONVERT_GYRO (2000.0 / 32767 * M_PI / 180) +#define CONVERT_GYRO_X (-CONVERT_GYRO) +#define CONVERT_GYRO_Y (-CONVERT_GYRO) +#define CONVERT_GYRO_Z (CONVERT_GYRO) #define BIT(x) (1 << (x)) -inline unsigned int set_bit_range(int start, int end) +#define PROXIMITY_THRESHOLD 1 + +inline unsigned int set_bit_range (int start, int end) { - int i; - unsigned int value = 0; + int i; + unsigned int value = 0; + + for (i = start; i < end; ++i) + value |= BIT(i); - for (i = start; i < end; ++i) - value |= BIT(i); - return value; + return value; } -inline float convert_from_vtf_format(int size, int exponent, unsigned int value) +inline float convert_from_vtf_format (int size, int exponent, unsigned int value) { - int divider=1; - int i; - float sample; - int mul = 1.0; - - value = value & set_bit_range(0, size*8); - if (value & BIT(size*8-1)) { - value = ((1LL << (size*8)) - value); - mul = -1.0; - } - sample = value * 1.0; - if (exponent < 0) { - exponent = abs(exponent); - for (i = 0; i < exponent; ++i) { - divider = divider*10; - } - return mul * sample/divider; - } else { - return mul * sample * pow(10.0, exponent); - } + int divider = 1; + int i; + float sample; + float mul = 1.0; + + value = value & set_bit_range(0, size * 8); + + if (value & BIT(size*8-1)) { + value = ((1LL << (size * 8)) - value); + mul = -1.0; + } + + sample = value * 1.0; + + if (exponent < 0) { + exponent = abs(exponent); + for (i = 0; i < exponent; ++i) + divider = divider * 10; + + return mul * sample/divider; + } + + return mul * sample * pow(10.0, exponent); } -// Platform sensor orientation -#define DEF_ORIENT_ACCEL_X -1 -#define DEF_ORIENT_ACCEL_Y -1 -#define DEF_ORIENT_ACCEL_Z -1 - -#define DEF_ORIENT_GYRO_X 1 -#define DEF_ORIENT_GYRO_Y 1 -#define DEF_ORIENT_GYRO_Z 1 - -// G to m/s2 -#define CONVERT_FROM_VTF16(s,d,x) (convert_from_vtf_format(s,d,x)) -#define CONVERT_A_G_VTF16E14_X(s,d,x) (DEF_ORIENT_ACCEL_X *\ - convert_from_vtf_format(s,d,x)*GRAVITY) -#define CONVERT_A_G_VTF16E14_Y(s,d,x) (DEF_ORIENT_ACCEL_Y *\ - convert_from_vtf_format(s,d,x)*GRAVITY) -#define CONVERT_A_G_VTF16E14_Z(s,d,x) (DEF_ORIENT_ACCEL_Z *\ - convert_from_vtf_format(s,d,x)*GRAVITY) - -// Degree/sec to radian/sec -#define CONVERT_G_D_VTF16E14_X(s,d,x) (DEF_ORIENT_GYRO_X *\ - convert_from_vtf_format(s,d,x) * \ - ((float)M_PI/180.0f)) -#define CONVERT_G_D_VTF16E14_Y(s,d,x) (DEF_ORIENT_GYRO_Y *\ - convert_from_vtf_format(s,d,x) * \ - ((float)M_PI/180.0f)) -#define CONVERT_G_D_VTF16E14_Z(s,d,x) (DEF_ORIENT_GYRO_Z *\ - convert_from_vtf_format(s,d,x) * \ - ((float)M_PI/180.0f)) - -// Milli gauss to micro tesla -#define CONVERT_M_MG_VTF16E14_X(s,d,x) (convert_from_vtf_format(s,d,x)/10) -#define CONVERT_M_MG_VTF16E14_Y(s,d,x) (convert_from_vtf_format(s,d,x)/10) -#define CONVERT_M_MG_VTF16E14_Z(s,d,x) (convert_from_vtf_format(s,d,x)/10) +/* Platform sensor orientation */ +#define DEF_ORIENT_ACCEL_X -1 +#define DEF_ORIENT_ACCEL_Y -1 +#define DEF_ORIENT_ACCEL_Z -1 +#define DEF_ORIENT_GYRO_X 1 +#define DEF_ORIENT_GYRO_Y 1 +#define DEF_ORIENT_GYRO_Z 1 + +/* G to m/s^2 */ +#define CONVERT_FROM_VTF16(s,d,x) convert_from_vtf_format(s,d,x) +#define CONVERT_A_G_VTF16E14_X(s,d,x) (DEF_ORIENT_ACCEL_X * convert_from_vtf_format(s,d,x) * GRAVITY) +#define CONVERT_A_G_VTF16E14_Y(s,d,x) (DEF_ORIENT_ACCEL_Y * convert_from_vtf_format(s,d,x) * GRAVITY) +#define CONVERT_A_G_VTF16E14_Z(s,d,x) (DEF_ORIENT_ACCEL_Z * convert_from_vtf_format(s,d,x) * GRAVITY) + +/* Degree/sec to radian/sec */ +#define CONVERT_G_D_VTF16E14_X(s,d,x) (DEF_ORIENT_GYRO_X * convert_from_vtf_format(s,d,x) * M_PI / 180) +#define CONVERT_G_D_VTF16E14_Y(s,d,x) (DEF_ORIENT_GYRO_Y * convert_from_vtf_format(s,d,x) * M_PI / 180) +#define CONVERT_G_D_VTF16E14_Z(s,d,x) (DEF_ORIENT_GYRO_Z * convert_from_vtf_format(s,d,x) * M_PI / 180) + +/* Milli gauss to micro tesla */ +#define CONVERT_M_MG_VTF16E14_X(s,d,x) (convert_from_vtf_format(s,d,x) / 10) +#define CONVERT_M_MG_VTF16E14_Y(s,d,x) (convert_from_vtf_format(s,d,x) / 10) +#define CONVERT_M_MG_VTF16E14_Z(s,d,x) (convert_from_vtf_format(s,d,x) / 10) -/*----------------------------------------------------------------------------*/ -static int64_t sample_as_int64(unsigned char* sample, struct datum_info_t* type) +static int64_t sample_as_int64 (unsigned char* sample, datum_info_t* type) { uint64_t u64; int i; @@ -167,15 +168,14 @@ static int64_t sample_as_int64(unsigned char* sample, struct datum_info_t* type) value_mask = sign_mask - 1; if (u64 & sign_mask) - /* Negative value: return 2-complement */ - return - ((~u64 & value_mask) + 1); + return - ((~u64 & value_mask) + 1); /* Negative value: return 2-complement */ else - return (int64_t) u64; /* Positive value */ + return (int64_t) u64; /* Positive value */ } } -static void reorder_fields(float* data, unsigned char map[MAX_CHANNELS]) +static void reorder_fields (float* data, unsigned char map[MAX_CHANNELS]) { int i; float temp[MAX_CHANNELS]; @@ -187,146 +187,243 @@ static void reorder_fields(float* data, unsigned char map[MAX_CHANNELS]) data[i] = temp[i]; } +static void mount_correction (float* data, float mm[9]) +{ + int i; + float temp[3]; + + for (i=0; i<3; i++) + temp[i] = data[0] * mm[i * 3] + data[1] * mm[i * 3 + 1] + data[2] * mm[i * 3 + 2]; -static void denoise (struct sensor_info_t* si, struct sensors_event_t* data, - int num_fields, int max_samples) + for (i=0; i<3; i++) + data[i] = temp[i]; +} + +static void clamp_gyro_readings_to_zero (int s, sensors_event_t* data) { - /* - * Smooth out incoming data using a moving average over a number of - * samples. We accumulate one second worth of samples, or max_samples, - * depending on which is lower. - */ + float x, y, z; + float near_zero; - int i; - float total; - int f; - int sampling_rate = (int) si->sampling_rate; - int history_size; - - /* Don't denoise anything if we have less than two samples per second */ - if (sampling_rate < 2) - return; - - /* Restrict window size to the min of sampling_rate and max_samples */ - if (sampling_rate > max_samples) - history_size = max_samples; + x = data->data[0]; + y = data->data[1]; + z = data->data[2]; + + /* If we're calibrated, don't filter out as much */ + if (sensor[s].cal_level > 0) + near_zero = 0.02; /* rad/s */ else - history_size = sampling_rate; - - /* Reset history if we're operating on an incorrect window size */ - if (si->history_size != history_size) { - si->history_size = history_size; - si->history_entries = 0; - si->history_index = 0; - si->history = (float*) realloc(si->history, - si->history_size * num_fields * sizeof(float)); + near_zero = 0.1; + + /* If motion on all axes is small enough */ + if (fabs(x) < near_zero && fabs(y) < near_zero && fabs(z) < near_zero) { + + /* + * Report that we're not moving at all... but not exactly zero as composite sensors (orientation, rotation vector) don't + * seem to react very well to it. + */ + + data->data[0] *= 0.000001; + data->data[1] *= 0.000001; + data->data[2] *= 0.000001; } +} - if (!si->history) - return; /* Unlikely, but still... */ - /* Update initialized samples count */ - if (si->history_entries < si->history_size) - si->history_entries++; +static void process_event_gyro_uncal (int s, int i, sensors_event_t* data) +{ + gyro_cal_t* gyro_data; + + if (sensor[s].type == SENSOR_TYPE_GYROSCOPE) { + gyro_data = (gyro_cal_t*) sensor[s].cal_data; - /* Record new sample */ - for (f=0; f < num_fields; f++) - si->history[si->history_index * num_fields + f] = data->data[f]; + memcpy(&sensor[i].sample, data, sizeof(sensors_event_t)); - /* Update our rolling index (next evicted cell) */ - si->history_index = (si->history_index + 1) % si->history_size; + sensor[i].sample.type = SENSOR_TYPE_GYROSCOPE_UNCALIBRATED; + sensor[i].sample.sensor = s; - /* For now simply compute a mobile mean for each field */ - for (f=0; f < num_fields; f++) { - total = 0; + sensor[i].sample.data[0] = data->data[0] + gyro_data->bias_x; + sensor[i].sample.data[1] = data->data[1] + gyro_data->bias_y; + sensor[i].sample.data[2] = data->data[2] + gyro_data->bias_z; - for (i=0; i < si->history_entries; i++) - total += si->history[i * num_fields + f]; + sensor[i].sample.uncalibrated_gyro.bias[0] = gyro_data->bias_x; + sensor[i].sample.uncalibrated_gyro.bias[1] = gyro_data->bias_y; + sensor[i].sample.uncalibrated_gyro.bias[2] = gyro_data->bias_z; - /* Output filtered data */ - data->data[f] = total / si->history_entries; + sensor[i].report_pending = 1; } } +static void process_event_magn_uncal (int s, int i, sensors_event_t* data) +{ + compass_cal_t* magn_data; + + if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD) { + magn_data = (compass_cal_t*) sensor[s].cal_data; + + memcpy(&sensor[i].sample, data, sizeof(sensors_event_t)); + + sensor[i].sample.type = SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED; + sensor[i].sample.sensor = s; + + sensor[i].sample.data[0] = data->data[0] + magn_data->offset[0][0]; + sensor[i].sample.data[1] = data->data[1] + magn_data->offset[1][0]; + sensor[i].sample.data[2] = data->data[2] + magn_data->offset[2][0]; + + sensor[i].sample.uncalibrated_magnetic.bias[0] = magn_data->offset[0][0]; + sensor[i].sample.uncalibrated_magnetic.bias[1] = magn_data->offset[1][0]; + sensor[i].sample.uncalibrated_magnetic.bias[2] = magn_data->offset[2][0]; + + sensor[i].report_pending = 1; + } +} -static int finalize_sample_default(int s, struct sensors_event_t* data) +static void process_event (int s, sensors_event_t* data) { - int i = sensor_info[s].catalog_index; - int sensor_type = sensor_catalog[i].type; + /* + * This gets the real event (post process - calibration, filtering & co.) and makes it into a virtual one. + * The specific processing function for each sensor will populate the necessary fields and set up the report pending flag. + */ + + int i; + + /* Go through out virtual sensors and check if we can use this event */ + for (i = 0; i < sensor_count; i++) + switch (sensor[i].type) { + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + process_event_gyro_uncal(s, i, data); + break; + case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: + process_event_magn_uncal(s, i, data); + break; + default: + break; + } +} + +static int finalize_sample_default (int s, sensors_event_t* data) +{ /* Swap fields if we have a custom channel ordering on this sensor */ - if (sensor_info[s].quirks & QUIRK_FIELD_ORDERING) - reorder_fields(data->data, sensor_info[s].order); + if (sensor[s].quirks & QUIRK_FIELD_ORDERING) + reorder_fields(data->data, sensor[s].order); + if (sensor[s].quirks & QUIRK_MOUNTING_MATRIX) + mount_correction(data->data, sensor[s].mounting_matrix); + + sensor[s].event_count++; - switch (sensor_type) { + switch (sensor[s].type) { case SENSOR_TYPE_ACCELEROMETER: - if (sensor_info[s].quirks & QUIRK_NOISY) - denoise(&sensor_info[s], data, 3, 20); + /* Always consider the accelerometer accurate */ + data->acceleration.status = SENSOR_STATUS_ACCURACY_HIGH; + if (sensor[s].quirks & QUIRK_BIASED) + calibrate_accel(s, data); + denoise(s, data); break; case SENSOR_TYPE_MAGNETIC_FIELD: - calibrate_compass (data, &sensor_info[s], get_timestamp()); - if (sensor_info[s].quirks & QUIRK_NOISY) - denoise(&sensor_info[s], data, 3, 100); + calibrate_compass (s, data); + denoise(s, data); break; case SENSOR_TYPE_GYROSCOPE: - case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: - calibrate_gyro(data, &sensor_info[s]); - if (sensor_info[s].quirks & QUIRK_NOISY) - denoise(&sensor_info[s], data, 3, 20); + + /* Report medium accuracy by default ; higher accuracy levels will be reported once, and if, we achieve calibration. */ + data->gyro.status = SENSOR_STATUS_ACCURACY_MEDIUM; + + /* + * We're only trying to calibrate data from continuously firing gyroscope drivers, as motion based ones use + * movement thresholds that may lead us to incorrectly estimate bias. + */ + if (sensor[s].selected_trigger != + sensor[s].motion_trigger_name) + calibrate_gyro(s, data); + + /* + * For noisy sensors drop a few samples to make sure we have at least GYRO_MIN_SAMPLES events in the + * filtering queue. This improves mean and std dev. + */ + if (sensor[s].filter_type) { + if (sensor[s].selected_trigger != + sensor[s].motion_trigger_name && + sensor[s].event_count < GYRO_MIN_SAMPLES) + return 0; + + denoise(s, data); + } + + /* Clamp near zero moves to (0,0,0) if appropriate */ + clamp_gyro_readings_to_zero(s, data); break; + case SENSOR_TYPE_PROXIMITY: + /* + * See iio spec for in_proximity* - depending on the device + * this value is either in meters either unit-less and cannot + * be translated to SI units. Where the translation is not possible + * lower values indicate something is close and higher ones indicate distance. + */ + if (data->data[0] > PROXIMITY_THRESHOLD) + data->data[0] = PROXIMITY_THRESHOLD; + + /* ... fall through ... */ case SENSOR_TYPE_LIGHT: case SENSOR_TYPE_AMBIENT_TEMPERATURE: case SENSOR_TYPE_TEMPERATURE: + case SENSOR_TYPE_INTERNAL_ILLUMINANCE: + case SENSOR_TYPE_INTERNAL_INTENSITY: /* Only keep two decimals for these readings */ data->data[0] = 0.01 * ((int) (data->data[0] * 100)); - /* ... fall through ... */ - - case SENSOR_TYPE_PROXIMITY: - /* - * These are on change sensors ; drop the sample if it - * has the same value as the previously reported one. - */ - if (data->data[0] == sensor_info[s].prev_val) + /* These are on change sensors ; drop the sample if it has the same value as the previously reported one. */ + if (data->data[0] == sensor[s].prev_val.data) return 0; - sensor_info[s].prev_val = data->data[0]; + sensor[s].prev_val.data = data->data[0]; + break; + case SENSOR_TYPE_STEP_COUNTER: + if (data->u64.step_counter == sensor[s].prev_val.data64) + return 0; + sensor[s].prev_val.data64 = data->u64.data[0]; break; + } + /* If there are active virtual sensors depending on this one - process the event */ + if (sensor[s].ref_count) + process_event(s, data); + + return 1; /* Return sample to Android */ } -static float transform_sample_default(int s, int c, unsigned char* sample_data) +static float transform_sample_default (int s, int c, unsigned char* sample_data) { - struct datum_info_t* sample_type = &sensor_info[s].channel[c].type_info; - int64_t s64 = sample_as_int64(sample_data, sample_type); - float scale = sensor_info[s].scale ? - sensor_info[s].scale : sensor_info[s].channel[c].scale; + datum_info_t* sample_type = &sensor[s].channel[c].type_info; + int64_t s64 = sample_as_int64(sample_data, sample_type); + float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale; /* In case correction has been requested using properties, apply it */ - scale *= sensor_info[s].channel[c].opt_scale; + float correction = sensor[s].channel[c].opt_scale; + + /* Correlated with "acquire_immediate_value" method */ + if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD) + return CONVERT_GAUSS_TO_MICROTESLA((sensor[s].offset + s64) * scale) * correction; /* Apply default scaling rules */ - return (sensor_info[s].offset + s64) * scale; + return (sensor[s].offset + s64) * scale * correction; } -static int finalize_sample_ISH(int s, struct sensors_event_t* data) +static int finalize_sample_ISH (int s, sensors_event_t* data) { - int i = sensor_info[s].catalog_index; - int sensor_type = sensor_catalog[i].type; float pitch, roll, yaw; /* Swap fields if we have a custom channel ordering on this sensor */ - if (sensor_info[s].quirks & QUIRK_FIELD_ORDERING) - reorder_fields(data->data, sensor_info[s].order); + if (sensor[s].quirks & QUIRK_FIELD_ORDERING) + reorder_fields(data->data, sensor[s].order); - if (sensor_type == SENSOR_TYPE_ORIENTATION) { + if (sensor[s].type == SENSOR_TYPE_ORIENTATION) { pitch = data->data[0]; roll = data->data[1]; @@ -337,92 +434,72 @@ static int finalize_sample_ISH(int s, struct sensors_event_t* data) data->data[2] = -roll; } + /* Add this event to our global records, for filtering purposes */ + record_sample(s, data); + return 1; /* Return sample to Android */ } -static float transform_sample_ISH(int s, int c, unsigned char* sample_data) +static float transform_sample_ISH (int s, int c, unsigned char* sample_data) { - struct datum_info_t* sample_type = &sensor_info[s].channel[c].type_info; + datum_info_t* sample_type = &sensor[s].channel[c].type_info; int val = (int) sample_as_int64(sample_data, sample_type); - int i = sensor_info[s].catalog_index; - int sensor_type = sensor_catalog[i].type; float correction; int data_bytes = (sample_type->realbits)/8; - int exponent = sensor_info[s].offset; + int exponent = sensor[s].offset; /* In case correction has been requested using properties, apply it */ - correction = sensor_info[s].channel[c].opt_scale; + correction = sensor[s].channel[c].opt_scale; - switch (sensor_type) { + switch (sensor_desc[s].type) { case SENSOR_TYPE_ACCELEROMETER: switch (c) { case 0: - return correction * - CONVERT_A_G_VTF16E14_X( - data_bytes, exponent, val); + return correction * CONVERT_A_G_VTF16E14_X(data_bytes, exponent, val); case 1: - return correction * - CONVERT_A_G_VTF16E14_Y( - data_bytes, exponent, val); + return correction * CONVERT_A_G_VTF16E14_Y(data_bytes, exponent, val); case 2: - return correction * - CONVERT_A_G_VTF16E14_Z( - data_bytes, exponent, val); + return correction * CONVERT_A_G_VTF16E14_Z(data_bytes, exponent, val); } break; - case SENSOR_TYPE_GYROSCOPE: switch (c) { case 0: - return correction * - CONVERT_G_D_VTF16E14_X( - data_bytes, exponent, val); + return correction * CONVERT_G_D_VTF16E14_X(data_bytes, exponent, val); case 1: - return correction * - CONVERT_G_D_VTF16E14_Y( - data_bytes, exponent, val); + return correction * CONVERT_G_D_VTF16E14_Y(data_bytes, exponent, val); case 2: - return correction * - CONVERT_G_D_VTF16E14_Z( - data_bytes, exponent, val); + return correction * CONVERT_G_D_VTF16E14_Z(data_bytes, exponent, val); } break; case SENSOR_TYPE_MAGNETIC_FIELD: switch (c) { case 0: - return correction * - CONVERT_M_MG_VTF16E14_X( - data_bytes, exponent, val); + return correction * CONVERT_M_MG_VTF16E14_X(data_bytes, exponent, val); case 1: - return correction * - CONVERT_M_MG_VTF16E14_Y( - data_bytes, exponent, val); + return correction * CONVERT_M_MG_VTF16E14_Y(data_bytes, exponent, val); case 2: - return correction * - CONVERT_M_MG_VTF16E14_Z( - data_bytes, exponent, val); + return correction * CONVERT_M_MG_VTF16E14_Z(data_bytes, exponent, val); } break; case SENSOR_TYPE_LIGHT: - return (float) val; + return (float) val; case SENSOR_TYPE_ORIENTATION: - return correction * convert_from_vtf_format( - data_bytes, exponent, val); + return correction * convert_from_vtf_format(data_bytes, exponent, val); case SENSOR_TYPE_ROTATION_VECTOR: - return correction * convert_from_vtf_format( - data_bytes, exponent, val); + return correction * convert_from_vtf_format(data_bytes, exponent, val); } return 0; @@ -433,57 +510,52 @@ void select_transform (int s) { char prop_name[PROP_NAME_MAX]; char prop_val[PROP_VALUE_MAX]; - int i = sensor_info[s].catalog_index; + int i = sensor[s].catalog_index; const char *prefix = sensor_catalog[i].tag; sprintf(prop_name, PROP_BASE, prefix, "transform"); - if (property_get(prop_name, prop_val, "")) { + if (property_get(prop_name, prop_val, "")) if (!strcmp(prop_val, "ISH")) { - ALOGI( "Using Intel Sensor Hub semantics on %s\n", - sensor_info[s].friendly_name); + ALOGI( "Using Intel Sensor Hub semantics on %s\n", sensor[s].friendly_name); - sensor_info[s].ops.transform = transform_sample_ISH; - sensor_info[s].ops.finalize = finalize_sample_ISH; + sensor[s].ops.transform = transform_sample_ISH; + sensor[s].ops.finalize = finalize_sample_ISH; return; } - } - sensor_info[s].ops.transform = transform_sample_default; - sensor_info[s].ops.finalize = finalize_sample_default; + sensor[s].ops.transform = transform_sample_default; + sensor[s].ops.finalize = finalize_sample_default; } -float acquire_immediate_value(int s, int c) +float acquire_immediate_float_value (int s, int c) { char sysfs_path[PATH_MAX]; float val; int ret; - int dev_num = sensor_info[s].dev_num; - int i = sensor_info[s].catalog_index; + int dev_num = sensor[s].dev_num; + int i = sensor[s].catalog_index; const char* raw_path = sensor_catalog[i].channel[c].raw_path; const char* input_path = sensor_catalog[i].channel[c].input_path; - float scale = sensor_info[s].scale ? - sensor_info[s].scale : sensor_info[s].channel[c].scale; - float offset = sensor_info[s].offset; - int sensor_type = sensor_catalog[i].type; + float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale; + float offset = sensor[s].offset; float correction; /* In case correction has been requested using properties, apply it */ - correction = sensor_info[s].channel[c].opt_scale; + correction = sensor[s].channel[c].opt_scale; /* Acquire a sample value for sensor s / channel c through sysfs */ - if (input_path[0]) { + if (sensor[s].channel[c].input_path_present) { sprintf(sysfs_path, BASE_PATH "%s", dev_num, input_path); ret = sysfs_read_float(sysfs_path, &val); - if (!ret) { + if (!ret) return val * correction; - } - }; + } - if (!raw_path[0]) + if (!sensor[s].channel[c].raw_path_present) return 0; sprintf(sysfs_path, BASE_PATH "%s", dev_num, raw_path); @@ -493,12 +565,50 @@ float acquire_immediate_value(int s, int c) return 0; /* - There is no transform ops defined yet for Raw sysfs values - Use this function to perform transformation as well. - */ - if (sensor_type == SENSOR_TYPE_MAGNETIC_FIELD) - return CONVERT_GAUSS_TO_MICROTESLA ((val + offset) * scale) * - correction; + * There is no transform ops defined yet for raw sysfs values. + * Use this function to perform transformation as well. + */ + if (sensor[s].type == SENSOR_TYPE_MAGNETIC_FIELD) + return CONVERT_GAUSS_TO_MICROTESLA ((val + offset) * scale) * correction; + + return (val + offset) * scale * correction; +} + +uint64_t acquire_immediate_uint64_value (int s, int c) +{ + char sysfs_path[PATH_MAX]; + uint64_t val; + int ret; + int dev_num = sensor[s].dev_num; + int i = sensor[s].catalog_index; + const char* raw_path = sensor_catalog[i].channel[c].raw_path; + const char* input_path = sensor_catalog[i].channel[c].input_path; + float scale = sensor[s].scale ? sensor[s].scale : sensor[s].channel[c].scale; + float offset = sensor[s].offset; + int sensor_type = sensor_catalog[i].type; + float correction; + + /* In case correction has been requested using properties, apply it */ + correction = sensor[s].channel[c].opt_scale; + + /* Acquire a sample value for sensor s / channel c through sysfs */ + + if (sensor[s].channel[c].input_path_present) { + sprintf(sysfs_path, BASE_PATH "%s", dev_num, input_path); + ret = sysfs_read_uint64(sysfs_path, &val); + + if (!ret) + return val * correction; + }; + + if (!sensor[s].channel[c].raw_path_present) + return 0; + + sprintf(sysfs_path, BASE_PATH "%s", dev_num, raw_path); + ret = sysfs_read_uint64(sysfs_path, &val); + + if (ret == -1) + return 0; return (val + offset) * scale * correction; }