Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MS5611, BMP280 SPI update #58

Open
wants to merge 2 commits into
base: raceflight
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 67 additions & 5 deletions src/main/drivers/barometer_bmp280.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#include <platform.h>

Expand All @@ -26,9 +27,12 @@

#include "system.h"
#include "bus_i2c.h"
#include "bus_spi.h"

#include "barometer_bmp280.h"

//#define DEBUG_BMP280

#ifdef BARO

#ifndef BMP280_I2C_INSTANCE
Expand Down Expand Up @@ -105,21 +109,69 @@ static void bmp280_start_up(void);
static void bmp280_get_up(void);
STATIC_UNIT_TESTED void bmp280_calculate(int32_t *pressure, int32_t *temperature);

#if defined(USE_SPI) && defined(BMP280_SPI_INSTANCE)
#define DISABLE_BMP280 IOHi(bmp280CsPin)
#define ENABLE_BMP280 IOLo(bmp280CsPin)

static IO_t bmp280CsPin = IO_NONE;

bool baroBMP280Write(uint8_t reg, uint8_t data)
{
ENABLE_BMP280;
delayMicroseconds(1);
spiTransferByte(BMP280_SPI_INSTANCE, reg);
spiTransferByte(BMP280_SPI_INSTANCE, data);
DISABLE_BMP280;

return true;
}

bool baroBMP280Read(uint8_t reg, uint8_t length, uint8_t *data)
{
bool ack = false;

ENABLE_BMP280;
delayMicroseconds(1);
spiTransferByte(BMP280_SPI_INSTANCE, reg | 0x80); // read transaction
ack = spiTransfer(BMP280_SPI_INSTANCE, data, NULL, length);
DISABLE_BMP280;

return ack;
}
#else
bool baroBMP280Write(uint8_t reg, uint8_t data)
{
return i2cWrite(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, reg, data);
}

bool baroBMP280Read(uint8_t reg, uint8_t length, uint8_t *data)
{
return i2cRead(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, reg, length, data);
}
#endif


bool bmp280Detect(baro_t *baro)
{
if (bmp280InitDone)
return true;

#if defined(USE_SPI) && defined(BMP280_SPI_INSTANCE)
bmp280CsPin = IOGetByTag(IO_TAG(BMP280_CS_PIN));
IOInit(bmp280CsPin, OWNER_SYSTEM, RESOURCE_SPI);
IOConfigGPIO(bmp280CsPin, SPI_IO_CS_CFG);
#endif

delay(20);

i2cRead(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CHIP_ID_REG, 1, &bmp280_chip_id); /* read Chip Id */
baroBMP280Read(BMP280_CHIP_ID_REG, 1, &bmp280_chip_id); /* read Chip Id */
if (bmp280_chip_id != BMP280_DEFAULT_CHIP_ID)
return false;

// read calibration
i2cRead(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG, 24, (uint8_t *)&bmp280_cal);
baroBMP280Read(BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG, 24, (uint8_t *)&bmp280_cal);
// set oversampling + power mode (forced), and start sampling
i2cWrite(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, BMP280_MODE);
baroBMP280Write(BMP280_CTRL_MEAS_REG, BMP280_MODE);

bmp280InitDone = true;

Expand Down Expand Up @@ -151,17 +203,22 @@ static void bmp280_start_up(void)
{
// start measurement
// set oversampling + power mode (forced), and start sampling
i2cWrite(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_CTRL_MEAS_REG, BMP280_MODE);
baroBMP280Write(BMP280_CTRL_MEAS_REG, BMP280_MODE);
}

static void bmp280_get_up(void)
{
uint8_t data[BMP280_DATA_FRAME_SIZE];

// read data from sensor
i2cRead(BMP280_I2C_INSTANCE, BMP280_I2C_ADDR, BMP280_PRESSURE_MSB_REG, BMP280_DATA_FRAME_SIZE, data);
baroBMP280Read(BMP280_PRESSURE_MSB_REG, BMP280_DATA_FRAME_SIZE, data);
bmp280_up = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
bmp280_ut = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));

#ifdef DEBUG_BMP280
debug[0] = bmp280_up;
debug[1] = bmp280_ut;
#endif
}

