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