/*
The microcontroller sends a start sequence to start
a pressure or temperature measurement. After
converting time (4.5ms), the result value (UP or UT,
respectively) can be read via the I2C interface. For
calculating temperature in C and pressure in hPa,
the calibration data has to be used. These
constants can be read out from the BMP085
EEPROM via the I2C interface at software
initialization.

set oversampling_setting to 3

start temp measurement, wait 4.5ms, read UT, start press measurement, 25.5ms (high resolution), read UP, calculate pressure/temp in physical units

UP is 16 to 19 bit pressure data
uT is 16 bit temperature data
*/
//#define OSS_address 0xF4
uint8_t OSS =4;	// Oversampling Setting
int32_t ac1	=0;
int32_t ac2	=0; 
int32_t ac3	=0; 
uint32_t ac4=0;
uint32_t ac5=0;
uint32_t ac6=0;
int32_t b1	=0; 
int32_t b2	=0;
int32_t mb	=0;
int32_t mc	=0;
int32_t md	=0;
int16_t temperature = 0;
int32_t pressure = 0;
int16_t altitude = 0;


int32_t BMP085_Read2(unsigned char address)
	{
	uint8_t response[2];
	
	if(!i2cMasterReadRegisters(&Pressure_I2C.i2cInfo, address, sizeof(response), response))
		rprintf("\npressure read failed");

	//combine values
	int32_t val = (response[0] << 8) + response[1];

	return val;
	}

int32_t BMP085_Read(unsigned char address)
	{
	uint8_t response[1];
	
	if(!i2cMasterReadRegisters(&Pressure_I2C.i2cInfo, address, sizeof(response), response))
		rprintf("\npressure read failed");

	//combine values
	int32_t val = response[0];

	return val;
	}

void BMP085_Calibration(void)
	{
	ac1 = BMP085_Read2(0xAA);
	ac2 = BMP085_Read2(0xAC);
	ac3 = BMP085_Read2(0xAE);
	ac4 = BMP085_Read2(0xB0);
	ac5 = BMP085_Read2(0xB2);
	ac6 = BMP085_Read2(0xB4);
	b1 = BMP085_Read2(0xB6);
	b2 = BMP085_Read2(0xB8);
	mb = BMP085_Read2(0xBA);
	mc = BMP085_Read2(0xBC);
	md = BMP085_Read2(0xBE);

	/*rprintf("\n\nPressure Sensor Calibration Coefficients");
	rprintf("\nAC1 = %d", ac1);
	rprintf("\nAC2 = %d", ac2);
	rprintf("\nAC3 = %d", ac3);
	rprintf("\nAC4 = %u", ac4);
	rprintf("\nAC5 = %u", ac5);
	rprintf("\nAC6 = %u", ac6);
	rprintf("\nB1 = %d", b1);
	rprintf("\nB2 = %d", b2);
	rprintf("\nMB = %d", mb);
	rprintf("\nMC = %d", mc);
	rprintf("\nMD = %d\n", md);*/
	}

int32_t BMP085_ReadTemp(void)
	{
	int32_t temp;

	//ask for temp
	i2cMasterWriteRegister(&Pressure_I2C.i2cInfo, 0xF4, 0x2E);

	delay_ms(7);	// max time is 4.5ms
	
	//receive temp, UT = MSB<<8 + LSB;
	temp = (BMP085_Read(0xF6) << 8) + BMP085_Read(0xF7);
	
	return temp;
	}

int32_t BMP085_ReadPres(void)
	{
	int32_t pres;

	//ask for pres
	i2cMasterWriteRegister(&Pressure_I2C.i2cInfo, 0xF4, (0x34 + (OSS<<6)));

	delay_ms(26);	// max time is 26ms for OSS 3
	
	//receive pres, UP = (MSB<<16 + LSB<<8 + XLSB) >> (8-oss)
	pres = ( (BMP085_Read(0xF6) <<16) + (BMP085_Read(0xF7)<<8) + BMP085_Read(0xF8) ) >> (8-OSS);
	
	//rprintf("\n%ld, %ld, %ld",(BMP085_Read(0xF6)<<16),(BMP085_Read(0xF7)<<8),(BMP085_Read(0xF8)));
	//pres &= 0x0000FFFF;

	return pres;
	}

void BMP085_Convert(void)
	{
	int32_t ut;
	int32_t up;
	int32_t x1, x2, b5, b6, x3, b3, p;
	uint32_t b4, b7;
	
	ut = BMP085_ReadTemp();
	up = BMP085_ReadPres();//washington dc should be 101.33kpa
	rprintf("\nut=%ld",ut);
	rprintf("\nup=%ld",up);
	
	//TEST - force values to match datasheet example
	/*ut = 27898;
	up = 23843;
	ac1 = 408;
	ac2 = -72;
	ac3 = -14383;
	ac4 = 32741;
	ac5 = 32757;
	ac6 = 23153;
	b1 = 6190;
	b2 = 4;
	mb = -32768;
	mc = -8711;
	md = 2868;*/
	
	//calculate true temperature
	x1 = ( ut - ac6) * ac5 >> 15;
	x2 = ( mc << 11) / (x1 + md);
	b5 = x1 + x2;
	temperature = (b5 + 8) >> 4;
	
	//calculate true pressure
	b6 = b5 - 4000;
//	rprintf("\nb6 %ld",b6);
	x1 = (b2 * (b6 * b6 >> 12)) >> 11;
//	rprintf("\nx1 %ld",x1);
	x2 = ac2 * b6 >> 11;
//	rprintf("\nx2 %ld",x2);
	x3 = x1 + x2;
//	rprintf("\nx3 %ld",x3);
	b3 = (( (ac1 * 4 + x3) << OSS ) + 2)/4;
//	rprintf("\nb3 %ld",b3);
	x1 = ac3 * b6 >> 13;
//	rprintf("\nx1 %ld",x1);
	x2 = (b1 * (b6 * b6 >> 12)) >> 16;
//	rprintf("\nx2 %ld",x2);
	x3 = ((x1 + x2) + 2) >> 2;
//	rprintf("\nx3 %ld",x3);
	b4 = ac4 * (uint32_t)(x3 + 32768) >> 15;
//	rprintf("\nb4 %lu",b4);
	b7 = ( (uint32_t)up - b3) * (50000 >> OSS);
//	rprintf("\nb7 %lu",b7);
	p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
//	rprintf("\np %ld",p);
	x1 = (p >> 8) * (p >> 8);
//	rprintf("\nx1 %ld",x1);
	x1 = (x1 * 3038) >> 16;
//	rprintf("\nx1 %ld",x1);
	x2 = (-7357 * p) >> 16;
//	rprintf("\nx2 %ld",x2);
	pressure = p + ((x1 + x2 + 3791) >> 4);

	//convert to altitude
	altitude = 44330.75*(1-pow((double)pressure/101325, 0.19029));
	}
