From b6cc2df29d2f5ac2ce27ab38d8533b58727f186a Mon Sep 17 00:00:00 2001 From: gussy Date: Thu, 10 Dec 2009 04:28:21 +0000 Subject: [PATCH] Finished off initial revision of BMP085 drivers. Added math.h to pios.h includes. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@62 ebee16cc-31ac-478f-84a7-5cbb03baadba --- flight/PiOS/Common/pios_bmp085.c | 102 ++++++++++++++++++++++++++++--- flight/PiOS/inc/pios_bmp085.h | 10 ++- flight/PiOS/pios.h | 1 + 3 files changed, 102 insertions(+), 11 deletions(-) diff --git a/flight/PiOS/Common/pios_bmp085.c b/flight/PiOS/Common/pios_bmp085.c index 5d4565f28..c6bef27f9 100644 --- a/flight/PiOS/Common/pios_bmp085.c +++ b/flight/PiOS/Common/pios_bmp085.c @@ -5,7 +5,7 @@ * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009. * @brief IRQ Enable/Disable routines * @see The GNU Public License (GPL) Version 3 - * @defgroup PIOS_BMP085 Bosch BMP085 Barometric Pressure Sensor Functions + * @defgroup PIOS_BMP085 BMP085 Functions * @{ * *****************************************************************************/ @@ -29,9 +29,14 @@ /* Project Includes */ #include "pios.h" +/* Glocal Variables */ +ConversionTypeTypeDef CurrentRead; /* Local Variables */ static BMP085CalibDataTypeDef CalibData; +static uint16_t RawPressure; +static uint16_t RawTemperature; + /** * Initialise the BMP085 sensor @@ -52,15 +57,84 @@ void PIOS_BMP085_Init(void) PIOS_BMP085_Read(BMP085_CALIB_ADDR + 20, (uint8_t *) &CalibData.MD, 2); } + /** * Start the ADC conversion * \param[in] PresOrTemp BMP085_PRES_ADDR or BMP085_TEMP_ADDR * \return Raw ADC value */ -void PIOS_BMP085_StartADC(uint16_t *PresOrTemp) +void PIOS_BMP085_StartADC(ConversionTypeTypeDef Type) { /* Start the conversion */ - PIOS_BMP085_Write(BMP085_CTRL_ADDR, (uint8_t *)PresOrTemp, 2); + if(Type == Temperature) { + PIOS_BMP085_Write(BMP085_CTRL_ADDR, (uint8_t *)BMP085_TEMP_ADDR, 2); + } else if(Type == Pressure) { + PIOS_BMP085_Write(BMP085_CTRL_ADDR, (uint8_t *)BMP085_PRES_ADDR, 2); + } + + CurrentRead = Type; +} + + +/** +* Read the ADC conversion value (once ADC converion has completed) +* \param[in] PresOrTemp BMP085_PRES_ADDR or BMP085_TEMP_ADDR +* \return Raw ADC value +*/ +void PIOS_BMP085_ReadADC(void) +{ + uint8_t LSB, MSB; + + /* Read the conversion */ + PIOS_BMP085_Read(BMP085_TEMP_ADDR, &LSB, 2); + PIOS_BMP085_Read(BMP085_TEMP_ADDR, &MSB, 2); + + /* Store the 16bit result */ + if(CurrentRead == Temperature) { + RawTemperature = ((MSB << 8) + LSB); + } else { + RawPressure = ((MSB << 8) + LSB); + } +} + + +/** +* Get the converted raw values +* \param[out] Pressure Pointer to the pressure variable +* \param[out] Altitude Pointer to the altitude variable +* \param[out] Temperature Pointer to the temperature variable +*/ +void PIOS_BMP085_GetValues(uint16_t *Pressure, uint16_t *Altitude, uint16_t *Temperature) +{ + /* Straight from the datasheet */ + int32_t X1, X2, X3, B3, B5, B6, P; + uint32_t B4, B7; + + /* Convert Temperatre */ + X1 = (RawTemperature - CalibData.AC6) * CalibData.AC5 >> 15; + X2 = ((int32_t) CalibData.MC << 11) / (X1 + CalibData.MD); + B5 = X1 + X2; + *Temperature = (B5 + 8) >> 4; + + /* Calculate Pressure */ + B6 = B5 - 4000; + X1 = (CalibData.B2 * (B6 * B6 >> 12)) >> 11; + X2 = CalibData.AC2 * B6 >> 11; + X3 = X1 + X2; + B3 = ((int32_t) CalibData.AC1 * 4 + X3 + 2) >> 2; + X1 = CalibData.AC3 * B6 >> 13; + X2 = (CalibData.B1 * (B6 * B6 >> 12)) >> 16; + X3 = ((X1 + X2) + 2) >> 2; + B4 = (CalibData.AC4 * (uint32_t) (X3 + 32768)) >> 15; + B7 = ((uint32_t) RawPressure - B3) * 50000; + P = B7 < 0x80000000 ? (B7 * 2) / B4 : (B7 / B4) * 2; + X1 = (P >> 8) * (P >> 8); + X1 = (X1 * 3038) >> 16; + X2 = (-7357 * P) >> 16; + *Pressure = P + ((X1 + X2 + 3791) >> 4); + + /* Calculate Altitude */ + *Altitude = (uint16_t) 44330 * (1 - (pow((*Pressure/BMP085_P0), (1/5.255)))); } /** @@ -142,10 +216,18 @@ int32_t PIOS_BMP085_Write(uint16_t address, uint8_t *buffer, uint8_t len) return error < 0 ? -1 : 0; } - -/* Read the values from the sensor -* \param[out] Pressure Pointer to the pressure variable -* \param[out] Altitude Pointer to the altitude variable -* \param[out] Temperature Pointer to the temperature variable - -void PIOS_BMP085_ReadADC(uint16_t *Pressure, uint16_t *Altitude, uint16_t *Temperature)*/ \ No newline at end of file +/* +Example of how to use this module: + PIOS_BMP085_Init(); + + (We could possibly use an interrupt on EOC to read the ADC and start a new conversion?) + PIOS_BMP085_StartADC(Temperature); + (Once conversion is done) + PIOS_BMP085_ReadADC(); + + PIOS_BMP085_StartADC(Pressure); + (Once conversion is done) + PIOS_BMP085_ReadADC(); + + PIOS_BMP085_GetValues(&Pressure, &Altitude, &Temperature); +*/ \ No newline at end of file diff --git a/flight/PiOS/inc/pios_bmp085.h b/flight/PiOS/inc/pios_bmp085.h index fe45fb29d..46991283a 100644 --- a/flight/PiOS/inc/pios_bmp085.h +++ b/flight/PiOS/inc/pios_bmp085.h @@ -36,6 +36,7 @@ #define BMP085_TEMP_ADDR 0x2E #define BMP085_ADC_MSB 0xF6 #define BMP085_ADC_LSB 0xF7 +#define BMP085_P0 101325 /* Local Types */ typedef struct { @@ -52,9 +53,16 @@ typedef struct { uint16_t MD; } BMP085CalibDataTypeDef; +typedef enum { + Pressure, + Temperature +} ConversionTypeTypeDef; + /* Public Functions */ void PIOS_BMP085_Init(void); -void PIOS_BMP085_StartADC(uint16_t *PresOrTemp); +void PIOS_BMP085_StartADC(ConversionTypeTypeDef Type); +void PIOS_BMP085_ReadADC(void); +void PIOS_BMP085_GetValues(uint16_t *Pressure, uint16_t *Altitude, uint16_t *Temperature); int32_t PIOS_BMP085_Read(u16 address, uint8_t *buffer, uint8_t len); int32_t PIOS_BMP085_Write(uint16_t address, uint8_t *buffer, uint8_t len); diff --git a/flight/PiOS/pios.h b/flight/PiOS/pios.h index 8f591d6c6..a0ba4dd4c 100644 --- a/flight/PiOS/pios.h +++ b/flight/PiOS/pios.h @@ -37,6 +37,7 @@ #include #include #include +#include /* STM32 Std Perf Lib */ #include