3131* POSSIBILITY OF SUCH DAMAGE.
3232*
3333* @file bme68x.c
34- * @date 2020-11-02
35- * @version v4.4.2
34+ * @date 2021-03-18
35+ * @version v4.4.4
3636*
3737*/
3838
@@ -84,9 +84,12 @@ static uint8_t calc_res_heat(uint16_t temp, const struct bme68x_dev *dev);
8484
8585#endif
8686
87- /* This internal API is used to calculate the field data of sensor */
87+ /* This internal API is used to read a single data of the sensor */
8888static int8_t read_field_data (uint8_t index , struct bme68x_data * data , struct bme68x_dev * dev );
8989
90+ /* This internal API is used to read all data fields of the sensor */
91+ static int8_t read_all_field_data (struct bme68x_data * const data [], struct bme68x_dev * dev );
92+
9093/* This internal API is used to switch between SPI memory pages */
9194static int8_t set_mem_page (uint8_t reg_addr , struct bme68x_dev * dev );
9295
@@ -478,31 +481,49 @@ int8_t bme68x_get_op_mode(uint8_t *op_mode, struct bme68x_dev *dev)
478481/*
479482 * @brief This API is used to get the remaining duration that can be used for heating.
480483 */
481- uint16_t bme68x_get_meas_dur (const uint8_t op_mode , const struct bme68x_conf * conf )
484+ uint32_t bme68x_get_meas_dur (const uint8_t op_mode , struct bme68x_conf * conf , struct bme68x_dev * dev )
482485{
483- uint32_t tph_dur = 0 ; /* Calculate in us */
486+ int8_t rslt ;
487+ uint32_t meas_dur = 0 ; /* Calculate in us */
484488 uint32_t meas_cycles ;
485489 uint8_t os_to_meas_cycles [6 ] = { 0 , 1 , 2 , 4 , 8 , 16 };
486490
487491 if (conf != NULL )
488492 {
489- meas_cycles = os_to_meas_cycles [conf -> os_temp ];
490- meas_cycles += os_to_meas_cycles [conf -> os_pres ];
491- meas_cycles += os_to_meas_cycles [conf -> os_hum ];
492-
493- /* TPH measurement duration */
494- tph_dur = meas_cycles * UINT32_C (1963 );
495- tph_dur += UINT32_C (477 * 4 ); /* TPH switching duration */
496- tph_dur += UINT32_C (477 * 5 ); /* Gas measurement duration */
497- tph_dur += UINT32_C (500 ); /* Get it to the closest integer when converted to ms.*/
498- tph_dur /= UINT32_C (1000 ); /* Convert to ms */
499- if (op_mode != BME68X_PARALLEL_MODE )
493+ /* Boundary check for temperature oversampling */
494+ rslt = boundary_check (& conf -> os_temp , BME68X_OS_16X , dev );
495+
496+ if (rslt == BME68X_OK )
497+ {
498+ /* Boundary check for pressure oversampling */
499+ rslt = boundary_check (& conf -> os_pres , BME68X_OS_16X , dev );
500+ }
501+
502+ if (rslt == BME68X_OK )
500503 {
501- tph_dur += UINT32_C (1 ); /* Wake up duration of 1ms */
504+ /* Boundary check for humidity oversampling */
505+ rslt = boundary_check (& conf -> os_hum , BME68X_OS_16X , dev );
506+ }
507+
508+ if (rslt == BME68X_OK )
509+ {
510+ meas_cycles = os_to_meas_cycles [conf -> os_temp ];
511+ meas_cycles += os_to_meas_cycles [conf -> os_pres ];
512+ meas_cycles += os_to_meas_cycles [conf -> os_hum ];
513+
514+ /* TPH measurement duration */
515+ meas_dur = meas_cycles * UINT32_C (1963 );
516+ meas_dur += UINT32_C (477 * 4 ); /* TPH switching duration */
517+ meas_dur += UINT32_C (477 * 5 ); /* Gas measurement duration */
518+
519+ if (op_mode != BME68X_PARALLEL_MODE )
520+ {
521+ meas_dur += UINT32_C (1000 ); /* Wake up duration of 1ms */
522+ }
502523 }
503524 }
504525
505- return ( uint16_t ) tph_dur ;
526+ return meas_dur ;
506527}
507528
508529/*
@@ -514,8 +535,8 @@ int8_t bme68x_get_data(uint8_t op_mode, struct bme68x_data *data, uint8_t *n_dat
514535{
515536 int8_t rslt ;
516537 uint8_t i = 0 , j = 0 , new_fields = 0 ;
517- struct bme68x_data * field_ptr [3 ];
518- struct bme68x_data field_data [3 ];
538+ struct bme68x_data * field_ptr [3 ] = { 0 } ;
539+ struct bme68x_data field_data [3 ] = { { 0 } } ;
519540
520541 field_ptr [0 ] = & field_data [0 ];
521542 field_ptr [1 ] = & field_data [1 ];
@@ -544,9 +565,11 @@ int8_t bme68x_get_data(uint8_t op_mode, struct bme68x_data *data, uint8_t *n_dat
544565 else if ((op_mode == BME68X_PARALLEL_MODE ) || (op_mode == BME68X_SEQUENTIAL_MODE ))
545566 {
546567 /* Read the 3 fields and count the number of new data fields */
547- for (i = 0 ; ((i < 3 ) && (rslt == BME68X_OK )); i ++ )
568+ rslt = read_all_field_data (field_ptr , dev );
569+
570+ new_fields = 0 ;
571+ for (i = 0 ; (i < 3 ) && (rslt == BME68X_OK ); i ++ )
548572 {
549- rslt = read_field_data (i , field_ptr [i ], dev );
550573 if (field_ptr [i ]-> status & BME68X_NEW_DATA_MSK )
551574 {
552575 new_fields ++ ;
@@ -1126,7 +1149,7 @@ static uint8_t calc_gas_wait(uint16_t dur)
11261149 return durval ;
11271150}
11281151
1129- /* This internal API is used to calculate the field data of sensor */
1152+ /* This internal API is used to read a single data of the sensor */
11301153static int8_t read_field_data (uint8_t index , struct bme68x_data * data , struct bme68x_dev * dev )
11311154{
11321155 int8_t rslt = BME68X_OK ;
@@ -1215,6 +1238,84 @@ static int8_t read_field_data(uint8_t index, struct bme68x_data *data, struct bm
12151238 return rslt ;
12161239}
12171240
1241+ /* This internal API is used to read all data fields of the sensor */
1242+ static int8_t read_all_field_data (struct bme68x_data * const data [], struct bme68x_dev * dev )
1243+ {
1244+ int8_t rslt = BME68X_OK ;
1245+ uint8_t buff [BME68X_LEN_FIELD * 3 ] = { 0 };
1246+ uint8_t gas_range_l , gas_range_h ;
1247+ uint32_t adc_temp ;
1248+ uint32_t adc_pres ;
1249+ uint16_t adc_hum ;
1250+ uint16_t adc_gas_res_low , adc_gas_res_high ;
1251+ uint8_t off ;
1252+ uint8_t set_val [30 ] = { 0 }; /* idac, res_heat, gas_wait */
1253+ uint8_t i ;
1254+
1255+ if (!data [0 ] && !data [1 ] && !data [2 ])
1256+ {
1257+ rslt = BME68X_E_NULL_PTR ;
1258+ }
1259+
1260+ if (rslt == BME68X_OK )
1261+ {
1262+ rslt = bme68x_get_regs (BME68X_REG_FIELD0 , buff , (uint32_t ) BME68X_LEN_FIELD * 3 , dev );
1263+ }
1264+
1265+ if (rslt == BME68X_OK )
1266+ {
1267+ rslt = bme68x_get_regs (BME68X_REG_IDAC_HEAT0 , set_val , 30 , dev );
1268+ }
1269+
1270+ for (i = 0 ; ((i < 3 ) && (rslt == BME68X_OK )); i ++ )
1271+ {
1272+ off = (uint8_t )(i * BME68X_LEN_FIELD );
1273+ data [i ]-> status = buff [off ] & BME68X_NEW_DATA_MSK ;
1274+ data [i ]-> gas_index = buff [off ] & BME68X_GAS_INDEX_MSK ;
1275+ data [i ]-> meas_index = buff [off + 1 ];
1276+
1277+ /* read the raw data from the sensor */
1278+ adc_pres =
1279+ (uint32_t ) (((uint32_t ) buff [off + 2 ] * 4096 ) | ((uint32_t ) buff [off + 3 ] * 16 ) |
1280+ ((uint32_t ) buff [off + 4 ] / 16 ));
1281+ adc_temp =
1282+ (uint32_t ) (((uint32_t ) buff [off + 5 ] * 4096 ) | ((uint32_t ) buff [off + 6 ] * 16 ) |
1283+ ((uint32_t ) buff [off + 7 ] / 16 ));
1284+ adc_hum = (uint16_t ) (((uint32_t ) buff [off + 8 ] * 256 ) | (uint32_t ) buff [off + 9 ]);
1285+ adc_gas_res_low = (uint16_t ) ((uint32_t ) buff [off + 13 ] * 4 | (((uint32_t ) buff [off + 14 ]) / 64 ));
1286+ adc_gas_res_high = (uint16_t ) ((uint32_t ) buff [off + 15 ] * 4 | (((uint32_t ) buff [off + 16 ]) / 64 ));
1287+ gas_range_l = buff [off + 14 ] & BME68X_GAS_RANGE_MSK ;
1288+ gas_range_h = buff [off + 16 ] & BME68X_GAS_RANGE_MSK ;
1289+ if (dev -> variant_id == BME68X_VARIANT_GAS_HIGH )
1290+ {
1291+ data [i ]-> status |= buff [off + 16 ] & BME68X_GASM_VALID_MSK ;
1292+ data [i ]-> status |= buff [off + 16 ] & BME68X_HEAT_STAB_MSK ;
1293+ }
1294+ else
1295+ {
1296+ data [i ]-> status |= buff [off + 14 ] & BME68X_GASM_VALID_MSK ;
1297+ data [i ]-> status |= buff [off + 14 ] & BME68X_HEAT_STAB_MSK ;
1298+ }
1299+
1300+ data [i ]-> idac = set_val [data [i ]-> gas_index ];
1301+ data [i ]-> res_heat = set_val [10 + data [i ]-> gas_index ];
1302+ data [i ]-> gas_wait = set_val [20 + data [i ]-> gas_index ];
1303+ data [i ]-> temperature = calc_temperature (adc_temp , dev );
1304+ data [i ]-> pressure = calc_pressure (adc_pres , dev );
1305+ data [i ]-> humidity = calc_humidity (adc_hum , dev );
1306+ if (dev -> variant_id == BME68X_VARIANT_GAS_HIGH )
1307+ {
1308+ data [i ]-> gas_resistance = calc_gas_resistance (adc_gas_res_high , gas_range_h , dev );
1309+ }
1310+ else
1311+ {
1312+ data [i ]-> gas_resistance = calc_gas_resistance (adc_gas_res_low , gas_range_l , dev );
1313+ }
1314+ }
1315+
1316+ return rslt ;
1317+ }
1318+
12181319/* This internal API is used to switch between SPI memory pages */
12191320static int8_t set_mem_page (uint8_t reg_addr , struct bme68x_dev * dev )
12201321{
@@ -1380,7 +1481,7 @@ static int8_t set_conf(const struct bme68x_heatr_conf *conf, uint8_t op_mode, ui
13801481 rh_reg_addr [i ] = BME68X_REG_RES_HEAT0 + i ;
13811482 rh_reg_data [i ] = calc_res_heat (conf -> heatr_temp_prof [i ], dev );
13821483 gw_reg_addr [i ] = BME68X_REG_GAS_WAIT0 + i ;
1383- gw_reg_data [i ] = (uint8_t )conf -> heatr_dur_prof [i ];
1484+ gw_reg_data [i ] = (uint8_t ) conf -> heatr_dur_prof [i ];
13841485 }
13851486
13861487 (* nb_conv ) = conf -> profile_len ;
0 commit comments