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