EFM32 Gecko Software Documentation  efm32g-doc-5.1.2
bmp280_support.c
1  /*
2 ****************************************************************************
3 * Copyright (C) 2015 - 2016 Bosch Sensortec GmbH
4 *
5 * bmp280_support.c
6 * Date: 2016/07/01
7 * Revision: 1.0.6
8 *
9 * Usage: Sensor Driver support file for BMP280 sensor
10 *
11 ****************************************************************************
12 * License:
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * Neither the name of the copyright holder nor the names of the
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
30 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
33 * OR CONTRIBUTORS BE LIABLE FOR ANY
34 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
35 * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
36 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
41 * ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
43 *
44 * The information provided is believed to be accurate and reliable.
45 * The copyright holder assumes no responsibility
46 * for the consequences of use
47 * of such information nor for any infringement of patents or
48 * other rights of third parties which may result from its use.
49 * No license is granted by implication or otherwise under any patent or
50 * patent rights of the copyright holder.
51 **************************************************************************/
52 /*---------------------------------------------------------------------------*/
53 /* Includes*/
54 /*---------------------------------------------------------------------------*/
55 #include "bmp280.h"
56 
57 #define BMP280_API
58 /*Enable the macro BMP280_API to use this support file */
59 /*----------------------------------------------------------------------------*
60 * The following functions are used for reading and writing of
61 * sensor data using I2C or SPI communication
62 *----------------------------------------------------------------------------*/
63 #ifdef BMP280_API
64 /* \Brief: The function is used as I2C bus read
65  * \Return : Status of the I2C read
66  * \param dev_addr : The device address of the sensor
67  * \param reg_addr : Address of the first register, where data is going to be read
68  * \param reg_data : This is the data read from the sensor, which is held in an array
69  * \param cnt : The no of bytes of data to be read
70  */
71 s8 BMP280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
72  /* \Brief: The function is used as I2C bus write
73  * \Return : Status of the I2C write
74  * \param dev_addr : The device address of the sensor
75  * \param reg_addr : Address of the first register, where data is to be written
76  * \param reg_data : It is a value held in the array,
77  * which is written in the register
78  * \param cnt : The no of bytes of data to be written
79  */
80 s8 BMP280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
81 /* \Brief: The function is used as SPI bus write
82  * \Return : Status of the SPI write
83  * \param dev_addr : The device address of the sensor
84  * \param reg_addr : Address of the first register, where data is to be written
85  * \param reg_data : It is a value held in the array,
86  * which is written in the register
87  * \param cnt : The no of bytes of data to be written
88  */
89 s8 BMP280_SPI_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
90 /* \Brief: The function is used as SPI bus read
91  * \Return : Status of the SPI read
92  * \param dev_addr : The device address of the sensor
93  * \param reg_addr : Address of the first register, where data is going to be read
94  * \param reg_data : This is the data read from the sensor, which is held in an array
95  * \param cnt : The no of bytes of data to be read */
96 s8 BMP280_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
97 /*
98  * \Brief: SPI/I2C init routine
99 */
100 s8 I2C_routine(void);
101 s8 SPI_routine(void);
102 #endif
103 /********************End of I2C/SPI function declarations***********************/
104 /* Brief : The delay routine
105  * \param : delay in ms
106 */
107 void BMP280_delay_msek(u32 msek);
108 /* This function is an example for reading sensor data
109  * \param: None
110  * \return: communication result
111  */
112 s32 bmp280_data_readout_template(void);
113 /*----------------------------------------------------------------------------*
114  * struct bmp280_t parameters can be accessed by using bmp280
115  * bmp280_t having the following parameters
116  * Bus write function pointer: BMP280_WR_FUNC_PTR
117  * Bus read function pointer: BMP280_RD_FUNC_PTR
118  * Delay function pointer: delay_msec
119  * I2C address: dev_addr
120  * Chip id of the sensor: chip_id
121  *---------------------------------------------------------------------------*/
122 struct bmp280_t bmp280;
123 /* This function is an example for reading sensor data
124  * \param: None
125  * \return: communication result
126  */
127 s32 bmp280_data_readout_template(void)
128 {
129  /* The variable used to assign the standby time*/
130  u8 v_standby_time_u8 = BMP280_INIT_VALUE;
131 
132  /* The variables used in individual data read APIs*/
133  /* The variable used to read uncompensated temperature*/
134  s32 v_data_uncomp_tem_s32 = BMP280_INIT_VALUE;
135  /* The variable used to read uncompensated pressure*/
136  s32 v_data_uncomp_pres_s32 = BMP280_INIT_VALUE;
137  /* The variable used to read real temperature*/
138  s32 v_actual_temp_s32 = BMP280_INIT_VALUE;
139  /* The variable used to read real pressure*/
140  u32 v_actual_press_u32 = BMP280_INIT_VALUE;
141 
142  /* The variables used in combined data read APIs*/
143  /* The variable used to read uncompensated temperature*/
144  s32 v_data_uncomp_tem_combined_s32 = BMP280_INIT_VALUE;
145  /* The variable used to read uncompensated pressure*/
146  s32 v_data_uncomp_pres_combined_s32 = BMP280_INIT_VALUE;
147  /* The variable used to read real temperature*/
148  s32 v_actual_temp_combined_s32 = BMP280_INIT_VALUE;
149  /* The variable used to read real pressure*/
150  u32 v_actual_press_combined_u32 = BMP280_INIT_VALUE;
151 
152  /* result of communication results*/
153  s32 com_rslt = ERROR;
154 /*********************** START INITIALIZATION ************************/
155  /* Based on the user need configure I2C or SPI interface.
156  * It is example code to explain how to use the bma2x2 API*/
157  #ifdef BMP280
158  I2C_routine();
159  /*SPI_routine(); */
160  #endif
161 /*--------------------------------------------------------------------------*
162  * This function used to assign the value/reference of
163  * the following parameters
164  * I2C address
165  * Bus Write
166  * Bus read
167  * Chip id
168 *-------------------------------------------------------------------------*/
169  com_rslt = bmp280_init(&bmp280);
170 
171  /* For initialization it is required to set the mode of
172  * the sensor as "NORMAL"
173  * data acquisition/read/write is possible in this mode
174  * by using the below API able to set the power mode as NORMAL*/
175  /* Set the power mode as NORMAL*/
176  com_rslt += bmp280_set_power_mode(BMP280_NORMAL_MODE);
177  /* For reading the pressure and temperature data it is required to
178  * set the work mode
179  * The measurement period in the Normal mode is depends on the setting of
180  * over sampling setting of pressure, temperature and standby time
181  *
182  * OSS pressure OSS temperature OSS
183  * ultra low power x1 x1
184  * low power x2 x1
185  * standard resolution x4 x1
186  * high resolution x8 x2
187  * ultra high resolution x16 x2
188  */
189  /* The oversampling settings are set by using the following API*/
190  com_rslt += bmp280_set_work_mode(BMP280_ULTRA_LOW_POWER_MODE);
191 /*------------------------------------------------------------------------*
192 ************************* START GET and SET FUNCTIONS DATA ****************
193 *---------------------------------------------------------------------------*/
194  /* This API used to Write the standby time of the sensor input
195  * value have to be given*/
196  /* Normal mode comprises an automated perpetual cycling between an (active)
197  * Measurement period and an (inactive) standby period.
198  * The standby time is determined by the contents of the register t_sb.
199  * Standby time can be set using BMP280_STANDBYTIME_125_MS.
200  * Usage Hint : BMP280_set_standbydur(BMP280_STANDBYTIME_125_MS)*/
201 
202  com_rslt += bmp280_set_standby_durn(BMP280_STANDBY_TIME_1_MS);
203 
204  /* This API used to read back the written value of standby time*/
205  com_rslt += bmp280_get_standby_durn(&v_standby_time_u8);
206 /*-----------------------------------------------------------------*
207 ************************* END GET and SET FUNCTIONS ****************
208 *------------------------------------------------------------------*/
209 
210 /************************* END INITIALIZATION *************************/
211 
212 /*------------------------------------------------------------------*
213 ****** INDIVIDUAL APIs TO READ UNCOMPENSATED PRESSURE AND TEMPERATURE*******
214 *---------------------------------------------------------------------*/
215  /* API is used to read the uncompensated temperature*/
216  com_rslt += bmp280_read_uncomp_temperature(&v_data_uncomp_tem_s32);
217 
218  /* API is used to read the uncompensated pressure*/
219  com_rslt += bmp280_read_uncomp_pressure(&v_data_uncomp_pres_s32);
220 
221  /* API is used to read the true temperature*/
222  /* Input value as uncompensated temperature*/
223  v_actual_temp_s32 = bmp280_compensate_temperature_int32(v_data_uncomp_tem_s32);
224 
225  /* API is used to read the true pressure*/
226  /* Input value as uncompensated pressure*/
227  v_actual_press_u32 = bmp280_compensate_pressure_int32(v_data_uncomp_pres_s32);
228 
229 /*------------------------------------------------------------------*
230 ******* STAND-ALONE APIs TO READ COMBINED TRUE PRESSURE AND TEMPERATURE********
231 *---------------------------------------------------------------------*/
232 
233 
234  /* API is used to read the uncompensated temperature and pressure*/
235  com_rslt += bmp280_read_uncomp_pressure_temperature(&v_data_uncomp_pres_combined_s32,
236  &v_data_uncomp_tem_combined_s32);
237 
238  /* API is used to read the true temperature and pressure*/
239  com_rslt += bmp280_read_pressure_temperature(&v_actual_press_combined_u32,
240  &v_actual_temp_combined_s32);
241 
242 
243 
244 /************************* START DE-INITIALIZATION ***********************/
245 
246  /* For de-initialization it is required to set the mode of
247  * the sensor as "SLEEP"
248  * the device reaches the lowest power consumption only
249  * In SLEEP mode no measurements are performed
250  * All registers are accessible
251  * by using the below API able to set the power mode as SLEEP*/
252  /* Set the power mode as SLEEP*/
253  com_rslt += bmp280_set_power_mode(BMP280_SLEEP_MODE);
254 
255  return com_rslt;
256 /************************* END DE-INITIALIZATION **********************/
257 }
258 
259 #ifdef BMP280_API
260 /*--------------------------------------------------------------------------*
261 * The following function is used to map the I2C bus read, write, delay and
262 * device address with global structure bmp280_t
263 *-------------------------------------------------------------------------*/
264 s8 I2C_routine(void) {
265 /*--------------------------------------------------------------------------*
266  * By using bmp280 the following structure parameter can be accessed
267  * Bus write function pointer: BMP280_WR_FUNC_PTR
268  * Bus read function pointer: BMP280_RD_FUNC_PTR
269  * Delay function pointer: delay_msec
270  * I2C address: dev_addr
271  *--------------------------------------------------------------------------*/
272  bmp280.bus_write = BMP280_I2C_bus_write;
273  bmp280.bus_read = BMP280_I2C_bus_read;
274  bmp280.dev_addr = BMP280_I2C_ADDRESS2;
275  bmp280.delay_msec = BMP280_delay_msek;
276 
277  return BMP280_INIT_VALUE;
278 }
279 
280 /*---------------------------------------------------------------------------*
281  * The following function is used to map the SPI bus read, write and delay
282  * with global structure bmp280_t
283  *--------------------------------------------------------------------------*/
284 s8 SPI_routine(void) {
285 /*--------------------------------------------------------------------------*
286  * By using bmp280 the following structure parameter can be accessed
287  * Bus write function pointer: BMP280_WR_FUNC_PTR
288  * Bus read function pointer: BMP280_RD_FUNC_PTR
289  * Delay function pointer: delay_msec
290  *--------------------------------------------------------------------------*/
291 
292  bmp280.bus_write = BMP280_SPI_bus_write;
293  bmp280.bus_read = BMP280_SPI_bus_read;
294  bmp280.delay_msec = BMP280_delay_msek;
295 
296  return BMP280_INIT_VALUE;
297 }
298 
299 /************** I2C/SPI buffer length ******/
300 
301 #define I2C_BUFFER_LEN 8
302 #define SPI_BUFFER_LEN 5
303 #define BUFFER_LENGTH 0xFF
304 #define SPI_READ 0x80
305 #define SPI_WRITE 0x7F
306 #define BMP280_DATA_INDEX 1
307 #define BMP280_ADDRESS_INDEX 2
308 
309 /*-------------------------------------------------------------------*
310 * This is a sample code for read and write the data by using I2C/SPI
311 * Use either I2C or SPI based on your need
312 * The device address defined in the bmp180.c
313 *
314 *-----------------------------------------------------------------------*/
315  /* \Brief: The function is used as I2C bus write
316  * \Return : Status of the I2C write
317  * \param dev_addr : The device address of the sensor
318  * \param reg_addr : Address of the first register, where data is to be written
319  * \param reg_data : It is a value held in the array,
320  * which is written in the register
321  * \param cnt : The no of bytes of data to be written
322  */
323 s8 BMP280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
324 {
325  s32 iError = BMP280_INIT_VALUE;
326  u8 array[I2C_BUFFER_LEN];
327  u8 stringpos = BMP280_INIT_VALUE;
328  array[BMP280_INIT_VALUE] = reg_addr;
329  for (stringpos = BMP280_INIT_VALUE; stringpos < cnt; stringpos++) {
330  array[stringpos + BMP280_DATA_INDEX] = *(reg_data + stringpos);
331  }
332  /*
333  * Please take the below function as your reference for
334  * write the data using I2C communication
335  * "IERROR = I2C_WRITE_STRING(DEV_ADDR, ARRAY, CNT+1)"
336  * add your I2C write function here
337  * iError is an return value of I2C read function
338  * Please select your valid return value
339  * In the driver SUCCESS defined as BMP280_INIT_VALUE
340  * and FAILURE defined as -1
341  * Note :
342  * This is a full duplex operation,
343  * The first read data is discarded, for that extra write operation
344  * have to be initiated.Thus cnt+1 operation done in the I2C write string function
345  * For more information please refer data sheet SPI communication:
346  */
347  return (s8)iError;
348 }
349 
350  /* \Brief: The function is used as I2C bus read
351  * \Return : Status of the I2C read
352  * \param dev_addr : The device address of the sensor
353  * \param reg_addr : Address of the first register, where data is going to be read
354  * \param reg_data : This is the data read from the sensor, which is held in an array
355  * \param cnt : The no of data to be read
356  */
357 s8 BMP280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
358 {
359  s32 iError = BMP280_INIT_VALUE;
360  u8 array[I2C_BUFFER_LEN] = {BMP280_INIT_VALUE};
361  u8 stringpos = BMP280_INIT_VALUE;
362  array[BMP280_INIT_VALUE] = reg_addr;
363  /* Please take the below function as your reference
364  * to read the data using I2C communication
365  * add your I2C rad function here.
366  * "IERROR = I2C_WRITE_READ_STRING(DEV_ADDR, ARRAY, ARRAY, 1, CNT)"
367  * iError is an return value of SPI write function
368  * Please select your valid return value
369  * In the driver SUCCESS defined as BMP280_INIT_VALUE
370  * and FAILURE defined as -1
371  */
372  for (stringpos = BMP280_INIT_VALUE; stringpos < cnt; stringpos++) {
373  *(reg_data + stringpos) = array[stringpos];
374  }
375  return (s8)iError;
376 }
377 
378 /* \Brief: The function is used as SPI bus read
379  * \Return : Status of the SPI read
380  * \param dev_addr : The device address of the sensor
381  * \param reg_addr : Address of the first register, where data is going to be read
382  * \param reg_data : This is the data read from the sensor, which is held in an array
383  * \param cnt : The no of data to be read
384  */
385 s8 BMP280_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
386 {
387  s32 iError=BMP280_INIT_VALUE;
388  u8 array[SPI_BUFFER_LEN]={BUFFER_LENGTH};
389  u8 stringpos;
390  /* For the SPI mode only 7 bits of register addresses are used.
391  The MSB of register address denotes the type of SPI data transfer, whether
392  read/write (read as 1/write as 0)*/
393  array[BMP280_INIT_VALUE] = reg_addr|SPI_READ;
394  /*read routine is initiated by masking register address with 0x80*/
395  /*
396  * Please take the below function as your reference to
397  * read the data using SPI communication
398  * " IERROR = SPI_READ_WRITE_STRING(ARRAY, ARRAY, CNT+1)"
399  * add your SPI read function here
400  * iError is an return value of SPI read function
401  * Please select your valid return value
402  * In the driver SUCCESS defined as 0
403  * and FAILURE defined as -1
404  * Note :
405  * This is a full duplex operation,
406  * The first read data is discarded, for that extra write operation
407  * have to be initiated. Thus cnt+1 operation done in the SPI read
408  * and write string function
409  * For more information please refer the SPI communication in data sheet
410  */
411  for (stringpos = BMP280_INIT_VALUE; stringpos < cnt; stringpos++) {
412  *(reg_data + stringpos) = array[stringpos+BMP280_DATA_INDEX];
413  }
414  return (s8)iError;
415 }
416 
417 /* \Brief: The function is used as SPI bus write
418  * \Return : Status of the SPI write
419  * \param dev_addr : The device address of the sensor
420  * \param reg_addr : Address of the first register, where data is to be written
421  * \param reg_data : It is a value held in the array,
422  * which is written in the register
423  * \param cnt : The no of bytes of data to be written
424  */
425 s8 BMP280_SPI_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
426 {
427  s32 iError = BMP280_INIT_VALUE;
428  u8 array[SPI_BUFFER_LEN * BMP280_ADDRESS_INDEX];
429  u8 stringpos = BMP280_INIT_VALUE;
430  u8 index = BMP280_INIT_VALUE;
431 
432  for (stringpos = BMP280_INIT_VALUE; stringpos < cnt; stringpos++) {
433  /* the operation of (reg_addr++)&0x7F done as per the
434  SPI communication protocol specified in the data sheet*/
435  index = stringpos * BMP280_ADDRESS_INDEX;
436  array[index] = (reg_addr++) & SPI_WRITE;
437  array[index + BMP280_DATA_INDEX] = *(reg_data + stringpos);
438  }
439  /* Please take the below function as your reference
440  * to write the data using SPI communication
441  * add your SPI write function here.
442  * "IERROR = SPI_WRITE_STRING(ARRAY, CNT*2)"
443  * iError is an return value of SPI write function
444  * Please select your valid return value
445  * In the driver SUCCESS is defined as 0 and FAILURE is defined as -1
446  */
447  return (s8)iError;
448 }
449 
450 /* Brief : The delay routine
451  * \param : delay in ms
452 */
453 void BMP280_delay_msek(u32 msek)
454 {
455  /*Here you can write your own delay routine*/
456 }
457 #endif
BMP280_RETURN_FUNCTION_TYPE bmp280_init(struct bmp280_t *bmp280)
This function is used for initialize the bus read and bus write functions and assign the chip id and ...
Definition: bmp280.c:85
u8 dev_addr
Definition: bmp280.h:771
BMP280_RETURN_FUNCTION_TYPE bmp280_read_uncomp_pressure_temperature(s32 *v_uncomp_pressure_s32, s32 *v_uncomp_temperature_s32)
reads uncompensated pressure and temperature
Definition: bmp280.c:364
BMP280_RETURN_FUNCTION_TYPE bmp280_set_power_mode(u8 v_power_mode_u8)
This API used to set the Operational Mode from the sensor in the register 0xF4 bit 0 and 1...
Definition: bmp280.c:809
BMP280_RETURN_FUNCTION_TYPE bmp280_get_standby_durn(u8 *v_standby_durn_u8)
This API used to Read the standby duration time from the sensor in the register 0xF5 bit 5 to 7...
Definition: bmp280.c:1058
u32 bmp280_compensate_pressure_int32(s32 v_uncomp_pressure_s32)
Reads actual pressure from uncompensated pressure and returns the value in Pascal(Pa) ...
Definition: bmp280.c:280
unsigned int u32
Definition: bmp280.h:284
BMP280 Sensor Driver Support Header File.
BMP280_RETURN_FUNCTION_TYPE bmp280_read_uncomp_temperature(s32 *v_uncomp_temperature_s32)
This API is used to read uncompensated temperature in the registers 0xFA, 0xFB and 0xFC...
Definition: bmp280.c:139
void(* delay_msec)(BMP280_MDELAY_DATA_TYPE)
Definition: bmp280.h:778
signed int s32
Definition: bmp280.h:278
BMP280_RETURN_FUNCTION_TYPE bmp280_read_uncomp_pressure(s32 *v_uncomp_pressure_s32)
This API is used to read uncompensated pressure. in the registers 0xF7, 0xF8 and 0xF9.
Definition: bmp280.c:235
BMP280_RETURN_FUNCTION_TYPE bmp280_read_pressure_temperature(u32 *v_pressure_u32, s32 *v_temperature_s32)
This API reads the true pressure and temperature.
Definition: bmp280.c:425
BMP280_RETURN_FUNCTION_TYPE bmp280_set_work_mode(u8 v_work_mode_u8)
This API is used to write the working mode of the sensor.
Definition: bmp280.c:1157
unsigned char u8
Definition: bmp280.h:282
s32 bmp280_compensate_temperature_int32(s32 v_uncomp_temperature_s32)
Reads actual temperature from uncompensated temperature.
Definition: bmp280.c:185
BMP280_RETURN_FUNCTION_TYPE bmp280_set_standby_durn(u8 v_standby_durn_u8)
This API used to Read the standby duration time from the sensor in the register 0xF5 bit 5 to 7...
Definition: bmp280.c:1111
This structure holds BMP280 initialization parameters.
Definition: bmp280.h:767
signed char s8
Definition: bmp280.h:276