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 BMA280_I2C_ADDR1                    (0x18)
16 #define BMA280_I2C_ADDR2                    (0x19)
17 #define BMA280_I2C_ADDR3                    (0x10)
18 #define BMA280_I2C_ADDR4                    (0x11)
19 #define BMA280_I2C_ADDR_TRANS(n)            ((n) << 1)
20 #define BMA280_I2C_ADDR                     BMA280_I2C_ADDR_TRANS(BMA280_I2C_ADDR1)
21 
22 
23 #define BMA280_INIT_VALUE                   (0)
24 #define BMA280_GEN_READ_WRITE_LENGTH        (1)
25 #define BMA280_INTERFACE_IDLE_TIME_DELAY    (1)
26 #define BMA280_LSB_MSB_READ_LENGTH          (2)
27 #define BMA280_SHIFT_TWO_BITS               (2)
28 #define BMA280_SHIFT_FOUR_BITS              (4)
29 #define BMA280_SHIFT_FIVE_BITS              (5)
30 #define BMA280_SHIFT_SIX_BITS               (6)
31 #define BMA280_SHIFT_EIGHT_BITS             (8)
32 #define BMA280_12_BIT_SHIFT                 (0xF0)
33 
34 #define BMA280_FIFO_MODE_STATUS_RANGE       (2)
35 #define BMA280_FIFO_DATA_SELECT_RANGE       (4)
36 #define BMA280_FIFO_MODE_RANGE              (4)
37 #define BMA280_FIFO_WML_RANGE               (32)
38 #define BMA280_FIFO_XYZ_DATA_ENABLED        (0x00)
39 #define BMA280_FIFO_X_DATA_ENABLED          (0x01)
40 #define BMA280_FIFO_Y_DATA_ENABLED          (0x02)
41 #define BMA280_FIFO_Z_DATA_ENABLED          (0x03)
42 #define BMA280_FIFO_DATA_ENABLED_MASK       (0x03)
43 #define BMA280_FIFO_XYZ_AXES_FRAME_SIZE     (6)
44 #define BMA280_FIFO_SINGLE_AXIS_FRAME_SIZE  (2)
45 #define BMA280_ACCEL_BW_MIN_RANGE           (7)
46 #define BMA280_ACCEL_BW_1000HZ_RANGE        (15)
47 #define BMA280_ACCEL_BW_MAX_RANGE           (16)
48 #define BMA280_SLEEP_DURN_MIN_RANGE         (4)
49 #define BMA280_SLEEP_TIMER_MODE_RANGE       (2)
50 #define BMA280_SLEEP_DURN_MAX_RANGE         (16)
51 #define BMA280_POWER_MODE_RANGE             (6)
52 #define BMA280_SELF_TEST_AXIS_RANGE         (4)
53 #define BMA280_SELF_TEST_SIGN_RANGE         (2)
54 
55 #define BMA280_EEP_OFFSET                   (0x16)
56 #define BMA280_IMAGE_BASE                   (0x38)
57 #define BMA280_IMAGE_LEN                    (22)
58 #define BMA280_CHIP_ID_ADDR                 (0x00)
59 #define BMA280_CHIP_ID_VALUE                (0xFB)
60 #define BMA280_X_AXIS_LSB_ADDR              (0x02)
61 #define BMA280_X_AXIS_MSB_ADDR              (0x03)
62 #define BMA280_Y_AXIS_LSB_ADDR              (0x04)
63 #define BMA280_Y_AXIS_MSB_ADDR              (0x05)
64 #define BMA280_Z_AXIS_LSB_ADDR              (0x06)
65 #define BMA280_Z_AXIS_MSB_ADDR              (0x07)
66 #define BMA280_TEMP_ADDR                    (0x08)
67 #define BMA280_STAT1_ADDR                   (0x09)
68 #define BMA280_STAT2_ADDR                   (0x0A)
69 #define BMA280_STAT_TAP_SLOPE_ADDR          (0x0B)
70 #define BMA280_STAT_ORIENT_HIGH_ADDR        (0x0C)
71 #define BMA280_STAT_FIFO_ADDR               (0x0E)
72 #define BMA280_RANGE_SELECT_ADDR            (0x0F)
73 #define BMA280_BW_SELECT_ADDR               (0x10)
74 #define BMA280_MODE_CTRL_ADDR               (0x11)
75 #define BMA280_LOW_NOISE_CTRL_ADDR          (0x12)
76 #define BMA280_DATA_CTRL_ADDR               (0x13)
77 #define BMA280_RST_ADDR                     (0x14)
78 #define BMA280_INTR_ENABLE1_ADDR            (0x16)
79 #define BMA280_INTR_ENABLE2_ADDR            (0x17)
80 #define BMA280_INTR_SLOW_NO_MOTION_ADDR     (0x18)
81 #define BMA280_INTR1_PAD_SELECT_ADDR        (0x19)
82 #define BMA280_INTR_DATA_SELECT_ADDR        (0x1A)
83 #define BMA280_INTR2_PAD_SELECT_ADDR        (0x1B)
84 #define BMA280_INTR_SOURCE_ADDR             (0x1E)
85 #define BMA280_INTR_SET_ADDR                (0x20)
86 #define BMA280_INTR_CTRL_ADDR               (0x21)
87 #define BMA280_LOW_DURN_ADDR                (0x22)
88 #define BMA280_LOW_THRES_ADDR               (0x23)
89 #define BMA280_LOW_HIGH_HYST_ADDR           (0x24)
90 #define BMA280_HIGH_DURN_ADDR               (0x25)
91 #define BMA280_HIGH_THRES_ADDR              (0x26)
92 #define BMA280_SLOPE_DURN_ADDR              (0x27)
93 #define BMA280_SLOPE_THRES_ADDR             (0x28)
94 #define BMA280_SLOW_NO_MOTION_THRES_ADDR    (0x29)
95 #define BMA280_TAP_PARAM_ADDR               (0x2A)
96 #define BMA280_TAP_THRES_ADDR               (0x2B)
97 #define BMA280_ORIENT_PARAM_ADDR            (0x2C)
98 #define BMA280_THETA_BLOCK_ADDR             (0x2D)
99 #define BMA280_THETA_FLAT_ADDR              (0x2E)
100 #define BMA280_FLAT_HOLD_TIME_ADDR          (0x2F)
101 #define BMA280_SELFTEST_ADDR                (0x32)
102 #define BMA280_EEPROM_CTRL_ADDR             (0x33)
103 #define BMA280_SERIAL_CTRL_ADDR             (0x34)
104 #define BMA280_OFFSET_CTRL_ADDR             (0x36)
105 #define BMA280_OFFSET_PARAMS_ADDR           (0x37)
106 #define BMA280_OFFSET_X_AXIS_ADDR           (0x38)
107 #define BMA280_OFFSET_Y_AXIS_ADDR           (0x39)
108 #define BMA280_OFFSET_Z_AXIS_ADDR           (0x3A)
109 #define BMA280_GP0_ADDR                     (0x3B)
110 #define BMA280_GP1_ADDR                     (0x3C)
111 #define BMA280_FIFO_MODE_ADDR               (0x3E)
112 #define BMA280_FIFO_DATA_OUTPUT_ADDR        (0x3F)
113 #define BMA280_FIFO_WML_TRIG                (0x30)
114 
115 #define BMA280_12_RESOLUTION            (0)
116 #define BMA280_10_RESOLUTION            (1)
117 #define BMA280_14_RESOLUTION            (2)
118 
119 #define BMA280_ENABLE_SOFT_RESET_VALUE  (0xB6)
120 #define BMA280_RANGE_SELECT_POS         (0)
121 #define BMA280_RANGE_SELECT_LEN         (4)
122 #define BMA280_RANGE_SELECT_MSK         (0x0F)
123 #define BMA280_RANGE_SELECT_REG         BMA280_RANGE_SELECT_ADDR
124 
125 #define BMA280_RANGE_2G     (3)
126 #define BMA280_RANGE_4G     (5)
127 #define BMA280_RANGE_8G     (8)
128 #define BMA280_RANGE_16G    (12)
129 
130 #define BMA280_BW_15_63     (15)
131 #define BMA280_BW_31_25     (31)
132 #define BMA280_BW_62_5      (62)
133 #define BMA280_BW_125       (125)
134 #define BMA280_BW_250       (250)
135 #define BMA280_BW_500       (500)
136 #define BMA280_BW_1000      (1000)
137 
138 #define BMA280_BW_7_81HZ    (0x08)
139 #define BMA280_BW_15_63HZ   (0x09)
140 #define BMA280_BW_31_25HZ   (0x0A)
141 #define BMA280_BW_62_50HZ   (0x0B)
142 #define BMA280_BW_125HZ     (0x0C)
143 #define BMA280_BW_250HZ     (0x0D)
144 #define BMA280_BW_500HZ     (0x0E)
145 #define BMA280_BW_1000HZ    (0x0F)
146 #define BMA280_BW_BIT_MASK  (~0x0F)
147 
148 #define BMA280_SLEEP_DURN_0_5MS     (0x05)
149 #define BMA280_SLEEP_DURN_1MS       (0x06)
150 #define BMA280_SLEEP_DURN_2MS       (0x07)
151 #define BMA280_SLEEP_DURN_4MS       (0x08)
152 #define BMA280_SLEEP_DURN_6MS       (0x09)
153 #define BMA280_SLEEP_DURN_10MS      (0x0A)
154 #define BMA280_SLEEP_DURN_25MS      (0x0B)
155 #define BMA280_SLEEP_DURN_50MS      (0x0C)
156 #define BMA280_SLEEP_DURN_100MS     (0x0D)
157 #define BMA280_SLEEP_DURN_500MS     (0x0E)
158 #define BMA280_SLEEP_DURN_1S        (0x0F)
159 #define BMA280_SLEEP_DURN_POS       (1)
160 #define BMA280_SLEEP_DURN_LEN       (4)
161 #define BMA280_SLEEP_DURN_MSK       (0x1E)
162 #define BMA280_SLEEP_DURN_REG       BMA280_MODE_CTRL_ADDR
163 #define BMA280_SLEEP_MODE           (0x40)
164 #define BMA280_DEEP_SUSPEND_MODE    (0x20)
165 #define BMA280_SUSPEND_MODE         (0x80)
166 #define BMA280_NORMAL_MODE          (0x40)
167 
168 #define BMA280_LOWPOWER_MODE        (0x40)
169 
170 #define BMA280_MODE_CTRL_POS        (5)
171 #define BMA280_MODE_CTRL_LEN        (3)
172 #define BMA280_MODE_CTRL_MSK        (0xE0)
173 #define BMA280_MODE_CTRL_REG        BMA280_MODE_CTRL_ADDR
174 #define BMA280_LOW_POWER_MODE_POS   (6)
175 #define BMA280_LOW_POWER_MODE_LEN   (1)
176 #define BMA280_LOW_POWER_MODE_MSK   (0x40)
177 #define BMA280_LOW_POWER_MODE_REG   BMA280_LOW_NOISE_CTRL_ADDR
178 
179 #define BMA280_DEFAULT_ODR_100HZ    (100)
180 
181 #define BMA280_FIFO_DEPTH_MAX       (32)
182 #define BMA280_FIFO_DATA_NUM        (6)
183 #define BMA280_FIFO_BUFF_LEN        (BMA280_FIFO_DEPTH_MAX * BMA280_FIFO_DATA_NUM)
184 // bma280 sensitivity factor table, the unit is LSB/g
185 #define BMA280_IRQ_CLEAR_VAL        (0x80)
186 #define BMA280_IRQ_LATCHED          (0x0f)
187 #define BMA280_IRQ_NON_LATCHED      (0)
188 
189 #define BMA280_IRQ_FIFO_STAT        (0x40)
190 #define BMA280_IRQ_DATA_READY_STAT  (0x80)
191 
192 #define BMA280_IRQ_DATA_READY_ENABLE    (0x10)
193 #define BMA280_IRQ_FIFO_FULL_ENABLE     (0x20)
194 #define BMA280_IRQ_FIFO_WML_ENABLE      (0x40)
195 
196 #define BMA280_IRQ_MAP_DATA_INT2        (0x80)
197 #define BMA280_IRQ_MAP_FIFO_WML_INT2    (0x40)
198 #define BMA280_IRQ_CONFIG_PUSH_PULL     (0x04)
199 #define BMA280_IRQ_FIFO_WML_MODE        (0x40)
200 #define BMA280_IRQ_PIN                  (62)
201 #define BMA280_FIFO_DEPTH_USD           (20)
202 #define BMA280_GET_BITSLICE(regvar, bitname) \
203     ((regvar & bitname##_MSK) >> bitname##_POS)
204 
205 #define BMA280_SET_BITSLICE(regvar, bitname, val) \
206     ((regvar & ~bitname##_MSK) | ((val << bitname##_POS) & bitname##_MSK))
207 
208 // bma280 sensitivity factor table, the unit is LSB/g
209 static uint32_t           bma280_factor[4]       = { 1024, 512, 256, 128 };
210 static uint32_t           current_factor         = 0;
211 
212 i2c_dev_t bma280_ctx                             = {
213     .port                 = 3,
214     .config.dev_addr      = BMA280_I2C_ADDR,
215 };
216 static int drv_acc_bosch_bma280_data_ready_init(void);
217 
drv_acc_bosch_bma280_soft_reset(i2c_dev_t * drv)218 int drv_acc_bosch_bma280_soft_reset(i2c_dev_t *drv)
219 {
220     int     ret   = 0;
221     uint8_t value = BMA280_ENABLE_SOFT_RESET_VALUE;
222     ret           = sensor_i2c_write(drv, BMA280_RST_ADDR, &value, I2C_DATA_LEN,
223                            I2C_OP_RETRIES);
224     if (unlikely(ret)) {
225         return -1;
226     }
227     return 0;
228 }
229 
drv_acc_bosch_bma280_validate_id(i2c_dev_t * drv,uint8_t id_value)230 int drv_acc_bosch_bma280_validate_id(i2c_dev_t *drv, uint8_t id_value)
231 {
232     uint8_t value = 0x00;
233     int     ret   = 0;
234 
235     if (drv == NULL) {
236         return -1;
237     }
238 
239     ret = sensor_i2c_read(drv, BMA280_CHIP_ID_ADDR, &value, I2C_DATA_LEN,
240                           I2C_OP_RETRIES);
241     if (unlikely(ret)) {
242         return ret;
243     }
244 
245     if (id_value != value) {
246         return -1;
247     }
248 
249     return 0;
250 }
251 
drv_acc_bosch_bma280_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)252 int drv_acc_bosch_bma280_set_power_mode(i2c_dev_t *      drv,
253                                                dev_power_mode_e mode)
254 {
255     uint8_t value = 0x00;
256     int     ret = 0;
257 
258     ret = sensor_i2c_read(drv, BMA280_MODE_CTRL_REG, &value, I2C_DATA_LEN,
259                           I2C_OP_RETRIES);
260     if (unlikely(ret)) {
261         return ret;
262     }
263 
264     switch (mode) {
265         case DEV_POWER_ON: {
266             if ((value & BMA280_MODE_CTRL_MSK) == BMA280_NORMAL_MODE) {
267                 return 0;
268             }
269             value |= BMA280_NORMAL_MODE;
270             ret = sensor_i2c_write(drv, BMA280_MODE_CTRL_REG, &value,
271                                    I2C_DATA_LEN, I2C_OP_RETRIES);
272             if (unlikely(ret)) {
273                 return ret;
274             }
275         } break;
276 
277         case DEV_POWER_OFF: {
278             if ((value & BMA280_MODE_CTRL_MSK) == BMA280_DEEP_SUSPEND_MODE) {
279                 return 0;
280             }
281 
282             value |= BMA280_DEEP_SUSPEND_MODE;
283             ret = sensor_i2c_write(drv, BMA280_MODE_CTRL_REG, &value,
284                                    I2C_DATA_LEN, I2C_OP_RETRIES);
285             if (unlikely(ret)) {
286                 return ret;
287             }
288         } break;
289 
290         case DEV_SLEEP: {
291             if ((value & BMA280_MODE_CTRL_MSK) == BMA280_SLEEP_MODE) {
292                 return 0;
293             }
294 
295             value |= BMA280_SLEEP_MODE;
296             ret = sensor_i2c_write(drv, BMA280_MODE_CTRL_REG, &value,
297                                    I2C_DATA_LEN, I2C_OP_RETRIES);
298             if (unlikely(ret)) {
299                 return ret;
300             }
301 
302         } break;
303 
304         case DEV_SUSPEND: {
305             if ((value & BMA280_MODE_CTRL_MSK) == BMA280_SUSPEND_MODE) {
306                 return 0;
307             }
308 
309             value |= BMA280_SUSPEND_MODE;
310             ret = sensor_i2c_write(drv, BMA280_MODE_CTRL_REG, &value,
311                                    I2C_DATA_LEN, I2C_OP_RETRIES);
312             if (unlikely(ret)) {
313                 return ret;
314             }
315 
316         } break;
317 
318         default:
319             break;
320     }
321     return 0;
322 }
323 
drv_acc_bosch_bma280_set_odr(i2c_dev_t * drv,uint32_t odr)324 int drv_acc_bosch_bma280_set_odr(i2c_dev_t *drv, uint32_t odr)
325 {
326     int      ret   = 0;
327     uint8_t  value = 0x00;
328     uint32_t bw    = odr / 2;
329 
330     ret = sensor_i2c_read(drv, BMA280_BW_SELECT_ADDR, &value, I2C_DATA_LEN,
331                           I2C_OP_RETRIES);
332     if (unlikely(ret)) {
333         return ret;
334     }
335 
336     if (bw >= BMA280_BW_1000) {
337         value &= BMA280_BW_BIT_MASK;
338         value |= BMA280_BW_1000HZ;
339     } else if (bw >= BMA280_BW_500) {
340         value &= BMA280_BW_BIT_MASK;
341         value |= BMA280_BW_500HZ;
342     } else if (bw >= BMA280_BW_250) {
343         value &= BMA280_BW_BIT_MASK;
344         value |= BMA280_BW_250HZ;
345     } else if (bw >= BMA280_BW_125) {
346         value &= BMA280_BW_BIT_MASK;
347         value |= BMA280_BW_125HZ;
348     } else if (bw >= BMA280_BW_62_5) {
349         value &= BMA280_BW_BIT_MASK;
350         value |= BMA280_BW_62_50HZ;
351     } else if (bw >= BMA280_BW_31_25) {
352         value &= BMA280_BW_BIT_MASK;
353         value |= BMA280_BW_31_25HZ;
354     } else {
355         value &= BMA280_BW_BIT_MASK;
356         value |= BMA280_BW_15_63HZ;
357     }
358 
359     ret = sensor_i2c_write(drv, BMA280_BW_SELECT_ADDR, &value, I2C_DATA_LEN,
360                            I2C_OP_RETRIES);
361     if (unlikely(ret)) {
362         return ret;
363     }
364     return 0;
365 }
366 
drv_acc_bosch_bma280_set_range(i2c_dev_t * drv,uint32_t range)367 int drv_acc_bosch_bma280_set_range(i2c_dev_t *drv, uint32_t range)
368 {
369     int     ret   = 0;
370     uint8_t value = 0x00;
371 
372     ret = sensor_i2c_read(drv, BMA280_RANGE_SELECT_REG, &value, I2C_DATA_LEN,
373                           I2C_OP_RETRIES);
374     if (unlikely(ret)) {
375         return ret;
376     }
377 
378     switch (range) {
379         case ACC_RANGE_2G: {
380             value =
381               BMA280_SET_BITSLICE(value, BMA280_RANGE_SELECT, BMA280_RANGE_2G);
382         } break;
383 
384         case ACC_RANGE_4G: {
385             value =
386               BMA280_SET_BITSLICE(value, BMA280_RANGE_SELECT, BMA280_RANGE_4G);
387         } break;
388 
389         case ACC_RANGE_8G: {
390             value =
391               BMA280_SET_BITSLICE(value, BMA280_RANGE_SELECT, BMA280_RANGE_8G);
392         } break;
393 
394         case ACC_RANGE_16G: {
395             value =
396               BMA280_SET_BITSLICE(value, BMA280_RANGE_SELECT, BMA280_RANGE_16G);
397         } break;
398 
399         default:
400             break;
401     }
402 
403     /* Write the range register 0x0F*/
404     ret = sensor_i2c_write(drv, BMA280_RANGE_SELECT_REG, &value, I2C_DATA_LEN,
405                            I2C_OP_RETRIES);
406     if (unlikely(ret)) {
407         return ret;
408     }
409 
410     if (range <= ACC_RANGE_16G) {
411         current_factor = bma280_factor[range];
412     }
413 
414     return 0;
415 }
416 
417 
drv_acc_bosch_bma280_open(void)418 int drv_acc_bosch_bma280_open(void)
419 {
420     int ret = 0;
421     ret = drv_acc_bosch_bma280_data_ready_init();
422     if (unlikely(ret)) {
423         return -1;
424     }
425 
426     ret = drv_acc_bosch_bma280_set_power_mode(&bma280_ctx, DEV_POWER_ON);
427     if (unlikely(ret)) {
428         return -1;
429     }
430     return 0;
431 }
432 
drv_acc_bosch_bma280_close(void)433 int drv_acc_bosch_bma280_close(void)
434 {
435     int ret = 0;
436     ret     = drv_acc_bosch_bma280_set_power_mode(&bma280_ctx, DEV_POWER_OFF);
437     if (unlikely(ret)) {
438         return -1;
439     }
440     return 0;
441 }
442 
drv_acc_bosch_bma280_data_ready_init(void)443 static int drv_acc_bosch_bma280_data_ready_init(void)
444 {
445     int     ret;
446     uint8_t value;
447     value = BMA280_IRQ_DATA_READY_ENABLE;
448     ret   = sensor_i2c_write(&bma280_ctx, BMA280_INTR_ENABLE2_ADDR, &value,
449                            I2C_DATA_LEN, I2C_OP_RETRIES);
450     if (unlikely(ret)) {
451         return ret;
452     }
453 
454     value = BMA280_IRQ_MAP_DATA_INT2;
455     ret   = sensor_i2c_write(&bma280_ctx, BMA280_INTR_DATA_SELECT_ADDR, &value,
456                            I2C_DATA_LEN, I2C_OP_RETRIES);
457     if (unlikely(ret)) {
458         return ret;
459     }
460 
461     value = BMA280_IRQ_CONFIG_PUSH_PULL;
462     ret   = sensor_i2c_write(&bma280_ctx, BMA280_INTR_SET_ADDR, &value,
463                            I2C_DATA_LEN, I2C_OP_RETRIES);
464     if (unlikely(ret)) {
465         return ret;
466     }
467 
468 
469     value = BMA280_IRQ_CLEAR_VAL | BMA280_IRQ_NON_LATCHED;
470     ret   = sensor_i2c_write(&bma280_ctx, BMA280_INTR_CTRL_ADDR, &value,
471                            I2C_DATA_LEN, I2C_OP_RETRIES);
472     if (unlikely(ret)) {
473         return ret;
474     }
475     return 0;
476 }
477 
drv_acc_bosch_bma280_read(void * buf,size_t len)478 int drv_acc_bosch_bma280_read(void *buf, size_t len)
479 {
480     int           ret = 0;
481     size_t        size;
482     uint8_t       reg[6];
483     accel_data_t *accel = (accel_data_t *)buf;
484     if (buf == NULL) {
485         return -1;
486     }
487 
488     size = sizeof(accel_data_t);
489     if (len < size) {
490         return -1;
491     }
492 
493     ret = sensor_i2c_read(&bma280_ctx, BMA280_X_AXIS_LSB_ADDR, &reg[0],
494                           I2C_REG_LEN, I2C_OP_RETRIES);
495     ret |= sensor_i2c_read(&bma280_ctx, BMA280_X_AXIS_MSB_ADDR, &reg[1],
496                            I2C_REG_LEN, I2C_OP_RETRIES);
497     ret |= sensor_i2c_read(&bma280_ctx, BMA280_Y_AXIS_LSB_ADDR, &reg[2],
498                            I2C_REG_LEN, I2C_OP_RETRIES);
499     ret |= sensor_i2c_read(&bma280_ctx, BMA280_Y_AXIS_MSB_ADDR, &reg[3],
500                            I2C_REG_LEN, I2C_OP_RETRIES);
501     ret |= sensor_i2c_read(&bma280_ctx, BMA280_Z_AXIS_LSB_ADDR, &reg[4],
502                            I2C_REG_LEN, I2C_OP_RETRIES);
503     ret |= sensor_i2c_read(&bma280_ctx, BMA280_Z_AXIS_MSB_ADDR, &reg[5],
504                            I2C_REG_LEN, I2C_OP_RETRIES);
505     if (unlikely(ret)) {
506         return -1;
507     }
508 
509     accel->data[DATA_AXIS_X] =
510       (int32_t)((((int32_t)((int8_t)reg[1])) << BMA280_SHIFT_EIGHT_BITS) |
511                 (reg[0] & BMA280_12_BIT_SHIFT));
512     accel->data[DATA_AXIS_X] =
513       accel->data[DATA_AXIS_X] >> BMA280_SHIFT_FOUR_BITS;
514 
515     accel->data[DATA_AXIS_Y] =
516       (int32_t)((((int32_t)((int8_t)reg[3])) << BMA280_SHIFT_EIGHT_BITS) |
517                 (reg[2] & BMA280_12_BIT_SHIFT));
518     accel->data[DATA_AXIS_Y] =
519       accel->data[DATA_AXIS_Y] >> BMA280_SHIFT_FOUR_BITS;
520 
521     accel->data[DATA_AXIS_Z] =
522       (int32_t)((((int32_t)((int8_t)reg[5])) << BMA280_SHIFT_EIGHT_BITS) |
523                 (reg[4] & BMA280_12_BIT_SHIFT));
524     accel->data[DATA_AXIS_Z] =
525       accel->data[DATA_AXIS_Z] >> BMA280_SHIFT_FOUR_BITS;
526 
527     if (current_factor != 0) {
528         // the unit of acc is mg, 1000 mg = 1 g.
529         accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] *
530                                    ACCELEROMETER_UNIT_FACTOR /
531                                    (int32_t)current_factor;
532         accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] *
533                                    ACCELEROMETER_UNIT_FACTOR /
534                                    (int32_t)current_factor;
535         accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] *
536                                    ACCELEROMETER_UNIT_FACTOR /
537                                    (int32_t)current_factor;
538     }
539     accel->timestamp = aos_now_ms();
540 
541     return (int)size;
542 
543 }
544 
drv_acc_bosch_bma280_irq_handle(void)545 void drv_acc_bosch_bma280_irq_handle(void)
546 {
547 
548 }
549 
drv_acc_bosch_bma280_ioctl(int cmd,unsigned long arg)550 static int drv_acc_bosch_bma280_ioctl(int cmd, unsigned long arg)
551 {
552     int ret = 0;
553 
554     switch (cmd) {
555         case SENSOR_IOCTL_ODR_SET: {
556             ret = drv_acc_bosch_bma280_set_odr(&bma280_ctx, arg);
557             if (unlikely(ret)) {
558                 return -1;
559             }
560         } break;
561         case SENSOR_IOCTL_RANGE_SET: {
562             ret = drv_acc_bosch_bma280_set_range(&bma280_ctx, arg);
563             if (unlikely(ret)) {
564                 return -1;
565             }
566         } break;
567         case SENSOR_IOCTL_SET_POWER: {
568             ret = drv_acc_bosch_bma280_set_power_mode(&bma280_ctx, arg);
569             if (unlikely(ret)) {
570                 return -1;
571             }
572         } break;
573         case SENSOR_IOCTL_GET_INFO: {
574             /* fill the dev info here */
575             dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
576             info->model             = "BMA280";
577             info->range_max         = 16;
578             info->range_min         = 2;
579             info->unit              = mg;
580         } break;
581 
582         default:
583             break;
584     }
585 
586     return 0;
587 }
588 
drv_acc_bosch_bma280_init(void)589 int drv_acc_bosch_bma280_init(void)
590 {
591     int          ret = 0;
592     sensor_obj_t sensor;
593 
594     memset(&sensor, 0, sizeof(sensor));
595 
596     /* fill the sensor obj parameters here */
597     sensor.io_port     = I2C_PORT;
598     sensor.tag         = TAG_DEV_ACC;
599     sensor.path        = dev_acc_path;
600     sensor.open        = drv_acc_bosch_bma280_open;
601     sensor.close       = drv_acc_bosch_bma280_close;
602     sensor.read        = drv_acc_bosch_bma280_read;
603     sensor.write       = NULL;
604     sensor.ioctl       = drv_acc_bosch_bma280_ioctl;
605     sensor.irq_handle  = drv_acc_bosch_bma280_irq_handle;
606     sensor.mode        = DEV_POLLING;
607     sensor.data_len = sizeof(accel_data_t);
608 
609     ret = sensor_create_obj(&sensor);
610     if (unlikely(ret)) {
611         return -1;
612     }
613 
614     ret = drv_acc_bosch_bma280_validate_id(&bma280_ctx, BMA280_CHIP_ID_VALUE);
615     if (unlikely(ret)) {
616         return -1;
617     }
618 
619     ret = drv_acc_bosch_bma280_soft_reset(&bma280_ctx);
620     if (unlikely(ret)) {
621         return -1;
622     }
623 
624     aos_msleep(5);
625     ret = drv_acc_bosch_bma280_set_range(&bma280_ctx, ACC_RANGE_8G);
626     if (unlikely(ret)) {
627         return -1;
628     }
629 
630     // set odr is 100hz, and will update
631     ret = drv_acc_bosch_bma280_set_odr(&bma280_ctx, BMA280_DEFAULT_ODR_100HZ);
632     if (unlikely(ret)) {
633         return -1;
634     }
635     ret = drv_acc_bosch_bma280_set_power_mode(&bma280_ctx, DEV_SLEEP);
636     if (unlikely(ret)) {
637         return -1;
638     }
639 
640     /* update the phy sensor info to sensor hal */
641     LOG("%s %s successfully \n", SENSOR_STR, __func__);
642     return 0;
643 }
644 
645 SENSOR_DRV_ADD(drv_acc_bosch_bma280_init);