mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-04 13:55:40 +08:00
[peripherals] add bmp085 peripheral
and use it on the lisa_m baro_board
This commit is contained in:
@@ -181,6 +181,7 @@ LISA_M_BARO ?= BARO_BOARD_BMP085
|
||||
ap.srcs += peripherals/ms5611_i2c.c
|
||||
ap.srcs += subsystems/sensors/baro_ms5611_i2c.c
|
||||
else ifeq ($(LISA_M_BARO), BARO_BOARD_BMP085)
|
||||
ap.srcs += peripherals/bmp085.c
|
||||
ap.srcs += $(SRC_BOARD)/baro_board.c
|
||||
ap.CFLAGS += -DUSE_I2C2
|
||||
endif
|
||||
|
||||
@@ -1,193 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/** @file boards/lisa_m/baro_board.c
|
||||
* Baro board interface for Bosch BMP085 on LisaM I2C2 with EOC check.
|
||||
*/
|
||||
|
||||
#include "subsystems/sensors/baro.h"
|
||||
#include <libopencm3/stm32/f1/gpio.h>
|
||||
#include "peripherals/bmp085_regs.h"
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
|
||||
#include "led.h"
|
||||
|
||||
struct Baro baro;
|
||||
struct BaroBoard baro_board;
|
||||
struct i2c_transaction baro_trans;
|
||||
struct bmp085_baro_calibration calibration;
|
||||
struct Bmp085 baro_bmp085;
|
||||
|
||||
#define BMP085_SAMPLE_PERIOD_MS (3 + (2 << BMP085_OSS) * 3)
|
||||
#define BMP085_SAMPLE_PERIOD (BMP075_SAMPLE_PERIOD_MS >> 1)
|
||||
|
||||
// FIXME: BARO DRDY connected to PB0 for lisa/m
|
||||
|
||||
static inline void bmp085_write_reg(uint8_t addr, uint8_t value)
|
||||
static bool_t baro_eoc(void)
|
||||
{
|
||||
baro_trans.buf[0] = addr;
|
||||
baro_trans.buf[1] = value;
|
||||
|
||||
i2c_transmit(&i2c2, &baro_trans, BMP085_ADDR, 2);
|
||||
|
||||
// FIXME, no while loops without timeout!!
|
||||
while (baro_trans.status == I2CTransPending || baro_trans.status == I2CTransRunning);
|
||||
}
|
||||
|
||||
static inline void bmp085_read_reg16(uint8_t addr)
|
||||
{
|
||||
baro_trans.buf[0] = addr;
|
||||
i2c_transceive(&i2c2, &baro_trans, BMP085_ADDR, 1, 2);
|
||||
}
|
||||
|
||||
static inline int16_t bmp085_read_reg16_blocking(uint8_t addr, uint32_t timeout)
|
||||
{
|
||||
uint32_t time = 0;
|
||||
|
||||
bmp085_read_reg16(addr);
|
||||
|
||||
while (baro_trans.status == I2CTransPending || baro_trans.status == I2CTransRunning) {
|
||||
if ((time == timeout) && (timeout != 0)) {
|
||||
return 0; /* Timeout of the i2c read */
|
||||
} else {
|
||||
time++;
|
||||
}
|
||||
}
|
||||
|
||||
return ((baro_trans.buf[0] << 8) | baro_trans.buf[1]);
|
||||
}
|
||||
|
||||
static inline void bmp085_read_reg24(uint8_t addr)
|
||||
{
|
||||
baro_trans.buf[0] = addr;
|
||||
i2c_transceive(&i2c2, &baro_trans, BMP085_ADDR, 1, 3);
|
||||
}
|
||||
|
||||
static void bmp085_baro_read_calibration(void)
|
||||
{
|
||||
calibration.ac1 = bmp085_read_reg16_blocking(0xAA, 10000); // AC1
|
||||
calibration.ac2 = bmp085_read_reg16_blocking(0xAC, 10000); // AC2
|
||||
calibration.ac3 = bmp085_read_reg16_blocking(0xAE, 10000); // AC3
|
||||
calibration.ac4 = bmp085_read_reg16_blocking(0xB0, 10000); // AC4
|
||||
calibration.ac5 = bmp085_read_reg16_blocking(0xB2, 10000); // AC5
|
||||
calibration.ac6 = bmp085_read_reg16_blocking(0xB4, 10000); // AC6
|
||||
calibration.b1 = bmp085_read_reg16_blocking(0xB6, 10000); // B1
|
||||
calibration.b2 = bmp085_read_reg16_blocking(0xB8, 10000); // B2
|
||||
calibration.mb = bmp085_read_reg16_blocking(0xBA, 10000); // MB
|
||||
calibration.mc = bmp085_read_reg16_blocking(0xBC, 10000); // MC
|
||||
calibration.md = bmp085_read_reg16_blocking(0xBE, 10000); // MD
|
||||
return gpio_get(GPIOB, GPIO0);
|
||||
}
|
||||
|
||||
void baro_init(void) {
|
||||
baro.status = BS_UNINITIALIZED;
|
||||
baro.absolute = 0;
|
||||
baro.differential = 0;
|
||||
baro_board.status = LBS_UNINITIALIZED;
|
||||
bmp085_baro_read_calibration();
|
||||
|
||||
/* STM32 specific (maybe this is a LISA/M specific driver anyway?) */
|
||||
bmp085_init(&baro_bmp085, &i2c2, BMP085_SLAVE_ADDR);
|
||||
|
||||
/* setup eoc check function */
|
||||
baro_bmp085.eoc = &baro_eoc;
|
||||
|
||||
gpio_clear(GPIOB, GPIO0);
|
||||
gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
|
||||
GPIO_CNF_INPUT_PULL_UPDOWN, GPIO0);
|
||||
}
|
||||
|
||||
static inline int baro_eoc(void)
|
||||
{
|
||||
return gpio_get(GPIOB, GPIO0);
|
||||
}
|
||||
|
||||
static inline void bmp085_request_pressure(void)
|
||||
{
|
||||
bmp085_write_reg(0xF4, 0x34 + (BMP085_OSS << 6));
|
||||
}
|
||||
|
||||
static inline void bmp085_request_temp(void)
|
||||
{
|
||||
bmp085_write_reg(0xF4, 0x2E);
|
||||
}
|
||||
|
||||
static inline void bmp085_read_pressure(void)
|
||||
{
|
||||
bmp085_read_reg24(0xF6);
|
||||
}
|
||||
|
||||
static inline void bmp085_read_temp(void)
|
||||
{
|
||||
bmp085_read_reg16(0xF6);
|
||||
}
|
||||
|
||||
void baro_periodic(void) {
|
||||
// check that nothing is in progress
|
||||
if (baro_trans.status == I2CTransPending) return;
|
||||
if (baro_trans.status == I2CTransRunning) return;
|
||||
if (!i2c_idle(&i2c2)) return;
|
||||
|
||||
switch (baro_board.status) {
|
||||
case LBS_UNINITIALIZED:
|
||||
baro_board_send_reset();
|
||||
baro_board.status = LBS_REQUEST;
|
||||
if (baro_bmp085.initialized) {
|
||||
baro.status = BS_RUNNING;
|
||||
break;
|
||||
case LBS_REQUEST:
|
||||
bmp085_request_pressure();
|
||||
baro_board.status = LBS_READ;
|
||||
break;
|
||||
case LBS_READ:
|
||||
if (baro_eoc()) {
|
||||
bmp085_read_pressure();
|
||||
baro_board.status = LBS_READING;
|
||||
bmp085_periodic(&baro_bmp085);
|
||||
}
|
||||
break;
|
||||
case LBS_REQUEST_TEMP:
|
||||
bmp085_request_temp();
|
||||
baro_board.status = LBS_READ_TEMP;
|
||||
break;
|
||||
case LBS_READ_TEMP:
|
||||
if (baro_eoc()) {
|
||||
bmp085_read_temp();
|
||||
baro_board.status = LBS_READING_TEMP;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else
|
||||
bmp085_read_eeprom_calib(&baro_bmp085);
|
||||
}
|
||||
|
||||
void baro_board_send_reset(void) {
|
||||
// This is a NOP at the moment
|
||||
}
|
||||
|
||||
// Apply temp calibration and sensor calibration to raw measurement to get Pa (from BMP085 datasheet)
|
||||
static int32_t baro_apply_calibration(int32_t raw)
|
||||
{
|
||||
int32_t b6 = calibration.b5 - 4000;
|
||||
int x1 = (calibration.b2 * (b6 * b6 >> 12)) >> 11;
|
||||
int x2 = calibration.ac2 * b6 >> 11;
|
||||
int32_t x3 = x1 + x2;
|
||||
int32_t b3 = (((calibration.ac1 * 4 + x3) << BMP085_OSS) + 2)/4;
|
||||
x1 = calibration.ac3 * b6 >> 13;
|
||||
x2 = (calibration.b1 * (b6 * b6 >> 12)) >> 16;
|
||||
x3 = ((x1 + x2) + 2) >> 2;
|
||||
uint32_t b4 = (calibration.ac4 * (uint32_t) (x3 + 32768)) >> 15;
|
||||
uint32_t b7 = (raw - b3) * (50000 >> BMP085_OSS);
|
||||
int32_t p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
|
||||
x1 = (p >> 8) * (p >> 8);
|
||||
x1 = (x1 * 3038) >> 16;
|
||||
x2 = (-7357 * p) >> 16;
|
||||
return p + ((x1 + x2 + 3791) >> 4);
|
||||
}
|
||||
|
||||
void baro_event(void (*b_abs_handler)(void))
|
||||
{
|
||||
if (baro_board.status == LBS_READING &&
|
||||
baro_trans.status != I2CTransPending && baro_trans.status != I2CTransRunning) {
|
||||
baro_board.status = LBS_REQUEST_TEMP;
|
||||
if (baro_trans.status == I2CTransSuccess) {
|
||||
int32_t tmp = (baro_trans.buf[0]<<16) | (baro_trans.buf[1] << 8) | baro_trans.buf[2];
|
||||
tmp = tmp >> (8 - BMP085_OSS);
|
||||
baro.absolute = baro_apply_calibration(tmp);
|
||||
bmp085_event(&baro_bmp085);
|
||||
|
||||
if (baro_bmp085.data_available) {
|
||||
baro.absolute = baro_bmp085.pressure;
|
||||
b_abs_handler();
|
||||
}
|
||||
}
|
||||
if (baro_board.status == LBS_READING_TEMP &&
|
||||
baro_trans.status != I2CTransPending && baro_trans.status != I2CTransRunning) {
|
||||
baro_board.status = LBS_REQUEST;
|
||||
if (baro_trans.status == I2CTransSuccess) {
|
||||
int32_t tmp = (baro_trans.buf[0] << 8) | baro_trans.buf[1];
|
||||
int32_t x1 = ((tmp - calibration.ac6) * calibration.ac5) >> 15;
|
||||
int32_t x2 = (calibration.mc << 11) / (x1 + calibration.md);
|
||||
calibration.b5 = x1 + x2;
|
||||
baro_board.temp = (calibration.b5 + 8) >> 4;
|
||||
}
|
||||
baro_bmp085.data_available = FALSE;
|
||||
|
||||
#ifdef ROTORCRAFT_BARO_LED
|
||||
RunOnceEvery(10,LED_TOGGLE(ROTORCRAFT_BARO_LED));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,52 +12,10 @@
|
||||
// for right now we abuse this file for the ms5611 baro on aspirin as well
|
||||
#if !BARO_MS5611_I2C && !BARO_MS5611
|
||||
|
||||
#include "mcu_periph/i2c.h"
|
||||
#include "peripherals/bmp085.h"
|
||||
|
||||
// absolute addr
|
||||
#define BMP085_ADDR 0xEE
|
||||
// Over sample setting (0-3)
|
||||
#define BMP085_OSS 3
|
||||
extern struct Bmp085 baro_bmp085;
|
||||
|
||||
enum LisaBaroStatus {
|
||||
LBS_UNINITIALIZED,
|
||||
LBS_REQUEST,
|
||||
LBS_READING,
|
||||
LBS_READ,
|
||||
LBS_REQUEST_TEMP,
|
||||
LBS_READING_TEMP,
|
||||
LBS_READ_TEMP,
|
||||
};
|
||||
|
||||
struct BaroBoard {
|
||||
enum LisaBaroStatus status;
|
||||
int32_t temp; ///< temperature in 0.1C
|
||||
};
|
||||
|
||||
struct bmp085_baro_calibration {
|
||||
// These values come from EEPROM on sensor
|
||||
int16_t ac1;
|
||||
int16_t ac2;
|
||||
int16_t ac3;
|
||||
uint16_t ac4;
|
||||
uint16_t ac5;
|
||||
uint16_t ac6;
|
||||
int16_t b1;
|
||||
int16_t b2;
|
||||
int16_t mb;
|
||||
int16_t mc;
|
||||
int16_t md;
|
||||
|
||||
// These values are calculated
|
||||
int32_t b5;
|
||||
};
|
||||
|
||||
extern struct BaroBoard baro_board;
|
||||
extern struct i2c_transaction baro_trans;
|
||||
extern struct bmp085_baro_calibration calibration;
|
||||
|
||||
extern void baro_board_send_reset(void);
|
||||
extern void baro_board_send_config(void);
|
||||
|
||||
#endif // !BARO_MS5611_xx
|
||||
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Martin Mueller
|
||||
* Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/** @file peripherals/bmp085.c
|
||||
* Bosch BMP085 driver interface.
|
||||
*/
|
||||
|
||||
#include "peripherals/bmp085.h"
|
||||
#include "peripherals/bmp085_regs.h"
|
||||
|
||||
|
||||
static int32_t bmp085_compensated_temperature(struct Bmp085Calib* calib, int32_t raw)
|
||||
{
|
||||
int32_t x1 = (raw - calib->ac6) * calib->ac5 / (1<<15);
|
||||
int32_t x2 = (calib->mc << 11) / (x1 + calib->md);
|
||||
calib->b5 = x1 + x2;
|
||||
return (calib->b5 + 8) >> 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Apply temp calibration and sensor calibration to raw measurement to get Pa
|
||||
* (from BMP085 datasheet)
|
||||
*/
|
||||
static int32_t bmp085_compensated_pressure(struct Bmp085Calib* calib, int32_t raw)
|
||||
{
|
||||
int32_t b6 = calib->b5 - 4000;
|
||||
int32_t x1 = (calib->b2 * (b6 * b6 >> 12)) >> 11;
|
||||
int32_t x2 = calib->ac2 * b6 >> 11;
|
||||
int32_t x3 = x1 + x2;
|
||||
int32_t b3 = (((calib->ac1 * 4 + x3) << BMP085_OSS) + 2)/4;
|
||||
x1 = calib->ac3 * b6 >> 13;
|
||||
x2 = (calib->b1 * (b6 * b6 >> 12)) >> 16;
|
||||
x3 = ((x1 + x2) + 2) >> 2;
|
||||
uint32_t b4 = (calib->ac4 * (uint32_t) (x3 + 32768)) >> 15;
|
||||
uint32_t b7 = (raw - b3) * (50000 >> BMP085_OSS);
|
||||
int32_t p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
|
||||
x1 = (p >> 8) * (p >> 8);
|
||||
x1 = (x1 * 3038) >> 16;
|
||||
x2 = (-7357 * p) >> 16;
|
||||
return p + ((x1 + x2 + 3791) >> 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function to always return TRUE on EndOfConversion check.
|
||||
* Ensure proper timing trough frequency of bmp085_periodic instead!
|
||||
*/
|
||||
static bool_t bmp085_eoc_true(void)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void bmp085_read_eeprom_calib(struct Bmp085* bmp)
|
||||
{
|
||||
if (bmp->status == BMP085_STATUS_UNINIT) {
|
||||
bmp->initialized = FALSE;
|
||||
bmp->i2c_trans.buf[0] = BMP085_EEPROM_AC1;
|
||||
i2c_transceive(bmp->i2c_p, &(bmp->i2c_trans), bmp->i2c_trans.slave_addr, 1, 22);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bmp085_init(struct Bmp085* bmp, struct i2c_periph *i2c_p, uint8_t addr)
|
||||
{
|
||||
/* set i2c_peripheral */
|
||||
bmp->i2c_p = i2c_p;
|
||||
|
||||
/* slave address */
|
||||
bmp->i2c_trans.slave_addr = addr;
|
||||
/* set initial status: Success or Done */
|
||||
bmp->i2c_trans.status = I2CTransDone;
|
||||
|
||||
bmp->data_available = FALSE;
|
||||
bmp->initialized = FALSE;
|
||||
bmp->status = BMP085_STATUS_UNINIT;
|
||||
|
||||
/* by default assign EOC function that always returns TRUE
|
||||
* ensure proper timing through frequeny of bmp_periodic!
|
||||
*/
|
||||
bmp->eoc = &bmp085_eoc_true;
|
||||
}
|
||||
|
||||
void bmp085_periodic(struct Bmp085* bmp)
|
||||
{
|
||||
switch (bmp->status) {
|
||||
case BMP085_STATUS_IDLE:
|
||||
/* start temp measurement */
|
||||
bmp->i2c_trans.buf[0] = BMP085_CTRL_REG;
|
||||
bmp->i2c_trans.buf[1] = BMP085_START_TEMP;
|
||||
i2c_transmit(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 2);
|
||||
bmp->status = BMP085_STATUS_START_TEMP;
|
||||
break;
|
||||
|
||||
case BMP085_STATUS_START_TEMP:
|
||||
/* read temp measurement */
|
||||
if (bmp->eoc()) {
|
||||
bmp->i2c_trans.buf[0] = BMP085_DAT_MSB;
|
||||
i2c_transceive(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 1, 2);
|
||||
bmp->status = BMP085_STATUS_READ_TEMP;
|
||||
}
|
||||
break;
|
||||
|
||||
case BMP085_STATUS_START_PRESS:
|
||||
/* read press measurement */
|
||||
if (bmp->eoc()) {
|
||||
bmp->i2c_trans.buf[0] = BMP085_DAT_MSB;
|
||||
i2c_transceive(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 1, 3);
|
||||
bmp->status = BMP085_STATUS_READ_PRESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bmp085_event(struct Bmp085* bmp)
|
||||
{
|
||||
if (bmp->i2c_trans.status == I2CTransSuccess) {
|
||||
switch (bmp->status) {
|
||||
case BMP085_STATUS_UNINIT:
|
||||
bmp->calib.ac1 = (bmp->i2c_trans.buf[0] << 8) | bmp->i2c_trans.buf[1];
|
||||
bmp->calib.ac2 = (bmp->i2c_trans.buf[2] << 8) | bmp->i2c_trans.buf[3];
|
||||
bmp->calib.ac3 = (bmp->i2c_trans.buf[4] << 8) | bmp->i2c_trans.buf[5];
|
||||
bmp->calib.ac4 = (bmp->i2c_trans.buf[6] << 8) | bmp->i2c_trans.buf[7];
|
||||
bmp->calib.ac5 = (bmp->i2c_trans.buf[8] << 8) | bmp->i2c_trans.buf[9];
|
||||
bmp->calib.ac6 = (bmp->i2c_trans.buf[10] << 8) | bmp->i2c_trans.buf[11];
|
||||
bmp->calib.b1 = (bmp->i2c_trans.buf[12] << 8) | bmp->i2c_trans.buf[13];
|
||||
bmp->calib.b2 = (bmp->i2c_trans.buf[14] << 8) | bmp->i2c_trans.buf[15];
|
||||
bmp->calib.mb = (bmp->i2c_trans.buf[16] << 8) | bmp->i2c_trans.buf[17];
|
||||
bmp->calib.mc = (bmp->i2c_trans.buf[18] << 8) | bmp->i2c_trans.buf[19];
|
||||
bmp->calib.md = (bmp->i2c_trans.buf[20] << 8) | bmp->i2c_trans.buf[21];
|
||||
bmp->status = BMP085_STATUS_IDLE;
|
||||
bmp->initialized = TRUE;
|
||||
break;
|
||||
|
||||
case BMP085_STATUS_READ_TEMP:
|
||||
/* get uncompensated temperature */
|
||||
bmp->ut = (bmp->i2c_trans.buf[0] << 8) | bmp->i2c_trans.buf[1];
|
||||
bmp->temperature = bmp085_compensated_temperature(&(bmp->calib), bmp->ut);
|
||||
/* start high res pressure measurement */
|
||||
bmp->i2c_trans.buf[0] = BMP085_CTRL_REG;
|
||||
bmp->i2c_trans.buf[1] = BMP085_START_P3;
|
||||
i2c_transmit(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 2);
|
||||
bmp->status = BMP085_STATUS_START_PRESS;
|
||||
break;
|
||||
|
||||
case BMP085_STATUS_READ_PRESS:
|
||||
/* get uncompensated pressure */
|
||||
bmp->up = (bmp->i2c_trans.buf[0]<<16) |
|
||||
(bmp->i2c_trans.buf[1] << 8) |
|
||||
bmp->i2c_trans.buf[2];
|
||||
bmp->up = bmp->up >> (8 - BMP085_OSS);
|
||||
bmp->pressure = bmp085_compensated_pressure(&(bmp->calib), bmp->up);
|
||||
bmp->data_available = TRUE;
|
||||
bmp->status = BMP085_STATUS_IDLE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (bmp->i2c_trans.status == I2CTransFailed) {
|
||||
/* try again */
|
||||
if (bmp->initialized)
|
||||
bmp->status = BMP085_STATUS_IDLE;
|
||||
else
|
||||
bmp->status = BMP085_STATUS_UNINIT;
|
||||
bmp->i2c_trans.status = I2CTransDone;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Martin Mueller
|
||||
* Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/** @file peripherals/bmp085.h
|
||||
* Bosch BMP085 driver interface.
|
||||
*/
|
||||
|
||||
#ifndef BMP085_H
|
||||
#define BMP085_H
|
||||
|
||||
#include "mcu_periph/i2c.h"
|
||||
#include "std.h"
|
||||
|
||||
enum Bmp085Status {
|
||||
BMP085_STATUS_UNINIT,
|
||||
BMP085_STATUS_IDLE,
|
||||
BMP085_STATUS_START_TEMP,
|
||||
BMP085_STATUS_READ_TEMP,
|
||||
BMP085_STATUS_START_PRESS,
|
||||
BMP085_STATUS_READ_PRESS
|
||||
};
|
||||
|
||||
struct Bmp085Calib {
|
||||
// These values come from EEPROM on sensor
|
||||
int16_t ac1;
|
||||
int16_t ac2;
|
||||
int16_t ac3;
|
||||
uint16_t ac4;
|
||||
uint16_t ac5;
|
||||
uint16_t ac6;
|
||||
int16_t b1;
|
||||
int16_t b2;
|
||||
int16_t mb;
|
||||
int16_t mc;
|
||||
int16_t md;
|
||||
|
||||
// These values are calculated
|
||||
int32_t b5;
|
||||
};
|
||||
|
||||
typedef bool_t (*Bmp085EOC)(void);
|
||||
|
||||
struct Bmp085 {
|
||||
struct i2c_periph *i2c_p;
|
||||
struct i2c_transaction i2c_trans;
|
||||
Bmp085EOC eoc; ///< function to check End Of Conversion
|
||||
enum Bmp085Status status; ///< state machine status
|
||||
bool_t initialized; ///< config done flag
|
||||
volatile bool_t data_available; ///< data ready flag
|
||||
struct Bmp085Calib calib;
|
||||
int32_t ut; ///< uncompensated temperature
|
||||
int32_t up; ///< uncompensated pressure
|
||||
int32_t temperature; ///< temperature in 0.1 deg Celcius
|
||||
int32_t pressure; ///< pressure in Pascal
|
||||
};
|
||||
|
||||
extern void bmp085_read_eeprom_calib(struct Bmp085* bmp);
|
||||
extern void bmp085_init(struct Bmp085* bmp, struct i2c_periph *i2c_p, uint8_t addr);
|
||||
extern void bmp085_periodic(struct Bmp085* bmp);
|
||||
extern void bmp085_event(struct Bmp085* bmp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Martin Mueller
|
||||
* Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/** @file peripherals/bmp085_regs.h
|
||||
* Bosch BMP085 register definitions.
|
||||
*/
|
||||
|
||||
#ifndef BMP085_REGS_H
|
||||
#define BMP085_REGS_H
|
||||
|
||||
#define BMP085_EEPROM_AC1 0xAA
|
||||
#define BMP085_EEPROM_AC2 0xAC
|
||||
#define BMP085_EEPROM_AC3 0xAE
|
||||
#define BMP085_EEPROM_AC4 0xB0
|
||||
#define BMP085_EEPROM_AC5 0xB2
|
||||
#define BMP085_EEPROM_AC6 0xB4
|
||||
#define BMP085_EEPROM_B1 0xB6
|
||||
#define BMP085_EEPROM_B2 0xB8
|
||||
#define BMP085_EEPROM_MB 0xBA
|
||||
#define BMP085_EEPROM_MC 0xBC
|
||||
#define BMP085_EEPROM_MD 0xBE
|
||||
|
||||
#define BMP085_CTRL_REG 0xF4
|
||||
|
||||
#define BMP085_START_TEMP 0x2E
|
||||
#define BMP085_START_P0 0x34
|
||||
#define BMP085_START_P1 0x74
|
||||
#define BMP085_START_P2 0xB4
|
||||
#define BMP085_START_P3 0xF4
|
||||
|
||||
#define BMP085_DAT_MSB 0xF6
|
||||
#define BMP085_DAT_LSB 0xF7
|
||||
#define BMP085_DAT_XLSB 0xF8
|
||||
|
||||
/// Over sample setting (0-3)
|
||||
#define BMP085_OSS 3
|
||||
|
||||
#define BMP085_SLAVE_ADDR 0xEE
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user