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 
15 #define H3LIS331DL_I2C_ADDR1                 	(0x18)
16 #define H3LIS331DL_I2C_ADDR2                 	(0x19)
17 #define H3LIS331DL_I2C_ADDR_TRANS(n)         	((n)<<1)
18 #define H3LIS331DL_I2C_ADDR                  	H3LIS331DL_I2C_ADDR_TRANS(H3LIS331DL_I2C_ADDR1)
19 
20 #define H3LIS331DL_ACC_TEMP_L            		0x0B
21 #define H3LIS331DL_ACC_TEMP_H            		0x0C
22 
23 #define H3LIS331DL_ACC_WHO_AM_I              	0x0F
24 #define H3LIS331DL_ACC_ACT_THS             		0x1E
25 #define H3LIS331DL_ACC_ACT_DUR	          		0x1F
26 
27 #define H3LIS331DL_ACC_CTRL_REG1             	0x20
28 #define H3LIS331DL_ACC_CTRL_REG2             	0x21
29 #define H3LIS331DL_ACC_CTRL_REG3            	0x22
30 #define H3LIS331DL_ACC_CTRL_REG4             	0x23
31 #define H3LIS331DL_ACC_CTRL_REG5             	0x24
32 #define H3LIS331DL_ACC_STATUS_REG           	0x27
33 #define H3LIS331DL_ACC_OUT_X_L              	0x28
34 #define H3LIS331DL_ACC_OUT_X_H              	0x29
35 #define H3LIS331DL_ACC_OUT_Y_L              	0x2A
36 #define H3LIS331DL_ACC_OUT_Y_H              	0x2B
37 #define H3LIS331DL_ACC_OUT_Z_L              	0x2C
38 #define H3LIS331DL_ACC_OUT_Z_H              	0x2D
39 
40 #define H3LIS331DL_ACC_RANGE_100G              	(0x0)
41 #define H3LIS331DL_ACC_RANGE_200G              	(0x1)
42 #define H3LIS331DL_ACC_RANGE_400G               (0x3)
43 #define H3LIS331DL_ACC_RANGE_MSK              	(0x30)
44 #define H3LIS331DL_ACC_RANGE_POS              	(4)
45 
46 #define H3LIS331DL_ACC_SENSITIVITY_100G        	49
47 #define H3LIS331DL_ACC_SENSITIVITY_200G        	98
48 #define H3LIS331DL_ACC_SENSITIVITY_400G         195
49 
50 #define H3LIS331DL_ACC_CHIP_ID_VALUE			(0x32)
51 
52 #define H3LIS331DL_SHIFT_EIGHT_BITS           	(8)
53 #define H3LIS331DL_SHIFT_FOUR_BITS             	(4)
54 
55 #define H3LIS331DL_16_BIT_SHIFT               	(0xFF)
56 #define H3LIS331DL_ACC_MUL                    	(1000)
57 
58 #define H3LIS331DL_ACC_ODR_POWER_DOWN			(0x00)
59 #define H3LIS331DL_ACC_ODR_0_5_HZ               (0x40)
60 #define H3LIS331DL_ACC_ODR_1_HZ               	(0x60)
61 #define H3LIS331DL_ACC_ODR_2_HZ               	(0x80)
62 #define H3LIS331DL_ACC_ODR_5_HZ               	(0xA0)
63 #define H3LIS331DL_ACC_ODR_10_HZ               	(0xC0)
64 #define H3LIS331DL_ACC_ODR_50_HZ              	(0x20)
65 #define H3LIS331DL_ACC_ODR_100_HZ              	(0x28)
66 #define H3LIS331DL_ACC_ODR_400_HZ              	(0x30)
67 #define H3LIS331DL_ACC_ODR_1000_HZ              (0x38)
68 #define H3LIS331DL_ACC_ODR_MSK                 	(0xF8)
69 #define H3LIS331DL_ACC_ODR_POS                 	(3)
70 
71 #define H3LIS331DL_ACC_DEFAULT_ODR_100HZ        (100)
72 
73 #define H3LIS331DL_BDU_ENABLE					(0x80)
74 
75 #define H3LIS331DL_ACC_STATUS_ZYXDA				(0x08)
76 
77 #define H3LIS331DL_GET_BITSLICE(regvar, bitname)\
78 ((regvar & bitname##_MSK) >> bitname##_POS)
79 
80 #define H3LIS331DL_SET_BITSLICE(regvar, bitname, val)\
81 	((regvar & ~bitname##_MSK) | ((val<<bitname##_POS)&bitname##_MSK))
82 
83 
84 static int32_t h3lis331dl_acc_factor[ACC_RANGE_MAX] = { 0, 0, 0, 0, 0, 0, 0, H3LIS331DL_ACC_SENSITIVITY_100G, H3LIS331DL_ACC_SENSITIVITY_200G,
85                                      H3LIS331DL_ACC_SENSITIVITY_400G };
86 static int32_t cur_acc_factor = 0;
87 
88 
89 i2c_dev_t h3lis331dl_ctx = {
90     .port = 3,
91     .config.address_width = 8,
92     .config.freq = 400000,
93     .config.dev_addr = H3LIS331DL_I2C_ADDR,
94 };
95 
drv_acc_st_h3lis331dl_validate_id(i2c_dev_t * drv,uint8_t id_value)96 static int drv_acc_st_h3lis331dl_validate_id(i2c_dev_t* drv, uint8_t id_value)
97 {
98     uint8_t value = 0x00;
99     int ret = 0;
100 
101     if(drv == NULL){
102         return -1;
103     }
104 
105     ret = sensor_i2c_read(drv, H3LIS331DL_ACC_WHO_AM_I, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
106 
107 	LOG("H3LIS331DL ID: %x\n", value);
108     if(unlikely(ret)){
109         return ret;
110     }
111 
112     if (id_value != value){
113         return -1;
114     }
115 
116     return 0;
117 }
118 
drv_acc_st_h3lis331dl_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)119 static int drv_acc_st_h3lis331dl_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
120 {
121     uint8_t value  = 0x00;
122     int ret = 0;
123 
124     ret = sensor_i2c_read(drv, H3LIS331DL_ACC_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
125     if(unlikely(ret)){
126         return ret;
127     }
128 
129     switch(mode){
130         case DEV_POWER_ON:{
131             value = H3LIS331DL_SET_BITSLICE(value,H3LIS331DL_ACC_ODR,H3LIS331DL_ACC_ODR_10_HZ);
132             ret = sensor_i2c_write(drv, H3LIS331DL_ACC_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
133             if(unlikely(ret)){
134                 return ret;
135             }
136         }break;
137 
138         case DEV_POWER_OFF:{
139             value = H3LIS331DL_SET_BITSLICE(value,H3LIS331DL_ACC_ODR,H3LIS331DL_ACC_ODR_POWER_DOWN);
140             ret = sensor_i2c_write(drv, H3LIS331DL_ACC_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
141             if(unlikely(ret)){
142                 return ret;
143             }
144         }break;
145 
146         case DEV_SLEEP:{
147             value = H3LIS331DL_SET_BITSLICE(value,H3LIS331DL_ACC_ODR,H3LIS331DL_ACC_ODR_10_HZ);
148             ret = sensor_i2c_write(drv, H3LIS331DL_ACC_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
149             if(unlikely(ret)){
150                 return ret;
151             }
152 
153         }break;
154 
155        default:break;
156     }
157     return 0;
158 }
159 
drv_acc_st_h3lis331dl_hz2odr(uint32_t hz)160 static uint8_t drv_acc_st_h3lis331dl_hz2odr(uint32_t hz)
161 {
162     if(hz > 400)
163         return H3LIS331DL_ACC_ODR_1000_HZ;
164     else if(hz > 100)
165         return H3LIS331DL_ACC_ODR_400_HZ;
166     else if(hz > 50)
167         return H3LIS331DL_ACC_ODR_100_HZ;
168     else if(hz > 10)
169         return H3LIS331DL_ACC_ODR_50_HZ;
170     else if(hz > 5)
171         return H3LIS331DL_ACC_ODR_10_HZ;
172     else if(hz > 2)
173         return H3LIS331DL_ACC_ODR_5_HZ;
174     else if(hz > 1)
175         return H3LIS331DL_ACC_ODR_2_HZ;
176 	else
177 		return H3LIS331DL_ACC_ODR_1_HZ;
178 
179 }
180 
drv_acc_st_h3lis331dl_set_odr(i2c_dev_t * drv,uint32_t hz)181 static int drv_acc_st_h3lis331dl_set_odr(i2c_dev_t* drv, uint32_t hz)
182 {
183     int ret = 0;
184     uint8_t value = 0x00;
185     uint8_t odr = drv_acc_st_h3lis331dl_hz2odr(hz);
186 
187     ret = sensor_i2c_read(drv, H3LIS331DL_ACC_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
188     if(unlikely(ret)){
189         return ret;
190     }
191 
192     value = H3LIS331DL_SET_BITSLICE(value,H3LIS331DL_ACC_ODR,odr);
193 
194     ret = sensor_i2c_write(drv, H3LIS331DL_ACC_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
195     if(unlikely(ret)){
196         return ret;
197     }
198     return 0;
199 }
200 
drv_acc_st_h3lis331dl_set_range(i2c_dev_t * drv,uint32_t range)201 static int drv_acc_st_h3lis331dl_set_range(i2c_dev_t* drv, uint32_t range)
202 {
203 
204     int ret = 0;
205     uint8_t value = 0x00;
206     uint8_t tmp = 0;
207 
208     ret = sensor_i2c_read(drv, H3LIS331DL_ACC_CTRL_REG4, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
209     if(unlikely(ret)){
210         return ret;
211     }
212 
213     switch (range){
214         case ACC_RANGE_100G:{
215             tmp = H3LIS331DL_ACC_RANGE_100G;
216         }break;
217 
218         case ACC_RANGE_200G:{
219             tmp = H3LIS331DL_ACC_RANGE_200G;
220         }break;
221 
222         case ACC_RANGE_400G:{
223             tmp = H3LIS331DL_ACC_RANGE_400G;
224         }break;
225 
226         default:break;
227     }
228 
229     value  = H3LIS331DL_SET_BITSLICE(value,H3LIS331DL_ACC_RANGE,tmp);
230 
231     ret = sensor_i2c_write(drv, H3LIS331DL_ACC_CTRL_REG4, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
232     if(unlikely(ret)){
233         return ret;
234     }
235 
236     if((range >= ACC_RANGE_100G)&&(range <= ACC_RANGE_400G)){
237         cur_acc_factor = h3lis331dl_acc_factor[range];
238     }
239 
240     return 0;
241 }
242 
243 
drv_acc_st_h3lis331dl_set_bdu(i2c_dev_t * drv)244 static int drv_acc_st_h3lis331dl_set_bdu(i2c_dev_t* drv)
245 {
246     uint8_t value = 0x00;
247     int ret = 0;
248 
249     ret = sensor_i2c_read(drv, H3LIS331DL_ACC_CTRL_REG4, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
250     if(unlikely(ret)){
251         return ret;
252     }
253     value |= H3LIS331DL_BDU_ENABLE;
254 
255     ret = sensor_i2c_write(drv, H3LIS331DL_ACC_CTRL_REG4, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
256     if(unlikely(ret)){
257         return ret;
258     }
259     return 0;
260 }
261 
drv_acc_st_h3lis331dl_irq_handle(void)262 static void drv_acc_st_h3lis331dl_irq_handle(void)
263 {
264     /* no handle so far */
265 }
266 
drv_acc_st_h3lis331dl_open(void)267 static int drv_acc_st_h3lis331dl_open(void)
268 {
269     int ret = 0;
270     ret  = drv_acc_st_h3lis331dl_set_power_mode(&h3lis331dl_ctx, DEV_POWER_ON);
271     if(unlikely(ret)){
272         return -1;
273     }
274 
275     ret = drv_acc_st_h3lis331dl_set_range(&h3lis331dl_ctx, ACC_RANGE_100G);
276     if(unlikely(ret)){
277         return -1;
278     }
279 
280     ret = drv_acc_st_h3lis331dl_set_odr(&h3lis331dl_ctx, H3LIS331DL_ACC_DEFAULT_ODR_100HZ);
281     if(unlikely(ret)){
282         return -1;
283     }
284 
285     return 0;
286 
287 }
288 
drv_acc_st_h3lis331dl_close(void)289 static int drv_acc_st_h3lis331dl_close(void)
290 {
291     int ret = 0;
292     ret  = drv_acc_st_h3lis331dl_set_power_mode(&h3lis331dl_ctx, DEV_POWER_OFF);
293     if(unlikely(ret)){
294         return -1;
295     }
296     return 0;
297 }
298 
drv_acc_st_h3lis331dl_read(void * buf,size_t len)299 static int drv_acc_st_h3lis331dl_read(void *buf, size_t len)
300 {
301 
302     int ret = 0;
303     size_t size;
304     uint8_t reg[6];
305     accel_data_t *accel = (accel_data_t *)buf;
306     if(buf == NULL){
307         return -1;
308     }
309 
310     size = sizeof(accel_data_t);
311     if(len < size){
312         return -1;
313     }
314 
315 	ret = sensor_i2c_read(&h3lis331dl_ctx, (H3LIS331DL_ACC_OUT_X_L | 0x80), reg, 6, I2C_OP_RETRIES);
316 
317 	if(unlikely(ret)){
318         return -1;
319     }
320     accel->data[DATA_AXIS_X] = (int16_t)((((int16_t)((int8_t)reg[1]))<< H3LIS331DL_SHIFT_EIGHT_BITS)|(reg[0]));
321 	accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] >> H3LIS331DL_SHIFT_FOUR_BITS;
322     accel->data[DATA_AXIS_Y] = (int16_t)((((int16_t)((int8_t)reg[3]))<< H3LIS331DL_SHIFT_EIGHT_BITS)|(reg[2]));
323 	accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] >> H3LIS331DL_SHIFT_FOUR_BITS;
324 	accel->data[DATA_AXIS_Z] = (int16_t)((((int16_t)((int8_t)reg[5]))<< H3LIS331DL_SHIFT_EIGHT_BITS)|(reg[4]));
325 	accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] >> H3LIS331DL_SHIFT_FOUR_BITS;
326 
327     if(cur_acc_factor != 0){
328         accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] * cur_acc_factor;
329         accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] * cur_acc_factor;
330         accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] * cur_acc_factor;
331     }
332 
333     accel->timestamp = aos_now_ms();
334 
335     return (int)size;
336 }
337 
drv_acc_st_h3lis331dl_ioctl(int cmd,unsigned long arg)338 static int drv_acc_st_h3lis331dl_ioctl(int cmd, unsigned long arg)
339 {
340     int ret = 0;
341     dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
342 
343     switch(cmd){
344         case SENSOR_IOCTL_ODR_SET:{
345             ret = drv_acc_st_h3lis331dl_set_odr(&h3lis331dl_ctx, arg);
346             if(unlikely(ret)){
347                 return -1;
348             }
349         }break;
350         case SENSOR_IOCTL_RANGE_SET:{
351             ret = drv_acc_st_h3lis331dl_set_range(&h3lis331dl_ctx, arg);
352             if(unlikely(ret)){
353                 return -1;
354             }
355         }break;
356         case SENSOR_IOCTL_SET_POWER:{
357             ret = drv_acc_st_h3lis331dl_set_power_mode(&h3lis331dl_ctx, arg);
358             if(unlikely(ret)){
359                 return -1;
360             }
361         }break;
362         case SENSOR_IOCTL_GET_INFO:{
363             /* fill the dev info here */
364             info->model = "H3LIS331DL";
365             info->range_max = 100;
366             info->range_min = 400;
367             info->unit = mg;
368 
369         }break;
370        default:break;
371     }
372 
373     return 0;
374 }
375 
drv_acc_st_h3lis331dl_init(void)376 int drv_acc_st_h3lis331dl_init(void){
377     int ret = 0;
378     sensor_obj_t sensor;
379     memset(&sensor, 0, sizeof(sensor));
380 
381     /* fill the sensor obj parameters here */
382     sensor.io_port    = I2C_PORT;
383     sensor.tag        = TAG_DEV_ACC;
384     sensor.path       = dev_acc_path;
385     sensor.open       = drv_acc_st_h3lis331dl_open;
386     sensor.close      = drv_acc_st_h3lis331dl_close;
387     sensor.read       = drv_acc_st_h3lis331dl_read;
388     sensor.write      = NULL;
389     sensor.ioctl      = drv_acc_st_h3lis331dl_ioctl;
390     sensor.irq_handle = drv_acc_st_h3lis331dl_irq_handle;
391 
392     ret = sensor_create_obj(&sensor);
393     if(unlikely(ret)){
394         return -1;
395     }
396 
397     ret = drv_acc_st_h3lis331dl_validate_id(&h3lis331dl_ctx, H3LIS331DL_ACC_CHIP_ID_VALUE);
398     if(unlikely(ret)){
399         return -1;
400     }
401 
402     ret = drv_acc_st_h3lis331dl_set_range(&h3lis331dl_ctx, ACC_RANGE_8G);
403     if(unlikely(ret)){
404         return -1;
405     }
406 
407 	ret = drv_acc_st_h3lis331dl_set_bdu(&h3lis331dl_ctx);
408     if(unlikely(ret)){
409         return -1;
410     }
411 
412     //set odr is 100hz, and will update
413     ret = drv_acc_st_h3lis331dl_set_odr(&h3lis331dl_ctx, H3LIS331DL_ACC_DEFAULT_ODR_100HZ);
414     if(unlikely(ret)){
415         return -1;
416     }
417 
418     /* update the phy sensor info to sensor hal */
419     LOG("%s %s successfully \n", SENSOR_STR, __func__);
420     return 0;
421 }
422 
423 SENSOR_DRV_ADD(drv_acc_st_h3lis331dl_init);
424 
425 
426