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

Add DPS310 to Matek boards F722,F722-SE,F722-HD and F722-PX #578

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b3a9417
Add dps310 to F722 matek board
JulioCesarMatias May 22, 2021
93dab35
parse DPS310 to hardware detect
JulioCesarMatias May 22, 2021
9dd3944
parse DPS310 to settings.c
JulioCesarMatias May 22, 2021
3d83ded
correct name of i2c and spi bus functions that are different from bet…
JulioCesarMatias May 22, 2021
9b2c18f
add new function to bus_spi.c to use with DPS310
JulioCesarMatias May 22, 2021
961a429
remove new function of bus_spi.c and use the SPI_CLOCK_STANDARD
JulioCesarMatias May 22, 2021
67ca563
remove owner and #define
JulioCesarMatias May 22, 2021
4ad909e
add extension in makefile
JulioCesarMatias May 22, 2021
6cdb890
fix
JulioCesarMatias May 22, 2021
2fa32f1
to *c.
JulioCesarMatias May 23, 2021
3732941
force new build
JulioCesarMatias May 23, 2021
a895792
move #define to MATEKF722
JulioCesarMatias May 23, 2021
ff621a1
fix compilation error
JulioCesarMatias May 23, 2021
b05453b
remove unused #define
JulioCesarMatias May 23, 2021
8ec625e
version SE
JulioCesarMatias May 26, 2021
52e273b
fix laggy and steppy
JulioCesarMatias May 26, 2021
66b0869
#ifdef
JulioCesarMatias May 26, 2021
45c689f
remover variable duplication
JulioCesarMatias May 26, 2021
2bde7f9
redo the function deviceConfigure
JulioCesarMatias May 26, 2021
9918bb8
add functions
JulioCesarMatias May 26, 2021
66576f6
move
JulioCesarMatias May 26, 2021
c37f776
fix compilation error
JulioCesarMatias May 26, 2021
9fa0bc5
bool to void
JulioCesarMatias May 26, 2021
2af0eea
add dps310 in hd and px version
JulioCesarMatias May 27, 2021
f185c9a
maybe it works
JulioCesarMatias May 27, 2021
5d1cded
add #define DEFAULT_BARO_DPS310
JulioCesarMatias May 27, 2021
be7b986
#if check dps310
JulioCesarMatias May 27, 2021
34f30e9
sub func
JulioCesarMatias May 29, 2021
01f3143
fix compilation error
JulioCesarMatias May 29, 2021
63cee29
add matek f405 se
JulioCesarMatias Sep 19, 2021
986e6d9
Merge branch 'master' of https://github.com/JulioCesarMatias/EmuFligh…
JulioCesarMatias Sep 19, 2021
ae84655
iflight f745
JulioCesarMatias Sep 19, 2021
c67d44a
force new build
JulioCesarMatias Sep 19, 2021
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
1 change: 1 addition & 0 deletions make/source.mk
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
drivers/barometer/barometer_bmp280.c \
drivers/barometer/barometer_fake.c \
drivers/barometer/barometer_ms5611.c \
drivers/barometer/barometer_dps310.c \
drivers/barometer/barometer_lps.c \
drivers/barometer/barometer_qmp6988.c \
drivers/beesign.c \
Expand Down
344 changes: 344 additions & 0 deletions src/main/drivers/barometer/barometer_dps310.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,344 @@
/*
* This file is part of Cleanflight, Betaflight and INAV.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 3, as described below:
*
* This file is free software: you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see http://www.gnu.org/licenses/.
*
* Copyright: INAVFLIGHT
*/

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

#include "platform.h"

#include "build/build_config.h"
#include "build/debug.h"
#include "common/utils.h"

#include "drivers/io.h"
#include "drivers/bus.h"
#include "drivers/bus_spi.h"
#include "drivers/time.h"
#include "drivers/barometer/barometer.h"
#include "drivers/barometer/barometer_dps310.h"
#include "drivers/resource.h"

#if defined(USE_BARO) && defined(USE_BARO_DPS310)

#define DPS310_I2C_ADDR 0x76

#define DPS310_REG_PSR_B2 0x00
#define DPS310_REG_PSR_B1 0x01
#define DPS310_REG_PSR_B0 0x02
#define DPS310_REG_TMP_B2 0x03
#define DPS310_REG_TMP_B1 0x04
#define DPS310_REG_TMP_B0 0x05
#define DPS310_REG_PRS_CFG 0x06
#define DPS310_REG_TMP_CFG 0x07
#define DPS310_REG_MEAS_CFG 0x08
#define DPS310_REG_CFG_REG 0x09

