Skip to content

Commit

Permalink
SPI driver support
Browse files Browse the repository at this point in the history
Add HMC5883/5983 driver
Add BMP280 driver
Add MS5611 driver
  • Loading branch information
MJ666 committed Feb 16, 2016
1 parent 24ffc0f commit bebba3d
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 73 deletions.
24 changes: 22 additions & 2 deletions src/main/drivers/barometer_bmp280.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@

#include "barometer_bmp280.h"

//#define DEBUG_BMP280

#ifdef BARO

#ifndef BMP280_I2C_INSTANCE
Expand Down Expand Up @@ -108,8 +110,10 @@ 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 GPIO_SetBits(BMP280_CS_GPIO, BMP280_CS_PIN)
#define ENABLE_BMP280 GPIO_ResetBits(BMP280_CS_GPIO, BMP280_CS_PIN)
#define DISABLE_BMP280 IOHi(bmp280CsPin)
#define ENABLE_BMP280 IOLo(bmp280CsPin)

static IO_t bmp280CsPin = IO_NONE;

bool baroBMP280Write(uint8_t reg, uint8_t data)
{
Expand Down Expand Up @@ -152,6 +156,12 @@ 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);

baroBMP280Read(BMP280_CHIP_ID_REG, 1, &bmp280_chip_id); /* read Chip Id */
Expand Down Expand Up @@ -204,6 +214,11 @@ static void bmp280_get_up(void)
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[0] = bmp280_ut;
#endif
}

// Returns temperature in DegC, resolution is 0.01 DegC. Output value of "5123" equals 51.23 DegC
Expand Down Expand Up @@ -249,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
79 changes: 31 additions & 48 deletions src/main/drivers/barometer_ms5611.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@

#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
//#define DEBUG_MS5611

#ifndef MS5611_I2C_INSTANCE
#define MS5611_I2C_INSTANCE I2C_DEVICE
Expand Down Expand Up @@ -69,33 +69,13 @@ 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;

typedef bool (*baroMS5611ReadRegisterFunc)(uint8_t reg_, uint8_t len_, uint8_t *buf);
typedef bool (*baroMS5611WriteRegisterFunc)(uint8_t reg_, uint8_t data);

typedef struct baroMS5611Config_s {
baroMS5611ReadRegisterFunc read;
baroMS5611WriteRegisterFunc write;
} baroMS5611Config_t;

baroMS5611Config_t baroMS5611config;

#ifdef USE_I2C
bool baroMS5611WriteI2C(uint8_t reg, uint8_t data)
{
return i2cWrite(MS5611_I2C_INSTANCE, MS5611_ADDR, reg, data);
}

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

#if defined(USE_SPI) && defined(MS5611_SPI_INSTANCE)
#define DISABLE_MS5611 GPIO_SetBits(MS5611_CS_GPIO, MS5611_CS_PIN)
#define ENABLE_MS5611 GPIO_ResetBits(MS5611_CS_GPIO, MS5611_CS_PIN)
#define DISABLE_MS5611 IOHi(ms5611CsPin)
#define ENABLE_MS5611 IOLo(ms5611CsPin)

static IO_t ms5611CsPin = IO_NONE;

bool baroMS5611WriteSPI(uint8_t reg, uint8_t data)
bool baroMS5611Write(uint8_t reg, uint8_t data)
{
ENABLE_MS5611;
delayMicroseconds(1);
Expand All @@ -106,7 +86,7 @@ bool baroMS5611WriteSPI(uint8_t reg, uint8_t data)
return true;
}

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

Expand All @@ -118,6 +98,16 @@ bool baroMS5611ReadSPI(uint8_t reg, uint8_t length, uint8_t *data)

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)
Expand All @@ -126,23 +116,16 @@ bool ms5611Detect(baro_t *baro)
uint8_t sig;
int i;

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

