2 ****************************************************************************
3 * Copyright (C) 2014 - 2015 Bosch Sensortec GmbH
9 * Usage: Sensor Driver support file for BME280 sensor
11 ****************************************************************************
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
17 * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
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.
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.
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
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 /*---------------------------------------------------------------------------*/
54 /*---------------------------------------------------------------------------*/
57 /*----------------------------------------------------------------------------*
58 * The following functions are used for reading and writing of
59 * sensor data using I2C or SPI communication
60 *----------------------------------------------------------------------------*/
62 /* \Brief: The function is used as I2C bus read
63 * \Return : Status of the I2C read
64 * \param dev_addr : The device address of the sensor
65 * \param reg_addr : Address of the first register, will data is going to be read
66 * \param reg_data : This data read from the sensor, which is hold in an array
67 * \param cnt : The no of byte of data to be read
69 s8 BME280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
70 /* \Brief: The function is used as I2C bus write
71 * \Return : Status of the I2C write
72 * \param dev_addr : The device address of the sensor
73 * \param reg_addr : Address of the first register, will data is going to be written
74 * \param reg_data : It is a value hold in the array,
75 * will be used for write the value into the register
76 * \param cnt : The no of byte of data to be write
78 s8 BME280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
79 /* \Brief: The function is used as SPI bus write
80 * \Return : Status of the SPI write
81 * \param dev_addr : The device address of the sensor
82 * \param reg_addr : Address of the first register, will data is going to be written
83 * \param reg_data : It is a value hold in the array,
84 * will be used for write the value into the register
85 * \param cnt : The no of byte of data to be write
87 s8 BME280_SPI_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
88 /* \Brief: The function is used as SPI bus read
89 * \Return : Status of the SPI read
90 * \param dev_addr : The device address of the sensor
91 * \param reg_addr : Address of the first register, will data is going to be read
92 * \param reg_data : This data read from the sensor, which is hold in an array
93 * \param cnt : The no of byte of data to be read */
94 s8 BME280_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt);
96 * \Brief: SPI/I2C init routine
101 /********************End of I2C/SPI function declarations***********************/
102 /* Brief : The delay routine
103 * \param : delay in ms
105 void BME280_delay_msek(u32 msek);
106 /* This function is an example for reading sensor data
108 * \return: communication result
110 s32 bme280_data_readout_template(void);
111 /*----------------------------------------------------------------------------*
112 * struct bme280_t parameters can be accessed by using bme280
113 * bme280_t having the following parameters
114 * Bus write function pointer: BME280_WR_FUNC_PTR
115 * Bus read function pointer: BME280_RD_FUNC_PTR
116 * Delay function pointer: delay_msec
117 * I2C address: dev_addr
118 * Chip id of the sensor: chip_id
119 *---------------------------------------------------------------------------*/
120 struct bme280_t bme280;
121 /* This function is an example for reading sensor data
123 * \return: communication result
125 s32 bme280_data_readout_template(void)
127 /* The variable used to assign the standby time*/
128 u8 v_stand_by_time_u8 = BME280_INIT_VALUE;
129 /* The variable used to read uncompensated temperature*/
130 s32 v_data_uncomp_tem_s32 = BME280_INIT_VALUE;
131 /* The variable used to read uncompensated pressure*/
132 s32 v_data_uncomp_pres_s32 = BME280_INIT_VALUE;
133 /* The variable used to read uncompensated pressure*/
134 s32 v_data_uncomp_hum_s32 = BME280_INIT_VALUE;
135 /* The variable used to read real temperature*/
136 s32 v_actual_temp_s32 = BME280_INIT_VALUE;
137 /* The variable used to read real pressure*/
138 u32 v_actual_press_u32 = BME280_INIT_VALUE;
139 /* The variable used to read real humidity*/
140 u32 v_actual_humity_u32 = BME280_INIT_VALUE;
141 /* result of communication results*/
142 s32 com_rslt = ERROR;
146 /*********************** START INITIALIZATION ************************/
147 /* Based on the user need configure I2C or SPI interface.
148 * It is example code to explain how to use the bme280 API*/
153 /*--------------------------------------------------------------------------*
154 * This function used to assign the value/reference of
155 * the following parameters
160 *-------------------------------------------------------------------------*/
161 com_rslt = bme280_init(&bme280);
163 /* For initialization it is required to set the mode of
164 * the sensor as "NORMAL"
165 * data acquisition/read/write is possible in this mode
166 * by using the below API able to set the power mode as NORMAL*/
167 /* Set the power mode as NORMAL*/
168 com_rslt += bme280_set_power_mode(BME280_NORMAL_MODE);
169 /* For reading the pressure, humidity and temperature data it is required to
170 * set the OSS setting of humidity, pressure and temperature
171 * The "BME280_CTRLHUM_REG_OSRSH" register sets the humidity
172 * data acquisition options of the device.
173 * changes to this registers only become effective after a write operation to
174 * "BME280_CTRLMEAS_REG" register.
175 * In the code automated reading and writing of "BME280_CTRLHUM_REG_OSRSH"
176 * register first set the "BME280_CTRLHUM_REG_OSRSH" and then read and write
177 * the "BME280_CTRLMEAS_REG" register in the function*/
178 com_rslt += bme280_set_oversamp_humidity(BME280_OVERSAMP_1X);
180 /* set the pressure oversampling*/
181 com_rslt += bme280_set_oversamp_pressure(BME280_OVERSAMP_2X);
182 /* set the temperature oversampling*/
183 com_rslt += bme280_set_oversamp_temperature(BME280_OVERSAMP_4X);
184 /*--------------------------------------------------------------------------*/
185 /*------------------------------------------------------------------------*
186 ************************* START GET and SET FUNCTIONS DATA ****************
187 *---------------------------------------------------------------------------*/
188 /* This API used to Write the standby time of the sensor input
189 * value have to be given
190 * Normal mode comprises an automated perpetual cycling between an (active)
191 * Measurement period and an (inactive) standby period.
192 * The standby time is determined by the contents of the register t_sb.
193 * Standby time can be set using BME280_STANDBYTIME_125_MS.
194 * Usage Hint : bme280_set_standbydur(BME280_STANDBYTIME_125_MS)*/
196 com_rslt += bme280_set_standby_durn(BME280_STANDBY_TIME_1_MS);
198 /* This API used to read back the written value of standby time*/
199 com_rslt += bme280_get_standby_durn(&v_stand_by_time_u8);
200 /*-----------------------------------------------------------------*
201 ************************* END GET and SET FUNCTIONS ****************
202 *------------------------------------------------------------------*/
204 /************************* END INITIALIZATION *************************/
206 /*------------------------------------------------------------------*
207 ************ START READ UNCOMPENSATED PRESSURE, TEMPERATURE
208 AND HUMIDITY DATA ********
209 *---------------------------------------------------------------------*/
210 /* API is used to read the uncompensated temperature*/
211 com_rslt += bme280_read_uncomp_temperature(&v_data_uncomp_tem_s32);
213 /* API is used to read the uncompensated pressure*/
214 com_rslt += bme280_read_uncomp_pressure(&v_data_uncomp_pres_s32);
216 /* API is used to read the uncompensated humidity*/
217 com_rslt += bme280_read_uncomp_humidity(&v_data_uncomp_hum_s32);
219 /* API is used to read the uncompensated temperature,pressure
221 com_rslt += bme280_read_uncomp_pressure_temperature_humidity(
222 &v_data_uncomp_tem_s32, &v_data_uncomp_pres_s32, &v_data_uncomp_hum_s32);
223 /*--------------------------------------------------------------------*
224 ************ END READ UNCOMPENSATED PRESSURE AND TEMPERATURE********
225 *-------------------------------------------------------------------------*/
227 /*------------------------------------------------------------------*
228 ************ START READ TRUE PRESSURE, TEMPERATURE
229 AND HUMIDITY DATA ********
230 *---------------------------------------------------------------------*/
231 /* API is used to read the true temperature*/
232 /* Input value as uncompensated temperature and output format*/
233 com_rslt += bme280_compensate_temperature_int32(v_data_uncomp_tem_s32);
235 /* API is used to read the true pressure*/
236 /* Input value as uncompensated pressure */
237 com_rslt += bme280_compensate_pressure_int32(v_data_uncomp_pres_s32);
239 /* API is used to read the true humidity*/
240 /* Input value as uncompensated humidity and output format*/
241 com_rslt += bme280_compensate_H_int32(v_data_uncomp_hum_s32);
243 /* API is used to read the true temperature, humidity and pressure*/
244 com_rslt += bme280_read_pressure_temperature_humidity(
245 &v_actual_press_u32, &v_actual_temp_s32, &v_actual_humity_u32);
246 /*--------------------------------------------------------------------*
247 ************ END READ TRUE PRESSURE, TEMPERATURE AND HUMIDITY ********
248 *-------------------------------------------------------------------------*/
250 /*-----------------------------------------------------------------------*
251 ************************* START DE-INITIALIZATION ***********************
252 *-------------------------------------------------------------------------*/
253 /* For de-initialization it is required to set the mode of
254 * the sensor as "SLEEP"
255 * the device reaches the lowest power consumption only
256 * In SLEEP mode no measurements are performed
257 * All registers are accessible
258 * by using the below API able to set the power mode as SLEEP*/
259 /* Set the power mode as SLEEP*/
260 com_rslt += bme280_set_power_mode(BME280_SLEEP_MODE);
261 /*---------------------------------------------------------------------*
262 ************************* END DE-INITIALIZATION **********************
263 *---------------------------------------------------------------------*/
268 #define MASK_DATA1 0xFF
269 #define MASK_DATA2 0x80
270 #define MASK_DATA3 0x7F
271 /*--------------------------------------------------------------------------*
272 * The following function is used to map the I2C bus read, write, delay and
273 * device address with global structure bme280
274 *-------------------------------------------------------------------------*/
275 s8 I2C_routine(void) {
276 /*--------------------------------------------------------------------------*
277 * By using bme280 the following structure parameter can be accessed
278 * Bus write function pointer: BME280_WR_FUNC_PTR
279 * Bus read function pointer: BME280_RD_FUNC_PTR
280 * Delay function pointer: delay_msec
281 * I2C address: dev_addr
282 *--------------------------------------------------------------------------*/
283 bme280.bus_write = BME280_I2C_bus_write;
284 bme280.bus_read = BME280_I2C_bus_read;
285 bme280.dev_addr = BME280_I2C_ADDRESS2;
286 bme280.delay_msec = BME280_delay_msek;
288 return BME280_INIT_VALUE;
291 /*---------------------------------------------------------------------------*
292 * The following function is used to map the SPI bus read, write and delay
293 * with global structure bme280
294 *--------------------------------------------------------------------------*/
295 s8 SPI_routine(void) {
296 /*--------------------------------------------------------------------------*
297 * By using bme280 the following structure parameter can be accessed
298 * Bus write function pointer: BME280_WR_FUNC_PTR
299 * Bus read function pointer: BME280_RD_FUNC_PTR
300 * Delay function pointer: delay_msec
301 *--------------------------------------------------------------------------*/
303 bme280.bus_write = BME280_SPI_bus_write;
304 bme280.bus_read = BME280_SPI_bus_read;
305 bme280.delay_msec = BME280_delay_msek;
307 return BME280_INIT_VALUE;
310 /************** I2C/SPI buffer length ******/
311 #define I2C_BUFFER_LEN 8
312 #define SPI_BUFFER_LEN 5
314 /*-------------------------------------------------------------------*
315 * This is a sample code for read and write the data by using I2C/SPI
316 * Use either I2C or SPI based on your need
317 * The device address defined in the bme280.h file
318 *-----------------------------------------------------------------------*/
319 /* \Brief: The function is used as I2C bus write
320 * \Return : Status of the I2C write
321 * \param dev_addr : The device address of the sensor
322 * \param reg_addr : Address of the first register, will data is going to be written
323 * \param reg_data : It is a value hold in the array,
324 * will be used for write the value into the register
325 * \param cnt : The no of byte of data to be write
327 s8 BME280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
329 s32 iError = BME280_INIT_VALUE;
330 u8 array[I2C_BUFFER_LEN];
331 u8 stringpos = BME280_INIT_VALUE;
332 array[BME280_INIT_VALUE] = reg_addr;
333 for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {
334 array[stringpos + BME280_ONE_U8X] = *(reg_data + stringpos);
337 * Please take the below function as your reference for
338 * write the data using I2C communication
339 * "IERROR = I2C_WRITE_STRING(DEV_ADDR, ARRAY, CNT+1)"
340 * add your I2C write function here
341 * iError is an return value of I2C read function
342 * Please select your valid return value
343 * In the driver SUCCESS defined as 0
344 * and FAILURE defined as -1
346 * This is a full duplex operation,
347 * The first read data is discarded, for that extra write operation
348 * have to be initiated. For that cnt+1 operation done in the I2C write string function
349 * For more information please refer data sheet SPI communication:
354 /* \Brief: The function is used as I2C bus read
355 * \Return : Status of the I2C read
356 * \param dev_addr : The device address of the sensor
357 * \param reg_addr : Address of the first register, will data is going to be read
358 * \param reg_data : This data read from the sensor, which is hold in an array
359 * \param cnt : The no of data byte of to be read
361 s8 BME280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
363 s32 iError = BME280_INIT_VALUE;
364 u8 array[I2C_BUFFER_LEN] = {BME280_INIT_VALUE};
365 u8 stringpos = BME280_INIT_VALUE;
366 array[BME280_INIT_VALUE] = reg_addr;
367 /* Please take the below function as your reference
368 * for read the data using I2C communication
369 * add your I2C rad function here.
370 * "IERROR = I2C_WRITE_READ_STRING(DEV_ADDR, ARRAY, ARRAY, 1, CNT)"
371 * iError is an return value of SPI write function
372 * Please select your valid return value
373 * In the driver SUCCESS defined as 0
374 * and FAILURE defined as -1
376 for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {
377 *(reg_data + stringpos) = array[stringpos];
382 /* \Brief: The function is used as SPI bus read
383 * \Return : Status of the SPI read
384 * \param dev_addr : The device address of the sensor
385 * \param reg_addr : Address of the first register, will data is going to be read
386 * \param reg_data : This data read from the sensor, which is hold in an array
387 * \param cnt : The no of byte of data to be read
389 s8 BME280_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
391 s32 iError=BME280_INIT_VALUE;
392 u8 array[SPI_BUFFER_LEN]={MASK_DATA1};
394 /* For the SPI mode only 7 bits of register addresses are used.
395 The MSB of register address is declared the bit what functionality it is
396 read/write (read as 1/write as BME280_INIT_VALUE)*/
397 array[BME280_INIT_VALUE] = reg_addr|MASK_DATA2;/*read routine is initiated register address is mask with 0x80*/
399 * Please take the below function as your reference for
400 * read the data using SPI communication
401 * " IERROR = SPI_READ_WRITE_STRING(ARRAY, ARRAY, CNT+1)"
402 * add your SPI read function here
403 * iError is an return value of SPI read function
404 * Please select your valid return value
405 * In the driver SUCCESS defined as 0
406 * and FAILURE defined as -1
408 * This is a full duplex operation,
409 * The first read data is discarded, for that extra write operation
410 * have to be initiated. For that cnt+1 operation done in the SPI read
411 * and write string function
412 * For more information please refer data sheet SPI communication:
414 for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {
415 *(reg_data + stringpos) = array[stringpos+BME280_ONE_U8X];
420 /* \Brief: The function is used as SPI bus write
421 * \Return : Status of the SPI write
422 * \param dev_addr : The device address of the sensor
423 * \param reg_addr : Address of the first register, will data is going to be written
424 * \param reg_data : It is a value hold in the array,
425 * will be used for write the value into the register
426 * \param cnt : The no of byte of data to be write
428 s8 BME280_SPI_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
430 s32 iError = BME280_INIT_VALUE;
431 u8 array[SPI_BUFFER_LEN * BME280_TWO_U8X];
432 u8 stringpos = BME280_INIT_VALUE;
433 for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {
434 /* the operation of (reg_addr++)&0x7F done: because it ensure the
435 BME280_INIT_VALUE and 1 of the given value
436 It is done only for 8bit operation*/
437 array[stringpos * BME280_TWO_U8X] = (reg_addr++) & MASK_DATA3;
438 array[stringpos * BME280_TWO_U8X + BME280_ONE_U8X] = *(reg_data + stringpos);
440 /* Please take the below function as your reference
441 * for write the data using SPI communication
442 * add your SPI write function here.
443 * "IERROR = SPI_WRITE_STRING(ARRAY, CNT*2)"
444 * iError is an return value of SPI write function
445 * Please select your valid return value
446 * In the driver SUCCESS defined as 0
447 * and FAILURE defined as -1
452 /* Brief : The delay routine
453 * \param : delay in ms
455 void BME280_delay_msek(u32 msek)
457 /*Here you can write your own delay routine*/