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