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