1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6 
7 #include "aos/kernel.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "sensor_drv_api.h"
12 #include "sensor_hal.h"
13 
14 #define BMA421_I2C_ADDR_LOW                     (0x18)
15 #define BMA421_I2C_ADDR_HIGH                    (0x19)
16 #define BMA421_I2C_ADDR_TRANS(n)                ((n)<<1)
17 #define BMA421_I2C_ADDR                         BMA421_I2C_ADDR_TRANS(BMA421_I2C_ADDR_LOW)
18 
19 #define BMA421_CHIP_ID_ADDR                     UINT8_C(0X00)
20 #define BMA421_CHIP_ID_VALUE                    (0x11)
21 
22 #define BMA421_POWER_CONF_ADDR                  UINT8_C(0x7C)
23 #define BMA421_POWER_CTRL_ADDR                  UINT8_C(0x7D)
24 
25 #define BMA421_ACCEL_CONFIG_ADDR                UINT8_C(0X40)
26 #define BMA421_ACCEL_CONFIG1_ADDR               UINT8_C(0X41)
27 
28 #define BMA421_DEFAULT_ODR_100HZ                (100)
29 #define BMA421_CMD_ADDR                         UINT8_C(0X7E)
30 
31 #define BMA421_OUTPUT_DATA_RATE_0_78HZ          UINT8_C(0x01)
32 #define BMA421_OUTPUT_DATA_RATE_1_56HZ          UINT8_C(0x02)
33 #define BMA421_OUTPUT_DATA_RATE_3_12HZ          UINT8_C(0x03)
34 #define BMA421_OUTPUT_DATA_RATE_6_25HZ          UINT8_C(0x04)
35 #define BMA421_OUTPUT_DATA_RATE_12_5HZ          UINT8_C(0x05)
36 #define BMA421_OUTPUT_DATA_RATE_25HZ            UINT8_C(0x06)
37 #define BMA421_OUTPUT_DATA_RATE_50HZ            UINT8_C(0x07)
38 #define BMA421_OUTPUT_DATA_RATE_100HZ           UINT8_C(0x08)
39 #define BMA421_OUTPUT_DATA_RATE_200HZ           UINT8_C(0x09)
40 #define BMA421_OUTPUT_DATA_RATE_400HZ           UINT8_C(0x0A)
41 #define BMA421_OUTPUT_DATA_RATE_800HZ           UINT8_C(0x0B)
42 #define BMA421_OUTPUT_DATA_RATE_1600HZ          UINT8_C(0x0C)
43 
44 #define BMA421_ACCEL_OSR4_AVG1                  UINT8_C(0)
45 #define BMA421_ACCEL_OSR2_AVG2                  UINT8_C(1)
46 #define BMA421_ACCEL_NORMAL_AVG4                UINT8_C(2)
47 #define BMA421_ACCEL_CIC_AVG8                   UINT8_C(3)
48 #define BMA421_ACCEL_RES_AVG16                  UINT8_C(4)
49 #define BMA421_ACCEL_RES_AVG32                  UINT8_C(5)
50 #define BMA421_ACCEL_RES_AVG64                  UINT8_C(6)
51 #define BMA421_ACCEL_RES_AVG128                 UINT8_C(7)
52 
53 #define BMA421_ACCEL_RANGE_2G                   UINT8_C(0)
54 #define BMA421_ACCEL_RANGE_4G                   UINT8_C(1)
55 #define BMA421_ACCEL_RANGE_8G                   UINT8_C(2)
56 #define BMA421_ACCEL_RANGE_16G                  UINT8_C(3)
57 
58 #define BMA421_DATA_0_ADDR                      UINT8_C(0X0A)
59 #define BMA421_DATA_8_ADDR                      UINT8_C(0X12)
60 #define BMA421_ACCEL_DATA_LENGTH                UINT8_C(6)
61 
62 #define BMA421_ENABLE                           UINT8_C(0x01)
63 #define BMA421_DISABLE                          UINT8_C(0x00)
64 
65 #define BMA421_ADVANCE_POWER_SAVE_MSK           UINT8_C(0x01)
66 
67 #define BMA421_ACCEL_ENABLE_POS                 UINT8_C(2)
68 #define BMA421_ACCEL_ENABLE_MSK                 UINT8_C(0x04)
69 
70 #define BMA421_ACCEL_PERF_POS                   UINT8_C(7)
71 
72 #define BMA421_ACCEL_ODR_POS                    UINT8_C(0)
73 #define BMA421_ACCEL_ODR_MSK                    UINT8_C(0x0F)
74 
75 #define BMA421_ACCEL_RANGE_POS                  UINT8_C(0)
76 #define BMA421_ACCEL_RANGE_MSK                  UINT8_C(0x03)
77 
78 #define BMA421_ENABLE_SOFT_RESET_VALUE          UINT8_C(0XB6)
79 
80 #define BMA421_GET_BITSLICE(regvar, bitname)\
81   ((regvar & bitname##_MSK) >> bitname##_POS)
82 #define BMA421_SET_BITSLICE(regvar, bitname, val)\
83   ((regvar & ~bitname##_MSK) | \
84   ((val<<bitname##_POS)&bitname##_MSK))
85 #define BMA421_SET_BITS_POS_0(reg_data, bitname, data) \
86     ((reg_data & ~(bitname##_MSK)) | \
87     (data & bitname##_MSK))
88 
89 #define BMA421_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK))
90 
91 static uint32_t bma421_factor[4] = { 16384, 8192, 4096, 2048 };
92 static uint32_t current_factor = 0;
93 static uint32_t set_range_failed = 0;
94 
95 i2c_dev_t bma421_ctx = {
96     .port = 3,
97     .config.dev_addr = BMA421_I2C_ADDR,
98 };
99 
drv_acc_bosch_bma421_soft_reset(i2c_dev_t * drv)100 int drv_acc_bosch_bma421_soft_reset(i2c_dev_t* drv)
101 {
102     int ret = 0;
103     uint8_t value = BMA421_ENABLE_SOFT_RESET_VALUE;
104     ret = sensor_i2c_write(drv, BMA421_CMD_ADDR, &value,
105                            I2C_DATA_LEN, I2C_OP_RETRIES);
106     aos_msleep(2);
107     if(unlikely(ret)) {
108         return -1;
109     }
110     return 0;
111 }
112 
drv_acc_bosch_bma421_validate_id(i2c_dev_t * drv)113 int drv_acc_bosch_bma421_validate_id(i2c_dev_t* drv)
114 {
115     uint8_t value = 0x00;
116     int ret = 0;
117 
118     if(drv == NULL) {
119         return -1;
120     }
121 
122     ret = sensor_i2c_read(drv, BMA421_CHIP_ID_ADDR, &value, I2C_DATA_LEN,
123                           I2C_OP_RETRIES);
124     if(unlikely(ret)) {
125         LOG("%s %s  sensor_i2c_read \n", SENSOR_STR, __func__);
126         return ret;
127     }
128 
129     if(BMA421_CHIP_ID_VALUE != value) {
130         LOG("%s %s  value=%x \n", SENSOR_STR, __func__, value);
131         return -1;
132     }
133 
134     return 0;
135 }
136 
drv_acc_bosch_bma421_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)137 int drv_acc_bosch_bma421_set_power_mode(i2c_dev_t* drv,
138                                                dev_power_mode_e mode)
139 {
140 
141     uint8_t value, value1 = 0x00;
142     int ret = 0;
143     switch(mode) {
144         case DEV_POWER_ON: {
145             ret = sensor_i2c_read(drv, BMA421_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
146                                   I2C_OP_RETRIES);
147             if(unlikely(ret)) {
148                 return ret;
149             }
150             value |= (BMA421_ENABLE << BMA421_ACCEL_PERF_POS);
151             ret = sensor_i2c_write(drv, BMA421_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
152                                    I2C_OP_RETRIES);
153             aos_msleep(2);
154             if(unlikely(ret)) {
155                 return ret;
156             }
157 
158             ret = sensor_i2c_read(drv, BMA421_POWER_CTRL_ADDR, &value1, I2C_DATA_LEN,
159                                   I2C_OP_RETRIES);
160             if(unlikely(ret)) {
161                 return ret;
162             }
163             value1 = BMA421_SET_BITSLICE(value1, BMA421_ACCEL_ENABLE, BMA421_ENABLE);
164             ret = sensor_i2c_write(drv, BMA421_POWER_CTRL_ADDR, &value1, I2C_DATA_LEN,
165                                    I2C_OP_RETRIES);
166             aos_msleep(2);
167             if(unlikely(ret)) {
168                 return ret;
169             }
170         }
171         break;
172         case DEV_POWER_OFF:
173         case DEV_SLEEP:
174         case DEV_SUSPEND: {
175             ret = sensor_i2c_read(drv, BMA421_POWER_CTRL_ADDR, &value, I2C_DATA_LEN,
176                                   I2C_OP_RETRIES);
177             if(unlikely(ret)) {
178                 return ret;
179             }
180             value = BMA421_SET_BITSLICE(value, BMA421_ACCEL_ENABLE, BMA421_DISABLE);
181             ret = sensor_i2c_write(drv, BMA421_POWER_CTRL_ADDR, &value, I2C_DATA_LEN,
182                                    I2C_OP_RETRIES);
183             aos_msleep(2);
184             if(unlikely(ret)) {
185                 return ret;
186             }
187 
188             ret = sensor_i2c_read(drv, BMA421_POWER_CONF_ADDR, &value1, I2C_DATA_LEN,
189                                   I2C_OP_RETRIES);
190             if(unlikely(ret)) {
191                 return ret;
192             }
193             value1 = BMA421_SET_BITS_POS_0(value1, BMA421_ADVANCE_POWER_SAVE, BMA421_ENABLE);
194             ret = sensor_i2c_write(drv, BMA421_POWER_CONF_ADDR, &value1, I2C_DATA_LEN,
195                                    I2C_OP_RETRIES);
196             aos_msleep(2);
197             if(unlikely(ret)) {
198                 return ret;
199             }
200         }
201         break;
202 
203         default:
204             break;
205     }
206     return 0;
207 }
208 
drv_acc_bosch_bma421_set_odr(i2c_dev_t * drv,uint32_t hz)209 int drv_acc_bosch_bma421_set_odr(i2c_dev_t* drv, uint32_t hz)
210 {
211     int ret = 0;
212     uint8_t value = 0x00;
213     uint8_t odr = 0x00;
214 
215     ret = sensor_i2c_read(drv, BMA421_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
216                           I2C_OP_RETRIES);
217     if(unlikely(ret)) {
218         return ret;
219     }
220 
221     if(hz >= 800) {
222         odr = BMA421_OUTPUT_DATA_RATE_1600HZ;
223     } else if(hz >= 400) {
224         odr = BMA421_OUTPUT_DATA_RATE_800HZ;
225     } else if(hz >= 200) {
226         odr = BMA421_OUTPUT_DATA_RATE_400HZ;
227     } else if(hz >= 100) {
228         odr = BMA421_OUTPUT_DATA_RATE_200HZ;
229     } else if(hz >= 50) {
230         odr = BMA421_OUTPUT_DATA_RATE_100HZ;
231     } else if(hz >= 25) {
232         odr = BMA421_OUTPUT_DATA_RATE_50HZ;
233     } else if(hz >= 12) {
234         odr = BMA421_OUTPUT_DATA_RATE_25HZ;
235     } else if(hz >= 6) {
236         odr = BMA421_OUTPUT_DATA_RATE_12_5HZ;
237     } else if(hz >= 3) {
238         odr = BMA421_OUTPUT_DATA_RATE_6_25HZ;
239     } else {
240         odr = BMA421_OUTPUT_DATA_RATE_3_12HZ;
241     }
242 
243     value = BMA421_SET_BITSLICE(value, BMA421_ACCEL_ODR, odr);
244     ret = sensor_i2c_write(drv, BMA421_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
245                            I2C_OP_RETRIES);
246     aos_msleep(2);
247     if(unlikely(ret)) {
248         return ret;
249     }
250     return 0;
251 }
252 
drv_acc_bosch_bma421_set_range(i2c_dev_t * drv,uint32_t range)253 int drv_acc_bosch_bma421_set_range(i2c_dev_t* drv, uint32_t range)
254 {
255     int ret = 0;
256     uint8_t value = 0x00;
257     uint8_t acc_range = 0x00;
258 
259     ret = sensor_i2c_read(drv, BMA421_ACCEL_CONFIG1_ADDR, &value, I2C_DATA_LEN,
260                           I2C_OP_RETRIES);
261     if(unlikely(ret)) {
262         set_range_failed = 1;
263         return ret;
264     }
265 
266     switch(range) {
267         case ACC_RANGE_2G: {
268             acc_range = BMA421_ACCEL_RANGE_2G;
269         }
270         break;
271 
272         case ACC_RANGE_4G: {
273             acc_range = BMA421_ACCEL_RANGE_4G;
274         }
275         break;
276 
277         case ACC_RANGE_8G: {
278             acc_range = BMA421_ACCEL_RANGE_8G;
279         }
280         break;
281 
282         case ACC_RANGE_16G: {
283             acc_range = BMA421_ACCEL_RANGE_16G;
284         }
285         break;
286 
287         default:
288             break;
289     }
290 
291     value = BMA421_SET_BITSLICE(value, BMA421_ACCEL_RANGE, acc_range);
292     ret = sensor_i2c_write(drv, BMA421_ACCEL_CONFIG1_ADDR, &value, I2C_DATA_LEN,
293                            I2C_OP_RETRIES);
294     aos_msleep(2);
295     if(unlikely(ret)) {
296         set_range_failed = 2;
297         return ret;
298     }
299 
300     if((range >= ACC_RANGE_2G)&&(range <= ACC_RANGE_16G)) {
301         current_factor = bma421_factor[range];
302     }
303 
304     set_range_failed = 3;
305     return 0;
306 }
307 
drv_acc_bosch_bma421_irq_handle(void)308 void drv_acc_bosch_bma421_irq_handle(void)
309 {
310     /* no handle so far */
311 }
312 
drv_acc_bosch_bma421_open(void)313 int drv_acc_bosch_bma421_open(void)
314 {
315     int ret = 0;
316     ret  = drv_acc_bosch_bma421_set_power_mode(&bma421_ctx, DEV_POWER_ON);
317     if(unlikely(ret)) {
318         return -1;
319     }
320     return 0;
321 
322 }
323 
324 
drv_acc_bosch_bma421_close(void)325 int drv_acc_bosch_bma421_close(void)
326 {
327     int ret = 0;
328     ret  = drv_acc_bosch_bma421_set_power_mode(&bma421_ctx, DEV_POWER_OFF);
329     if(unlikely(ret)) {
330         return -1;
331     }
332     return 0;
333 }
334 
drv_acc_bosch_bma421_read(void * buf,size_t len)335 int drv_acc_bosch_bma421_read(void *buf, size_t len)
336 {
337     int ret = 0;
338     size_t size;
339     uint8_t reg[6];
340     uint8_t range = 0;
341     accel_data_t *accel = (accel_data_t *)buf;
342 
343     if(buf == NULL) {
344         return -1;
345     }
346 
347     size = sizeof(accel_data_t);
348     if(len < size) {
349         return -1;
350     }
351     ret  = sensor_i2c_read(&bma421_ctx, 0x41,  &range, I2C_REG_LEN, I2C_OP_RETRIES);
352     ret  = sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR,  &reg[0], I2C_REG_LEN,
353                            I2C_OP_RETRIES);
354     ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+1,  &reg[1], I2C_REG_LEN,
355                            I2C_OP_RETRIES);
356     ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+2,  &reg[2], I2C_REG_LEN,
357                            I2C_OP_RETRIES);
358     ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+3,  &reg[3], I2C_REG_LEN,
359                            I2C_OP_RETRIES);
360     ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+4,  &reg[4], I2C_REG_LEN,
361                            I2C_OP_RETRIES);
362     ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+5,  &reg[5], I2C_REG_LEN,
363                            I2C_OP_RETRIES);
364 
365     if(unlikely(ret)) {
366         return -1;
367     }
368 
369     accel->data[DATA_AXIS_X] = ((int16_t)((reg[1] << 8) | reg[0]));
370     accel->data[DATA_AXIS_Y] = ((int16_t)((reg[3] << 8) | reg[2]));
371     accel->data[DATA_AXIS_Z] = ((int16_t)((reg[5] << 8) | reg[4]));
372     if(current_factor != 0) {
373         accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] *
374                                    ACCELEROMETER_UNIT_FACTOR / (int32_t)current_factor;
375         accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] *
376                                    ACCELEROMETER_UNIT_FACTOR / (int32_t)current_factor;
377         accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] *
378                                    ACCELEROMETER_UNIT_FACTOR / (int32_t)current_factor;
379     }
380     accel->timestamp = aos_now_ms();
381 
382     return (int)size;
383 }
384 
drv_acc_bosch_bma421_ioctl(int cmd,unsigned long arg)385 static int drv_acc_bosch_bma421_ioctl(int cmd, unsigned long arg)
386 {
387     int ret = 0;
388 
389     switch(cmd) {
390         case SENSOR_IOCTL_ODR_SET: {
391             ret = drv_acc_bosch_bma421_set_odr(&bma421_ctx, arg);
392             if(unlikely(ret)) {
393                 return -1;
394             }
395         }
396         break;
397         case SENSOR_IOCTL_RANGE_SET: {
398             ret = drv_acc_bosch_bma421_set_range(&bma421_ctx, arg);
399             if(unlikely(ret)) {
400                 return -1;
401             }
402         }
403         break;
404         case SENSOR_IOCTL_SET_POWER: {
405             ret = drv_acc_bosch_bma421_set_power_mode(&bma421_ctx, arg);
406             if(unlikely(ret)) {
407                 return -1;
408             }
409         }
410         break;
411         case SENSOR_IOCTL_GET_INFO: {
412             dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
413             info->model = "BMA421";
414             info->range_max = 16;
415             info->range_min = 2;
416             info->unit = mg;
417         }
418         break;
419 
420         default:
421             break;
422     }
423 
424     return 0;
425 }
426 
drv_acc_bosch_bma421_init(void)427 int drv_acc_bosch_bma421_init(void) {
428     int ret = 0;
429     sensor_obj_t sensor;
430     memset(&sensor, 0, sizeof(sensor));
431 
432     /* fill the sensor obj parameters here */
433     sensor.io_port    = I2C_PORT;
434     sensor.tag        = TAG_DEV_ACC;
435     sensor.path       = dev_acc_path;
436     sensor.open       = drv_acc_bosch_bma421_open;
437     sensor.close      = drv_acc_bosch_bma421_close;
438     sensor.read       = drv_acc_bosch_bma421_read;
439     sensor.write      = NULL;
440     sensor.ioctl      = drv_acc_bosch_bma421_ioctl;
441     sensor.irq_handle = drv_acc_bosch_bma421_irq_handle;
442     ret = sensor_create_obj(&sensor);
443     if(unlikely(ret)) {
444         return -1;
445     }
446 
447     ret = drv_acc_bosch_bma421_validate_id(&bma421_ctx);
448     if(unlikely(ret)) {
449         return -1;
450     }
451 
452     ret = drv_acc_bosch_bma421_soft_reset(&bma421_ctx);
453     if(unlikely(ret)) {
454         return -1;
455     }
456 
457     ret = drv_acc_bosch_bma421_set_range(&bma421_ctx, ACC_RANGE_8G);
458     if(unlikely(ret)) {
459         return -1;
460     }
461 
462     /* set odr is 100hz, and will update */
463     ret = drv_acc_bosch_bma421_set_odr(&bma421_ctx, BMA421_DEFAULT_ODR_100HZ);
464     if(unlikely(ret)) {
465         return -1;
466     }
467     ret = drv_acc_bosch_bma421_set_power_mode(&bma421_ctx, DEV_SLEEP);
468     if(unlikely(ret)) {
469         return -1;
470     }
471 
472     /* update the phy sensor info to sensor hal */
473     LOG("%s %s successfully \n", SENSOR_STR, __func__);
474     return 0;
475 }
476 
477 
478 SENSOR_DRV_ADD(drv_acc_bosch_bma421_init);
479 
480