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_G_RANGE                                 0x0f
25 #define NSA_REG_ODR_AXIS_DISABLE                        0x10
26 #define NSA_REG_POWERMODE_BW                            0x11
27 #define NSA_REG_SWAP_POLARITY                           0x12
28 #define NSA_REG_INTERRUPT_SETTINGS0                     0x15
29 #define NSA_REG_INTERRUPT_SETTINGS1                     0x16
30 #define NSA_REG_INTERRUPT_SETTINGS2                     0x17
31 #define NSA_REG_INTERRUPT_MAPPING1                      0x19
32 #define NSA_REG_INTERRUPT_MAPPING2                      0x1a
33 #define NSA_REG_INTERRUPT_MAPPING3                      0x1b
34 #define NSA_REG_INT_PIN_CONFIG                          0x20
35 #define NSA_REG_INT_LATCH                               0x21
36 #define NSA_REG_ACTIVE_DURATION                         0x27
37 #define NSA_REG_ACTIVE_THRESHOLD                        0x28
38 #define NSA_REG_CUSTOM_OFFSET_X                         0x38
39 #define NSA_REG_CUSTOM_OFFSET_Y                         0x39
40 #define NSA_REG_CUSTOM_OFFSET_Z                         0x3a
41 #define NSA_REG_ENGINEERING_MODE                        0x7f
42 #define NSA_REG_SENSITIVITY_TRIM_X                      0x80
43 #define NSA_REG_SENSITIVITY_TRIM_Y                      0x81
44 #define NSA_REG_SENSITIVITY_TRIM_Z                      0x82
45 #define NSA_REG_COARSE_OFFSET_TRIM_X                    0x83
46 #define NSA_REG_COARSE_OFFSET_TRIM_Y                    0x84
47 #define NSA_REG_COARSE_OFFSET_TRIM_Z                    0x85
48 #define NSA_REG_FINE_OFFSET_TRIM_X                      0x86
49 #define NSA_REG_FINE_OFFSET_TRIM_Y                      0x87
50 #define NSA_REG_FINE_OFFSET_TRIM_Z                      0x88
51 #define NSA_REG_SENS_COMP                               0x8c
52 #define NSA_REG_SENS_COARSE_TRIM                        0xd1
53 
54 #define DA215_NORMAL_MODE                               0x00
55 #define DA215_SUSPEND_MODE                              0x01
56 
57 #define DA215_I2C_SLAVE_ADDR                            (0x27)
58 
59 #define DA215_ACC_DATA_SIZE                             6
60 
61 #define DA215_CHIP_ID_VAL                               0x13
62 #define DA215_ADDR_TRANS(n)                             ((n) << 1)
63 
64 #define DA215_GET_BITSLICE(regvar, bitname)             ((regvar & bitname##__MSK) >> bitname##__POS)
65 #define DA215_SET_BITSLICE(regvar, bitname, val)        ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
66 
67 i2c_dev_t da215_ctx = {
68     .port = 2,
69     .config.address_width = 8,
70     .config.freq = 400000,
71     .config.dev_addr = DA215_ADDR_TRANS(DA215_I2C_SLAVE_ADDR)
72 };
73 
drv_acc_mir3_da215_validate_id(i2c_dev_t * drv,uint8_t id_value)74 static int drv_acc_mir3_da215_validate_id(i2c_dev_t* drv, uint8_t id_value)
75 {
76     int     ret = 0;
77     uint8_t value = 0;
78 
79     if(drv == NULL){
80         return -1;
81     }
82 
83     ret = sensor_i2c_read(drv, NSA_REG_WHO_AM_I, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
84     if(unlikely(ret)) {
85         return ret;
86     }
87 
88     if (id_value != value){
89         return -1;
90     }
91     return 0;
92 }
93 
drv_acc_mir3_da215_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)94 static int drv_acc_mir3_da215_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
95 {
96     int     ret = 0;
97     uint8_t dev_mode;
98 
99 
100     switch(mode){
101         case DEV_POWER_OFF:
102         case DEV_SLEEP:{
103             dev_mode = (uint8_t)0x80;
104             break;
105             }
106         case DEV_POWER_ON:{
107             dev_mode = (uint8_t)0x34;
108             break;
109             }
110         default:return -1;
111     }
112 
113     ret = sensor_i2c_write(drv, NSA_REG_POWERMODE_BW, &dev_mode, I2C_DATA_LEN, I2C_OP_RETRIES);
114     if(unlikely(ret)) {
115         return ret;
116     }
117     dev_mode = 0;
118     ret = sensor_i2c_read(drv, NSA_REG_POWERMODE_BW, &dev_mode, I2C_DATA_LEN, I2C_OP_RETRIES);
119 
120     LOG("sensor_i2c_read:0x%x \n", dev_mode);
121 
122     return 0;
123 }
124 
drv_acc_mir3_da215_set_default_config(i2c_dev_t * drv)125 static int drv_acc_mir3_da215_set_default_config(i2c_dev_t* drv)
126 {
127     int     ret = 0;
128     uint8_t value = 0;
129 
130     value = 0x83;
131     ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE,
132                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
133     if (unlikely(ret)) {
134         return ret;
135     }
136 
137     value = 0x69;
138     ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE,
139                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
140     if (unlikely(ret)) {
141         return ret;
142     }
143 
144     value = 0xbd;
145     ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE,
146                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
147     if (unlikely(ret)) {
148         return ret;
149     }
150 
151     ret = sensor_i2c_read(drv, 0x8e, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
152     if (unlikely(ret)) {
153         return ret;
154     }
155     if (value == 0) {
156         value = 0x50;
157         ret = sensor_i2c_write(drv, 0x8e, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
158         if (unlikely(ret)) {
159             return ret;
160         }
161     }
162 
163     value = 0x40;
164     ret = sensor_i2c_write(drv, NSA_REG_G_RANGE,
165                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
166     if (unlikely(ret)) {
167         return ret;
168     }
169 
170     value = 0x00;
171     ret = sensor_i2c_write(drv, NSA_REG_INT_PIN_CONFIG,
172                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
173     if (unlikely(ret)) {
174         return ret;
175     }
176 
177     ret = drv_acc_mir3_da215_set_power_mode(drv, DEV_SLEEP);
178     if (unlikely(ret)) {
179         return ret;
180     }
181 
182     value = 0x07;
183     ret = sensor_i2c_write(drv, NSA_REG_ODR_AXIS_DISABLE,
184                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
185     if (unlikely(ret)) {
186         return ret;
187     }
188 
189     value = 0x04;
190     ret = sensor_i2c_write(drv, NSA_REG_INTERRUPT_MAPPING2,
191                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
192     if (unlikely(ret)) {
193         return ret;
194     }
195 
196     value = 0x04;
197     ret = sensor_i2c_write(drv, NSA_REG_INTERRUPT_SETTINGS0,
198                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
199     if (unlikely(ret)) {
200         return ret;
201     }
202 
203     return 0;
204 }
205 
drv_acc_mir3_da215_irq_handle(void)206 static void drv_acc_mir3_da215_irq_handle(void)
207 {
208     /* no handle so far */
209 }
210 
drv_acc_mir3_da215_open(void)211 static int drv_acc_mir3_da215_open(void)
212 {
213     int ret = 0;
214 
215     ret = drv_acc_mir3_da215_set_power_mode(&da215_ctx, DEV_POWER_ON);
216     if(unlikely(ret)) {
217         return -1;
218     }
219 
220     LOG("%s %s successfully \n", SENSOR_STR, __func__);
221     return 0;
222 
223 }
224 
drv_acc_mir3_da215_close(void)225 static int drv_acc_mir3_da215_close(void)
226 {
227     int ret = 0;
228 
229     ret = drv_acc_mir3_da215_set_power_mode(&da215_ctx, DEV_POWER_OFF);
230     if(unlikely(ret)) {
231         return -1;
232     }
233 
234     LOG("%s %s successfully \n", SENSOR_STR, __func__);
235     return 0;
236 }
237 
drv_acc_mir3_da215_read(void * buf,size_t len)238 static int drv_acc_mir3_da215_read(void *buf, size_t len)
239 {
240     int ret = 0;
241     size_t size;
242     uint8_t acc_raw[DA215_ACC_DATA_SIZE] = {0};
243     accel_data_t* pdata = (accel_data_t*)buf;
244 
245     if(buf == NULL){
246         return -1;
247     }
248 
249     size = sizeof(accel_data_t);
250     if(len < size){
251         return -1;
252     }
253 
254     ret = sensor_i2c_read(&da215_ctx, NSA_REG_ACC_X_LSB, acc_raw, DA215_ACC_DATA_SIZE, I2C_OP_RETRIES);
255     if (unlikely(ret)) {
256         return -1;
257     }
258 
259     pdata->data[0] = (int32_t)((int16_t)(acc_raw[1] << 8 | acc_raw[0]) >> 4);
260     pdata->data[1] = (int32_t)((int16_t)(acc_raw[3] << 8 | acc_raw[2]) >> 4);
261     pdata->data[2] = (int32_t)((int16_t)(acc_raw[5] << 8 | acc_raw[4]) >> 4);
262 
263     pdata->timestamp = aos_now_ms();
264 
265     return (int)size;
266 }
267 
drv_acc_mir3_da215_write(const void * buf,size_t len)268 static int drv_acc_mir3_da215_write(const void *buf, size_t len)
269 {
270     (void)buf;
271     (void)len;
272     return 0;
273 }
274 
drv_acc_mir3_da215_ioctl(int cmd,unsigned long arg)275 static int drv_acc_mir3_da215_ioctl(int cmd, unsigned long arg)
276 {
277     int ret = 0;
278 
279     switch (cmd) {
280         case SENSOR_IOCTL_SET_POWER:{
281             ret = drv_acc_mir3_da215_set_power_mode(&da215_ctx, arg);
282             if(unlikely(ret)) {
283                 return -1;
284             }
285         }break;
286         case SENSOR_IOCTL_GET_INFO:{
287             /* fill the dev info here */
288             dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
289             info->model = "DA215";
290             info->unit = mg;
291         }break;
292         default:
293             return -1;
294     }
295 
296     LOG("%s %s successfully \n", SENSOR_STR, __func__);
297     return 0;
298 }
299 
drv_acc_mir3_da215_init(void)300 int drv_acc_mir3_da215_init(void)
301 {
302     int ret = 0;
303     sensor_obj_t sensor;
304     memset(&sensor, 0, sizeof(sensor));
305 
306     /* fill the sensor obj parameters here */
307     sensor.tag = TAG_DEV_ACC;
308     sensor.path = dev_acc_path;
309     sensor.io_port = I2C_PORT;
310     sensor.open = drv_acc_mir3_da215_open;
311     sensor.close = drv_acc_mir3_da215_close;
312     sensor.read = drv_acc_mir3_da215_read;
313     sensor.write = drv_acc_mir3_da215_write;
314     sensor.ioctl = drv_acc_mir3_da215_ioctl;
315     sensor.irq_handle = drv_acc_mir3_da215_irq_handle;
316     ret = sensor_create_obj(&sensor);
317     if(unlikely(ret)) {
318         return -1;
319     }
320 
321     ret = drv_acc_mir3_da215_validate_id(&da215_ctx, DA215_CHIP_ID_VAL);
322     if(unlikely(ret)) {
323         return -1;
324     }
325 
326     ret = drv_acc_mir3_da215_set_default_config(&da215_ctx);
327     if(unlikely(ret)) {
328         return -1;
329     }
330 
331     LOG("%s %s successfully \n", SENSOR_STR, __func__);
332     return 0;
333 }
334 
335 SENSOR_DRV_ADD(drv_acc_mir3_da215_init);
336 
337