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