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