/* * Copyright (C) 2016 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 #include #include #include "chre/util/nanoapp/log.h" /** * @file * A nanoapp exclusively for testing, which saves locally defined ashCalParam * of accel, gyro and mag to storage and lodas them back to check correctness. * The loaded back asCalParam should be identical to the saved one, subject to * storage quantization error. * It's suggested that a copy of the original storage be made before running * this test nanoapp so the original storage can be retained. * Note that ASH functionality is not required for CHRE. */ #define LOG_TAG "[AshWorld]" #ifdef CHRE_NANOAPP_INTERNAL namespace chre { namespace { #endif // CHRE_NANOAPP_INTERNAL uint32_t gCyclicTimerHandle; int gCyclicTimerCount; struct ashCalParams accCalParams = { .offset = {0.0, 1.0, 2.0}, .offsetTempCelsius = 3.0, .tempSensitivity = {4.0, 5.0, 6.0}, .tempIntercept = {7.0, 8.0, 9.0}, .scaleFactor = {10.0, 11.0, 12.0}, .crossAxis = {13.0, 14.0, 15.0}, .offsetSource = 16, .offsetTempCelsiusSource = 17, .tempSensitivitySource = 18, .tempInterceptSource = 19, .scaleFactorSource = 20, .crossAxisSource = 21, }; struct ashCalParams gyrCalParams = { .offset = {100.0, 101.0, 102.0}, .offsetTempCelsius = 103.0, .tempSensitivity = {104.0, 105.0, 106.0}, .tempIntercept = {107.0, 108.0, 109.0}, .scaleFactor = {110.0, 111.0, 112.0}, .crossAxis = {113.0, 114.0, 115.0}, .offsetSource = 116, .offsetTempCelsiusSource = 117, .tempSensitivitySource = 118, .tempInterceptSource = 119, .scaleFactorSource = 120, .crossAxisSource = 121, }; struct ashCalParams magCalParams = { .offset = {200.0, 201.0, 202.0}, .offsetTempCelsius = 203.0, .tempSensitivity = {204.0, 205.0, 206.0}, .tempIntercept = {207.0, 208.0, 209.0}, .scaleFactor = {210.0, 211.0, 212.0}, .crossAxis = {213.0, 214.0, 215.0}, .offsetSource = 216, .offsetTempCelsiusSource = 217, .tempSensitivitySource = 218, .tempInterceptSource = 219, .scaleFactorSource = 220, .crossAxisSource = 221, }; bool nanoappStart() { LOGI("App started on platform ID %" PRIx64, chreGetPlatformId()); gCyclicTimerHandle = chreTimerSet(3000000000 /* duration: 3sec */, &gCyclicTimerHandle /* data */, false /* oneShot */); gCyclicTimerCount = 0; return true; } void handleTimerEvent(const void *eventData) { LOGI("Cyclic timer event received %" PRIu32, gCyclicTimerCount); bool success = false; uint64_t tic = 0, toc = 0; uint8_t sensor = CHRE_SENSOR_TYPE_ACCELEROMETER; struct ashCalParams *sensorCalParams = &accCalParams; if ((gCyclicTimerCount / 2) == 1) { sensor = CHRE_SENSOR_TYPE_GYROSCOPE; sensorCalParams = &gyrCalParams; } else if ((gCyclicTimerCount / 2) == 2) { sensor = CHRE_SENSOR_TYPE_GEOMAGNETIC_FIELD; sensorCalParams = &magCalParams; } if (gCyclicTimerCount >= 6) { chreTimerCancel(gCyclicTimerHandle); LOGI("Timer cancelled"); } else if (gCyclicTimerCount % 2 == 0) { tic = chreGetTime(); success = ashSaveCalibrationParams(sensor, sensorCalParams); toc = chreGetTime(); LOGI("*** save sensor %" PRIu8 ": %s, time %" PRIu64 " us", sensor, success ? "success" : "failure", (toc - tic) / 1000); } else { struct ashCalParams p; tic = chreGetTime(); success = ashLoadCalibrationParams(sensor, ASH_CAL_STORAGE_ASH, &p); toc = chreGetTime(); LOGI("*** load sensor %" PRIu8 ": %s, time %" PRIu64 " us", sensor, success ? "success" : "fail", (toc - tic) / 1000); LOGI("offset %f %f %f", p.offset[0], p.offset[1], p.offset[2]); LOGI("offsetTempCelsius %f", p.offsetTempCelsius); LOGI("tempSensitivity %f %f %f", p.tempSensitivity[0], p.tempSensitivity[1], p.tempSensitivity[2]); LOGI("tempIntercept %f %f %f", p.tempIntercept[0], p.tempIntercept[1], p.tempIntercept[2]); LOGI("scaleFactor %f %f %f", p.scaleFactor[0], p.scaleFactor[1], p.scaleFactor[2]); LOGI("crossAxis %f %f %f", p.crossAxis[0], p.crossAxis[1], p.crossAxis[2]); LOGI("%" PRIu8 " %" PRIu8 " %" PRIu8 " %" PRIu8 " %" PRIu8 " %" PRIu8, p.offsetSource, p.offsetTempCelsiusSource, p.tempSensitivitySource, p.tempInterceptSource, p.scaleFactorSource, p.crossAxisSource); } gCyclicTimerCount++; } void nanoappHandleEvent(uint32_t senderInstanceId, uint16_t eventType, const void *eventData) { switch (eventType) { case CHRE_EVENT_TIMER: handleTimerEvent(eventData); break; default: LOGW("Unknown event received"); break; } } void nanoappEnd() { LOGI("Stopped"); } #ifdef CHRE_NANOAPP_INTERNAL } // anonymous namespace } // namespace chre #include "chre/util/nanoapp/app_id.h" #include "chre/platform/static_nanoapp_init.h" CHRE_STATIC_NANOAPP_INIT(AshWorld, chre::kAshWorldAppId, 0); #endif // CHRE_NANOAPP_INTERNAL