| /* |
| * STMicroelectronics Magnetometer Sensor Class |
| * |
| * Copyright 2013-2015 STMicroelectronics Inc. |
| * Author: Denis Ciocca - <[email protected]> |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"). |
| */ |
| |
| #include <fcntl.h> |
| #include <assert.h> |
| #include <signal.h> |
| |
| #include "Magnetometer.h" |
| |
| #ifdef CONFIG_ST_HAL_MAGN_CALIB_ENABLED |
| extern "C" { |
| #include "STCompass_API.h" |
| } |
| #endif /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| |
| Magnetometer::Magnetometer(HWSensorBaseCommonData *data, const char *name, |
| struct iio_sampling_frequency_available *sfa, int handle, |
| unsigned int hw_fifo_len, int pipe_data_fd, float power_consumption, bool wakeup) : |
| HWSensorBaseWithPollrate(data, name, sfa, handle, |
| SENSOR_TYPE_MAGNETIC_FIELD, hw_fifo_len, pipe_data_fd, power_consumption) |
| { |
| sensor_t_data.stringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD; |
| sensor_t_data.flags = SENSOR_FLAG_CONTINUOUS_MODE; |
| |
| if (wakeup) |
| sensor_t_data.flags |= SENSOR_FLAG_WAKE_UP; |
| |
| sensor_t_data.resolution = GAUSS_TO_UTESLA(data->channels[0].scale); |
| sensor_t_data.maxRange = sensor_t_data.resolution * (pow(2.0, data->channels[0].bits_used - 1.0) - 1); |
| |
| #ifdef CONFIG_ST_HAL_MAGN_CALIB_ENABLED |
| type_dependencies[SENSOR_BASE_DEPENDENCY_0] = SENSOR_TYPE_ACCELEROMETER; |
| #endif /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| } |
| |
| Magnetometer::~Magnetometer() |
| { |
| |
| } |
| |
| int Magnetometer::Enable(int handle, bool enable) |
| { |
| #ifdef CONFIG_ST_HAL_MAGN_CALIB_ENABLED |
| int err; |
| bool old_status; |
| |
| old_status = GetStatus(); |
| |
| err = HWSensorBaseWithPollrate::Enable(handle, enable); |
| if (err < 0) |
| return err; |
| |
| if (GetStatus() && !old_status) |
| STCompass_API_Init(NULL); |
| |
| return 0; |
| #else /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| return HWSensorBaseWithPollrate::Enable(handle, enable); |
| #endif /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| } |
| |
| void Magnetometer::ProcessData(SensorBaseData *data) |
| { |
| float tmp_raw_data[num_data_axis]; |
| #ifdef CONFIG_ST_HAL_MAGN_CALIB_ENABLED |
| int64_t time_diff = 0; |
| int err, nomaxdata = 10; |
| SensorBaseData accel_data; |
| #endif /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| |
| memcpy(tmp_raw_data, data->raw, num_data_axis * sizeof(float)); |
| |
| data->raw[0] = GAUSS_TO_UTESLA(SENSOR_X_DATA(tmp_raw_data[0], tmp_raw_data[1], tmp_raw_data[2], CONFIG_ST_HAL_MAGN_ROT_MATRIX)); |
| data->raw[1] = GAUSS_TO_UTESLA(SENSOR_Y_DATA(tmp_raw_data[0], tmp_raw_data[1], tmp_raw_data[2], CONFIG_ST_HAL_MAGN_ROT_MATRIX)); |
| data->raw[2] = GAUSS_TO_UTESLA(SENSOR_Z_DATA(tmp_raw_data[0], tmp_raw_data[1], tmp_raw_data[2], CONFIG_ST_HAL_MAGN_ROT_MATRIX)); |
| |
| #ifdef CONFIG_ST_HAL_MAGN_CALIB_ENABLED |
| do { |
| err = GetLatestValidDataFromDependency(SENSOR_BASE_DEPENDENCY_0, &accel_data); |
| if (err < 0) { |
| nomaxdata--; |
| usleep(200); |
| continue; |
| } |
| |
| time_diff = data->timestamp - accel_data.timestamp; |
| |
| } while ((time_diff >= GetRealPollrate()) && (nomaxdata > 0)); |
| |
| if (err >= 0) |
| STCompass_API_Run(accel_data.raw, data->raw); |
| |
| sensor_event.magnetic.status = STCompass_API_Get_Calibration_Data(data->offset); |
| #else /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| sensor_event.magnetic.status = SENSOR_STATUS_UNRELIABLE; |
| #endif /* CONFIG_ST_HAL_MAGN_CALIB_ENABLED */ |
| |
| data->processed[0] = data->raw[0] - data->offset[0]; |
| data->processed[1] = data->raw[1] - data->offset[1]; |
| data->processed[2] = data->raw[2] - data->offset[2]; |
| |
| sensor_event.magnetic.azimuth = data->processed[0]; |
| sensor_event.magnetic.pitch = data->processed[1]; |
| sensor_event.magnetic.roll = data->processed[2]; |
| sensor_event.timestamp = data->timestamp; |
| |
| HWSensorBaseWithPollrate::WriteDataToPipe(); |
| HWSensorBaseWithPollrate::ProcessData(data); |
| } |