Skip to content

Commit

Permalink
Merge pull request #2203 from mlyle/mpl-BuMP
Browse files Browse the repository at this point in the history
revolution: support i2c BMP280 baros on clones
  • Loading branch information
tracernz authored Apr 4, 2019
2 parents c5f1441 + a3f59e4 commit 3b6e3ca
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 94 deletions.
223 changes: 137 additions & 86 deletions flight/PiOS/Common/pios_bmp280.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,6 @@ static int32_t PIOS_BMP280_Common_Init(const struct pios_bmp280_cfg *cfg)
dev->cfg = cfg;

uint8_t data[24];
uint16_t ref_digT1;
if (PIOS_BMP280_Read(BMP280_CAL_ADDR, data, 2) != 0)
return -2;

/* Ignore first result */
if (PIOS_BMP280_Read(BMP280_CAL_ADDR, data, 2) != 0)
return -2;

ref_digT1 = (data[ 1] << 8) | data[ 0];

if (PIOS_BMP280_Read(BMP280_CAL_ADDR, data, 24) != 0)
return -2;
Expand All @@ -180,13 +171,8 @@ static int32_t PIOS_BMP280_Common_Init(const struct pios_bmp280_cfg *cfg)
dev->digP8 = (data[21] << 8) | data[20];
dev->digP9 = (data[23] << 8) | data[22];

if (ref_digT1 != dev->digT1) {
/* Values inconsistent, so no good device detect */
return -10;
}

if ((ref_digT1 == dev->digT2) &&
(ref_digT1 == dev->digP1)) {
if ((dev->digT1 == dev->digT2) &&
(dev->digT1 == dev->digP1)) {
/* Values invariant, so no good device detect */
return -11;
}
Expand All @@ -199,37 +185,6 @@ static int32_t PIOS_BMP280_Common_Init(const struct pios_bmp280_cfg *cfg)
return 0;
}

/**
* Initialise the BMP280 sensor
*/
#ifndef PIOS_EXCLUDE_BMP280_I2C
int32_t PIOS_BMP280_Init(const struct pios_bmp280_cfg *cfg, pios_i2c_t i2c_device)
{
dev = (struct bmp280_dev *) PIOS_BMP280_alloc();
if (dev == NULL)
return -1;

dev->i2c_id = i2c_device;

return PIOS_BMP280_Common_Init(cfg);
}
#endif /* PIOS_EXCLUDE_BMP280_I2C */

#ifdef PIOS_INCLUDE_BMP280_SPI
int32_t PIOS_BMP280_SPI_Init(const struct pios_bmp280_cfg *cfg, pios_spi_t spi_device,
uint32_t spi_slave)
{
dev = (struct bmp280_dev *) PIOS_BMP280_alloc();
if (dev == NULL)
return -1;

dev->spi_id = spi_device;
dev->spi_slave = spi_slave;

return PIOS_BMP280_Common_Init(cfg);
}
#endif /* PIOS_INCLUDE_BMP280_SPI */

/**
* Claim the BMP280 device semaphore.
* \return 0 if no error
Expand Down Expand Up @@ -348,8 +303,31 @@ static int32_t PIOS_BMP280_ReadADC()
return 0;
}

static inline int32_t PIOS_BMP280_CheckData(const uint8_t *data,
const uint8_t *data_b)
{
int i;

/* Verify we got consistent results */
for (i = 0; i < 6; i++) {
if (data[i] != data_b[i]) {
return -3;
}
}

/* Verify the probed data varies */
for (i = 1; i < 6; i++) {
if (data[i] != data[0]) {
return 0;
}
}

return -4;
}