#define DPS310_REG_RESET 0x0C
#define DPS310_REG_ID 0x0D

#define DPS310_REG_COEF 0x10
#define DPS310_REG_COEF_SRCE 0x28


#define DPS310_ID_REV_AND_PROD_ID (0x10)

#define DPS310_RESET_BIT_SOFT_RST (0x09) // 0b1001

#define DPS310_MEAS_CFG_COEF_RDY (1 << 7)
#define DPS310_MEAS_CFG_SENSOR_RDY (1 << 6)
#define DPS310_MEAS_CFG_TMP_RDY (1 << 5)
#define DPS310_MEAS_CFG_PRS_RDY (1 << 4)

#define DPS310_MEAS_CFG_MEAS_CTRL_MASK (0x7)
#define DPS310_MEAS_CFG_MEAS_CTRL_CONT (0x7)
#define DPS310_MEAS_CFG_MEAS_TEMP_SING (0x2)
#define DPS310_MEAS_CFG_MEAS_IDLE (0x0)

#define DPS310_PRS_CFG_BIT_PM_RATE_32HZ (0x50) // 101 - 32 measurements pr. sec.
#define DPS310_PRS_CFG_BIT_PM_PRC_16 (0x04) // 0100 - 16 times (Standard).

#define DPS310_TMP_CFG_BIT_TMP_EXT (0x80) //
#define DPS310_TMP_CFG_BIT_TMP_RATE_32HZ (0x50) // 101 - 32 measurements pr. sec.
#define DPS310_TMP_CFG_BIT_TMP_PRC_16 (0x04) // 0100 - 16 times (Standard).

#define DPS310_CFG_REG_BIT_P_SHIFT (0x04)
#define DPS310_CFG_REG_BIT_T_SHIFT (0x08)

#define DPS310_COEF_SRCE_BIT_TMP_COEF_SRCE (0x80)

typedef struct {
int16_t c0; // 12bit
int16_t c1; // 12bit
int32_t c00; // 20bit
int32_t c10; // 20bit
int16_t c01; // 16bit
int16_t c11; // 16bit
int16_t c20; // 16bit
int16_t c21; // 16bit
int16_t c30; // 16bit
} calibrationCoefficients_t;

typedef struct {
calibrationCoefficients_t calib;
float pressure; // Pa
float temperature; // DegC
} baroState_t;

static baroState_t baroState;

static uint8_t dps310_chip_id = 0;

// Helper functions
static uint8_t registerRead(busDevice_t * busDev, uint8_t reg)
{
return busReadRegister(busDev, reg);
}

static void registerWrite(busDevice_t * busDev, uint8_t reg, uint8_t value)
{
busWriteRegister(busDev, reg, value);
}

static void registerWriteBits(busDevice_t * busDev, uint8_t reg, uint8_t mask, uint8_t bits)
{
uint8_t val = registerRead(busDev, reg);

if ((val & mask) != bits) {
val = (val & (~mask)) | bits;
registerWrite(busDev, reg, val);
}
}

static void registerSetBits(busDevice_t * busDev, uint8_t reg, uint8_t setbits)
{
registerWriteBits(busDev, reg, setbits, setbits);
}

static int32_t getTwosComplement(uint32_t raw, uint8_t length)
{
if (raw & ((int)1 << (length - 1))) {
return ((int32_t)raw) - ((int32_t)1 << length);
}
else {
return raw;
}
}

