/**************************************************************************************/
/********************          Library BMP280 & AHT20              ********************/
/*          Author : Subeer Kumar Sarkar                                              */
/*          Website: iotthinghub.com                                                  */
/*                                                                                    */
/**************************************************************************************/

#include "BMP280+AHT20.h"

float BMP280_Temperature, BMP280_Pressure, BMP280_Altitude;
float AHT20_Temperature, AHT20_Humidity;
extern I2C_HandleTypeDef hi2c1;

#define BME280_ADDRESS 0xEC  // SDIO is grounded, the 7 bit address is 0x76 and 8 bit address = 0x76<<1 = 0xEC


uint8_t chipID;

int32_t temperature_raw, pressure_raw;

uint16_t dig_T1,  \
         dig_P1; \

int16_t  dig_T2, dig_T3, \
         dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9; \



void BMP280_init(uint8_t t_sb,uint8_t filter, uint8_t osrs_t, uint8_t osrs_p,uint8_t mode)
{
	HAL_I2C_Mem_Read(&hi2c1,BME280_ADDRESS,ID_REG,1,&chipID,1,1000);
	uint8_t u8_config,u8_ctrl_meas;
	u8_config=(t_sb<<5)|(filter<<2);
	u8_ctrl_meas=(osrs_t<<5)|(osrs_p<<2)|mode;
	HAL_I2C_Mem_Read(&hi2c1,BME280_ADDRESS,CONFIG_REG,1,&u8_config,1,1000);
	HAL_I2C_Mem_Read(&hi2c1,BME280_ADDRESS,CTRL_MEAS_REG,1,&u8_ctrl_meas,1,1000);
	BMP280_get_calib_values();
}

void BMP280_get_calib_values(void)
{
	uint8_t trimming_buff[24];
    HAL_I2C_Mem_Read(&hi2c1,BME280_ADDRESS,TRIMMING_PRA,1,trimming_buff,24,1000);
	dig_T1=(trimming_buff[0])+(trimming_buff[1]<<8);
	dig_T2=(trimming_buff[2])+(trimming_buff[3]<<8);
	dig_T3=(trimming_buff[4])+(trimming_buff[5]<<8);
	dig_P1=(trimming_buff[6])+(trimming_buff[7]<<8);
	dig_P2=(trimming_buff[8])+(trimming_buff[9]<<8);
	dig_P3=(trimming_buff[10])+(trimming_buff[11]<<8);
	dig_P4=(trimming_buff[12])+(trimming_buff[13]<<8);
	dig_P5=(trimming_buff[14])+(trimming_buff[15]<<8);
	dig_P6=(trimming_buff[16])+(trimming_buff[17]<<8);
	dig_P7=(trimming_buff[18])+(trimming_buff[19]<<8);
	dig_P8=(trimming_buff[20])+(trimming_buff[21]<<8);
	dig_P9=(trimming_buff[22])+(trimming_buff[23]<<8);
}
void BMP280_calc_values(void)
{
	uint8_t status, rx_buff[6];
	do
	{
		HAL_I2C_Mem_Read(&hi2c1,BME280_ADDRESS,STATUS_REG,1,&status,1,1000);
	} while(((status&0b00001000)==8)||((status&0b00000001)==1));
    HAL_I2C_Mem_Read(&hi2c1,BME280_ADDRESS,TEMP_REG,1,rx_buff,6,1000);
    temperature_raw=(rx_buff[3]<<12)+(rx_buff[4]<<4)+(rx_buff[5]>>4);
    pressure_raw=(rx_buff[0]<<12)+(rx_buff[1]<<4)+(rx_buff[2]>>4);
	
	double var1, var2;
	var1=(((double)temperature_raw)/16384.0-((double)dig_T1)/1024.0)*((double)dig_T2);
	var2=((((double)temperature_raw)/131072.0-((double)dig_T1)/8192.0)*(((double)temperature_raw)/131072.0-((double)dig_T1)/8192.0))*((double)dig_T3);
	double t_fine = (int32_t)(var1+var2);
    volatile	float T = (var1+var2)/5120.0;
	BMP280_Temperature=T;
	var1=((double)t_fine/2.0)-64000.0;
    var2=var1*var1*((double)dig_P6)/32768.0;
    var2=var2+var1*((double)dig_P5)*2.0;
    var2=(var2/4.0)+(((double)dig_P4)*65536.0);
    var1=(((double)dig_P3)*var1*var1/524288.0+((double)dig_P2)*var1)/524288.0;
    var1=(1.0+var1/32768.0)*((double)dig_P1);
	volatile double p=1048576.0-(double)pressure_raw;
    p=(p-(var2/4096.0))*6250.0/var1;
    var1=((double)dig_P9)*p*p/2147483648.0;
    var2=p*((double)dig_P8)/32768.0;
    p=p+(var1+var2+((double)dig_P7))/16.0;
    BMP280_Pressure=p;
	//altitude=44330.0*(1-(powf(101325.0/pressure, 1/5.255f));
	BMP280_Altitude=44330.0*(1-pow(BMP280_Pressure/101325.0,1.0/5.255));
}

void AHT20_init(void)
{
    uint8_t Tx_INIT[3]={AHT20_INIT,0x08,0x00};
    HAL_I2C_Master_Transmit(&hi2c1,AHT20_ADD<<1,Tx_INIT,3,200);
}

void AHT20_Read(void)
{
	uint32_t temperature,humidity;
    uint8_t Tx_Soft[1]={AHT20_RESET};
    uint8_t Tx_Trig[3]={AHT20_TRIG,0x33,0x00};
    uint8_t Rx_Data[6];
    HAL_I2C_Master_Transmit(&hi2c1,AHT20_ADD<<1,Tx_Trig,3,200);
	HAL_Delay(100);
	HAL_I2C_Master_Receive(&hi2c1,(AHT20_ADD<<1|0x01),Rx_Data,6,200);
	temperature=((Rx_Data[3]&0x0f)<<16)+(Rx_Data[4]<<8)+(Rx_Data[5]);
	AHT20_Temperature=((float)temperature/1048576)*200-50;
	humidity=(Rx_Data[1]<<12)+(Rx_Data[2]<<4)+(Rx_Data[3]>>4);
	AHT20_Humidity=(float)humidity/1048576*100;
}