Skip to content
Closed
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
31 changes: 31 additions & 0 deletions src/bar/BarGizmoDPS310.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "bar.h"
#include "../hal/MF_I2C.h"
#include "dps3/src/Dps3xx.h"

class BarGizmoDPS310: public BarGizmo {
protected:
Dps3xx pressureSensor;
public:
BarGizmoDPS310(MF_I2C *i2c, int8_t i2c_adr, uint32_t sampleRate) {
if (i2c_adr == 0) {
i2c_adr = 0x77; // default i2c address for the DPS310
}
pressureSensor.begin(*i2c, i2c_adr);
int16_t ret = pressureSensor.startMeasureBothCont(
DPS__MEASUREMENT_RATE_128, DPS__OVERSAMPLING_RATE_2,
DPS__MEASUREMENT_RATE_128, DPS__OVERSAMPLING_RATE_2
);
// TODO: find a way to make gizmo check fail (bar.cpp line 90)
if (ret != 0) {
Serial.println("bar init start measure cont failed");
while (1);
}
}

bool update(float *press, float *temp) override {
uint8_t measureCount = 1;
return pressureSensor.getContResults(temp, measureCount, press, measureCount) == 0;
}
};
6 changes: 6 additions & 0 deletions src/bar/bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ SOFTWARE.
#include "BarGizmoMS5611.h"
#include "BarGizmoHP203B.h"
#include "BarGizmoBMP580.h"
#include "BarGizmoDPS310.h"
#include <math.h>

//create global module instance
Expand Down Expand Up @@ -78,6 +79,11 @@ int Bar::setup() {
gizmo = new BarGizmoBMP580(config.i2c_bus, config.i2c_adr, config.sampleRate);
}
break;
case Cfg::bar_gizmo_enum::mf_DPS310 :
if(config.i2c_bus) {
gizmo = new BarGizmoDPS310(config.i2c_bus, config.i2c_adr, config.sampleRate);
}
break;
}

