diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | ash/ash.mk | 16 | ||||
-rw-r--r-- | ash/platform/linux/ash.cc | 22 | ||||
-rw-r--r-- | ash/platform/slpi/ash.cc | 165 | ||||
-rw-r--r-- | platform/slpi/include/chre/platform/slpi/smgr_client.h | 35 | ||||
-rw-r--r-- | platform/slpi/platform_sensor.cc | 5 |
6 files changed, 244 insertions, 0 deletions
@@ -70,6 +70,7 @@ include apps/sensor_world/sensor_world.mk include apps/timer_world/timer_world.mk include apps/wifi_world/wifi_world.mk include apps/wwan_world/wwan_world.mk +include ash/ash.mk include chre_api/chre_api.mk include core/core.mk include external/external.mk diff --git a/ash/ash.mk b/ash/ash.mk new file mode 100644 index 00000000..e735917a --- /dev/null +++ b/ash/ash.mk @@ -0,0 +1,16 @@ +# +# ASH Makefile +# + +# Common Compiler Flags ######################################################## + +# Include paths. +COMMON_CFLAGS += -Iash/include + +# Hexagon-specific Source Files ################################################ + +HEXAGON_SRCS += ash/platform/slpi/ash.cc + +# x86-specific Source Files #################################################### + +X86_SRCS += ash/platform/linux/ash.cc diff --git a/ash/platform/linux/ash.cc b/ash/platform/linux/ash.cc new file mode 100644 index 00000000..7b10b3e4 --- /dev/null +++ b/ash/platform/linux/ash.cc @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ash_api/ash.h" + +bool ashSetCalibration(uint8_t sensorType, const struct ashCalInfo *calInfo) { + // TODO: Implement this. + return false; +} diff --git a/ash/platform/slpi/ash.cc b/ash/platform/slpi/ash.cc new file mode 100644 index 00000000..cf25f887 --- /dev/null +++ b/ash/platform/slpi/ash.cc @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cinttypes> + +extern "C" { + +#include "fixed_point.h" +#include "sns_smgr_api_v01.h" + +} // extern "C" + +#include "ash_api/ash.h" +#include "chre/platform/assert.h" +#include "chre/platform/log.h" +#include "chre/platform/memory.h" +#include "chre/platform/slpi/smgr_client.h" +#include "chre_api/chre/sensor.h" + +using chre::getSensorServiceQmiClientHandle; +using chre::memoryAlloc; +using chre::memoryFree; + +namespace { + +//! The timeout for QMI messages in milliseconds. +constexpr uint32_t kQmiTimeoutMs = 1000; + +//! The constant to convert magnetometer readings from uT in Android to Gauss +//! in SMGR. +constexpr float kGaussPerMicroTesla = 0.01f; + +/** + * @param sensorType One of the CHRE_SENSOR_TYPE_* constants. + * @return true if runtime sensor calibration is supported on this platform. + */ +bool isCalibrationSupported(uint8_t sensorType) { + switch (sensorType) { + case CHRE_SENSOR_TYPE_ACCELEROMETER: + case CHRE_SENSOR_TYPE_GYROSCOPE: + case CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD: + return true; + default: + return false; + } +} + +/** + * @param sensorType One of the CHRE_SENSOR_TYPE_* constants. + * @return The sensor ID of the sensor type as defined in the SMGR API. + */ +uint8_t getSensorId(uint8_t sensorType) { + switch (sensorType) { + case CHRE_SENSOR_TYPE_ACCELEROMETER: + return SNS_SMGR_ID_ACCEL_V01; + case CHRE_SENSOR_TYPE_GYROSCOPE: + return SNS_SMGR_ID_GYRO_V01; + case CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD: + return SNS_SMGR_ID_MAG_V01; + default: + return 0; + } +} + +/** + * Populates the calibration request mesasge. + * + * @param sensorType One of the CHRE_SENSOR_TYPE_* constants. + * @param calInfo The sensor calibraion info supplied by the user. + * @param calRequest The SMGR cal request message to be populated. + */ +void populateCalRequest(uint8_t sensorType, const ashCalInfo *calInfo, + sns_smgr_sensor_cal_req_msg_v01 *calRequest) { + CHRE_ASSERT(calInfo); + CHRE_ASSERT(calRequest); + + calRequest->usage = SNS_SMGR_CAL_DYNAMIC_V01; + calRequest->SensorId = getSensorId(sensorType); + calRequest->DataType = SNS_SMGR_DATA_TYPE_PRIMARY_V01; + + // Convert from micro Tesla to Gauss for magnetometer bias + float scaling = 1.0f; + if (sensorType == CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD) { + scaling = kGaussPerMicroTesla; + } + + // Convert from Android to SMGR's NED coordinate and invert the sign as SMGR + // defines Sc = CM * (Su + Bias) in sns_rh_calibrate_cm_and_bias(). + calRequest->ZeroBias_len = 3; + calRequest->ZeroBias[0] = FX_FLTTOFIX_Q16(-calInfo->bias[1] * scaling); + calRequest->ZeroBias[1] = FX_FLTTOFIX_Q16(-calInfo->bias[0] * scaling); + calRequest->ZeroBias[2] = FX_FLTTOFIX_Q16(calInfo->bias[2] * scaling); + + // ScaleFactor will be over-written by compensation matrix. + calRequest->ScaleFactor_len = 3; + calRequest->ScaleFactor[0] = FX_FLTTOFIX_Q16(1.0); + calRequest->ScaleFactor[1] = FX_FLTTOFIX_Q16(1.0); + calRequest->ScaleFactor[2] = FX_FLTTOFIX_Q16(1.0); + + // Convert from Android to SMGR's NED coordinate. + calRequest->CompensationMatrix_valid = true; + calRequest->CompensationMatrix_len = 9; + calRequest->CompensationMatrix[0] = FX_FLTTOFIX_Q16(calInfo->compMatrix[4]); + calRequest->CompensationMatrix[1] = FX_FLTTOFIX_Q16(calInfo->compMatrix[3]); + calRequest->CompensationMatrix[2] = FX_FLTTOFIX_Q16(-calInfo->compMatrix[5]); + calRequest->CompensationMatrix[3] = FX_FLTTOFIX_Q16(calInfo->compMatrix[1]); + calRequest->CompensationMatrix[4] = FX_FLTTOFIX_Q16(calInfo->compMatrix[0]); + calRequest->CompensationMatrix[5] = FX_FLTTOFIX_Q16(-calInfo->compMatrix[2]); + calRequest->CompensationMatrix[6] = FX_FLTTOFIX_Q16(-calInfo->compMatrix[7]); + calRequest->CompensationMatrix[7] = FX_FLTTOFIX_Q16(-calInfo->compMatrix[6]); + calRequest->CompensationMatrix[8] = FX_FLTTOFIX_Q16(calInfo->compMatrix[8]); + + calRequest->CalibrationAccuracy_valid = true; + calRequest->CalibrationAccuracy = calInfo->accuracy; +} + +} // namespace + +bool ashSetCalibration(uint8_t sensorType, const struct ashCalInfo *calInfo) { + bool success = false; + if (!isCalibrationSupported(sensorType)) { + LOGE("Attempting to set calibration of sensor %" PRIu8, sensorType); + } else { + // Allocate request and response for sensor calibraton. + auto *calRequest = memoryAlloc<sns_smgr_sensor_cal_req_msg_v01>(); + auto *calResponse = memoryAlloc<sns_smgr_sensor_cal_resp_msg_v01>(); + + if (calRequest == nullptr || calResponse == nullptr) { + LOGE("Failed to allocated sensor cal memory"); + } else { + populateCalRequest(sensorType, calInfo, calRequest); + + qmi_client_error_type status = qmi_client_send_msg_sync( + getSensorServiceQmiClientHandle(), SNS_SMGR_CAL_REQ_V01, + calRequest, sizeof(*calRequest), calResponse, sizeof(*calResponse), + kQmiTimeoutMs); + + if (status != QMI_NO_ERR) { + LOGE("Error setting sensor calibration: status %d", status); + } else if (calResponse->Resp.sns_result_t != SNS_RESULT_SUCCESS_V01) { + LOGE("Setting sensor calibration failed with error: %" PRIu8, + calResponse->Resp.sns_err_t); + } else { + success = true; + } + } + + memoryFree(calRequest); + memoryFree(calResponse); + } + return success; +} diff --git a/platform/slpi/include/chre/platform/slpi/smgr_client.h b/platform/slpi/include/chre/platform/slpi/smgr_client.h new file mode 100644 index 00000000..f0fd90e0 --- /dev/null +++ b/platform/slpi/include/chre/platform/slpi/smgr_client.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CHRE_PLATFORM_SLPI_SMGR_CLIENT_H_ +#define CHRE_PLATFORM_SLPI_SMGR_CLIENT_H_ + +extern "C" { + +#include "qmi_client.h" + +} // extern "C" + +namespace chre { + +/** + * @return A QMI sensor service client handle + */ +qmi_client_type getSensorServiceQmiClientHandle(); + +} // namespace chre + +#endif // CHRE_PLATFORM_SLPI_SMGR_CLIENT_H_ diff --git a/platform/slpi/platform_sensor.cc b/platform/slpi/platform_sensor.cc index e5643d22..ae659e23 100644 --- a/platform/slpi/platform_sensor.cc +++ b/platform/slpi/platform_sensor.cc @@ -34,6 +34,7 @@ extern "C" { #include "chre/platform/log.h" #include "chre/platform/platform_sensor.h" #include "chre/platform/slpi/platform_sensor_util.h" +#include "chre/platform/slpi/smgr_client.h" namespace chre { namespace { @@ -1004,4 +1005,8 @@ void PlatformSensor::setLastEvent(const ChreSensorData *event) { memcpy(lastEvent, event, lastEventSize); } +qmi_client_type getSensorServiceQmiClientHandle() { + return gPlatformSensorServiceQmiClientHandle; +} + } // namespace chre |