]> git.itanic.dy.fi Git - BME280_driver/blob - bme280_support.c
Corrected the magic numbers with valid names
[BME280_driver] / bme280_support.c
1 /*
2 ****************************************************************************
3 * Copyright (C) 2014 - 2015 Bosch Sensortec GmbH
4 *
5 * bme280_support.c
6 * Date: 2015/03/27
7 * Revision: 1.0.5 $
8 *
9 * Usage: Sensor Driver support file for BME280 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 "bme280.h"
56
57 /*----------------------------------------------------------------------------*
58 *  The following functions are used for reading and writing of
59 *       sensor data using I2C or SPI communication
60 *----------------------------------------------------------------------------*/
61 #ifdef BME280_API
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
68  */
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
77  */
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
86  */
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);
95 /*
96  * \Brief: SPI/I2C init routine
97 */
98 s8 I2C_routine(void);
99 s8 SPI_routine(void);
100 #endif
101 /********************End of I2C/SPI function declarations***********************/
102 /*      Brief : The delay routine
103  *      \param : delay in ms
104 */
105 void BME280_delay_msek(u32 msek);
106 /* This function is an example for reading sensor data
107  *      \param: None
108  *      \return: communication result
109  */
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
122  *      \param: None
123  *      \return: communication result
124  */
125 s32 bme280_data_readout_template(void)
126 {
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;
143
144
145
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*/
149   #ifdef BME280_API
150         I2C_routine();
151         /*SPI_routine(); */
152         #endif
153 /*--------------------------------------------------------------------------*
154  *  This function used to assign the value/reference of
155  *      the following parameters
156  *      I2C address
157  *      Bus Write
158  *      Bus read
159  *      Chip id
160 *-------------------------------------------------------------------------*/
161         com_rslt = bme280_init(&bme280);
162
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);
179
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)*/
195
196         com_rslt += bme280_set_standby_durn(BME280_STANDBY_TIME_1_MS);
197
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 *------------------------------------------------------------------*/
203
204 /************************* END INITIALIZATION *************************/
205
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);
212
213         /* API is used to read the uncompensated pressure*/
214         com_rslt += bme280_read_uncomp_pressure(&v_data_uncomp_pres_s32);
215
216         /* API is used to read the uncompensated humidity*/
217         com_rslt += bme280_read_uncomp_humidity(&v_data_uncomp_hum_s32);
218
219         /* API is used to read the uncompensated temperature,pressure
220         and humidity data */
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 *-------------------------------------------------------------------------*/
226
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);
234
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);
238
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);
242
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 *-------------------------------------------------------------------------*/
249
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 *---------------------------------------------------------------------*/
264 return com_rslt;
265 }
266
267 #ifdef BME280_API
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;
287
288         return BME280_INIT_VALUE;
289 }
290
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  *--------------------------------------------------------------------------*/
302
303         bme280.bus_write = BME280_SPI_bus_write;
304         bme280.bus_read = BME280_SPI_bus_read;
305         bme280.delay_msec = BME280_delay_msek;
306
307         return BME280_INIT_VALUE;
308 }
309
310 /************** I2C/SPI buffer length ******/
311 #define I2C_BUFFER_LEN 8
312 #define SPI_BUFFER_LEN 5
313
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
326  */
327 s8 BME280_I2C_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
328 {
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);
335         }
336         /*
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
345         * Note :
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:
350         */
351         return (s8)iError;
352 }
353
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
360  */
361 s8 BME280_I2C_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
362 {
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
375          */
376         for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {
377                 *(reg_data + stringpos) = array[stringpos];
378         }
379         return (s8)iError;
380 }
381
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
388  */
389 s8 BME280_SPI_bus_read(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
390 {
391         s32 iError=BME280_INIT_VALUE;
392         u8 array[SPI_BUFFER_LEN]={MASK_DATA1};
393         u8 stringpos;
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*/
398         /*
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
407         * Note :
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:
413         */
414         for (stringpos = BME280_INIT_VALUE; stringpos < cnt; stringpos++) {
415                 *(reg_data + stringpos) = array[stringpos+BME280_ONE_U8X];
416         }
417         return (s8)iError;
418 }
419
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
427  */
428 s8 BME280_SPI_bus_write(u8 dev_addr, u8 reg_addr, u8 *reg_data, u8 cnt)
429 {
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);
439         }
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
448          */
449         return (s8)iError;
450 }
451
452 /*      Brief : The delay routine
453  *      \param : delay in ms
454 */
455 void BME280_delay_msek(u32 msek)
456 {
457         /*Here you can write your own delay routine*/
458 }
459 #endif