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 DA312B_NORMAL_MODE                               0x00
55 #define DA312B_SUSPEND_MODE                              0x01
56 
57 #define DA312B_I2C_SLAVE_ADDR                            (0x27)
58 
59 #define DA312B_ACC_DATA_SIZE                             6
60 
61 #define DA312B_CHIP_ID_VAL                               0x13
62 #define DA312B_ADDR_TRANS(n)                             ((n) << 1)
63 
64 #define DA312B_GET_BITSLICE(regvar, bitname)             ((regvar & bitname##__MSK) >> bitname##__POS)
65 #define DA312B_SET_BITSLICE(regvar, bitname, val)        ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
66 
67 i2c_dev_t da312B_ctx = {
68     .port = 2,
69     .config.address_width = 8,
70     .config.freq = 100000,
71     .config.dev_addr = DA312B_ADDR_TRANS(DA312B_I2C_SLAVE_ADDR)
72 };
73 
drv_acc_mir3_da312B_validate_id(i2c_dev_t * drv,uint8_t id_value)74 static int drv_acc_mir3_da312B_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_da312B_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)94 static int drv_acc_mir3_da312B_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 
118     return 0;
119 }
120 
drv_acc_mir3_da312B_set_default_config(i2c_dev_t * drv)121 static int drv_acc_mir3_da312B_set_default_config(i2c_dev_t* drv)
122 {
123     int     ret = 0;
124     uint8_t value = 0;
125 
126     value = 0x83;
127     ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE,
128                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
129     if (unlikely(ret)) {
130         return ret;
131     }
132 
133     value = 0x69;
134     ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE,
135                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
136     if (unlikely(ret)) {
137         return ret;
138     }
139 
140     value = 0xbd;
141     ret = sensor_i2c_write(drv, NSA_REG_ENGINEERING_MODE,
142                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
143     if (unlikely(ret)) {
144         return ret;
145     }
146 
147     ret = sensor_i2c_read(drv, 0x8e, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
148     if (unlikely(ret)) {
149         return ret;
150     }
151     if (value == 0) {
152         value = 0x50;
153         ret = sensor_i2c_write(drv, 0x8e, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
154         if (unlikely(ret)) {
155             return ret;
156         }
157     }
158 
159     value = 0x40;
160     ret = sensor_i2c_write(drv, NSA_REG_G_RANGE,
161                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
162     if (unlikely(ret)) {
163         return ret;
164     }
165 
166     value = 0x00;
167     ret = sensor_i2c_write(drv, NSA_REG_INT_PIN_CONFIG,
168                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
169     if (unlikely(ret)) {
170         return ret;
171     }
172 
173     ret = drv_acc_mir3_da312B_set_power_mode(drv, DEV_SLEEP);
174     if (unlikely(ret)) {
175         return ret;
176     }
177 
178     value = 0x07;
179     ret = sensor_i2c_write(drv, NSA_REG_ODR_AXIS_DISABLE,
180                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
181     if (unlikely(ret)) {
182         return ret;
183     }
184 
185     value = 0x04;
186     ret = sensor_i2c_write(drv, NSA_REG_INTERRUPT_MAPPING2,
187                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
188     if (unlikely(ret)) {
189         return ret;
190     }
191 
192     value = 0x04;
193     ret = sensor_i2c_write(drv, NSA_REG_INTERRUPT_SETTINGS0,
194                             &value, I2C_DATA_LEN, I2C_OP_RETRIES);
195     if (unlikely(ret)) {
196         return ret;
197     }
198 
199     return 0;
200 }
201 
drv_acc_mir3_da312B_irq_handle(void)202 static void drv_acc_mir3_da312B_irq_handle(void)
203 {
204     /* no handle so far */
205 }
206 
drv_acc_mir3_da312B_open(void)207 static int drv_acc_mir3_da312B_open(void)
208 {
209     int ret = 0;
210 
211     ret = drv_acc_mir3_da312B_set_power_mode(&da312B_ctx, DEV_POWER_ON);
212     if(unlikely(ret)) {
213         return -1;
214     }
215 
216     LOG("%s %s successfully \n", SENSOR_STR, __func__);
217     return 0;
218 
219 }
220 
drv_acc_mir3_da312B_close(void)221 static int drv_acc_mir3_da312B_close(void)
222 {
223     int ret = 0;
224 
225     ret = drv_acc_mir3_da312B_set_power_mode(&da312B_ctx, DEV_POWER_OFF);
226     if(unlikely(ret)) {
227         return -1;
228     }
229 
230     LOG("%s %s successfully \n", SENSOR_STR, __func__);
231     return 0;
232 }
233 
drv_acc_mir3_da312B_read(void * buf,size_t len)234 static int drv_acc_mir3_da312B_read(void *buf, size_t len)
235 {
236     int ret = 0;
237     size_t size;
238     uint8_t acc_raw[DA312B_ACC_DATA_SIZE] = {0};
239     accel_data_t* pdata = (accel_data_t*)buf;
240 
241     if(buf == NULL){
242         return -1;
243     }
244 
245     size = sizeof(accel_data_t);
246     if(len < size){
247         return -1;
248     }
249 
250     ret = sensor_i2c_read(&da312B_ctx, NSA_REG_ACC_X_LSB, acc_raw, DA312B_ACC_DATA_SIZE, I2C_OP_RETRIES);
251     if (unlikely(ret)) {
252         return -1;
253     }
254 
255     pdata->data[0] = (int32_t)((int16_t)(acc_raw[1] << 8 | acc_raw[0]) >> 4);
256     pdata->data[1] = (int32_t)((int16_t)(acc_raw[3] << 8 | acc_raw[2]) >> 4);
257     pdata->data[2] = (int32_t)((int16_t)(acc_raw[5] << 8 | acc_raw[4]) >> 4);
258 
259     pdata->timestamp = aos_now_ms();
260 
261     return (int)size;
262 }
263 
drv_acc_mir3_da312B_write(const void * buf,size_t len)264 static int drv_acc_mir3_da312B_write(const void *buf, size_t len)
265 {
266     (void)buf;
267     (void)len;
268     return 0;
269 }
270 
drv_acc_mir3_da312B_ioctl(int cmd,unsigned long arg)271 static int drv_acc_mir3_da312B_ioctl(int cmd, unsigned long arg)
272 {
273     int ret = 0;
274 
275     switch (cmd) {
276         case SENSOR_IOCTL_SET_POWER:{
277             ret = drv_acc_mir3_da312B_set_power_mode(&da312B_ctx, arg);
278             if(unlikely(ret)) {
279                 return -1;
280             }
281         }break;
282         case SENSOR_IOCTL_GET_INFO:{
283             /* fill the dev info here */
284             dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
285             info->model = "DA312B";
286             info->unit = mg;
287         }break;
288         default:
289             return -1;
290     }
291 
292     LOG("%s %s successfully \n", SENSOR_STR, __func__);
293     return 0;
294 }
295 
drv_acc_mir3_da312B_init(void)296 int drv_acc_mir3_da312B_init(void)
297 {
298     int ret = 0;
299     sensor_obj_t sensor;
300     memset(&sensor, 0, sizeof(sensor));
301 
302     /* fill the sensor obj parameters here */
303     sensor.tag = TAG_DEV_ACC;
304     sensor.path = dev_acc_path;
305     sensor.io_port = I2C_PORT;
306     sensor.open = drv_acc_mir3_da312B_open;
307     sensor.close = drv_acc_mir3_da312B_close;
308     sensor.read = drv_acc_mir3_da312B_read;
309     sensor.write = drv_acc_mir3_da312B_write;
310     sensor.ioctl = drv_acc_mir3_da312B_ioctl;
311     sensor.irq_handle = drv_acc_mir3_da312B_irq_handle;
312     ret = sensor_create_obj(&sensor);
313     if(unlikely(ret)) {
314         return -1;
315     }
316 
317     ret = drv_acc_mir3_da312B_validate_id(&da312B_ctx, DA312B_CHIP_ID_VAL);
318     if(unlikely(ret)) {
319         return -1;
320     }
321 
322     ret = drv_acc_mir3_da312B_set_default_config(&da312B_ctx);
323     if(unlikely(ret)) {
324         return -1;
325     }
326 
327     LOG("%s %s successfully \n", SENSOR_STR, __func__);
328     return 0;
329 }
330 
331 SENSOR_DRV_ADD(drv_acc_mir3_da312B_init);
332 
333