// Returns temperature in DegC, resolution is 0.01 DegC. Output value of "5123" equals 51.23 DegC
Expand Down Expand Up @@ -207,6 +264,11 @@ STATIC_UNIT_TESTED void bmp280_calculate(int32_t *pressure, int32_t *temperature
t = bmp280_compensate_T(bmp280_ut);
p = bmp280_compensate_P(bmp280_up);

#ifdef DEBUG_BMP280
debug[2] = t;
debug[3] = p;
#endif

if (pressure)
*pressure = (int32_t)(p / 256);
if (temperature)
Expand Down
76 changes: 69 additions & 7 deletions src/main/drivers/barometer_ms5611.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,22 @@

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#include <platform.h>
#include "debug.h"

#include "barometer.h"

#include "gpio.h"
#include "io.h"
#include "system.h"
#include "bus_i2c.h"
#include "bus_spi.h"

#include "build_config.h"

//#define DEBUG_MS5611

#ifndef MS5611_I2C_INSTANCE
#define MS5611_I2C_INSTANCE I2C_DEVICE
#endif
Expand Down Expand Up @@ -64,15 +69,62 @@ STATIC_UNIT_TESTED uint32_t ms5611_up; // static result of pressure measurement
STATIC_UNIT_TESTED uint16_t ms5611_c[PROM_NB]; // on-chip ROM
static uint8_t ms5611_osr = CMD_ADC_4096;

#if defined(USE_SPI) && defined(MS5611_SPI_INSTANCE)
#define DISABLE_MS5611 IOHi(ms5611CsPin)
#define ENABLE_MS5611 IOLo(ms5611CsPin)

static IO_t ms5611CsPin = IO_NONE;

bool baroMS5611Write(uint8_t reg, uint8_t data)
{
ENABLE_MS5611;
delayMicroseconds(1);
spiTransferByte(MS5611_SPI_INSTANCE, reg);
spiTransferByte(MS5611_SPI_INSTANCE, data);
DISABLE_MS5611;

return true;
}

bool baroMS5611Read(uint8_t reg, uint8_t length, uint8_t *data)
{
bool ack = false;

ENABLE_MS5611;
delayMicroseconds(1);
spiTransferByte(MS5611_SPI_INSTANCE, reg | 0x80); // read transaction
ack = spiTransfer(MS5611_SPI_INSTANCE, data, NULL, length);
DISABLE_MS5611;

return ack;
}
#else
bool baroMS5611Write(uint8_t reg, uint8_t data)
{
return i2cWrite(MS5611_I2C_INSTANCE, MS5611_ADDR, reg, data);
}

bool baroMS5611Read(uint8_t reg, uint8_t length, uint8_t *data)
{
return i2cRead(MS5611_I2C_INSTANCE, MS5611_ADDR, reg, length, data);
}
#endif

bool ms5611Detect(baro_t *baro)
{
bool ack = false;
uint8_t sig;
int i;

#if defined(USE_SPI) && defined(MS5611_SPI_INSTANCE)
ms5611CsPin = IOGetByTag(IO_TAG(MS5611_CS_PIN));
IOInit(ms5611CsPin, OWNER_SYSTEM, RESOURCE_SPI);
IOConfigGPIO(ms5611CsPin, SPI_IO_CS_CFG);
#endif

delay(10); // No idea how long the chip takes to power-up, but let's make it 10ms

ack = i2cRead(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD, 1, &sig);
ack = baroMS5611Read(CMD_PROM_RD, 1, &sig);
if (!ack)
return false;

Expand All @@ -98,14 +150,14 @@ bool ms5611Detect(baro_t *baro)

static void ms5611_reset(void)
{
i2cWrite(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_RESET, 1);
baroMS5611Write(CMD_RESET, 1);
delayMicroseconds(2800);
}

static uint16_t ms5611_prom(int8_t coef_num)
{
uint8_t rxbuf[2] = { 0, 0 };
i2cRead(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD + coef_num * 2, 2, rxbuf); // send PROM READ command
baroMS5611Read(CMD_PROM_RD + coef_num * 2, 2, rxbuf); // send PROM READ command
return rxbuf[0] << 8 | rxbuf[1];
}

Expand Down Expand Up @@ -142,28 +194,34 @@ STATIC_UNIT_TESTED int8_t ms5611_crc(uint16_t *prom)
static uint32_t ms5611_read_adc(void)
{
uint8_t rxbuf[3];
i2cRead(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_READ, 3, rxbuf); // read ADC
baroMS5611Read(CMD_ADC_READ, 3, rxbuf); // read ADC
return (rxbuf[0] << 16) | (rxbuf[1] << 8) | rxbuf[2];
}

static void ms5611_start_ut(void)
{
i2cWrite(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D2 + ms5611_osr, 1); // D2 (temperature) conversion start!
baroMS5611Write(CMD_ADC_CONV + CMD_ADC_D2 + ms5611_osr, 1); // D2 (temperature) conversion start!
}

static void ms5611_get_ut(void)
{
ms5611_ut = ms5611_read_adc();
#ifdef DEBUG_MS5611
debug[0] = ms5611_ut;
#endif
}

static void ms5611_start_up(void)
{
i2cWrite(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_ADC_CONV + CMD_ADC_D1 + ms5611_osr, 1); // D1 (pressure) conversion start!
baroMS5611Write(CMD_ADC_CONV + CMD_ADC_D1 + ms5611_osr, 1); // D1 (pressure) conversion start!
}

static void ms5611_get_up(void)
{
ms5611_up = ms5611_read_adc();
#ifdef DEBUG_MS5611
debug[1] = ms5611_up;
#endif
}

STATIC_UNIT_TESTED void ms5611_calculate(int32_t *pressure, int32_t *temperature)
Expand Down Expand Up @@ -191,6 +249,10 @@ STATIC_UNIT_TESTED void ms5611_calculate(int32_t *pressure, int32_t *temperature
}
press = ((((int64_t)ms5611_up * sens) >> 21) - off) >> 15;

#ifdef DEBUG_MS5611
debug[2] = temp;
debug[3] = press;
#endif

if (pressure)
*pressure = press;
Expand Down
Loading