#ifndef PIOS_EXCLUDE_BMP280_I2C
static int32_t PIOS_BMP280_I2C_Read(uint8_t address, uint8_t *buffer, uint8_t len)
static int32_t PIOS_BMP280_I2C_Read(pios_i2c_t i2c_id,
uint8_t address, uint8_t *buffer, uint8_t len)
{
const struct pios_i2c_txn txn_list[] = {
{
Expand All @@ -358,81 +336,151 @@ static int32_t PIOS_BMP280_I2C_Read(uint8_t address, uint8_t *buffer, uint8_t le
.rw = PIOS_I2C_TXN_WRITE,
.len = 1,
.buf = &address,
}
,
},
{
.info = __func__,
.addr = BMP280_I2C_ADDR,
.rw = PIOS_I2C_TXN_READ,
.len = len,
.buf = buffer,
}
.info = __func__,
.addr = BMP280_I2C_ADDR,
.rw = PIOS_I2C_TXN_READ,
.len = len,
.buf = buffer,
}
};

return PIOS_I2C_Transfer(dev->i2c_id, txn_list, NELEMENTS(txn_list));
return PIOS_I2C_Transfer(i2c_id, txn_list, NELEMENTS(txn_list));
}

static int32_t PIOS_BMP280_I2C_Write(uint8_t *buffer, uint8_t len) {
static int32_t PIOS_BMP280_I2C_Write(pios_i2c_t i2c_id,
uint8_t *buffer, uint8_t len) {
const struct pios_i2c_txn txn_list[] = {
{
.info = __func__,
.addr = BMP280_I2C_ADDR,
.rw = PIOS_I2C_TXN_WRITE,
.len = len,
.buf = buffer,
}
,
.info = __func__,
.addr = BMP280_I2C_ADDR,
.rw = PIOS_I2C_TXN_WRITE,
.len = len,
.buf = buffer,
}
};

return PIOS_I2C_Transfer(dev->i2c_id, txn_list, NELEMENTS(txn_list));
return PIOS_I2C_Transfer(i2c_id, txn_list, NELEMENTS(txn_list));
}

/**
* Initialise the BMP280 sensor
*/
int32_t PIOS_BMP280_Init(const struct pios_bmp280_cfg *cfg, pios_i2c_t i2c_device)
{
uint8_t data[6];
uint8_t data_b[6];

/* Ignore first result */
if (PIOS_BMP280_I2C_Read(i2c_device, BMP280_CAL_ADDR, data, 6) != 0)
return -2;

if (PIOS_BMP280_I2C_Read(i2c_device, BMP280_CAL_ADDR, data, 6) != 0)
return -2;

if (PIOS_BMP280_I2C_Read(i2c_device, BMP280_CAL_ADDR, data_b, 6) != 0)
return -2;

int ret = PIOS_BMP280_CheckData(data, data_b);

if (ret) {
return ret;
}

dev = (struct bmp280_dev *) PIOS_BMP280_alloc();
if (dev == NULL)
return -1;

dev->i2c_id = i2c_device;

return PIOS_BMP280_Common_Init(cfg);
}
#endif /* PIOS_EXCLUDE_BMP280_I2C */

#ifdef PIOS_INCLUDE_BMP280_SPI
static int32_t PIOS_BMP280_ClaimBus(struct bmp280_dev *bmp_dev)
static int32_t PIOS_BMP280_ClaimBus(pios_spi_t spi_id, uint32_t spi_slave)
{
if (PIOS_SPI_ClaimBus(bmp_dev->spi_id) != 0)
if (PIOS_SPI_ClaimBus(spi_id) != 0)
return -2;

PIOS_DELAY_WaituS(1);
PIOS_SPI_RC_PinSet(bmp_dev->spi_id, bmp_dev->spi_slave, false);
PIOS_SPI_RC_PinSet(spi_id, spi_slave, false);
PIOS_DELAY_WaituS(1);

PIOS_SPI_SetClockSpeed(bmp_dev->spi_id, PIOS_BMP_SPI_SPEED);
PIOS_SPI_SetClockSpeed(spi_id, PIOS_BMP_SPI_SPEED);

return 0;
}

static void PIOS_BMP280_ReleaseBus(struct bmp280_dev *bmp_dev)
static void PIOS_BMP280_ReleaseBus(pios_spi_t spi_id, uint32_t spi_slave)
{
PIOS_SPI_RC_PinSet(bmp_dev->spi_id, bmp_dev->spi_slave, true);
PIOS_SPI_RC_PinSet(spi_id, spi_slave, true);

PIOS_SPI_ReleaseBus(bmp_dev->spi_id);
PIOS_SPI_ReleaseBus(spi_id);
}