static bool deviceConfigure(busDevice_t * busDev)
{
// Trigger a chip reset
registerSetBits(busDev, DPS310_REG_RESET, DPS310_RESET_BIT_SOFT_RST);

// Sleep 40ms
delay(40);

uint8_t status = registerRead(busDev, DPS310_REG_MEAS_CFG);

// Check if coefficients are available
if ((status & DPS310_MEAS_CFG_COEF_RDY) == 0) {
return false;
}

// Check if sensor initialization is complete
if ((status & DPS310_MEAS_CFG_SENSOR_RDY) == 0) {
return false;
}

// 1. Read the pressure calibration coefficients (c00, c10, c20, c30, c01, c11, and c21) from the Calibration Coefficient register.
// Note: The coefficients read from the coefficient register are 2's complement numbers.

// Do the read of the coefficients in multiple parts, as the chip will return a read failure when trying to read all at once over I2C.
#define COEFFICIENT_LENGTH 18
#define READ_LENGTH (COEFFICIENT_LENGTH / 2)

uint8_t coef[COEFFICIENT_LENGTH];
if (!busReadRegisterBuffer(busDev, DPS310_REG_COEF, coef, READ_LENGTH)) {
return false;
}

if (!busReadRegisterBuffer(busDev, DPS310_REG_COEF + READ_LENGTH, coef + READ_LENGTH, COEFFICIENT_LENGTH - READ_LENGTH)) {
return false;
}

// 0x11 c0 [3:0] + 0x10 c0 [11:4]
baroState.calib.c0 = getTwosComplement(((uint32_t)coef[0] << 4) | (((uint32_t)coef[1] >> 4) & 0x0F), 12);

// 0x11 c1 [11:8] + 0x12 c1 [7:0]
baroState.calib.c1 = getTwosComplement((((uint32_t)coef[1] & 0x0F) << 8) | (uint32_t)coef[2], 12);

// 0x13 c00 [19:12] + 0x14 c00 [11:4] + 0x15 c00 [3:0]
baroState.calib.c00 = getTwosComplement(((uint32_t)coef[3] << 12) | ((uint32_t)coef[4] << 4) | (((uint32_t)coef[5] >> 4) & 0x0F), 20);

// 0x15 c10 [19:16] + 0x16 c10 [15:8] + 0x17 c10 [7:0]
baroState.calib.c10 = getTwosComplement((((uint32_t)coef[5] & 0x0F) << 16) | ((uint32_t)coef[6] << 8) | (uint32_t)coef[7], 20);

// 0x18 c01 [15:8] + 0x19 c01 [7:0]
baroState.calib.c01 = getTwosComplement(((uint32_t)coef[8] << 8) | (uint32_t)coef[9], 16);

// 0x1A c11 [15:8] + 0x1B c11 [7:0]
baroState.calib.c11 = getTwosComplement(((uint32_t)coef[8] << 8) | (uint32_t)coef[9], 16);

// 0x1C c20 [15:8] + 0x1D c20 [7:0]
baroState.calib.c20 = getTwosComplement(((uint32_t)coef[12] << 8) | (uint32_t)coef[13], 16);

// 0x1E c21 [15:8] + 0x1F c21 [7:0]
baroState.calib.c21 = getTwosComplement(((uint32_t)coef[14] << 8) | (uint32_t)coef[15], 16);

// 0x20 c30 [15:8] + 0x21 c30 [7:0]
baroState.calib.c30 = getTwosComplement(((uint32_t)coef[16] << 8) | (uint32_t)coef[17], 16);

// PRS_CFG: pressure measurement rate (32 Hz) and oversampling (16 time standard)
registerSetBits(busDev, DPS310_REG_PRS_CFG, DPS310_PRS_CFG_BIT_PM_RATE_32HZ | DPS310_PRS_CFG_BIT_PM_PRC_16);

// TMP_CFG: temperature measurement rate (32 Hz) and oversampling (16 times)
const uint8_t TMP_COEF_SRCE = registerRead(busDev, DPS310_REG_COEF_SRCE) & DPS310_COEF_SRCE_BIT_TMP_COEF_SRCE;
registerSetBits(busDev, DPS310_REG_TMP_CFG, DPS310_TMP_CFG_BIT_TMP_RATE_32HZ | DPS310_TMP_CFG_BIT_TMP_PRC_16 | TMP_COEF_SRCE);

// CFG_REG: set pressure and temperature result bit-shift (required when the oversampling rate is >8 times)
registerSetBits(busDev, DPS310_REG_CFG_REG, DPS310_CFG_REG_BIT_T_SHIFT | DPS310_CFG_REG_BIT_P_SHIFT);

// MEAS_CFG: Continuous pressure and temperature measurement
registerSetBits(busDev, DPS310_REG_MEAS_CFG, DPS310_MEAS_CFG_MEAS_CTRL_CONT);

return true;
}

