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