/*
 * i2c_bme280.h
 *
 *  Created on: Nov 30, 2022
 *      Author: thomm
 */

#ifndef I2C_BME280_H_
#define I2C_BME280_H_



struct bme280_data
{
    /* Compensation parameters. */
    uint16_t dig_t1;
    int16_t dig_t2;
    int16_t dig_t3;
    uint16_t dig_p1;
    int16_t dig_p2;
    int16_t dig_p3;
    int16_t dig_p4;
    int16_t dig_p5;
    int16_t dig_p6;
    int16_t dig_p7;
    int16_t dig_p8;
    int16_t dig_p9;
    uint8_t dig_h1;
    int16_t dig_h2;
    uint8_t dig_h3;
    int16_t dig_h4;
    int16_t dig_h5;
    int8_t dig_h6;

    /* Compensated values. */
    int32_t comp_temp;
    uint32_t comp_press;
    uint32_t comp_humidity;

    /* Carryover between temperature and pressure/humidity compensation. */
    int32_t t_fine;

    uint8_t chip_id;
};

// Public API

/* probe, read cal table, and configure bme280 */
/* returns 1 on success, <= 0 on failure */
int bme280_init(void);

/* configure bme280 */
/* returns 1 on success, <= 0 on failure */
int bme280_setup(void);

void bme280_soak_test(void);
/* fetches data from the sensor */
/* returns 1 on success, <= 0 on failure */
int bme280_read_data(void);         // call bme280_read_data(), then use the 'getrs' below
float bme280_get_fTemperature(void);
float bme280_get_fPressure(void);
uint32_t bme280_get_uiHumidity(void);

/* read temp and humidity */
/* returns 1 on success, <= 0 on failure */
int bme280_ReadTempHumidity(float *Temp, float *Humi);

/* fetches data from the sensor */
/* returns 1 on success, <= 0 on failure */
int bme280_getValues(uint32_t *humid, float *tempr, float *pressr);   //api for APF, see scanSpectra in mms_spec.c

/* returns 1 on success, <= 0 on failure */
int bme280_read_compensation(struct bme280_data *data); //TODO: handle errors
void bme280_calc_temperature(struct bme280_data *data, int32_t adc_temp);
void bme280_calc_pressure(struct bme280_data *data, int32_t adc_press);
void bme280_calc_humidity(struct bme280_data *data, int32_t adc_humidity);
float bme280_calc_dewpoint(float humid, float tempr);

/* fetches data from the sensor and calculates compensated values */
/* returns 1 on success, <= 0 on failure */
int bme280_sample_fetch(struct bme280_data *data);

/* returns temperature in 0.01 degC */
int32_t bme280_get_temperature(struct bme280_data *data);

/* returns pressure in 1/256 Pa */
uint32_t bme280_get_pressure(struct bme280_data *data);

/* returns humidity in 1/1024 %RH */
uint32_t bme280_get_humidity(struct bme280_data *data);


void bme280_dev_test(void);
void bme280_test(void);

uint8_t bme280_readChipID(int prnFlg);   //TODO: handle errors
uint8_t bme280_readStatus(int prnFlg);   //TODO: handle errors
uint8_t bme280_readConfig(int prnFlg);   //TODO: handle errors
uint8_t bme280_readCtrlMeas(int prnFlg); //TODO: handle errors

/* returns 1 on success, <= 0 on failure */
int bme280_readStatus2(uint8_t* out_status);

// returns 0 on failure, 1 on success
int bme280_write_byte(uint8_t reg_addr, uint8_t device_data);
// returns 0 on failure, 1 on success
int bme280_read_byte(uint8_t reg_addr, uint8_t *data);
// returns 0 on failure, 1 on success
int bme280_read_buf(uint8_t reg_addr, uint8_t *data, uint8_t len);

// Baseboard RevB is 0x77, RevD is 0x76
#define BME280_I2C_7BIT_ADDR        0x76

#define BME280_REG_COMP_START 0x88
#define BME280_REG_DIG_T1     0x88
#define BME280_REG_DIG_T2     0x8A
#define BME280_REG_DIG_T3     0x8C

#define BME280_REG_DIG_P1     0x8E
#define BME280_REG_DIG_P2     0x90
#define BME280_REG_DIG_P3     0x92
#define BME280_REG_DIG_P4     0x94
#define BME280_REG_DIG_P5     0x96
#define BME280_REG_DIG_P6     0x98
#define BME280_REG_DIG_P7     0x9A
#define BME280_REG_DIG_P8     0x9C
#define BME280_REG_DIG_P9     0x9E

#define BME280_REG_HUM_COMP_PART1   0xA1
#define BME280_REG_DIG_H1     0xA1

#define BME280_REG_SOFTRESET  0xE0