static void deviceReadMeasurement(baroDev_t *baro)
{
// 1. Check if pressure is ready
bool pressure_ready = registerRead(&baro->busdev, DPS310_REG_MEAS_CFG) & DPS310_MEAS_CFG_PRS_RDY;
if (!pressure_ready) {
return;
}

// 2. Choose scaling factors kT (for temperature) and kP (for pressure) based on the chosen precision rate.
// The scaling factors are listed in Table 9.
static float kT = 253952; // 16 times (Standard)
static float kP = 253952; // 16 times (Standard)

// 3. Read the pressure and temperature result from the registers
// Read PSR_B2, PSR_B1, PSR_B0, TMP_B2, TMP_B1, TMP_B0
uint8_t buf[6];
if (!busReadRegisterBuffer(&baro->busdev, DPS310_REG_PSR_B2, buf, 6)) {
return;
}

const int32_t Praw = getTwosComplement((buf[0] << 16) + (buf[1] << 8) + buf[2], 24);
const int32_t Traw = getTwosComplement((buf[3] << 16) + (buf[4] << 8) + buf[5], 24);

// 4. Calculate scaled measurement results.
const float Praw_sc = Praw / kP;
const float Traw_sc = Traw / kT;

// 5. Calculate compensated measurement results.
const float c00 = baroState.calib.c00;
const float c01 = baroState.calib.c01;
const float c10 = baroState.calib.c10;
const float c11 = baroState.calib.c11;
const float c20 = baroState.calib.c20;
const float c21 = baroState.calib.c21;
const float c30 = baroState.calib.c30;

const float c0 = baroState.calib.c0;
const float c1 = baroState.calib.c1;

baroState.pressure = c00 + Praw_sc * (c10 + Praw_sc * (c20 + Praw_sc * c30)) + Traw_sc * c01 + Traw_sc * Praw_sc * (c11 + Praw_sc * c21);
baroState.temperature = c0 * 0.5f + c1 * Traw_sc;
}

static void deviceCalculate(int32_t *pressure, int32_t *temperature)
{
if (pressure) {
*pressure = baroState.pressure;
}

if (temperature) {
*temperature = (baroState.temperature * 100); // to centidegrees
}
}

#define DETECTION_MAX_RETRY_COUNT 5
static bool deviceDetect(busDevice_t * busDev)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it is this function that is causing problems

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm replacing it with another function, and implemented a 10ms delay to start

{
for (int retry = 0; retry < DETECTION_MAX_RETRY_COUNT; retry++) {
uint8_t chipId[1];

delay(100);

bool ack = busReadRegisterBuffer(busDev, DPS310_REG_ID, chipId, 1);

if (ack && chipId[0] == DPS310_ID_REV_AND_PROD_ID) {
return true;
}
};

return false;
}

bool baroDPS310Detect(baroDev_t *baro)
{
busDevice_t *busdev = &baro->busdev;
bool defaultAddressApplied = false;

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

if ((busdev->bustype == BUSTYPE_I2C) && (busdev->busdev_u.i2c.address == 0)) {
busdev->busdev_u.i2c.address = DPS310_I2C_ADDR;
defaultAddressApplied = true;
}

busReadRegisterBuffer(busdev, DPS310_REG_ID, &dps310_chip_id, 1); /* read Chip Id */
if (dps310_chip_id != DPS310_ID_REV_AND_PROD_ID) {
//if (!deviceDetect(busdev))
{
if (defaultAddressApplied) {
busdev->busdev_u.i2c.address = 0;
}
return false;
}
}
/*
if (!deviceConfigure(busdev)) {
return false;
}
*/
const uint32_t baroDelay = 1000000 / 32 / 2; // twice the sample rate to capture all new data

baro->ut_delay = 0;
baro->start_ut = NULL;
baro->get_ut = NULL;

baro->up_delay = baroDelay;
baro->start_up = NULL;
baro->get_up = deviceReadMeasurement;

baro->calculate = deviceCalculate;

return true;
}

#endif
29 changes: 29 additions & 0 deletions src/main/drivers/barometer/barometer_dps310.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* This file is part of Cleanflight, Betaflight and INAV.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License Version 3, as described below:
*
* This file is free software: you may copy, redistribute and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This file 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 this program. If not, see http://www.gnu.org/licenses/.
*
* Copyright: INAVFLIGHT
*/

#pragma once

bool baroDPS310Detect(baroDev_t *baro);
2 changes: 1 addition & 1 deletion src/main/interface/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const char * const lookupTableGyroHardware[] = {
#if defined(USE_SENSOR_NAMES) || defined(USE_BARO)
// sync with baroSensor_e
const char * const lookupTableBaroHardware[] = {
"AUTO", "NONE", "BMP085", "MS5611", "BMP280", "LPS", "QMP6988"
"AUTO", "NONE", "BMP085", "MS5611", "BMP280", "LPS", "QMP6988", "DPS310"
};
#endif
#if defined(USE_SENSOR_NAMES) || defined(USE_MAG)
Expand Down
Loading