#ifdef USE_I2C
ack = i2cRead(MS5611_I2C_INSTANCE, MS5611_ADDR, CMD_PROM_RD, 1, &sig);
if (ack) {
baroMS5611config.read = baroMS5611ReadI2C;
baroMS5611config.write = baroMS5611WriteI2C;
}
#endif
#if defined(USE_SPI) && defined(MS5611_SPI_INSTANCE)
ack = baroMS5611ReadSPI(CMD_PROM_RD, 1, &sig);
if (ack) {
baroMS5611config.read = baroMS5611ReadSPI;
baroMS5611config.write = baroMS5611WriteSPI;
}
ms5611CsPin = IOGetByTag(IO_TAG(MS5611_CS_PIN));
IOInit(ms5611CsPin, OWNER_SYSTEM, RESOURCE_SPI);
IOConfigGPIO(ms5611CsPin, SPI_IO_CS_CFG);
#endif
else

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

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

ms5611_reset();
Expand All @@ -167,14 +150,14 @@ bool ms5611Detect(baro_t *baro)

static void ms5611_reset(void)
{
baroMS5611config.write(CMD_RESET, 1);
baroMS5611Write(CMD_RESET, 1);
delayMicroseconds(2800);
}

static uint16_t ms5611_prom(int8_t coef_num)
{
uint8_t rxbuf[2] = { 0, 0 };
baroMS5611config.read(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 @@ -211,13 +194,13 @@ STATIC_UNIT_TESTED int8_t ms5611_crc(uint16_t *prom)
static uint32_t ms5611_read_adc(void)
{
uint8_t rxbuf[3];
baroMS5611config.read(CMD_ADC_READ, 3, rxbuf); // read ADC
baroMS5611Read(CMD_ADC_READ, 1, rxbuf); // read ADC
return (rxbuf[0] << 16) | (rxbuf[1] << 8) | rxbuf[2];
}

static void ms5611_start_ut(void)
{
baroMS5611config.write(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)
Expand All @@ -230,7 +213,7 @@ static void ms5611_get_ut(void)

static void ms5611_start_up(void)
{
baroMS5611config.write(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)
Expand Down
100 changes: 88 additions & 12 deletions src/main/drivers/compass_hmc5883l.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "nvic.h"
#include "gpio.h"
#include "bus_i2c.h"
#include "bus_spi.h"
#include "light_led.h"
#include "drivers/exti.h"

Expand Down Expand Up @@ -151,15 +152,90 @@ void hmc5883_extiHandler(extiCallbackRec_t* cb)
}
#endif

#if defined(USE_SPI) && defined(HMC5883_SPI_INSTANCE)
#define DISABLE_HMC5883 IOHi(hmc5883CsPin)
#define ENABLE_HMC5883 IOLo(hmc5883CsPin)

static IO_t hmc5883CsPin = IO_NONE;

bool baroHMC5883WriteRegister(uint8_t reg, uint8_t data)
{
// spiSetDivisor(HMC5883_SPI_INSTANCE, 16);

ENABLE_HMC5883;
delayMicroseconds(1);
spiTransferByte(HMC5883_SPI_INSTANCE, reg);
spiTransferByte(HMC5883_SPI_INSTANCE, data);
DISABLE_HMC5883;

return true;
}

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

// spiSetDivisor(HMC5883_SPI_INSTANCE, 16);

ENABLE_HMC5883;
delayMicroseconds(1);
spiTransferByte(HMC5883_SPI_INSTANCE, reg | 0x80); // read transaction
ack = spiTransfer(HMC5883_SPI_INSTANCE, data, NULL, length);
DISABLE_HMC5883;

return ack;
}

bool baroHMC5883Write(uint8_t reg, uint8_t data) {

uint8_t in;
uint8_t attemptsRemaining = 20;

// spiSetDivisor(HMC5883_SPI_INSTANCE, 16);

baroHMC5883WriteRegister(reg, data);
delayMicroseconds(10);

do {
baroHMC5883Read(reg, 1, &in);
if (in == data) {
return true;
} else {
debug[3]++;
baroHMC5883WriteRegister(reg, data);
delayMicroseconds(10);
}
} while (attemptsRemaining--);
return false;
}
#else
bool baroHMC5883Read(uint8_t reg, uint8_t length, uint8_t *data)
{
return i2cRead(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, reg, length, data);
}

bool baroHMC5883Write(uint8_t reg, uint8_t data)
{
return i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, reg, data);
}
#endif


bool hmc5883lDetect(mag_t* mag, const hmc5883Config_t *hmc5883ConfigToUse)
{
bool ack = false;
uint8_t sig = 0;
uint8_t buf[3];

#if defined(USE_SPI) && defined(HMC5883_SPI_INSTANCE)
hmc5883CsPin = IOGetByTag(IO_TAG(HMC5883_CS_PIN));
IOInit(hmc5883CsPin, OWNER_SYSTEM, RESOURCE_SPI);
IOConfigGPIO(hmc5883CsPin, SPI_IO_CS_CFG);
#endif

hmc5883Config = hmc5883ConfigToUse;

ack = i2cRead(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, 0x0A, 1, &sig);
if (!ack || sig != 'H')
ack = baroHMC5883Read(0x0A, 3, buf);
if (!ack || buf[0] != 'H') // || buf[1] != '4' || buf[2] != '3')
return false;

mag->init = hmc5883lInit;
Expand All @@ -183,15 +259,15 @@ void hmc5883lInit(void)
}
#endif
delay(50);
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x010 + HMC_POS_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to pos bias
baroHMC5883Write(HMC58X3_R_CONFA, 0x010 + HMC_POS_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to pos bias
// Note that the very first measurement after a gain change maintains the same gain as the previous setting.
// The new gain setting is effective from the second measurement and on.
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFB, 0x60); // Set the Gain to 2.5Ga (7:5->011)
baroHMC5883Write(HMC58X3_R_CONFB, 0x60); // Set the Gain to 2.5Ga (7:5->011)
delay(100);
hmc5883lRead(magADC);

for (i = 0; i < 10; i++) { // Collect 10 samples
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 1);
baroHMC5883Write(HMC58X3_R_MODE, 1);
delay(50);
hmc5883lRead(magADC); // Get the raw values in case the scales have already been changed.

Expand All @@ -209,9 +285,9 @@ void hmc5883lInit(void)
}

