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 BMA456_I2C_ADDR_LOW (0x18)
15 #define BMA456_I2C_ADDR_HIGH (0x19)
16 #define BMA456_I2C_ADDR_TRANS(n) ((n)<<1)
17 #define BMA456_I2C_ADDR BMA456_I2C_ADDR_TRANS(BMA456_I2C_ADDR_LOW)
18
19 #define BMA456_CHIP_ID_ADDR UINT8_C(0X00)
20 #define BMA456_CHIP_ID_VALUE (0x16)
21
22 #define BMA456_POWER_CONF_ADDR UINT8_C(0x7C)
23 #define BMA456_POWER_CTRL_ADDR UINT8_C(0x7D)
24
25 #define BMA456_ACCEL_CONFIG_ADDR UINT8_C(0X40)
26 #define BMA456_ACCEL_CONFIG1_ADDR UINT8_C(0X41)
27
28 #define BMA456_DEFAULT_ODR_100HZ (100)
29 #define BMA456_CMD_ADDR UINT8_C(0X7E)
30
31 #define BMA456_OUTPUT_DATA_RATE_0_78HZ UINT8_C(0x01)
32 #define BMA456_OUTPUT_DATA_RATE_1_56HZ UINT8_C(0x02)
33 #define BMA456_OUTPUT_DATA_RATE_3_12HZ UINT8_C(0x03)
34 #define BMA456_OUTPUT_DATA_RATE_6_25HZ UINT8_C(0x04)
35 #define BMA456_OUTPUT_DATA_RATE_12_5HZ UINT8_C(0x05)
36 #define BMA456_OUTPUT_DATA_RATE_25HZ UINT8_C(0x06)
37 #define BMA456_OUTPUT_DATA_RATE_50HZ UINT8_C(0x07)
38 #define BMA456_OUTPUT_DATA_RATE_100HZ UINT8_C(0x08)
39 #define BMA456_OUTPUT_DATA_RATE_200HZ UINT8_C(0x09)
40 #define BMA456_OUTPUT_DATA_RATE_400HZ UINT8_C(0x0A)
41 #define BMA456_OUTPUT_DATA_RATE_800HZ UINT8_C(0x0B)
42 #define BMA456_OUTPUT_DATA_RATE_1600HZ UINT8_C(0x0C)
43
44 #define BMA456_ACCEL_OSR4_AVG1 UINT8_C(0)
45 #define BMA456_ACCEL_OSR2_AVG2 UINT8_C(1)
46 #define BMA456_ACCEL_NORMAL_AVG4 UINT8_C(2)
47 #define BMA456_ACCEL_CIC_AVG8 UINT8_C(3)
48 #define BMA456_ACCEL_RES_AVG16 UINT8_C(4)
49 #define BMA456_ACCEL_RES_AVG32 UINT8_C(5)
50 #define BMA456_ACCEL_RES_AVG64 UINT8_C(6)
51 #define BMA456_ACCEL_RES_AVG128 UINT8_C(7)
52
53 #define BMA456_ACCEL_RANGE_2G UINT8_C(0)
54 #define BMA456_ACCEL_RANGE_4G UINT8_C(1)
55 #define BMA456_ACCEL_RANGE_8G UINT8_C(2)
56 #define BMA456_ACCEL_RANGE_16G UINT8_C(3)
57
58 #define BMA456_DATA_0_ADDR UINT8_C(0X0A)
59 #define BMA456_DATA_8_ADDR UINT8_C(0X12)
60 #define BMA456_ACCEL_DATA_LENGTH UINT8_C(6)
61
62 #define BMA456_ENABLE UINT8_C(0x01)
63 #define BMA456_DISABLE UINT8_C(0x00)
64
65 #define BMA456_ADVANCE_POWER_SAVE_MSK UINT8_C(0x01)
66
67 #define BMA456_ACCEL_ENABLE_POS UINT8_C(2)
68 #define BMA456_ACCEL_ENABLE_MSK UINT8_C(0x04)
69
70 #define BMA456_ACCEL_PERF_POS UINT8_C(7)
71
72 #define BMA456_ACCEL_ODR_POS UINT8_C(0)
73 #define BMA456_ACCEL_ODR_MSK UINT8_C(0x0F)
74
75 #define BMA456_ACCEL_RANGE_POS UINT8_C(0)
76 #define BMA456_ACCEL_RANGE_MSK UINT8_C(0x03)
77
78 #define BMA456_ENABLE_SOFT_RESET_VALUE UINT8_C(0XB6)
79
80 #define BMA456_GET_BITSLICE(regvar, bitname)\
81 ((regvar & bitname##_MSK) >> bitname##_POS)
82 #define BMA456_SET_BITSLICE(regvar, bitname, val)\
83 ((regvar & ~bitname##_MSK) | \
84 ((val<<bitname##_POS)&bitname##_MSK))
85 #define BMA456_SET_BITS_POS_0(reg_data, bitname, data) \
86 ((reg_data & ~(bitname##_MSK)) | \
87 (data & bitname##_MSK))
88
89 #define BMA456_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK))
90
91
92 static uint32_t bma456_factor[4] = { 16384, 8192, 4096, 2048 };
93 static uint32_t current_factor = 0;
94 static uint32_t set_range_failed = 0;
95
96 i2c_dev_t bma456_ctx = {
97 .port = 3,
98 .config.dev_addr = BMA456_I2C_ADDR,
99 };
100
drv_acc_bosch_bma456_soft_reset(i2c_dev_t * drv)101 int drv_acc_bosch_bma456_soft_reset(i2c_dev_t* drv)
102 {
103 int ret = 0;
104 uint8_t value = BMA456_ENABLE_SOFT_RESET_VALUE;
105 ret = sensor_i2c_write(drv, BMA456_CMD_ADDR, &value,
106 I2C_DATA_LEN, I2C_OP_RETRIES);
107 aos_msleep(2);
108 if(unlikely(ret)) {
109 return -1;
110 }
111 return 0;
112 }
113
drv_acc_bosch_bma456_validate_id(i2c_dev_t * drv)114 int drv_acc_bosch_bma456_validate_id(i2c_dev_t* drv)
115 {
116 uint8_t value = 0x00;
117 int ret = 0;
118
119 if(drv == NULL) {
120 return -1;
121 }
122
123 ret = sensor_i2c_read(drv, BMA456_CHIP_ID_ADDR, &value, I2C_DATA_LEN,
124 I2C_OP_RETRIES);
125 if(unlikely(ret)) {
126 LOG("%s %s sensor_i2c_read \n", SENSOR_STR, __func__);
127 return ret;
128 }
129
130 if(BMA456_CHIP_ID_VALUE != value) {
131 LOG("%s %s value=%x \n", SENSOR_STR, __func__, value);
132 return -1;
133 }
134
135 return 0;
136 }
137
drv_acc_bosch_bma456_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)138 int drv_acc_bosch_bma456_set_power_mode(i2c_dev_t* drv,
139 dev_power_mode_e mode)
140 {
141
142 uint8_t value, value1 = 0x00;
143 int ret = 0;
144 switch(mode) {
145 case DEV_POWER_ON: {
146 ret = sensor_i2c_read(drv, BMA456_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
147 I2C_OP_RETRIES);
148 if(unlikely(ret)) {
149 return ret;
150 }
151 value |= (BMA456_ENABLE << BMA456_ACCEL_PERF_POS);
152 ret = sensor_i2c_write(drv, BMA456_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
153 I2C_OP_RETRIES);
154 aos_msleep(2);
155 if(unlikely(ret)) {
156 return ret;
157 }
158
159 ret = sensor_i2c_read(drv, BMA456_POWER_CTRL_ADDR, &value1, I2C_DATA_LEN,
160 I2C_OP_RETRIES);
161 if(unlikely(ret)) {
162 return ret;
163 }
164 value1 = BMA456_SET_BITSLICE(value1, BMA456_ACCEL_ENABLE, BMA456_ENABLE);
165 ret = sensor_i2c_write(drv, BMA456_POWER_CTRL_ADDR, &value1, I2C_DATA_LEN,
166 I2C_OP_RETRIES);
167 aos_msleep(2);
168 if(unlikely(ret)) {
169 return ret;
170 }
171 }
172 break;
173 case DEV_POWER_OFF:
174 case DEV_SLEEP:
175 case DEV_SUSPEND: {
176
177 ret = sensor_i2c_read(drv, BMA456_POWER_CTRL_ADDR, &value, I2C_DATA_LEN,
178 I2C_OP_RETRIES);
179 if(unlikely(ret)) {
180 return ret;
181 }
182 value = BMA456_SET_BITSLICE(value, BMA456_ACCEL_ENABLE, BMA456_DISABLE);
183 ret = sensor_i2c_write(drv, BMA456_POWER_CTRL_ADDR, &value, I2C_DATA_LEN,
184 I2C_OP_RETRIES);
185 aos_msleep(2);
186 if(unlikely(ret)) {
187 return ret;
188 }
189
190 ret = sensor_i2c_read(drv, BMA456_POWER_CONF_ADDR, &value1, I2C_DATA_LEN,
191 I2C_OP_RETRIES);
192 if(unlikely(ret)) {
193 return ret;
194 }
195 value1 = BMA456_SET_BITS_POS_0(value1, BMA456_ADVANCE_POWER_SAVE, BMA456_ENABLE);
196 ret = sensor_i2c_write(drv, BMA456_POWER_CONF_ADDR, &value1, I2C_DATA_LEN,
197 I2C_OP_RETRIES);
198 aos_msleep(2);
199 if(unlikely(ret)) {
200 return ret;
201 }
202 }
203 break;
204
205 default:
206 break;
207 }
208 return 0;
209 }
210
drv_acc_bosch_bma456_set_odr(i2c_dev_t * drv,uint32_t hz)211 int drv_acc_bosch_bma456_set_odr(i2c_dev_t* drv, uint32_t hz)
212 {
213 int ret = 0;
214 uint8_t value = 0x00;
215 uint8_t odr = 0x00;
216
217 ret = sensor_i2c_read(drv, BMA456_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
218 I2C_OP_RETRIES);
219 if(unlikely(ret)) {
220 return ret;
221 }
222
223 if(hz >= 800) {
224 odr = BMA456_OUTPUT_DATA_RATE_1600HZ;
225 } else if(hz >= 400) {
226 odr = BMA456_OUTPUT_DATA_RATE_800HZ;
227 } else if(hz >= 200) {
228 odr = BMA456_OUTPUT_DATA_RATE_400HZ;
229 } else if(hz >= 100) {
230 odr = BMA456_OUTPUT_DATA_RATE_200HZ;
231 } else if(hz >= 50) {
232 odr = BMA456_OUTPUT_DATA_RATE_100HZ;
233 } else if(hz >= 25) {
234 odr = BMA456_OUTPUT_DATA_RATE_50HZ;
235 } else if(hz >= 12) {
236 odr = BMA456_OUTPUT_DATA_RATE_25HZ;
237 } else if(hz >= 6) {
238 odr = BMA456_OUTPUT_DATA_RATE_12_5HZ;
239 } else if(hz >= 3) {
240 odr = BMA456_OUTPUT_DATA_RATE_6_25HZ;
241 } else {
242 odr = BMA456_OUTPUT_DATA_RATE_3_12HZ;
243 }
244
245 value = BMA456_SET_BITSLICE(value, BMA456_ACCEL_ODR, odr);
246 ret = sensor_i2c_write(drv, BMA456_ACCEL_CONFIG_ADDR, &value, I2C_DATA_LEN,
247 I2C_OP_RETRIES);
248 aos_msleep(2);
249 if(unlikely(ret)) {
250 return ret;
251 }
252 return 0;
253 }
254
drv_acc_bosch_bma456_set_range(i2c_dev_t * drv,uint32_t range)255 int drv_acc_bosch_bma456_set_range(i2c_dev_t* drv, uint32_t range)
256 {
257 int ret = 0;
258 uint8_t value = 0x00;
259 uint8_t acc_range = 0x00;
260
261 ret = sensor_i2c_read(drv, BMA456_ACCEL_CONFIG1_ADDR, &value, I2C_DATA_LEN,
262 I2C_OP_RETRIES);
263 if(unlikely(ret)) {
264 set_range_failed = 1;
265 return ret;
266 }
267
268 switch(range) {
269 case ACC_RANGE_2G: {
270 acc_range = BMA456_ACCEL_RANGE_2G;
271 }
272 break;
273
274 case ACC_RANGE_4G: {
275 acc_range = BMA456_ACCEL_RANGE_4G;
276 }
277 break;
278
279 case ACC_RANGE_8G: {
280 acc_range = BMA456_ACCEL_RANGE_8G;
281 }
282 break;
283
284 case ACC_RANGE_16G: {
285 acc_range = BMA456_ACCEL_RANGE_16G;
286 }
287 break;
288
289 default:
290 break;
291 }
292
293 value = BMA456_SET_BITSLICE(value, BMA456_ACCEL_RANGE, acc_range);
294 ret = sensor_i2c_write(drv, BMA456_ACCEL_CONFIG1_ADDR, &value, I2C_DATA_LEN,
295 I2C_OP_RETRIES);
296 aos_msleep(2);
297 if(unlikely(ret)) {
298 set_range_failed = 2;
299 return ret;
300 }
301
302 if((range >= ACC_RANGE_2G)&&(range <= ACC_RANGE_16G)) {
303 current_factor = bma456_factor[range];
304 }
305
306 set_range_failed = 3;
307 return 0;
308 }
309
drv_acc_bosch_bma456_irq_handle(void)310 void drv_acc_bosch_bma456_irq_handle(void)
311 {
312 /* no handle so far */
313 }
314
drv_acc_bosch_bma456_open(void)315 int drv_acc_bosch_bma456_open(void)
316 {
317 int ret = 0;
318 ret = drv_acc_bosch_bma456_set_power_mode(&bma456_ctx, DEV_POWER_ON);
319 if(unlikely(ret)) {
320 return -1;
321 }
322 return 0;
323
324 }
325
drv_acc_bosch_bma456_close(void)326 int drv_acc_bosch_bma456_close(void)
327 {
328 int ret = 0;
329 ret = drv_acc_bosch_bma456_set_power_mode(&bma456_ctx, DEV_POWER_OFF);
330 if(unlikely(ret)) {
331 return -1;
332 }
333 return 0;
334 }
335
drv_acc_bosch_bma456_read(void * buf,size_t len)336 int drv_acc_bosch_bma456_read(void *buf, size_t len)
337 {
338 int ret = 0;
339 size_t size;
340 uint8_t reg[6];
341 uint8_t range = 0;
342 accel_data_t *accel = (accel_data_t *)buf;
343
344 if(buf == NULL) {
345 return -1;
346 }
347
348 size = sizeof(accel_data_t);
349 if(len < size) {
350 return -1;
351 }
352 ret = sensor_i2c_read(&bma456_ctx, 0x41, &range, I2C_REG_LEN, I2C_OP_RETRIES);
353 ret = sensor_i2c_read(&bma456_ctx, BMA456_DATA_8_ADDR, ®[0], I2C_REG_LEN,
354 I2C_OP_RETRIES);
355 ret |= sensor_i2c_read(&bma456_ctx, BMA456_DATA_8_ADDR+1, ®[1], I2C_REG_LEN,
356 I2C_OP_RETRIES);
357 ret |= sensor_i2c_read(&bma456_ctx, BMA456_DATA_8_ADDR+2, ®[2], I2C_REG_LEN,
358 I2C_OP_RETRIES);
359 ret |= sensor_i2c_read(&bma456_ctx, BMA456_DATA_8_ADDR+3, ®[3], I2C_REG_LEN,
360 I2C_OP_RETRIES);
361 ret |= sensor_i2c_read(&bma456_ctx, BMA456_DATA_8_ADDR+4, ®[4], I2C_REG_LEN,
362 I2C_OP_RETRIES);
363 ret |= sensor_i2c_read(&bma456_ctx, BMA456_DATA_8_ADDR+5, ®[5], I2C_REG_LEN,
364 I2C_OP_RETRIES);
365
366 if(unlikely(ret)) {
367 return -1;
368 }
369
370 accel->data[DATA_AXIS_X] = ((int16_t)((reg[1] << 8) | reg[0]));
371 accel->data[DATA_AXIS_Y] = ((int16_t)((reg[3] << 8) | reg[2]));
372 accel->data[DATA_AXIS_Z] = ((int16_t)((reg[5] << 8) | reg[4]));
373 if(current_factor != 0) {
374 accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] *
375 ACCELEROMETER_UNIT_FACTOR / (int32_t)current_factor;
376 accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] *
377 ACCELEROMETER_UNIT_FACTOR / (int32_t)current_factor;
378 accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] *
379 ACCELEROMETER_UNIT_FACTOR / (int32_t)current_factor;
380 }
381 accel->timestamp = aos_now_ms();
382
383 return (int)size;
384 }
385
drv_acc_bosch_bma456_ioctl(int cmd,unsigned long arg)386 static int drv_acc_bosch_bma456_ioctl(int cmd, unsigned long arg)
387 {
388 int ret = 0;
389
390 switch(cmd) {
391 case SENSOR_IOCTL_ODR_SET: {
392 ret = drv_acc_bosch_bma456_set_odr(&bma456_ctx, arg);
393 if(unlikely(ret)) {
394 return -1;
395 }
396 }
397 break;
398 case SENSOR_IOCTL_RANGE_SET: {
399 ret = drv_acc_bosch_bma456_set_range(&bma456_ctx, arg);
400 if(unlikely(ret)) {
401 return -1;
402 }
403 }
404 break;
405 case SENSOR_IOCTL_SET_POWER: {
406 ret = drv_acc_bosch_bma456_set_power_mode(&bma456_ctx, arg);
407 if(unlikely(ret)) {
408 return -1;
409 }
410 }
411 break;
412 case SENSOR_IOCTL_GET_INFO: {
413 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
414 info->model = "BMA456";
415 info->range_max = 16;
416 info->range_min = 2;
417 info->unit = mg;
418 }
419 break;
420
421 default:
422 break;
423 }
424
425 return 0;
426 }
427
drv_acc_bosch_bma456_init(void)428 int drv_acc_bosch_bma456_init(void) {
429 int ret = 0;
430 sensor_obj_t sensor;
431 memset(&sensor, 0, sizeof(sensor));
432
433 /* fill the sensor obj parameters here */
434 sensor.io_port = I2C_PORT;
435 sensor.tag = TAG_DEV_ACC;
436 sensor.path = dev_acc_path;
437 sensor.open = drv_acc_bosch_bma456_open;
438 sensor.close = drv_acc_bosch_bma456_close;
439 sensor.read = drv_acc_bosch_bma456_read;
440 sensor.write = NULL;
441 sensor.ioctl = drv_acc_bosch_bma456_ioctl;
442 sensor.irq_handle = drv_acc_bosch_bma456_irq_handle;
443 ret = sensor_create_obj(&sensor);
444 if(unlikely(ret)) {
445 return -1;
446 }
447
448 ret = drv_acc_bosch_bma456_validate_id(&bma456_ctx);
449 if(unlikely(ret)) {
450 return -1;
451 }
452
453 ret = drv_acc_bosch_bma456_soft_reset(&bma456_ctx);
454 if(unlikely(ret)) {
455 return -1;
456 }
457
458 ret = drv_acc_bosch_bma456_set_range(&bma456_ctx, ACC_RANGE_8G);
459 if(unlikely(ret)) {
460 return -1;
461 }
462
463 /* set odr is 100hz, and will update */
464 ret = drv_acc_bosch_bma456_set_odr(&bma456_ctx, BMA456_DEFAULT_ODR_100HZ);
465 if(unlikely(ret)) {
466 return -1;
467 }
468 ret = drv_acc_bosch_bma456_set_power_mode(&bma456_ctx, DEV_SLEEP);
469 if(unlikely(ret)) {
470 return -1;
471 }
472
473 /* update the phy sensor info to sensor hal */
474 LOG("%s %s successfully \n", SENSOR_STR, __func__);
475 return 0;
476 }
477
478
479 SENSOR_DRV_ADD(drv_acc_bosch_bma456_init);
480
481