1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "aos/kernel.h"
12 #include "ulog/ulog.h"
13
14 #include "sensor_drv_api.h"
15 #include "sensor_hal.h"
16
17 #define NSA_REG_SPI_I2C 0x00
18 #define NSA_REG_WHO_AM_I 0x01
19 #define NSA_REG_ACC_X_LSB 0x02
20 #define NSA_REG_ACC_X_MSB 0x03
21 #define NSA_REG_ACC_Y_LSB 0x04
22 #define NSA_REG_ACC_Y_MSB 0x05
23 #define NSA_REG_ACC_Z_LSB 0x06
24 #define NSA_REG_ACC_Z_MSB 0x07
25 #define NSA_REG_MOTION_FLAG 0x09
26 #define NSA_REG_NEWDATA_FLAG 0x0A
27 #define NSA_REG_STEPS_MSB 0x0D
28 #define NSA_REG_STEPS_LSB 0x0E
29 #define NSA_REG_G_RANGE 0x0f
30 #define NSA_REG_ODR_AXIS_DISABLE 0x10
31 #define NSA_REG_POWERMODE_BW 0x11
32 #define NSA_REG_SWAP_POLARITY 0x12
33 #define NSA_REG_FIFO_CTRL 0x14
34 #define NSA_REG_INTERRUPT_SETTINGS0 0x15
35 #define NSA_REG_INTERRUPT_SETTINGS1 0x16
36 #define NSA_REG_INTERRUPT_SETTINGS2 0x17
37 #define NSA_REG_INTERRUPT_MAPPING1 0x19
38 #define NSA_REG_INTERRUPT_MAPPING2 0x1a
39 #define NSA_REG_INTERRUPT_MAPPING3 0x1b
40 #define NSA_REG_INT_PIN_CONFIG 0x20
41 #define NSA_REG_INT_LATCH 0x21
42 #define NSA_REG_ACTIVE_DURATION 0x27
43 #define NSA_REG_ACTIVE_THRESHOLD 0x28
44 #define NSA_REG_TAP_DURATION 0x2A
45 #define NSA_REG_TAP_THRESHOLD 0x2B
46 #define NSA_REG_RESET_STEP 0x2E
47 #define NSA_REG_STEP_CONGIF1 0x2F
48 #define NSA_REG_STEP_CONGIF2 0x30
49 #define NSA_REG_STEP_CONGIF3 0x31
50 #define NSA_REG_STEP_CONGIF4 0x32
51 #define NSA_REG_STEP_FILTER 0x33
52 #define NSA_REG_CUSTOM_OFFSET_X 0x38
53 #define NSA_REG_CUSTOM_OFFSET_Y 0x39
54 #define NSA_REG_CUSTOM_OFFSET_Z 0x3a
55 #define NSA_REG_ENGINEERING_MODE 0x7f
56 #define NSA_REG_SENSITIVITY_TRIM_X 0x80
57 #define NSA_REG_SENSITIVITY_TRIM_Y 0x81
58 #define NSA_REG_SENSITIVITY_TRIM_Z 0x82
59 #define NSA_REG_COARSE_OFFSET_TRIM_X 0x83
60 #define NSA_REG_COARSE_OFFSET_TRIM_Y 0x84
61 #define NSA_REG_COARSE_OFFSET_TRIM_Z 0x85
62 #define NSA_REG_FINE_OFFSET_TRIM_X 0x86
63 #define NSA_REG_FINE_OFFSET_TRIM_Y 0x87
64 #define NSA_REG_FINE_OFFSET_TRIM_Z 0x88
65 #define NSA_REG_SENS_COMP 0x8c
66 #define NSA_REG_SENS_COARSE_TRIM 0xd1
67
68 #define DA217_NORMAL_MODE 0x00
69 #define DA217_SUSPEND_MODE 0x01
70
71 #define DA217_I2C_SLAVE_ADDR_LOW (0x26)
72 #define DA217_I2C_SLAVE_ADDR_HIGN (0x27)
73
74 #define DA217_ACC_DATA_SIZE 6
75
76 #define DA217_CHIP_ID_VAL 0x13
77 #define DA217_ADDR_TRANS(n) ((n) << 1)
78
79 #define DA217_GET_BITSLICE(regvar, bitname) \
80 ((regvar & bitname##__MSK) >> bitname##__POS)
81 #define DA217_SET_BITSLICE(regvar, bitname, val) \
82 ((regvar & ~bitname##__MSK) | ((val << bitname##__POS) & bitname##__MSK))
83
84 i2c_dev_t da217_ctx = { .port = 1,
85 .config.address_width = 8,
86 .config.freq = 100000,
87 .config.dev_addr =
88 DA217_ADDR_TRANS(DA217_I2C_SLAVE_ADDR_HIGN) };
89
drv_acc_mir3_da217_validate_id(i2c_dev_t * drv,uint8_t id_value)90 static int drv_acc_mir3_da217_validate_id(i2c_dev_t *drv, uint8_t id_value)
91 {
92 int ret = 0;
93 uint8_t value = 0;
94
95 if (drv == NULL) {
96 return -1;
97 }
98
99 ret = sensor_i2c_read(drv, NSA_REG_WHO_AM_I, &value, I2C_DATA_LEN,
100 I2C_OP_RETRIES);
101 if (unlikely(ret)) {
102 return ret;
103 }
104
105 if (id_value != value) {
106 return -1;
107 }
108 return 0;
109 }
110
drv_acc_mir3_da217_open_step_counter(i2c_dev_t * drv)111 UNUSED static int drv_acc_mir3_da217_open_step_counter(i2c_dev_t *drv)
112 {
113 int ret = 0;
114 uint8_t value = 0;
115
116 value = 0x01;
117 ret = sensor_i2c_write(drv, NSA_REG_STEP_CONGIF1, &value, I2C_DATA_LEN,
118 I2C_OP_RETRIES);
119 if (unlikely(ret)) {
120 return ret;
121 }
122
123 value = 0x62;
124 ret = sensor_i2c_write(drv, NSA_REG_STEP_CONGIF2, &value, I2C_DATA_LEN,
125 I2C_OP_RETRIES);
126 if (unlikely(ret)) {
127 return ret;
128 }
129
130 value = 0x46;
131 ret = sensor_i2c_write(drv, NSA_REG_STEP_CONGIF3, &value, I2C_DATA_LEN,
132 I2C_OP_RETRIES);
133 if (unlikely(ret)) {
134 return ret;
135 }
136
137 value = 0x32;
138 ret = sensor_i2c_write(drv, NSA_REG_STEP_CONGIF4, &value, I2C_DATA_LEN,
139 I2C_OP_RETRIES);
140 if (unlikely(ret)) {
141 return ret;
142 }
143
144 value = 0xa2;
145 ret = sensor_i2c_write(drv, NSA_REG_STEP_FILTER, &value, I2C_DATA_LEN,
146 I2C_OP_RETRIES);
147 if (unlikely(ret)) {
148 return ret;
149 }
150
151 return 0;
152 }
153
drv_acc_mir3_da217_close_step_counter(i2c_dev_t * drv)154 static int drv_acc_mir3_da217_close_step_counter(i2c_dev_t *drv)
155 {
156 int ret = 0;
157 uint8_t value = 0;
158
159 value = 0x22;
160 ret = sensor_i2c_write(drv, NSA_REG_STEP_FILTER, &value, I2C_DATA_LEN,
161 I2C_OP_RETRIES);
162 if (unlikely(ret)) {
163 return ret;
164 }
165
166 return 0;
167 }
168
drv_acc_mir3_da217_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)169 static int drv_acc_mir3_da217_set_power_mode(i2c_dev_t * drv,
170 dev_power_mode_e mode)
171 {
172 int ret = 0;
173 uint8_t dev_mode;
174
175
176 switch (mode) {
177 case DEV_POWER_OFF:
178 case DEV_SLEEP: {
179 dev_mode = (uint8_t)0x80;
180 break;
181 }
182 case DEV_POWER_ON: {
183 dev_mode = (uint8_t)0x34;
184 break;
185 }
186 default:
187 return -1;
188 }
189
190 ret = sensor_i2c_write(drv, NSA_REG_POWERMODE_BW, &dev_mode, I2C_DATA_LEN,
191 I2C_OP_RETRIES);
192 if (unlikely(ret)) {
193 return ret;
194 }
195
196 return 0;
197 }
198
drv_acc_mir3_da217_set_default_config(i2c_dev_t * drv)199 static int drv_acc_mir3_da217_set_default_config(i2c_dev_t *drv)
200 {
201 int ret = 0;
202 uint8_t value = 0;
203
204 value = 0x83;
205 ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE, &value, I2C_DATA_LEN,
206 I2C_OP_RETRIES);
207 if (unlikely(ret)) {
208 return ret;
209 }
210
211 value = 0x69;
212 ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE, &value, I2C_DATA_LEN,
213 I2C_OP_RETRIES);
214 if (unlikely(ret)) {
215 return ret;
216 }
217
218 value = 0xbd;
219 ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE, &value, I2C_DATA_LEN,
220 I2C_OP_RETRIES);
221 if (unlikely(ret)) {
222 return ret;
223 }
224
225 ret = sensor_i2c_read(drv, 0x8e, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
226 if (unlikely(ret)) {
227 return ret;
228 }
229 if (value == 0) {
230 value = 0x50;
231 ret = sensor_i2c_write(drv, 0x8e, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
232 if (unlikely(ret)) {
233 return ret;
234 }
235 }
236
237 value = 0x40;
238 ret = sensor_i2c_write(drv, NSA_REG_G_RANGE, &value, I2C_DATA_LEN,
239 I2C_OP_RETRIES);
240 if (unlikely(ret)) {
241 return ret;
242 }
243
244 value = 0x00;
245 ret = sensor_i2c_write(drv, NSA_REG_INT_PIN_CONFIG, &value, I2C_DATA_LEN,
246 I2C_OP_RETRIES);
247 if (unlikely(ret)) {
248 return ret;
249 }
250
251 ret = drv_acc_mir3_da217_set_power_mode(drv, DEV_SLEEP);
252 if (unlikely(ret)) {
253 return ret;
254 }
255
256 value = 0x07;
257 ret = sensor_i2c_write(drv, NSA_REG_ODR_AXIS_DISABLE, &value, I2C_DATA_LEN,
258 I2C_OP_RETRIES);
259 if (unlikely(ret)) {
260 return ret;
261 }
262
263 ret = drv_acc_mir3_da217_close_step_counter(drv);
264 if (unlikely(ret)) {
265 return ret;
266 }
267
268 value = 0x80;
269 ret = sensor_i2c_write(drv, NSA_REG_RESET_STEP, &value, I2C_DATA_LEN,
270 I2C_OP_RETRIES);
271 if (unlikely(ret)) {
272 return ret;
273 }
274
275 value = 0x04;
276 ret = sensor_i2c_write(drv, NSA_REG_INTERRUPT_MAPPING2, &value,
277 I2C_DATA_LEN, I2C_OP_RETRIES);
278 if (unlikely(ret)) {
279 return ret;
280 }
281
282 value = 0x04;
283 ret = sensor_i2c_write(drv, NSA_REG_INTERRUPT_SETTINGS0, &value,
284 I2C_DATA_LEN, I2C_OP_RETRIES);
285 if (unlikely(ret)) {
286 return ret;
287 }
288
289 return 0;
290 }
291
drv_acc_mir3_da217_irq_handle(void)292 static void drv_acc_mir3_da217_irq_handle(void)
293 {
294 /* no handle so far */
295 }
296
drv_acc_mir3_da217_open(void)297 static int drv_acc_mir3_da217_open(void)
298 {
299 int ret = 0;
300
301 ret = drv_acc_mir3_da217_set_power_mode(&da217_ctx, DEV_POWER_ON);
302 if (unlikely(ret)) {
303 return -1;
304 }
305
306 #ifdef AOS_SENSOR_ACC_SUPPORT_STEP
307 ret = drv_acc_mir3_da217_open_step_counter(&da217_ctx);
308 if (unlikely(ret)) {
309 return -1;
310 }
311 #endif
312
313 LOG("%s %s successfully \n", SENSOR_STR, __func__);
314 return 0;
315 }
316
drv_acc_mir3_da217_close(void)317 static int drv_acc_mir3_da217_close(void)
318 {
319 int ret = 0;
320
321 #ifdef AOS_SENSOR_ACC_SUPPORT_STEP
322 ret = drv_acc_mir3_da217_close_step_counter(&da217_ctx);
323 if (unlikely(ret)) {
324 return -1;
325 }
326 #endif
327
328 ret = drv_acc_mir3_da217_set_power_mode(&da217_ctx, DEV_POWER_OFF);
329 if (unlikely(ret)) {
330 return -1;
331 }
332
333 LOG("%s %s successfully \n", SENSOR_STR, __func__);
334 return 0;
335 }
336
drv_acc_mir3_da217_read(void * buf,size_t len)337 static int drv_acc_mir3_da217_read(void *buf, size_t len)
338 {
339 int ret = 0;
340 size_t size;
341 uint8_t acc_raw[DA217_ACC_DATA_SIZE] = { 0 };
342 accel_data_t *pdata = (accel_data_t *)buf;
343 #ifdef AOS_SENSOR_ACC_SUPPORT_STEP
344 uint8_t step_raw[2] = { 0 };
345 #endif
346
347 if (buf == NULL) {
348 return -1;
349 }
350
351 size = sizeof(accel_data_t);
352 if (len < size) {
353 return -1;
354 }
355
356 ret = sensor_i2c_read(&da217_ctx, NSA_REG_ACC_X_LSB, acc_raw,
357 DA217_ACC_DATA_SIZE, I2C_OP_RETRIES);
358 if (unlikely(ret)) {
359 return -1;
360 }
361
362 pdata->data[0] = (int32_t)((int16_t)(acc_raw[1] << 8 | acc_raw[0]) >> 4);
363 pdata->data[1] = (int32_t)((int16_t)(acc_raw[3] << 8 | acc_raw[2]) >> 4);
364 pdata->data[2] = (int32_t)((int16_t)(acc_raw[5] << 8 | acc_raw[4]) >> 4);
365
366 #ifdef AOS_SENSOR_ACC_SUPPORT_STEP
367 ret = sensor_i2c_read(&da217_ctx, NSA_REG_STEPS_MSB, step_raw, 2,
368 I2C_OP_RETRIES);
369 if (unlikely(ret)) {
370 return -1;
371 }
372 pdata->step = ((uint16_t)((step_raw[0] << 8 | step_raw[1]))) / 2;
373 #endif
374
375 pdata->timestamp = aos_now_ms();
376
377 return (int)size;
378 }
379
drv_acc_mir3_da217_write(const void * buf,size_t len)380 static int drv_acc_mir3_da217_write(const void *buf, size_t len)
381 {
382 (void)buf;
383 (void)len;
384 return 0;
385 }
386
drv_acc_mir3_da217_ioctl(int cmd,unsigned long arg)387 static int drv_acc_mir3_da217_ioctl(int cmd, unsigned long arg)
388 {
389 int ret = 0;
390
391 switch (cmd) {
392 case SENSOR_IOCTL_SET_POWER: {
393 ret = drv_acc_mir3_da217_set_power_mode(&da217_ctx, arg);
394 if (unlikely(ret)) {
395 return -1;
396 }
397 } break;
398 case SENSOR_IOCTL_GET_INFO: {
399 /* fill the dev info here */
400 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
401 info->model = "DA217";
402 info->unit = mg;
403 } break;
404 default:
405 return -1;
406 }
407
408 LOG("%s %s successfully \n", SENSOR_STR, __func__);
409 return 0;
410 }
411
drv_acc_mir3_da217_init(void)412 int drv_acc_mir3_da217_init(void)
413 {
414 int ret = 0;
415 sensor_obj_t sensor;
416
417 memset(&sensor, 0, sizeof(sensor));
418
419 /* fill the sensor obj parameters here */
420 sensor.tag = TAG_DEV_ACC;
421 sensor.path = dev_acc_path;
422 sensor.io_port = I2C_PORT;
423 sensor.open = drv_acc_mir3_da217_open;
424 sensor.close = drv_acc_mir3_da217_close;
425 sensor.read = drv_acc_mir3_da217_read;
426 sensor.write = drv_acc_mir3_da217_write;
427 sensor.ioctl = drv_acc_mir3_da217_ioctl;
428 sensor.irq_handle = drv_acc_mir3_da217_irq_handle;
429 ret = sensor_create_obj(&sensor);
430 if (unlikely(ret)) {
431 return -1;
432 }
433
434 ret = drv_acc_mir3_da217_validate_id(&da217_ctx, DA217_CHIP_ID_VAL);
435 if (unlikely(ret)) {
436 return -1;
437 }
438
439 ret = drv_acc_mir3_da217_set_default_config(&da217_ctx);
440 if (unlikely(ret)) {
441 return -1;
442 }
443
444 LOG("%s %s successfully \n", SENSOR_STR, __func__);
445 return 0;
446 }
447
448 SENSOR_DRV_ADD(drv_acc_mir3_da217_init);
449
450