// Apply the negative bias. (Same gain)
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x010 + HMC_NEG_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to negative bias.
baroHMC5883Write(HMC58X3_R_CONFA, 0x010 + HMC_NEG_BIAS); // Reg A DOR = 0x010 + MS1, MS0 set to negative bias.
for (i = 0; i < 10; i++) {
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 1);
baroHMC5883Write(HMC58X3_R_MODE, 1);
delay(50);
hmc5883lRead(magADC); // Get the raw values in case the scales have already been changed.

Expand All @@ -233,9 +309,9 @@ void hmc5883lInit(void)
magGain[Z] = fabsf(660.0f * HMC58X3_Z_SELF_TEST_GAUSS * 2.0f * 10.0f / xyz_total[Z]);

// leave test mode
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFA, 0x70); // Configuration Register A -- 0 11 100 00 num samples: 8 ; output rate: 15Hz ; normal measurement mode
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_CONFB, 0x20); // Configuration Register B -- 001 00000 configuration gain 1.3Ga
i2cWrite(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, HMC58X3_R_MODE, 0x00); // Mode register -- 000000 00 continuous Conversion Mode
baroHMC5883Write(HMC58X3_R_CONFA, 0x70); // Configuration Register A -- 0 11 100 00 num samples: 8 ; output rate: 15Hz ; normal measurement mode
baroHMC5883Write(HMC58X3_R_CONFB, 0x20); // Configuration Register B -- 001 00000 configuration gain 1.3Ga
baroHMC5883Write(HMC58X3_R_MODE, 0x00); // Mode register -- 000000 00 continuous Conversion Mode
delay(100);

if (!bret) { // Something went wrong so get a best guess
Expand Down Expand Up @@ -263,7 +339,7 @@ bool hmc5883lRead(int16_t *magData)
{
uint8_t buf[6];

bool ack = i2cRead(HMC5883L_I2C_INSTANCE, MAG_ADDRESS, MAG_DATA_REGISTER, 6, buf);
bool ack = baroHMC5883Read(MAG_DATA_REGISTER, 6, buf);
if (!ack) {
return false;
}
Expand Down
Loading

0 comments on commit bebba3d

Please sign in to comment.