//check gizmo
Expand Down
21 changes: 21 additions & 0 deletions src/bar/dps3/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 Infineon Technologies AG

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
50 changes: 50 additions & 0 deletions src/bar/dps3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[![Compile examples](https://github.com/Infineon/arduino-xensiv-dps3xx/actions/workflows/compile_examples.yml/badge.svg)](https://github.com/Infineon/arduino-xensiv-dps3xx/actions/workflows/compile_examples.yml)

# XENSIV™ Digital Pressure Sensor Arduino Library

Arduino library of Infineon's [**XENSIV™ Digital Pressure Sensors (DPS3xx)**](https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/).

<img src="https://www.infineon.com/export/sites/default/media/products/Small_Signal_Discretes/lowres-DPS368_VLGA-8-2_Combi.tif.png_1864837327.png" width=200>

## Supported Products

<table>
<tr>
<td rowspan=2>Products</td>
<td><img src="docs/img/dps310.png" height="80"></td>
<td><img src="docs/img/dps368.png" height="80"></td>
</tr>
<tr>
<td style="test-align : center"><a href="https://www.infineon.com/cms/de/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps310/">XENSIV™ DPS310</a></td>
<td style="test-align : center"><a href="https://www.infineon.com/cms/de/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps368/">XENSIV™ DPS368</a></td>
</tr>
<tr>
<td rowspan=2>Shield2Go</td>
<td><img src="docs/img/dps310-shield2go.png" height="80"></td>
<td><img src="docs/img/dps368-shield2go.png" height="80"></td>
</tr>
<tr>
<td style="test-align : center"><a href="https://www.infineon.com/cms/en/product/evaluation-boards/s2go-pressure-dps310/">XENSIV™ DPS310 Shield2Go</a></td>
<td style="test-align : center"><a href="https://www.infineon.com/cms/en/product/evaluation-boards/s2go-pressure-dps368/">XENSIV™ DPS368 Shield2Go</a></td>
</tr>
<tr>
<td rowspan=2>Kit 2Go</td>
<td><img src="docs/img/dps310-kit2go.png" height="80"></td>
<td><img src="docs/img/dps368-kit2go.png" height="80"></td>
</tr>
<tr>
<td style="test-align : center"><a href="https://www.infineon.com/cms/en/product/evaluation-boards/kit_dps310_2go/">XENSIV™ DPS310 Kit 2Go</a></td>
<td style="test-align : center"><a href="https://www.infineon.com/cms/en/product/evaluation-boards/kit_dps368_2go/">XENSIV™ DPS368 Kit 2Go</a></td>
</tr>
</table>

## Getting Started

### Installation
To install this library in the Arduino IDE, please go to **Sketch** > **Include Library** > **Manage Libraries...** and search for the `XENSIV Digital Pressure Sensor` library by `Infineon Technologies` in the Arduino library manager.

### Usage
Please see the example sketches in the `/examples` directory in this repository to learn more about the usage of the library. Especially, take care of the respective SPI and I²C configuration of the sensor. You can find more information in the [Wiki](https://github.com/Infineon/arduino-xensiv-dps3xx/wiki).

## License
See the [LICENSE](LICENSE.md) file for more details.
192 changes: 192 additions & 0 deletions src/bar/dps3/src/Dps3xx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
#include "Dps3xx.h"

using namespace dps;
using namespace dps3xx;

int16_t Dps3xx::getContResults(float *tempBuffer,
uint8_t &tempCount,
float *prsBuffer,
uint8_t &prsCount)
{
return DpsClass::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]);
}

int16_t Dps3xx::setInterruptSources(uint8_t intr_source, uint8_t polarity)
{
#ifndef DPS_DISABLESPI
// Interrupts are not supported with 4 Wire SPI
if (!m_SpiI2c & !m_threeWire)
{
return DPS__FAIL_UNKNOWN;
}
#endif
return writeByteBitfield(intr_source, registers[INT_SEL]) || writeByteBitfield(polarity, registers[INT_HL]);
}

void Dps3xx::init(void)
{
int16_t prodId = readByteBitfield(registers[PROD_ID]);
if (prodId < 0)
{
// Connected device is not a Dps3xx
m_initFail = 1U;
return;
}
m_productID = prodId;

int16_t revId = readByteBitfield(registers[REV_ID]);
if (revId < 0)
{
m_initFail = 1U;
return;
}
m_revisionID = revId;

// find out which temperature sensor is calibrated with coefficients...
int16_t sensor = readByteBitfield(registers[TEMP_SENSORREC]);
if (sensor < 0)
{
m_initFail = 1U;
return;
}

//...and use this sensor for temperature measurement
m_tempSensor = sensor;
if (writeByteBitfield((uint8_t)sensor, registers[TEMP_SENSOR]) < 0)
{
m_initFail = 1U;
return;
}

// read coefficients
if (readcoeffs() < 0)
{
m_initFail = 1U;
return;
}

// set to standby for further configuration
standby();

// set measurement precision and rate to standard values;
configTemp(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8);
configPressure(DPS__MEASUREMENT_RATE_4, DPS__OVERSAMPLING_RATE_8);

// perform a first temperature measurement
// the most recent temperature will be saved internally
// and used for compensation when calculating pressure
float trash;
measureTempOnce(trash);

// make sure the Dps3xx is in standby after initialization
standby();

// Fix IC with a fuse bit problem, which lead to a wrong temperature
// Should not affect ICs without this problem
correctTemp();
}

int16_t Dps3xx::readcoeffs(void)
{
// TODO: remove magic number
uint8_t buffer[18];
// read COEF registers to buffer
int16_t ret = readBlock(coeffBlock, buffer);
if (!ret)
return DPS__FAIL_INIT_FAILED;

// compose coefficients from buffer content
m_c0Half = ((uint32_t)buffer[0] << 4) | (((uint32_t)buffer[1] >> 4) & 0x0F);
getTwosComplement(&m_c0Half, 12);
// c0 is only used as c0*0.5, so c0_half is calculated immediately
m_c0Half = m_c0Half / 2U;

// now do the same thing for all other coefficients
m_c1 = (((uint32_t)buffer[1] & 0x0F) << 8) | (uint32_t)buffer[2];
getTwosComplement(&m_c1, 12);
m_c00 = ((uint32_t)buffer[3] << 12) | ((uint32_t)buffer[4] << 4) | (((uint32_t)buffer[5] >> 4) & 0x0F);
getTwosComplement(&m_c00, 20);
m_c10 = (((uint32_t)buffer[5] & 0x0F) << 16) | ((uint32_t)buffer[6] << 8) | (uint32_t)buffer[7];
getTwosComplement(&m_c10, 20);

m_c01 = ((uint32_t)buffer[8] << 8) | (uint32_t)buffer[9];
getTwosComplement(&m_c01, 16);

m_c11 = ((uint32_t)buffer[10] << 8) | (uint32_t)buffer[11];
getTwosComplement(&m_c11, 16);
m_c20 = ((uint32_t)buffer[12] << 8) | (uint32_t)buffer[13];
getTwosComplement(&m_c20, 16);
m_c21 = ((uint32_t)buffer[14] << 8) | (uint32_t)buffer[15];
getTwosComplement(&m_c21, 16);
m_c30 = ((uint32_t)buffer[16] << 8) | (uint32_t)buffer[17];
getTwosComplement(&m_c30, 16);
return DPS__SUCCEEDED;
}

int16_t Dps3xx::configTemp(uint8_t tempMr, uint8_t tempOsr)
{
int16_t ret = DpsClass::configTemp(tempMr, tempOsr);

writeByteBitfield(m_tempSensor, registers[TEMP_SENSOR]);
// set TEMP SHIFT ENABLE if oversampling rate higher than eight(2^3)
if (tempOsr > DPS3xx__OSR_SE)
{
ret = writeByteBitfield(1U, registers[TEMP_SE]);
}
else
{
ret = writeByteBitfield(0U, registers[TEMP_SE]);
}
return ret;
}

int16_t Dps3xx::configPressure(uint8_t prsMr, uint8_t prsOsr)
{
int16_t ret = DpsClass::configPressure(prsMr, prsOsr);
// set PM SHIFT ENABLE if oversampling rate higher than eight(2^3)
if (prsOsr > DPS3xx__OSR_SE)
{
ret = writeByteBitfield(1U, registers[PRS_SE]);
}
else
{
ret = writeByteBitfield(0U, registers[PRS_SE]);
}
return ret;
}

float Dps3xx::calcTemp(int32_t raw)
{
float temp = raw;

// scale temperature according to scaling table and oversampling
temp /= scaling_facts[m_tempOsr];

// update last measured temperature
// it will be used for pressure compensation
m_lastTempScal = temp;

// Calculate compensated temperature
temp = m_c0Half + m_c1 * temp;

return temp;
}

float Dps3xx::calcPressure(int32_t raw)
{
float prs = raw;

// scale pressure according to scaling table and oversampling
prs /= scaling_facts[m_prsOsr];

// Calculate compensated pressure
prs = m_c00 + prs * (m_c10 + prs * (m_c20 + prs * m_c30)) + m_lastTempScal * (m_c01 + prs * (m_c11 + prs * m_c21));

// return pressure
return prs;
}

int16_t Dps3xx::flushFIFO()
{
return writeByteBitfield(1U, registers[FIFO_FL]);
}
39 changes: 39 additions & 0 deletions src/bar/dps3/src/Dps3xx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef DPS3xx_H_INCLUDED
#define DPS3xx_H_INCLUDED

#include "DpsClass.h"
#include "util/dps3xx_config.h"

class Dps3xx : public DpsClass
{
public:
int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount);

/**
* @brief Set the source of interrupt (FIFO full, measurement values ready)
*
* @param intr_source Interrupt source as defined by Interrupt_source_3xx_e
* @param polarity
* @return status code
*/
int16_t setInterruptSources(uint8_t intr_source, uint8_t polarity = 1);

protected:
uint8_t m_tempSensor;

// compensation coefficients
int32_t m_c0Half;
int32_t m_c1;

/////// implement pure virtual functions ///////

void init(void);
int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr);
int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr);
int16_t readcoeffs(void);
int16_t flushFIFO();
float calcTemp(int32_t raw);
float calcPressure(int32_t raw);
};

#endif
Loading