1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6 /*********************************************************************************************
7 *
8 *Copyright (C) 2016 - 2020 Bosch Sensortec GmbH
9
10 *Redistribution and use in source and binary forms, with or without
11 *modification, are permitted provided that the following conditions are met:
12
13 *Redistributions of source code must retain the above copyright
14 *notice, this list of conditions and the following disclaimer.
15
16 *Redistributions in binary form must reproduce the above copyright
17 *notice, this list of conditions and the following disclaimer in the
18 *documentation and/or other materials provided with the distribution.
19
20 *Neither the name of the copyright holder nor the names of the
21 *contributors may be used to endorse or promote products derived from
22 *this software without specific prior written permission.
23
24 *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 *CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
26 *IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 *WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 *DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
29 *OR CONTRIBUTORS BE LIABLE FOR ANY
30 *DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31 *OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
32 *PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 *LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 *HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35 *WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 *ANY WAY OUT OF THE USE OF THIS
38 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
39
40 *The information provided is believed to be accurate and reliable.
41 *The copyright holder assumes no responsibility
42 *for the consequences of use
43 *of such information nor for any infringement of patents or
44 *other rights of third parties which may result from its use.
45 *No license is granted by implication or otherwise under any patent or
46 *patent rights of the copyright holder.
47 *
48 *
49 *******************************************************************************************/
50
51 #include "aos/kernel.h"
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include "sensor_drv_api.h"
56 #include "sensor_hal.h"
57 #define BMP380_BIT(x) ((uint8_t)(x))
58 #define BMP380_CHIP_ID_VAL BMP380_BIT(0X50)
59 #define BMP380_I2C_SLAVE_ADDR_LOW (0X76)
60 #define BMP380_I2C_SLAVE_ADDR_HIGH (0X77)
61
62 #define BMP380_I2C_ADDR_TRANS(n) ((n)<<1)
63 #define BMP380_I2C_ADDR BMP380_I2C_ADDR_TRANS(BMP380_I2C_SLAVE_ADDR_LOW)
64 #define BMP380_DEFAULT_ODR_1HZ (1)
65 #define BMP380_TEMPERATURE_DATA_SIZE (3)
66 #define BMP380_PRESSURE_DATA_SIZE (3)
67
68 #define BMP380_TEMPERATURE_MSB_DATA (2)
69 #define BMP380_TEMPERATURE_LSB_DATA (1)
70 #define BMP380_TEMPERATURE_XLSB_DATA (0)
71
72 #define BMP380_PRESSURE_MSB_DATA (2)
73 #define BMP380_PRESSURE_LSB_DATA (1)
74 #define BMP380_PRESSURE_XLSB_DATA (0)
75
76 /* API error codes */
77 #define BMP380_E_NULL_PTR INT8_C(-1)
78 #define BMP380_E_DEV_NOT_FOUND INT8_C(-2)
79 #define BMP380_E_INVALID_ODR_OSR_SETTINGS INT8_C(-3)
80 #define BMP380_E_CMD_EXEC_FAILED INT8_C(-4)
81 #define BMP380_E_CONFIGURATION_ERR INT8_C(-5)
82 #define BMP380_E_INVALID_LEN INT8_C(-6)
83 #define BMP380_E_COMM_FAIL INT8_C(-7)
84 #define BMP380_E_FIFO_WATERMARK_NOT_REACHED INT8_C(-8)
85
86 /* Register Address */
87 #define BMP380_CHIP_ID_ADDR UINT8_C(0x00)
88 #define BMP380_ERR_REG_ADDR UINT8_C(0x02)
89 #define BMP380_SENS_STATUS_REG_ADDR UINT8_C(0x03)
90 #define BMP380_DATA_ADDR UINT8_C(0x04)
91 #define BMP380_TDATA_ADDR UINT8_C(0x07)
92 #define BMP380_EVENT_ADDR UINT8_C(0x10)
93 #define BMP380_INT_STATUS_REG_ADDR UINT8_C(0x11)
94 #define BMP380_FIFO_LENGTH_ADDR UINT8_C(0x12)
95 #define BMP380_FIFO_DATA_ADDR UINT8_C(0x14)
96 #define BMP380_FIFO_WM_ADDR UINT8_C(0x15)
97 #define BMP380_FIFO_CONFIG_1_ADDR UINT8_C(0x17)
98 #define BMP380_FIFO_CONFIG_2_ADDR UINT8_C(0x18)
99 #define BMP380_INT_CTRL_ADDR UINT8_C(0x19)
100 #define BMP380_IF_CONF_ADDR UINT8_C(0x1A)
101 #define BMP380_PWR_CTRL_ADDR UINT8_C(0x1B)
102 #define BMP380_OSR_ADDR UINT8_C(0X1C)
103 #define BMP380_ODR_ADDR UINT8_C(0X1D)
104 #define BMP380_CALIB_DATA_ADDR UINT8_C(0x31)
105 #define BMP380_CMD_ADDR UINT8_C(0x7E)
106
107 #define BMP380_CALIB_DATA_ADDR UINT8_C(0x31)
108 #define BMP380_CALIB_DATA_LEN UINT8_C(21)
109 #define BMP380_CALIB_DATA_SIZE UINT8_C(21)
110
111 #define BMP380_ULTRA_LOW_POWER_MODE (0x00)
112 #define BMP380_LOW_POWER_MODE (0x01)
113 #define BMP380_STANDARD_RESOLUTION_MODE (0x02)
114 #define BMP380_HIGH_RESOLUTION_MODE (0x03)
115 #define BMP380_ULTRA_HIGH_RESOLUTION_MODE (0x04)
116 #define BMP380_HIGHEST_RESOLUTION_MODE (0x05)
117
118 /* Over sampling macros */
119 #define BMP380_NO_OVERSAMPLING UINT8_C(0x00)
120 #define BMP380_OVERSAMPLING_2X UINT8_C(0x01)
121 #define BMP380_OVERSAMPLING_4X UINT8_C(0x02)
122 #define BMP380_OVERSAMPLING_8X UINT8_C(0x03)
123 #define BMP380_OVERSAMPLING_16X UINT8_C(0x04)
124 #define BMP380_OVERSAMPLING_32X UINT8_C(0x05)
125
126 /* Odr setting macros */
127 #define BMP380_ODR_200_HZ UINT8_C(0x00)
128 #define BMP380_ODR_100_HZ UINT8_C(0x01)
129 #define BMP380_ODR_50_HZ UINT8_C(0x02)
130 #define BMP380_ODR_25_HZ UINT8_C(0x03)
131 #define BMP380_ODR_12_5_HZ UINT8_C(0x04)
132 #define BMP380_ODR_6_25_HZ UINT8_C(0x05)
133 #define BMP380_ODR_3_1_HZ UINT8_C(0x06)
134 #define BMP380_ODR_1_5_HZ UINT8_C(0x07)
135 #define BMP380_ODR_0_78_HZ UINT8_C(0x08)
136 #define BMP380_ODR_0_39_HZ UINT8_C(0x09)
137 #define BMP380_ODR_0_2_HZ UINT8_C(0x0A)
138 #define BMP380_ODR_0_1_HZ UINT8_C(0x0B)
139 #define BMP380_ODR_0_05_HZ UINT8_C(0x0C)
140 #define BMP380_ODR_0_02_HZ UINT8_C(0x0D)
141 #define BMP380_ODR_0_01_HZ UINT8_C(0x0E)
142 #define BMP380_ODR_0_006_HZ UINT8_C(0x0F)
143 #define BMP380_ODR_0_003_HZ UINT8_C(0x10)
144 #define BMP380_ODR_0_001_HZ UINT8_C(0x11)
145
146 #define BMP380_PRESS_ENABLED UINT8_C(0x01)
147 #define BMP380_TEMP_ENABLED UINT8_C(0x01)
148 /* CMD definition */
149 #define BMP380_SOFT_RST_CMD UINT8_C(0xB6)
150
151 /* Status macros */
152 #define BMP380_CMD_RDY UINT8_C(0x10)
153 #define BMP380_DRDY_PRESS UINT8_C(0x20)
154 #define BMP380_DRDY_TEMP UINT8_C(0x40)
155
156 /* Error status macros */
157 #define BMP380_FATAL_ERR UINT8_C(0x01)
158 #define BMP380_CMD_ERR UINT8_C(0x02)
159 #define BMP380_CONF_ERR UINT8_C(0x04)
160
161 /* Power mode macros */
162 #define BMP380_SLEEP_MODE UINT8_C(0x00)
163 #define BMP380_FORCED_MODE UINT8_C(0x01)
164 #define BMP380_NORMAL_MODE UINT8_C(0x03)
165
166 #define BMP380_PRESS_OS_MSK UINT8_C(0x07)
167 #define BMP380_PRESS_OS_POS UINT8_C(0x00)
168
169 #define BMP380_TEMP_OS_MSK UINT8_C(0x38)
170 #define BMP380_TEMP_OS_POS UINT8_C(0x03)
171
172 #define BMP380_OP_MODE_MSK UINT8_C(0x30)
173 #define BMP380_OP_MODE_POS UINT8_C(0x04)
174
175 #define BMP380_ODR_MSK UINT8_C(0x1F)
176 #define BMP380_ODR_POS UINT8_C(0x00)
177
178 #define BMP380_PRESS_EN_MSK UINT8_C(0x01)
179 #define BMP380_PRESS_EN_POS UINT8_C(0x00)
180
181 #define BMP380_TEMP_EN_MSK UINT8_C(0x02)
182 #define BMP380_TEMP_EN_POS UINT8_C(0x01)
183
184 #define BMP380_SHIFT_BY_01_BIT (1)
185 #define BMP380_SHIFT_BY_02_BITS (2)
186 #define BMP380_SHIFT_BY_03_BITS (3)
187 #define BMP380_SHIFT_BY_04_BITS (4)
188 #define BMP380_SHIFT_BY_05_BITS (5)
189 #define BMP380_SHIFT_BY_08_BITS (8)
190 #define BMP380_SHIFT_BY_11_BITS (11)
191 #define BMP380_SHIFT_BY_12_BITS (12)
192 #define BMP380_SHIFT_BY_13_BITS (13)
193 #define BMP380_SHIFT_BY_14_BITS (14)
194 #define BMP380_SHIFT_BY_15_BITS (15)
195 #define BMP380_SHIFT_BY_16_BITS (16)
196 #define BMP380_SHIFT_BY_17_BITS (17)
197 #define BMP380_SHIFT_BY_18_BITS (18)
198 #define BMP380_SHIFT_BY_19_BITS (19)
199 #define BMP380_SHIFT_BY_25_BITS (25)
200 #define BMP380_SHIFT_BY_31_BITS (31)
201 #define BMP380_SHIFT_BY_33_BITS (33)
202 #define BMP380_SHIFT_BY_35_BITS (35)
203 #define BMP380_SHIFT_BY_47_BITS (47)
204
205 /* Macro to combine two 8 bit data's to form a 16 bit data */
206 #define BMP380_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb)
207
208 #define BMP380_SET_BITSLICE(reg_data, bitname, data) \
209 ((reg_data & ~(bitname##_MSK)) | \
210 ((data << bitname##_POS) & bitname##_MSK))
211
212 #define BMP380_GET_BITSLICE(reg_data, bitname) \
213 ((reg_data & (bitname##_MSK)) >> \
214 (bitname##_POS))
215
216 #define BMP380_GET_LSB(var) (uint8_t)(var & BMA4_SET_LOW_BYTE)
217 #define BMP380_GET_MSB(var) (uint8_t)((var & BMA4_SET_HIGH_BYTE) >> 8)
218
219 typedef struct bmp380_calib_param_t {
220 uint16_t dig_T1;
221 uint16_t dig_T2;
222 int8_t dig_T3;
223 int16_t dig_P1;
224 int16_t dig_P2;
225 int8_t dig_P3;
226 int8_t dig_P4;
227 int16_t dig_P5;
228 int16_t dig_P6;
229 int8_t dig_P7;
230 int8_t dig_P8;
231 int16_t dig_P9;
232 int8_t dig_P10;
233 int8_t dig_P11;
234 int64_t t_fine;
235 }bmp380_calib_param_t;
236
237 static bmp380_calib_param_t g_bmp380_calib_table;
238
239 i2c_dev_t bmp380_ctx = {
240 .port = 3,
241 .config.address_width = 8,
242 .config.freq = 400000,
243 .config.dev_addr = BMP380_I2C_ADDR,
244 };
245
246 /**
247 * This function gets the calibration param
248 *
249 * @param[in] drv pointer to the i2c dev
250 * @return the operation status, 0 is OK, others is error
251 */
drv_baro_bosch_bmp380_get_calib_param(i2c_dev_t * drv)252 static int drv_baro_bosch_bmp380_get_calib_param(i2c_dev_t* drv)
253 {
254 int ret = 0;
255 uint8_t a_data_u8[BMP380_CALIB_DATA_SIZE] = {0};
256
257 ret = sensor_i2c_read(drv,BMP380_CALIB_DATA_ADDR,
258 a_data_u8,BMP380_CALIB_DATA_LEN,I2C_OP_RETRIES);
259
260 if (unlikely(ret) != 0) {
261 return ret;
262 }
263
264 g_bmp380_calib_table.dig_T1 = BMP380_CONCAT_BYTES(a_data_u8[1], a_data_u8[0]);
265 g_bmp380_calib_table.dig_T2 = BMP380_CONCAT_BYTES(a_data_u8[3], a_data_u8[2]);
266 g_bmp380_calib_table.dig_T3 = (int8_t)a_data_u8[4];
267 g_bmp380_calib_table.dig_P1 = (int16_t)BMP380_CONCAT_BYTES(a_data_u8[6], a_data_u8[5]);
268 g_bmp380_calib_table.dig_P2 = (int16_t)BMP380_CONCAT_BYTES(a_data_u8[8], a_data_u8[7]);
269 g_bmp380_calib_table.dig_P3 = (int8_t)a_data_u8[9];
270 g_bmp380_calib_table.dig_P4 = (int8_t)a_data_u8[10];
271 g_bmp380_calib_table.dig_P5 = BMP380_CONCAT_BYTES(a_data_u8[12], a_data_u8[11]);
272 g_bmp380_calib_table.dig_P6 = BMP380_CONCAT_BYTES(a_data_u8[14], a_data_u8[13]);
273 g_bmp380_calib_table.dig_P7 = (int8_t)a_data_u8[15];
274 g_bmp380_calib_table.dig_P8 = (int8_t)a_data_u8[16];
275 g_bmp380_calib_table.dig_P9 = (int16_t)BMP380_CONCAT_BYTES(a_data_u8[18], a_data_u8[17]);
276 g_bmp380_calib_table.dig_P10 = (int8_t)a_data_u8[19];
277 g_bmp380_calib_table.dig_P11 = (int8_t)a_data_u8[20];
278
279 return 0;
280 }
281
282 /**
283 * This function validates the chip ID of device
284 *
285 * @param[in] drv pointer to the i2c dev
286 * @param[in] id_value the expected CHIPID
287 * @return the operation status, 0 is OK, others is error
288 */
drv_baro_bosch_bmp380_validate_id(i2c_dev_t * drv,uint8_t id_value)289 static int drv_baro_bosch_bmp380_validate_id(i2c_dev_t* drv, uint8_t id_value)
290 {
291 int ret = 0;
292 uint8_t value = 0;
293
294 if (drv == NULL) {
295 return -1;
296 }
297
298 ret = sensor_i2c_read(drv, BMP380_CHIP_ID_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
299 if (unlikely(ret) != 0) {
300 return ret;
301 }
302
303 if (id_value != value) {
304 return -1;
305 }
306 return 0;
307 }
308
309 /**
310 * This function sets the baro workmode
311 *
312 * @param[in] drv pointer to the i2c dev
313 * @param[in] mode the workmode to be setted
314 * @return the operation status, 0 is OK, others is error
315 */
drv_baro_bosch_bmp380_set_work_mode(i2c_dev_t * drv,uint8_t mode)316 static int drv_baro_bosch_bmp380_set_work_mode(i2c_dev_t* drv,uint8_t mode)
317 {
318 uint8_t ret = 0;
319 uint8_t value = 0;
320 uint8_t temp = 0;
321 uint8_t baro = 0;
322
323 switch (mode) {
324 case BMP380_ULTRA_LOW_POWER_MODE:
325 temp = BMP380_NO_OVERSAMPLING;
326 baro = BMP380_NO_OVERSAMPLING;
327 break;
328
329 case BMP380_LOW_POWER_MODE:
330 temp = BMP380_OVERSAMPLING_2X;
331 baro = BMP380_OVERSAMPLING_2X;
332 break;
333
334 case BMP380_STANDARD_RESOLUTION_MODE:
335 temp = BMP380_OVERSAMPLING_4X;
336 baro = BMP380_OVERSAMPLING_4X;
337 break;
338
339 case BMP380_HIGH_RESOLUTION_MODE:
340 temp = BMP380_OVERSAMPLING_8X;
341 baro = BMP380_OVERSAMPLING_8X;
342 break;
343
344 case BMP380_ULTRA_HIGH_RESOLUTION_MODE:
345 temp = BMP380_OVERSAMPLING_16X;
346 baro = BMP380_OVERSAMPLING_16X;
347 break;
348
349 case BMP380_HIGHEST_RESOLUTION_MODE:
350 temp = BMP380_OVERSAMPLING_32X;
351 baro = BMP380_OVERSAMPLING_32X;
352 break;
353
354 default:
355 return -1;
356
357 }
358
359 ret = sensor_i2c_read(drv, BMP380_OSR_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
360 if (unlikely(ret) != 0) {
361 return ret;
362 }
363 value = BMP380_SET_BITSLICE(value,BMP380_PRESS_OS,baro);
364 value = BMP380_SET_BITSLICE(value,BMP380_TEMP_OS,temp);
365
366 ret = sensor_i2c_write(drv, BMP380_OSR_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
367 aos_msleep(2);
368 if (unlikely(ret) != 0) {
369 return ret;
370 }
371
372 return ret;
373 }
374
375 /**
376 * This function sets the baro powermode
377 *
378 * @param[in] drv pointer to the i2c dev
379 * @param[in] mode the powermode to be setted
380 * @return the operation status, 0 is OK, others is error
381 */
drv_baro_bosch_bmp380_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)382 static int drv_baro_bosch_bmp380_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
383 {
384 int ret = 0;
385 uint8_t value = 0x00;
386 uint8_t dev_mode;
387
388 switch(mode){
389 case DEV_POWER_OFF:
390 case DEV_SLEEP:{
391 dev_mode = (uint8_t)BMP380_SLEEP_MODE;
392
393 break;
394 }
395 case DEV_POWER_ON:{
396 dev_mode = (uint8_t)BMP380_NORMAL_MODE;
397 break;
398 }
399 default:return -1;
400 }
401
402 ret = sensor_i2c_read(drv, BMP380_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
403 if (unlikely(ret) != 0) {
404 return ret;
405 }
406 value = BMP380_SET_BITSLICE(value,BMP380_OP_MODE,dev_mode);
407 ret = sensor_i2c_write(drv, BMP380_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
408 aos_msleep(2);
409 if (unlikely(ret) != 0) {
410 return ret;
411 }
412
413 return 0;
414 }
415
416 /**
417 * This function enables the pressure sensor and temperature sensor
418 *
419 * @param[in] drv pointer to the i2c dev
420 * @return the operation status, 0 is OK, others is error
421 */
drv_baro_bosch_bmp380_enable_pressure_temp(i2c_dev_t * drv)422 static int drv_baro_bosch_bmp380_enable_pressure_temp(i2c_dev_t* drv)
423 {
424 int ret = 0;
425 uint8_t value = 0x00;
426
427 ret = sensor_i2c_read(drv, BMP380_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
428 if (unlikely(ret) != 0) {
429 return ret;
430 }
431
432 value = BMP380_SET_BITSLICE(value,BMP380_PRESS_EN,BMP380_PRESS_ENABLED);
433 value = BMP380_SET_BITSLICE(value,BMP380_TEMP_EN,BMP380_TEMP_ENABLED);
434
435 ret = sensor_i2c_write(drv, BMP380_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
436 aos_msleep(2);
437 if (unlikely(ret) != 0) {
438 return ret;
439 }
440
441 return 0;
442 }
443
444 /**
445 * This function gets the baro ODR according to HZ
446 *
447 * @param[in] drv pointer to the i2c dev
448 * @param[in] hz the frequency required
449 * @return the conrresponding baro ODR
450 */
drv_baro_bosch_bmp380_hz2odr(int hz)451 static uint8_t drv_baro_bosch_bmp380_hz2odr(int hz)
452 {
453 if (hz > 100)
454 return BMP380_ODR_200_HZ;
455 else if (hz > 50)
456 return BMP380_ODR_100_HZ;
457 else if (hz > 25)
458 return BMP380_ODR_50_HZ;
459 else if (hz > 12)
460 return BMP380_ODR_25_HZ;
461 else if (hz > 6)
462 return BMP380_ODR_12_5_HZ;
463 else if (hz > 3)
464 return BMP380_ODR_6_25_HZ;
465 else if (hz > 1)
466 return BMP380_ODR_3_1_HZ;
467 else
468 return BMP380_ODR_1_5_HZ;
469 }
470
471 /**
472 * This function sets the baro ODR
473 *
474 * @param[in] drv pointer to the i2c dev
475 * @param[in] hz the frequency required
476 * @return the operation status, 0 is OK, others is error
477 */
drv_baro_bosch_bmp380_set_odr(i2c_dev_t * drv,uint8_t odr)478 static int drv_baro_bosch_bmp380_set_odr(i2c_dev_t* drv, uint8_t odr)
479 {
480 int ret = 0;
481 uint8_t v_data_u8 = 0;
482
483 ret = sensor_i2c_read(drv,BMP380_ODR_ADDR,
484 &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES);
485 if (unlikely(ret) != 0) {
486 return ret;
487 }
488
489 v_data_u8 = BMP380_SET_BITSLICE(v_data_u8,BMP380_ODR,odr);
490 ret = sensor_i2c_write(drv,BMP380_ODR_ADDR,
491 &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES);
492 aos_msleep(2);
493 if (unlikely(ret) != 0) {
494 return ret;
495 }
496
497 return ret;
498 }
499
500 /**
501 * This function does the soft reset
502 *
503 * @param[in] drv pointer to the i2c dev
504 * @return the operation status, 0 is OK, others is error
505 */
drv_baro_bosch_bmp380_soft_reset(i2c_dev_t * drv)506 static int drv_baro_bosch_bmp380_soft_reset(i2c_dev_t* drv)
507 {
508 int ret = 0;
509 uint8_t cmd_rdy_status;
510 uint8_t cmd_err_status;
511 uint8_t v_data_u8 = BMP380_SOFT_RST_CMD;
512
513 ret = sensor_i2c_read(drv, BMP380_SENS_STATUS_REG_ADDR, &cmd_rdy_status, I2C_DATA_LEN, I2C_OP_RETRIES);
514
515 if ((cmd_rdy_status & BMP380_CMD_RDY) && (!unlikely(ret))) {
516 ret = sensor_i2c_write(drv,BMP380_CMD_ADDR,
517 &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES);
518 aos_msleep(2);
519 if (!unlikely(ret) != 0) {
520 ret = sensor_i2c_read(drv, BMP380_ERR_REG_ADDR, &cmd_err_status, I2C_DATA_LEN, I2C_OP_RETRIES);
521 if ((cmd_err_status & BMP380_CMD_ERR) || (unlikely(ret))) {
522 ret = BMP380_E_CMD_EXEC_FAILED;
523 }
524 }
525 } else {
526 ret = BMP380_E_CMD_EXEC_FAILED;
527 }
528
529 if (unlikely(ret) != 0) {
530 return ret;
531 }
532
533 return ret;
534 }
535
536 /**
537 * This function sets the sensor to default
538 *
539 * @param[in] drv pointer to the i2c dev
540 * @return the operation status, 0 is OK, others is error
541 */
drv_baro_bosch_bmp380_set_default_config(i2c_dev_t * drv)542 static int drv_baro_bosch_bmp380_set_default_config(i2c_dev_t* drv)
543 {
544 int ret = 0;
545 ret = drv_baro_bosch_bmp380_enable_pressure_temp(drv);
546 if (unlikely(ret) != 0) {
547 return ret;
548 }
549
550 ret = drv_baro_bosch_bmp380_set_power_mode(drv, DEV_SLEEP);
551 if (unlikely(ret) != 0) {
552 return ret;
553 }
554
555 ret = drv_baro_bosch_bmp380_set_odr(drv, BMP380_DEFAULT_ODR_1HZ);
556 if (unlikely(ret) != 0) {
557 return ret;
558 }
559
560 return 0;
561 }
562
563 /**
564 * This function reads the uncompensated baro data
565 *
566 * @param[in] drv pointer to the i2c dev
567 * @param[in out] pdata pointer to the baro data
568 * @return the operation status, 0 is OK, others is error
569 */
drv_baro_bosch_bmp380_read_uncomp_baro(i2c_dev_t * drv,barometer_data_t * pdata)570 static int drv_baro_bosch_bmp380_read_uncomp_baro(i2c_dev_t* drv, barometer_data_t* pdata)
571 {
572 int ret = 0;
573 uint8_t data[BMP380_PRESSURE_DATA_SIZE] = {0};
574
575 ret = sensor_i2c_read(drv, BMP380_DATA_ADDR, data, BMP380_PRESSURE_DATA_SIZE, I2C_OP_RETRIES);
576 if (unlikely(ret) != 0) {
577 return ret;
578 }
579
580 pdata->p = ((((uint32_t)(data[BMP380_PRESSURE_MSB_DATA]))<< BMP380_SHIFT_BY_16_BITS)
581 | (((uint32_t)(data[BMP380_PRESSURE_LSB_DATA]))<< BMP380_SHIFT_BY_08_BITS)
582 | ((uint32_t)data[BMP380_PRESSURE_XLSB_DATA]));
583 return ret;
584 }
585
586 /**
587 * This function compensates the uncompensated baro data
588 *
589 * @param[in out] pdata pointer to the baro data
590 * @return the operation status, 0 is OK, others is error
591 */
drv_baro_bosch_bmp380_compensate_baro(barometer_data_t * pdata)592 static int drv_baro_bosch_bmp380_compensate_baro( barometer_data_t* pdata)
593 {
594 int64_t partial_data1;
595 int64_t partial_data2;
596 int64_t partial_data3;
597 int64_t partial_data4;
598 int64_t partial_data5;
599 int64_t partial_data6;
600 int64_t offset;
601 int64_t sensitivity;
602 uint64_t comp_press;
603 uint32_t comp_baro = 0;
604
605 partial_data1 = g_bmp380_calib_table.t_fine * g_bmp380_calib_table.t_fine;
606 partial_data2 = partial_data1 / 64;
607 partial_data3 = (partial_data2 * g_bmp380_calib_table.t_fine) / 256;
608 partial_data4 = (g_bmp380_calib_table.dig_P8 * partial_data3) / 32;
609 partial_data5 = (g_bmp380_calib_table.dig_P7 * partial_data1) * 16;
610 partial_data6 = (g_bmp380_calib_table.dig_P6 * g_bmp380_calib_table.t_fine) * 4194304;
611 offset = (g_bmp380_calib_table.dig_P5 * 140737488355328) + partial_data4 + partial_data5 + partial_data6;
612
613 partial_data2 = (g_bmp380_calib_table.dig_P4 * partial_data3) / 32;
614 partial_data4 = (g_bmp380_calib_table.dig_P3 * partial_data1) * 4;
615 partial_data5 = (g_bmp380_calib_table.dig_P2 - 16384) * g_bmp380_calib_table.t_fine * 2097152;
616 sensitivity = ((g_bmp380_calib_table.dig_P1 - 16384) * 70368744177664) + partial_data2 + partial_data4 + partial_data5;
617
618 partial_data1 = (sensitivity / 16777216) * pdata->p;
619 partial_data2 = g_bmp380_calib_table.dig_P10 * g_bmp380_calib_table.t_fine;
620 partial_data3 = partial_data2 + (65536 * g_bmp380_calib_table.dig_P9);
621 partial_data4 = (partial_data3 * pdata->p) / 8192;
622 partial_data5 = (partial_data4 * pdata->p) / 512;
623 partial_data6 = (int64_t)((uint64_t)pdata->p * (uint64_t)pdata->p);
624 partial_data2 = (g_bmp380_calib_table.dig_P11 * partial_data6) / 65536;
625 partial_data3 = (partial_data2 * pdata->p) / 128;
626 partial_data4 = (offset / 4) + partial_data1 + partial_data5 + partial_data3;
627 comp_press = (((uint64_t)partial_data4 * 25) / (uint64_t)1099511627776);
628 comp_baro = (uint32_t)(comp_press) / 100;
629 pdata->p = comp_baro;
630 return 0;
631 }
632
633 /**
634 * This function reads the baro data and reports the data
635 *
636 * @param[in out] buf buffer for acc data
637 * @param[in out] len length of data
638 * @return the operation status, 0 is OK, others is error
639 */
drv_baro_bosch_bmp380_read_baro(i2c_dev_t * drv,barometer_data_t * pdata)640 static int drv_baro_bosch_bmp380_read_baro(i2c_dev_t* drv, barometer_data_t* pdata)
641 {
642 int ret = 0;
643
644 ret = drv_baro_bosch_bmp380_read_uncomp_baro(drv, pdata);
645 if (unlikely(ret) != 0) {
646 return ret;
647 }
648 ret = drv_baro_bosch_bmp380_compensate_baro(pdata);
649 if (unlikely(ret) != 0) {
650 return ret;
651 }
652
653 return 0;
654 }
655
656 /**
657 * This function compensates the uncompensated temp data
658 *
659 * @param[in out] pdata pointer to the baro data
660 * @return the operation status, 0 is OK, others is error
661 */
drv_baro_bosch_bmp380_comp_temp(temperature_data_t * pdata)662 static int drv_baro_bosch_bmp380_comp_temp(temperature_data_t* pdata)
663 {
664 uint64_t partial_data1;
665 uint64_t partial_data2;
666 uint64_t partial_data3;
667 int64_t partial_data4;
668 int64_t partial_data5;
669 int64_t partial_data6;
670 int64_t comp_temp;
671
672 partial_data1 = pdata->t - (256 * g_bmp380_calib_table.dig_T1);
673 partial_data2 = g_bmp380_calib_table.dig_T2 * partial_data1;
674 partial_data3 = partial_data1 * partial_data1;
675 partial_data4 = (int64_t)partial_data3 * g_bmp380_calib_table.dig_T3;
676 partial_data5 = ((int64_t)(partial_data2 * 262144) + partial_data4);
677 partial_data6 = partial_data5 / 4294967296;
678 /* Store t_lin in dev. structure for pressure calculation */
679 g_bmp380_calib_table.t_fine = partial_data6;
680 comp_temp = (int64_t)((partial_data6 * 25) / 16384);
681 pdata->t = (int32_t)(comp_temp);
682 return 0;
683 }
684
685 /**
686 * This function calibrate the uncompensated temp data
687 *
688 * @param[in] drv pointer to the i2c dev
689 * @return the operation status, 0 is OK, others is error
690 */
drv_baro_bosch_bmp380_cali_temp(i2c_dev_t * drv)691 static int drv_baro_bosch_bmp380_cali_temp(i2c_dev_t* drv)
692 {
693 int ret = 0;
694 uint8_t data[BMP380_TEMPERATURE_DATA_SIZE] = {0};
695 temperature_data_t temp;
696
697 ret = sensor_i2c_read(drv, BMP380_TDATA_ADDR, data, BMP380_TEMPERATURE_DATA_SIZE, I2C_OP_RETRIES);
698 if(unlikely(ret) != 0){
699 return ret;
700 }
701
702 temp.t = ((((uint32_t)(data[BMP380_TEMPERATURE_MSB_DATA]))<< BMP380_SHIFT_BY_16_BITS)
703 | (((uint32_t)(data[BMP380_TEMPERATURE_LSB_DATA]))<< BMP380_SHIFT_BY_08_BITS)
704 | ((uint32_t)data[BMP380_TEMPERATURE_XLSB_DATA]));
705
706 ret = drv_baro_bosch_bmp380_comp_temp(&temp);
707 if(unlikely(ret) != 0){
708 return ret;
709 }
710
711 return 0;
712 }
713
714 /**
715 * This function is the ISR
716 *
717 * @return
718 */
drv_baro_bosch_bmp380_irq_handle(void)719 static void drv_baro_bosch_bmp380_irq_handle(void)
720 {
721 /* no handle so far */
722 }
723
724 /**
725 * This function opens the baro
726 *
727 * @return the operation status, 0 is OK, others is error
728 */
drv_baro_bosch_bmp380_open(void)729 static int drv_baro_bosch_bmp380_open(void)
730 {
731 int ret = 0;
732
733 /* set the default config for the sensor here */
734 ret = drv_baro_bosch_bmp380_set_work_mode(&bmp380_ctx,BMP380_ULTRA_LOW_POWER_MODE);
735 if (unlikely(ret) != 0) {
736 return -1;
737 }
738 ret = drv_baro_bosch_bmp380_enable_pressure_temp(&bmp380_ctx);
739 if (unlikely(ret) != 0) {
740 return ret;
741 }
742 ret = drv_baro_bosch_bmp380_set_power_mode(&bmp380_ctx, DEV_POWER_ON);
743 if (unlikely(ret) != 0) {
744 return -1;
745 }
746
747 LOG("%s %s successfully \n", SENSOR_STR, __func__);
748 return 0;
749
750 }
751
752 /**
753 * This function closes the baro
754 *
755 * @return the operation status, 0 is OK, others is error
756 */
drv_baro_bosch_bmp380_close(void)757 static int drv_baro_bosch_bmp380_close(void)
758 {
759 int ret = 0;
760 ret = drv_baro_bosch_bmp380_set_power_mode(&bmp380_ctx, DEV_POWER_OFF);
761 if (unlikely(ret) != 0) {
762 return -1;
763 }
764 LOG("%s %s successfully \n", SENSOR_STR, __func__);
765 return 0;
766 }
767
768 /**
769 * This function reads the baro data and reports the data
770 *
771 * @param[in out] buf buffer for baro data
772 * @param[in out] len length of data
773 * @return the operation status, 0 is OK, others is error
774 */
drv_baro_bosch_bmp380_read(void * buf,size_t len)775 static int drv_baro_bosch_bmp380_read(void *buf, size_t len)
776 {
777 int ret = 0;
778 size_t size = 0;
779 barometer_data_t* pdata = (barometer_data_t*)buf;
780
781 if (buf == NULL) {
782 return -1;
783 }
784 size = sizeof(barometer_data_t);
785 if (len < size) {
786 return -1;
787 }
788
789 ret = drv_baro_bosch_bmp380_cali_temp(&bmp380_ctx);
790 if (unlikely(ret) != 0) {
791 return -1;
792 }
793
794 ret = drv_baro_bosch_bmp380_read_baro(&bmp380_ctx, pdata);
795 if (unlikely(ret) != 0) {
796 return -1;
797 }
798
799 pdata->timestamp = aos_now_ms();
800
801 return (int)size;
802 }
803
804 /**
805 * This function writess the baro
806 *
807 * @param[in out] buf buffer for written data
808 * @param[in out] len length of data
809 * @return the operation status, 0 is OK, others is error
810 */
drv_baro_bosch_bmp380_write(const void * buf,size_t len)811 static int drv_baro_bosch_bmp380_write(const void *buf, size_t len)
812 {
813 (void)buf;
814 (void)len;
815 return 0;
816 }
817
818 /**
819 * This function is for the baro ioctl
820 *
821 * @param[in] cmd the ioctl command
822 * @param[in] arg the correspondding parameter
823 * @return the operation status, 0 is OK, others is error
824 */
drv_baro_bosch_bmp380_ioctl(int cmd,unsigned long arg)825 static int drv_baro_bosch_bmp380_ioctl(int cmd, unsigned long arg)
826 {
827 int ret = 0;
828
829 switch(cmd){
830 case SENSOR_IOCTL_ODR_SET:{
831 uint8_t odr = drv_baro_bosch_bmp380_hz2odr(arg);
832 ret = drv_baro_bosch_bmp380_set_odr(&bmp380_ctx, odr);
833 if (unlikely(ret) != 0) {
834 return -1;
835 }
836 }break;
837 case SENSOR_IOCTL_SET_POWER:{
838 ret = drv_baro_bosch_bmp380_set_power_mode(&bmp380_ctx, arg);
839 if (unlikely(ret) != 0) {
840 return -1;
841 }
842 }break;
843 case SENSOR_IOCTL_GET_INFO:{
844 /* fill the dev info here */
845 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
846 info->model = "BMP380";
847 info->range_max = 1100;
848 info->range_min = 300;
849 info->unit = pa;
850
851 }break;
852
853 default:break;
854 }
855
856 LOG("%s %s successfully \n", SENSOR_STR, __func__);
857 return 0;
858 }
859
860 /**
861 * This function is for the baro initialization
862 *
863 * @return the operation status, 0 is OK, others is error
864 */
drv_baro_bosch_bmp380_init(void)865 int drv_baro_bosch_bmp380_init(void)
866 {
867 int ret = 0;
868 sensor_obj_t sensor;
869 memset(&sensor, 0, sizeof(sensor));
870 /* fill the sensor obj parameters here */
871 sensor.tag = TAG_DEV_BARO;
872 sensor.path = dev_baro_path;
873 sensor.io_port = I2C_PORT;
874 sensor.open = drv_baro_bosch_bmp380_open;
875 sensor.close = drv_baro_bosch_bmp380_close;
876 sensor.read = drv_baro_bosch_bmp380_read;
877 sensor.write = drv_baro_bosch_bmp380_write;
878 sensor.ioctl = drv_baro_bosch_bmp380_ioctl;
879 sensor.irq_handle = drv_baro_bosch_bmp380_irq_handle;
880
881 ret = sensor_create_obj(&sensor);
882 if (unlikely(ret) != 0) {
883 return -1;
884 }
885
886 ret = drv_baro_bosch_bmp380_validate_id(&bmp380_ctx, BMP380_CHIP_ID_VAL);
887 if (unlikely(ret) != 0) {
888 return -1;
889 }
890
891 ret = drv_baro_bosch_bmp380_soft_reset(&bmp380_ctx);
892 if (unlikely(ret) != 0) {
893 return -1;
894 }
895
896 ret = drv_baro_bosch_bmp380_set_default_config(&bmp380_ctx);
897 if (unlikely(ret) != 0) {
898 return -1;
899 }
900
901 ret = drv_baro_bosch_bmp380_get_calib_param(&bmp380_ctx);
902 if (unlikely(ret) != 0) {
903 return -1;
904 }
905
906 LOG("%s %s successfully \n", SENSOR_STR, __func__);
907 return 0;
908 }
909
910 SENSOR_DRV_ADD(drv_baro_bosch_bmp380_init);
911
912