1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "chre/platform/slpi/see/see_cal_helper.h"
18
19 #include "chre/core/sensor_type_helpers.h"
20 #include "chre/platform/assert.h"
21 #include "chre/platform/log.h"
22 #include "chre/platform/slpi/see/see_helper.h"
23 #include "chre/util/lock_guard.h"
24 #include "chre/util/macros.h"
25
26 namespace chre {
27
applyCalibration(uint8_t sensorType,const float input[3],float output[3]) const28 void SeeCalHelper::applyCalibration(uint8_t sensorType, const float input[3],
29 float output[3]) const {
30 bool applied = false;
31 size_t index = getCalIndexFromSensorType(sensorType);
32 if (index < ARRAY_SIZE(mCalInfo)) {
33 LockGuard<Mutex> lock(mMutex);
34
35 // TODO: Support compensation matrix and scaling factor calibration
36 if (mCalInfo[index].cal.hasBias) {
37 for (size_t i = 0; i < 3; i++) {
38 output[i] = input[i] - mCalInfo[index].cal.bias[i];
39 }
40 applied = true;
41 }
42 }
43
44 if (!applied) {
45 for (size_t i = 0; i < 3; i++) {
46 output[i] = input[i];
47 }
48 }
49 }
50
getBias(uint8_t sensorType,struct chreSensorThreeAxisData * biasData) const51 bool SeeCalHelper::getBias(uint8_t sensorType,
52 struct chreSensorThreeAxisData *biasData) const {
53 CHRE_ASSERT(biasData != nullptr);
54
55 bool success = false;
56 if (biasData != nullptr) {
57 size_t index = getCalIndexFromSensorType(sensorType);
58 if (index < ARRAY_SIZE(mCalInfo)) {
59 LockGuard<Mutex> lock(mMutex);
60
61 if (mCalInfo[index].cal.hasBias) {
62 biasData->header.baseTimestamp = mCalInfo[index].cal.timestamp;
63 biasData->header.readingCount = 1;
64 biasData->header.accuracy = mCalInfo[index].cal.accuracy;
65 biasData->header.reserved = 0;
66
67 for (size_t i = 0; i < 3; i++) {
68 biasData->readings[0].bias[i] = mCalInfo[index].cal.bias[i];
69 }
70 biasData->readings[0].timestampDelta = 0;
71 success = true;
72 }
73 }
74 }
75
76 return success;
77 }
78
areCalUpdatesEnabled(const sns_std_suid & suid) const79 bool SeeCalHelper::areCalUpdatesEnabled(const sns_std_suid &suid) const {
80 size_t index = getCalIndexFromSuid(suid);
81 if (index < ARRAY_SIZE(mCalInfo)) {
82 return mCalInfo[index].enabled;
83 }
84 return false;
85 }
86
configureCalUpdates(const sns_std_suid & suid,bool enable,SeeHelper & helper)87 bool SeeCalHelper::configureCalUpdates(const sns_std_suid &suid, bool enable,
88 SeeHelper &helper) {
89 bool success = false;
90
91 size_t index = getCalIndexFromSuid(suid);
92 if (index >= ARRAY_SIZE(mCalInfo)) {
93 CHRE_ASSERT(false);
94 } else if ((mCalInfo[index].enabled == enable) ||
95 helper.configureOnChangeSensor(suid, enable)) {
96 success = true;
97 mCalInfo[index].enabled = enable;
98 }
99
100 return success;
101 }
102
getCalSuidFromSensorType(uint8_t sensorType) const103 const sns_std_suid *SeeCalHelper::getCalSuidFromSensorType(
104 uint8_t sensorType) const {
105 // Mutex not needed, SUID is not modified after init
106 size_t calIndex = getCalIndexFromSensorType(sensorType);
107 if (calIndex < ARRAY_SIZE(mCalInfo) && mCalInfo[calIndex].suid.has_value()) {
108 return &mCalInfo[calIndex].suid.value();
109 }
110 return nullptr;
111 }
112
findCalibrationSensors(SeeHelper & seeHelper)113 bool SeeCalHelper::findCalibrationSensors(SeeHelper &seeHelper) {
114 bool success = true;
115
116 DynamicVector<sns_std_suid> suids;
117 for (size_t i = 0; i < ARRAY_SIZE(mCalInfo); i++) {
118 const char *calType = getDataTypeForCalSensorIndex(i);
119 if (!seeHelper.findSuidSync(calType, &suids)) {
120 success = false;
121 LOGE("Failed to find sensor '%s'", calType);
122 } else {
123 mCalInfo[i].suid = suids[0];
124 }
125 }
126
127 return success;
128 }
129
updateCalibration(const sns_std_suid & suid,bool hasBias,float bias[3],bool hasScale,float scale[3],bool hasMatrix,float matrix[9],uint8_t accuracy,uint64_t timestamp)130 void SeeCalHelper::updateCalibration(const sns_std_suid &suid, bool hasBias,
131 float bias[3], bool hasScale,
132 float scale[3], bool hasMatrix,
133 float matrix[9], uint8_t accuracy,
134 uint64_t timestamp) {
135 size_t index = getCalIndexFromSuid(suid);
136 if (index < ARRAY_SIZE(mCalInfo)) {
137 LockGuard<Mutex> lock(mMutex);
138 SeeCalData &calData = mCalInfo[index].cal;
139
140 calData.hasBias = hasBias;
141 if (hasBias) {
142 memcpy(calData.bias, bias, sizeof(calData.bias));
143 }
144
145 calData.hasScale = hasScale;
146 if (hasScale) {
147 memcpy(calData.scale, scale, sizeof(calData.scale));
148 }
149
150 calData.hasMatrix = hasMatrix;
151 if (hasMatrix) {
152 memcpy(calData.matrix, matrix, sizeof(calData.matrix));
153 }
154
155 calData.accuracy = accuracy;
156 calData.timestamp = timestamp;
157 }
158 }
159
getSensorTypeFromSuid(const sns_std_suid & suid,uint8_t * sensorType) const160 bool SeeCalHelper::getSensorTypeFromSuid(const sns_std_suid &suid,
161 uint8_t *sensorType) const {
162 size_t calSensorIndex = getCalIndexFromSuid(suid);
163 bool found = true;
164 switch (static_cast<SeeCalSensor>(calSensorIndex)) {
165 #ifdef CHRE_ENABLE_ACCEL_CAL
166 case SeeCalSensor::AccelCal:
167 *sensorType = CHRE_SENSOR_TYPE_ACCELEROMETER;
168 break;
169 #endif // CHRE_ENABLE_ACCEL_CAL
170 case SeeCalSensor::GyroCal:
171 *sensorType = CHRE_SENSOR_TYPE_GYROSCOPE;
172 break;
173 case SeeCalSensor::MagCal:
174 *sensorType = CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD;
175 break;
176 default:
177 // Don't assert here as SEE may send us calibration updates for other
178 // sensors even if CHRE doesn't request them.
179 found = false;
180 break;
181 }
182 return found;
183 }
184
getCalIndexFromSensorType(uint8_t sensorType)185 size_t SeeCalHelper::getCalIndexFromSensorType(uint8_t sensorType) {
186 SeeCalSensor index;
187 switch (sensorType) {
188 #ifdef CHRE_ENABLE_ACCEL_CAL
189 case CHRE_SENSOR_TYPE_ACCELEROMETER:
190 index = SeeCalSensor::AccelCal;
191 break;
192 #endif // CHRE_ENABLE_ACCEL_CAL
193 case CHRE_SENSOR_TYPE_GYROSCOPE:
194 index = SeeCalSensor::GyroCal;
195 break;
196 case CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD:
197 index = SeeCalSensor::MagCal;
198 break;
199 default:
200 index = SeeCalSensor::NumCalSensors;
201 }
202 return static_cast<size_t>(index);
203 }
204
getDataTypeForCalSensorIndex(size_t calSensorIndex)205 const char *SeeCalHelper::getDataTypeForCalSensorIndex(size_t calSensorIndex) {
206 switch (static_cast<SeeCalSensor>(calSensorIndex)) {
207 #ifdef CHRE_ENABLE_ACCEL_CAL
208 case SeeCalSensor::AccelCal:
209 return "accel_cal";
210 #endif // CHRE_ENABLE_ACCEL_CAL
211 case SeeCalSensor::GyroCal:
212 return "gyro_cal";
213 case SeeCalSensor::MagCal:
214 return "mag_cal";
215 default:
216 CHRE_ASSERT(false);
217 }
218 return nullptr;
219 }
220
getCalIndexFromSuid(const sns_std_suid & suid) const221 size_t SeeCalHelper::getCalIndexFromSuid(const sns_std_suid &suid) const {
222 size_t i = 0;
223 for (; i < ARRAY_SIZE(mCalInfo); i++) {
224 if (mCalInfo[i].suid.has_value() &&
225 suidsMatch(suid, mCalInfo[i].suid.value())) {
226 break;
227 }
228 }
229 return i;
230 }
231
232 } // namespace chre
233