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, ®[0], I2C_REG_LEN,
353 I2C_OP_RETRIES);
354 ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+1, ®[1], I2C_REG_LEN,
355 I2C_OP_RETRIES);
356 ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+2, ®[2], I2C_REG_LEN,
357 I2C_OP_RETRIES);
358 ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+3, ®[3], I2C_REG_LEN,
359 I2C_OP_RETRIES);
360 ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+4, ®[4], I2C_REG_LEN,
361 I2C_OP_RETRIES);
362 ret |= sensor_i2c_read(&bma421_ctx, BMA421_DATA_8_ADDR+5, ®[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