#define BME280_REG_HUM_COMP_PART2   0xE1
#define BME280_REG_DIG_H2     0xE1
#define BME280_REG_DIG_H3     0xE3
#define BME280_REG_DIG_H4     0xE4
#define BME280_REG_DIG_H5     0xE5
#define BME280_REG_DIG_H6     0xE7

#define BME280_REG_CHIPID     0xD0


#define BME280_REG_CTRL_HUM    0xF2
#define BME280_REG_STATUS     0xF3

#define BME280_REG_CTRL_MEAS  0xF4        // aka BME280_PWR_CTRL_ADDR, #define BME280_REG_CONTROL    0xF4
#define BME280_REG_CONFIG     0xF5

#define BME280_REG_PRESS_MSB  0xF7
#define BME280_REG_TEMP_MSB   0xFA
#define BME280_REG_HUM_MSB    0xFD


// Values for registers

#define BME280_CHIPID_VAL           0x60
// BMP280 ChipID
#define BMP280_CHIP_ID_SAMPLE_1     0x56
#define BMP280_CHIP_ID_SAMPLE_2     0x57
#define BMP280_CHIP_ID_MP           0x58

// BME280 sensor modes, register ctrl_meas mode[1:0]
#define BME280_MODE_SLEEP           0x00
#define BME280_MODE_FORCED          0x01        // 0x02 is also forced
#define BME280_MODE_NORMAL          0x03
#define BME280_SPI_3W_DISABLE       0x00

// Values bit shifted for BME280_CTRL_MEAS_VAL
#define BME280_TEMP_OVER_1X         (1 << 5)
#define BME280_TEMP_OVER_2X         (2 << 5)
#define BME280_TEMP_OVER_4X         (3 << 5)
#define BME280_TEMP_OVER_8X         (4 << 5)
#define BME280_TEMP_OVER_16X        (5 << 5)

#define BME280_PRESS_OVER_1X        (1 << 2)
#define BME280_PRESS_OVER_2X        (2 << 2)
#define BME280_PRESS_OVER_4X        (3 << 2)
#define BME280_PRESS_OVER_8X        (4 << 2)
#define BME280_PRESS_OVER_16X       (5 << 2)

#define BME280_HUMIDITY_OVER_1X     1
#define BME280_HUMIDITY_OVER_2X     2
#define BME280_HUMIDITY_OVER_4X     3
#define BME280_HUMIDITY_OVER_8X     4
#define BME280_HUMIDITY_OVER_16X    5

// standby (inactive) time in ms (used in normal mode), t_sb[2:0]
#define BME280_STANDBY_0_5MS        0x00    // standby time = 0.5 ms
#define BME280_STANDBY_62_5MS       0x01    // standby time = 62.5 ms
#define BME280_STANDBY_125MS        0x02    // standby time = 125 ms
#define BME280_STANDBY_250MS        0x03    // standby time = 250 ms
#define BME280_STANDBY_500MS        0x04    // standby time = 500 ms
#define BME280_STANDBY_1000MS       0x05    // standby time = 1000 ms
#define BME280_STANDBY_2000MS       0x06
#define BME280_STANDBY_4000MS       0x07

// oversampling setting. osrs_h[2:0], osrs_t[2:0], osrs_p[2:0]
#define BME280_SAMPLING_SKIPPED     0x00  //skipped, output set to 0x80000 (0x8000 for humidity)
#define BME280_SAMPLING_X1          0x01  // oversampling x1
#define BME280_SAMPLING_X2          0x02  // oversampling x2
#define BME280_SAMPLING_X4          0x03  // oversampling x4
#define BME280_SAMPLING_X8          0x04  // oversampling x8
#define BME280_SAMPLING_X16         0x05   // oversampling x16

#define BME280_FILTER_OFF           0
#define BME280_FILTER_2             (1 << 2)
#define BME280_FILTER_4             (2 << 2)
#define BME280_FILTER_8             (3 << 2)
#define BME280_FILTER_16            (4 << 2)


/* default configuration */
#define BME280_I2C_RETRY_COUNT      5
#define BME280_TEMP_OVER            BME280_TEMP_OVER_1X     // was 4X
#define BME280_PRESS_OVER           BME280_PRESS_OVER_1X    // was 4X
#define BME280_HUMIDITY_OVER        BME280_HUMIDITY_OVER_1X // was 4X
#define BME280_STANDBY              BME280_STANDBY_0_5MS     //BME280_STANDBY_250MS
#define BME280_FILTER               BME280_FILTER_OFF
/* end default configuration */

#define BME280_CTRL_MEAS_VAL        (BME280_PRESS_OVER |    \
                                     BME280_TEMP_OVER |     \
                                     BME280_MODE_FORCED)                // was NORMAL

#define BME280_CONFIG_VAL           (BME280_STANDBY |       \
                                     BME280_FILTER |        \
                                     BME280_SPI_3W_DISABLE)










#endif /* I2C_BME280_H_ */