static int32_t PIOS_BMP280_SPI_Read(uint8_t address, uint8_t *buffer, uint8_t len) {
if (PIOS_BMP280_ClaimBus(dev) != 0)
static int32_t PIOS_BMP280_SPI_Read(pios_spi_t spi_id, uint32_t spi_slave,
uint8_t address, uint8_t *buffer, uint8_t len) {
if (PIOS_BMP280_ClaimBus(spi_id, spi_slave) != 0)
return -1;

PIOS_SPI_TransferByte(dev->spi_id, 0x80 | address);
PIOS_SPI_TransferByte(spi_id, 0x80 | address);

int ret = PIOS_SPI_TransferBlock(dev->spi_id, NULL, buffer, len);
int ret = PIOS_SPI_TransferBlock(spi_id, NULL, buffer, len);

PIOS_BMP280_ReleaseBus(dev);
PIOS_BMP280_ReleaseBus(spi_id, spi_slave);

return ret;
}

static int32_t PIOS_BMP280_SPI_Write(uint8_t *buffer, uint8_t len) {
if (PIOS_BMP280_ClaimBus(dev) != 0)
static int32_t PIOS_BMP280_SPI_Write(pios_spi_t spi_id, uint32_t spi_slave,
uint8_t *buffer, uint8_t len) {
if (PIOS_BMP280_ClaimBus(spi_id, spi_slave) != 0)
return -1;

int ret = PIOS_SPI_TransferBlock(dev->spi_id, buffer, NULL, len);
int ret = PIOS_SPI_TransferBlock(spi_id, buffer, NULL, len);

PIOS_BMP280_ReleaseBus(dev);
PIOS_BMP280_ReleaseBus(spi_id, spi_slave);

return ret;
}

int32_t PIOS_BMP280_SPI_Init(const struct pios_bmp280_cfg *cfg, pios_spi_t spi_device,
uint32_t spi_slave)
{
uint8_t data[6];
uint8_t data_b[6];

/* Ignore first result */
if (PIOS_BMP280_SPI_Read(spi_device, spi_slave,
BMP280_CAL_ADDR, data, 6) != 0)
return -2;

if (PIOS_BMP280_SPI_Read(spi_device, spi_slave,
BMP280_CAL_ADDR, data, 6) != 0)
return -2;

if (PIOS_BMP280_SPI_Read(spi_device, spi_slave,
BMP280_CAL_ADDR, data_b, 6) != 0)
return -2;

int ret = PIOS_BMP280_CheckData(data, data_b);

if (ret) {
return ret;
}

dev = (struct bmp280_dev *) PIOS_BMP280_alloc();
if (dev == NULL)
return -1;

dev->spi_id = spi_device;
dev->spi_slave = spi_slave;

return PIOS_BMP280_Common_Init(cfg);
}

#endif /* PIOS_INCLUDE_BMP280_SPI */

/*
Expand All @@ -450,11 +498,12 @@ static int32_t PIOS_BMP280_Read(uint8_t address, uint8_t *buffer, uint8_t len)
if (0) {
#ifndef PIOS_EXCLUDE_BMP280_I2C
} else if (dev->i2c_id) {
return PIOS_BMP280_I2C_Read(address, buffer, len);
return PIOS_BMP280_I2C_Read(dev->i2c_id, address, buffer, len);
#endif
#ifdef PIOS_INCLUDE_BMP280_SPI
} else if (dev->spi_id) {
return PIOS_BMP280_SPI_Read(address, buffer, len);
return PIOS_BMP280_SPI_Read(dev->spi_id, dev->spi_slave,
address, buffer, len);
#endif
}

Expand All @@ -481,12 +530,14 @@ static int32_t PIOS_BMP280_WriteCommand(uint8_t address, uint8_t buffer)
if (0) {
#ifndef PIOS_EXCLUDE_BMP280_I2C
} else if (dev->i2c_id) {
return PIOS_BMP280_I2C_Write(data, sizeof(data));
return PIOS_BMP280_I2C_Write(dev->i2c_id,
data, sizeof(data));
#endif
#ifdef PIOS_INCLUDE_BMP280_SPI
} else if (dev->spi_id) {
data[0] &= 0x7f; /* Clear high bit */
return PIOS_BMP280_SPI_Write(data, sizeof(data));
return PIOS_BMP280_SPI_Write(dev->spi_id, dev->spi_slave,
data, sizeof(data));
#endif
}

Expand Down
7 changes: 7 additions & 0 deletions flight/PiOS/STM32/pios_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ int32_t PIOS_I2C_Init(pios_i2c_t *i2c_id, const struct pios_i2c_adapter_cfg *cfg
/* Initialize the state machine */
i2c_adapter_fsm_init(i2c_adapter);

if (PIOS_I2C_CheckClear(i2c_adapter)) {
/* Check for sanity before returning adapter and
* initing interrupts
*/
goto out_fail;
}

*i2c_id = i2c_adapter;

/* Configure and enable I2C interrupts */
Expand Down
23 changes: 15 additions & 8 deletions flight/targets/revolution/fw/pios_board.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,11 @@ void PIOS_Board_Init(void) {
/* Configure IO ports */

#if defined(PIOS_INCLUDE_I2C)
if ((!is_modified_clone) && PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) {
PIOS_HAL_CriticalError(PIOS_LED_HEARTBEAT, PIOS_HAL_PANIC_I2C_INT);
}

if ((!is_modified_clone) &&
(PIOS_I2C_CheckClear(pios_i2c_mag_pressure_adapter_id) != 0)) {
PIOS_HAL_CriticalError(PIOS_LED_HEARTBEAT, PIOS_HAL_PANIC_I2C_INT);
} else if (!is_modified_clone) {
if (PIOS_I2C_Init(&pios_i2c_mag_pressure_adapter_id, &pios_i2c_mag_pressure_adapter_cfg)) {
if (!is_modified_clone) {
PIOS_HAL_CriticalError(PIOS_LED_HEARTBEAT, PIOS_HAL_PANIC_I2C_INT);
}
} else {
if (AlarmsGet(SYSTEMALARMS_ALARM_I2C) == SYSTEMALARMS_ALARM_UNINITIALISED) {
AlarmsSet(SYSTEMALARMS_ALARM_I2C, SYSTEMALARMS_ALARM_OK);
}
Expand Down Expand Up @@ -590,6 +587,16 @@ void PIOS_Board_Init(void) {
//I2C is slow, sensor init as well, reset watchdog to prevent reset here
PIOS_WDG_Clear();

#if defined(PIOS_INCLUDE_BMP280) && !defined(PIOS_EXCLUDE_BMP280_I2C)
/* BMP280 I2C onboard support on clones */
if (is_modified_clone &&
(pios_i2c_mag_pressure_adapter_id) &&
(!PIOS_SENSORS_IsRegistered(PIOS_SENSOR_BARO))) {
PIOS_BMP280_Init(&pios_bmp280_cfg,
pios_i2c_mag_pressure_adapter_id);
}
#endif /* defined(PIOS_INCLUDE_BMP280) && !defined(PIOS_EXCLUDE_BMP280_I2C) */

#endif /* PIOS_INCLUDE_I2C */

#ifdef PIOS_INCLUDE_SPI
Expand Down
1 change: 1 addition & 0 deletions flight/targets/revolution/fw/pios_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#define PIOS_INCLUDE_MAX7456

/* Select the sensors to include */
#define PIOS_INCLUDE_BMP280
#define PIOS_INCLUDE_BMP280_SPI
#define PIOS_INCLUDE_HMC5883
#define PIOS_INCLUDE_HMC5983_I2C
Expand Down

0 comments on commit 3b6e3ca

Please sign in to comment.