blob: a581504723f498b465f848c73f09681240ca6e47 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2* Copyright Statement:
3*
4* This software/firmware and related documentation ("MediaTek Software") are
5* protected under relevant copyright laws. The information contained herein is
6* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
7* the prior written permission of MediaTek inc. and/or its licensors, any
8* reproduction, modification, use or disclosure of MediaTek Software, and
9* information contained herein, in whole or in part, shall be strictly
10* prohibited.
11*
12* MediaTek Inc. (C) 2017. All rights reserved.
13*
14* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
15* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
16* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
17* ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
18* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
19* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
20* NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
21* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
22* INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
23* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
24* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
25* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
26* SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
27* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
28* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
29* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
30* RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
31* MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
32* CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
33*/
34
35//sensor driver
36#include <stdio.h>
37#include <stdint.h>
38
39#include <stdio.h>
40#include <stdint.h>
41#include <pthread.h>
42#include <string.h>
43#include <dlfcn.h>
44#include <unistd.h>
45#include <errno.h>
46
47#include "zalloc.h"
48#include "log.h"
49
50#include "sensors.h"
51#include "module_sensor_helper.h"
52
53
54#define SENSOR_LIB "/usr/lib/libsensorhal.so.0"
55#define SENSOR_DISABLE 0
56#define SENSOR_ENABLE 1
57#define SENSOR_POLL_NS 20000000LL
58#define SENSOR_EVENT_BUFFER_SIZE 16
59#define BARO_EVENT_BUFFER_SIZE 16
60#define SENSOR_EVENT_LEN 15
61#define SENSOR_MODULE_STAT_MSG_LEN 8
62
63#define nsec_2_sec 1000000000
64#define nsec_2_msec 1000000
65
66typedef struct sensor_device {
67 char *name;
68 void *sensor_hal;
69
70 pthread_t poll_thread;
71 int poll_thread_exit;
72
73 pthread_t dataready_thread;
74 int dataready_thread_exit;
75
76 FILE *sensor_fp;
77 ssize_t sensor_count;
78 struct sensor_t* sensor_list;
79
80 sensors_event_t accEvent[SENSOR_EVENT_BUFFER_SIZE];
81 sensors_event_t gyroEvent[SENSOR_EVENT_BUFFER_SIZE];
82 sensors_event_t baroEvent[BARO_EVENT_BUFFER_SIZE];
83 int (*get_sensors_list)(struct sensor_t const** list);
84
85 sensors_poll_device_1_t* halInf;
86
87 //rectify time for sensor
88 struct timespec spec;
89
90 struct timespec odom_boottime;
91} sensor_device;
92
93static sensor_device *g_sensor_ctx = NULL;
94static int sensor_data_number = 0;
95
96int32_t get_sensor_handle(sensor_device *dev, int type)
97{
98 int i = 0;
99 for (i = 0; i < (int)(dev->sensor_count); i++) {
100 if (dev->sensor_list[i].type == type)
101 return dev->sensor_list[i].handle;
102 }
103 return -1;
104}
105
106int32_t sensor_set_event_rate(int handle, int64_t samplingPeriodNs, int odr)
107{
108 int64_t sampling_ns = samplingPeriodNs;
109 if (odr == 1)
110 {
111 int odr_us[8] = {0}; // 6.25,12.5,25,50,100,400,800
112 int i = 0,ret = -1;
113 ret = getODR(g_sensor_ctx->halInf, handle, odr_us);
114 if (ret)
115 {
116 LOG_ERROR("sensor get ODR return fail , ret = %d",ret);
117 return -1;
118 }
119 int sampling_us = (int)(sampling_ns / 1000);
120 /* get the nearest value */
121 /*int d_value = abs(odr_us[0] - sampling_us), index = 0, tmp;
122 for (i = 1; i < 8; i++)
123 {
124 LOG_DEBUG("odr[%d] = %d\n", i, odr_us[i]);
125 tmp = abs(odr_us[i] - sampling_us);
126 if (tmp < d_value) {
127 index = i;
128 d_value = tmp;
129 }
130 }
131 sampling_ns = odr_us[index] * 1000;
132 }
133 LOG_DEBUG("sampling rate %lld, the end sampling rate to be set to driver is %lld",samplingPeriodNs, sampling_ns);*/
134 for (i = 0; i < 8; i++)
135 {
136 LOG_DEBUG("odr[%d] = %d\n", i, odr_us[i]);
137 if (odr_us[i] == sampling_us)
138 break;
139 }
140 if (i == 8) {
141 LOG_DEBUG("sampling rate %lld is not matched with sensor odr setting",samplingPeriodNs);
142 }
143 }
144 return setDelay(g_sensor_ctx->halInf, handle, sampling_ns);
145}
146
147static int sensor_stop_thread(sensor_device *dev)
148{
149 dev->poll_thread_exit = 1;
150 dev->dataready_thread_exit = 1;
151 LOG_DEBUG("sensor thread exit~");
152 pthread_join(dev->poll_thread, NULL);
153 pthread_join(dev->dataready_thread, NULL);
154 return 0;
155}
156
157/*
158 * @ get ring arrary index,
159 * member:
160 * @len: the length of arrary
161 * @cur: cur positoon
162 * @offset: the offset of @in
163 * @out: the final index of the ring
164 */
165#define get_ring_idx(len, cur, offset, out) \
166 do \
167 { \
168 if ((cur + offset) >= len) { \
169 out = cur + offset - len; \
170 } else if((cur + offset) < 0) { \
171 out = len + (cur + offset); \
172 } else { \
173 out = cur + offset; \
174 } \
175 }while (0)
176
177#define get_ring_avilable_len(len, start, end, out) \
178 do \
179 { \
180 out = end + len - start; \
181 if (out >= len) \
182 out -= len; \
183 }while (0)
184
185//just cache event & calcu len of acc/gyro
186void sensor_data_print(sensor_device *dev, const sensors_event_t* buffer, size_t count)
187{
188 size_t i = 0;
189 int32_t next = 0;
190
191 LOG_INFO("Event number %d\n", count);
192 sensor_data_number += count;
193 for (i = 0; i < count; i++) {
194 const sensors_event_t* event = &buffer[i];
195 if (event->type != SENSOR_TYPE_META_DATA) {
196 if (!event->timestamp)
197 continue;
198 switch (event->type) {
199 case SENSOR_TYPE_ACCELEROMETER:
200 dev->accEvent[0] = *event;
201 LOG_TEST_INFO("acc: x %f, y %f, z %f, temp %f, time %lld\n",
202 dev->accEvent[0].acceleration.x, dev->accEvent[0].acceleration.y,
203 dev->accEvent[0].acceleration.z, dev->accEvent[0].acceleration.t,
204 dev->accEvent[0].timestamp);
205 break;
206
207 case SENSOR_TYPE_GYROSCOPE:
208 dev->gyroEvent[0] = *event;
209 LOG_TEST_INFO("gyro: x %f, y %f, z %f, temp %f, time %lld\n",
210 dev->gyroEvent[0].gyro.azimuth, dev->gyroEvent[0].gyro.pitch,
211 dev->gyroEvent[0].gyro.roll, dev->gyroEvent[0].gyro.temperature,
212 dev->gyroEvent[0].timestamp);
213 break;
214
215 case SENSOR_TYPE_PRESSURE:
216 dev->baroEvent[0] = *event;
217 LOG_TEST_INFO("Pressure: press %f, temp %f, time %lld\n",
218 dev->baroEvent[0].pressure.data,
219 dev->baroEvent[0].pressure.temperature,
220 dev->baroEvent[0].timestamp);
221 break;
222
223 default:
224 break;
225 }
226 }
227 }
228}
229
230static void *
231sensor_poll_thread(void *data)
232{
233 sensor_device *dev = (sensor_device *)data;
234 sensors_event_t mSensorEvent[SENSOR_EVENT_BUFFER_SIZE];
235 ssize_t count = 0;
236
237 sleep(3);
238
239 while (!dev->poll_thread_exit) {
240 count = service_poll(dev->halInf, mSensorEvent, SENSOR_EVENT_BUFFER_SIZE);
241 sensor_data_print(dev, mSensorEvent, count);
242 if (sensor_data_number > 100) {
243 LOG_INFO("sensor_data_number %d\n", sensor_data_number);
244 dev->poll_thread_exit = 1;
245 }
246 }
247 LOG_INFO("<-- sensor_poll_thread exit");
248 pthread_exit(0);
249}
250
251static int32_t sensor_hal_deinit(sensor_device* dev)
252{
253 free(dev->sensor_list);
254 dlclose(dev->sensor_hal);
255
256 return 0;
257}
258
259static int32_t sensor_hal_init(sensor_device* dev)
260{
261 void *module, *get_sensors_list;
262 int (*sensors_open)(sensors_poll_device_1_t** mSensorDevice);
263
264 module = dlopen(SENSOR_LIB, RTLD_NOW | RTLD_NOLOAD);
265 if (module) {
266 LOG_ERROR("Module '%s' already loaded", SENSOR_LIB);
267 goto ERROR;
268 }
269
270 LOG_DEBUG("Loading module '%s'", SENSOR_LIB);
271 module = dlopen(SENSOR_LIB, RTLD_NOW);
272 if (!module) {
273 LOG_ERROR("Failed to load module: %s", dlerror());
274 return -1;
275 }
276 sensors_open = dlsym(module, "sensor_open");
277 if (!sensors_open) {
278 LOG_ERROR("Failed to lookup sensors_open function: %s", dlerror());
279 goto ERROR;
280 }
281
282 get_sensors_list = dlsym(module, "sensors__get_sensors_list");
283 if (!get_sensors_list) {
284 LOG_ERROR("Failed to lookup get_sensors_list function: %s", dlerror());
285 goto ERROR;
286 }
287 dev->get_sensors_list = get_sensors_list;
288 sensors_open(&dev->halInf);
289
290 if (dev->halInf) {
291 struct sensor_t const* list;
292 ssize_t count = dev->get_sensors_list(&list);
293
294 LOG_DEBUG("get_sensors_list count %d",(int)count);
295 dev->sensor_count = count;
296 dev->sensor_list = (struct sensor_t *)zalloc(count * sizeof(struct sensor_t));
297 if(!dev->sensor_list)
298 goto ERROR;
299
300 memcpy(dev->sensor_list, list, count * sizeof(struct sensor_t));
301 if (count > 0) {
302 size_t i = 0 ;
303 LOG_DEBUG("------------------------sensor list BEGIN---------------------------");
304 for (i=0 ; i< count ; i++) {
305 dev->halInf->activate(
306 (struct sensors_poll_device_t *)(dev->halInf),
307 list[i].handle, SENSOR_DISABLE);
308 LOG_DEBUG("name:%s version:%d maxRange:%f\n",list[i].name, list[i].version, list[i].maxRange);
309 }
310 LOG_DEBUG("------------------------sensor list END---------------------------");
311 }
312 }
313 dev->sensor_hal = module;
314 return 0;
315ERROR:
316 dlclose(module);
317 return -1;
318}
319
320 static int32_t sensor_driver_init(struct sensor_device *dev)
321 {
322 int32_t ret;
323
324 ret = sensor_hal_init(dev);
325
326 dev->poll_thread_exit = 0;
327 ret = pthread_create(&dev->poll_thread, NULL, sensor_poll_thread, (void *)dev);
328 if (ret != 0) {
329 LOG_ERROR("can't create thread for sensor poll:%s",strerror(errno));
330 return -1;
331 }
332
333 return 0;
334}
335
336static void sensor_driver_start(struct sensor_device *dev)
337{
338 int32_t handle, samplingPeriodNs;
339
340 samplingPeriodNs = SENSOR_POLL_NS;
341
342 handle = get_sensor_handle(dev, SENSOR_TYPE_ACCELEROMETER);
343 activate(dev->halInf, handle, SENSOR_ENABLE);
344 sensor_set_event_rate(handle, samplingPeriodNs, 1);
345
346 handle = get_sensor_handle(dev, SENSOR_TYPE_GYROSCOPE);
347 activate(dev->halInf, handle, SENSOR_ENABLE);
348 sensor_set_event_rate(handle, samplingPeriodNs, 1);
349
350 handle = get_sensor_handle(dev, SENSOR_TYPE_PRESSURE);
351 activate(dev->halInf, handle, SENSOR_ENABLE);
352 sensor_set_event_rate(handle , samplingPeriodNs, 0);
353}
354
355static void sensor_driver_stop(struct sensor_device *dev)
356{
357 int32_t handle;
358
359 sensor_stop_thread(dev);
360
361 handle = get_sensor_handle(dev, SENSOR_TYPE_ACCELEROMETER);
362 activate(dev->halInf, handle, SENSOR_DISABLE);
363
364 handle = get_sensor_handle(dev, SENSOR_TYPE_GYROSCOPE);
365 activate(dev->halInf, handle, SENSOR_DISABLE);
366
367 handle = get_sensor_handle(dev, SENSOR_TYPE_PRESSURE);
368 activate(dev->halInf, handle, SENSOR_DISABLE);
369}
370
371static void sensor_driver_deinit(struct sensor_device *dev)
372{
373 sensor_hal_deinit(dev);
374}
375
376struct sensorhal {
377 char *name;
378 int32_t (*init)(struct sensor_device *dev);
379 void (*start)(struct sensor_device *dev);
380 void (*stop)(struct sensor_device *dev);
381 void (*deinit)(struct sensor_device *dev);
382};
383
384static struct sensorhal sensor_driver = {
385 .name = "mtk_sensor",
386 .init = sensor_driver_init,
387 .start = sensor_driver_start,
388 .stop = sensor_driver_stop,
389 .deinit = sensor_driver_deinit,
390};
391
392int module_sensor_init(void)
393{
394 struct sensor_device *dev;
395
396 dev = (sensor_device*)zalloc(sizeof(sensor_device));
397 if (!dev) {
398 LOG_ERROR("Fail to create sensor_device");
399 return -1;
400 }
401 g_sensor_ctx = dev;
402 sensor_driver_init(dev);
403 return 0;
404}
405
406int main()
407{
408 int err = 0;
409 struct sensor_device *dev;
410
411 err = module_sensor_init();
412 if (err < 0) {
413 LOG_INFO("Create sensor_device err\n");
414 return -1;
415 }
416 dev = g_sensor_ctx;
417
418 LOG_INFO("Enable and set data rate to sensor driver\n");
419 sensor_driver_start(dev);
420
421 do {
422 sleep(1);
423 } while (dev->poll_thread_exit == 0);
424
425 LOG_INFO("Disable sensor\n");
426 sensor_driver_stop(dev);
427
428 LOG_INFO("Unload sensorhal.so\n");
429 sensor_driver_deinit(dev);
430
431 return 0;
432}