diff --git a/LICENSE.md b/LICENSE.md index b95df3e..17b1dd6 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ # License Summary for Repository ``` Important Notice: -Changes, suggestions and commits in this repository may only be done putting them +Changes, suggestions and commits in this repository may only be done putting them under the same license of the respective file. All rights of the respective copyright holders shall be reserved. Brands and product names are trademarks of their respective owners. @@ -12,22 +12,22 @@ their respective licenses. Copyright (c) 2018 Infineon Technologies AG -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the -following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of conditions and the following -disclaimer. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials provided with the distribution. +Redistributions of source code must retain the above copyright notice, this list of conditions and the following +disclaimer. -Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote -products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided with the distribution. + +Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 03f9732..3ee799d 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,50 @@ -# DPS3xx Digital Pressure Sensor - - - - - -Library of Infineon's highly sensitive [DPS368 sensor](https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps368/) and [DPS310 sensor](https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps310/) for Arduino. - -## Summary -## DPS368 - -The [DPS368](https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps368/) is a miniaturized digital barometric air pressure sensor with ultra-high precision (±2 cm) and a low current consumption, capable of measuring both pressure and temperature. It is is an ultra small waterproof pressure sensor, environmentally protected against water (IPx8), dust & humidity Due to its robust package, it can withstand 50 m under water for one hour (IPx8). The pressure sensor element is based on a capacitive sensing principle which guarantees high precision during temperature changes. The small package (2.0 x 2.5 x 1.1 mm³) makes the DPS3xx ideal for mobile applications and wearable devices. - -### Summary of Features: - -* Package dimensions: 8-pin LGA, 2.0 x 2.5 x 1.1 mm³ -* Operation range: - * Pressure: 300–1200 hPa - * Temperature: -40–85°C -* Precision: ± 0.002 hPa (or ±0.02 m) -* Rel. accuracy: ± 0.06 hPa (or ±0.5 m) -* Abs. accuracy: ± 1 hPa (or ±8 m) -* Temperature accuracy: ± 0.5°C -* Avg. current consumption: 1.7 µA (pressure measurement@1 Hz sampling rate, standby: 0.5 µA) -* Integrated FIFO -* Interface: I2C and SPI (I2C with optional interrupt) - -### Benefits - -* Fast, ultra-low noise read-out allows for precise measurement of altitude, air flow and body movements -* Small package size ideal for wearable devices & mobile applications -* Sensor can be used in harsh environment (water, dust & humidity) -* Environmentally resistant package facilitates handling in assembly line - -### Target Applications - -* Smart watches & wearables (e.g. fitness tracking) -* Smart phone (e.g. navigation) -* Home appliances (e.g. air flow control) -* Drones (e.g. flight stability) - -## DPS310 - -The [DPS310](https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf?fileId=5546d462576f34750157750826c42242) is a miniaturized digital barometric air pressure sensor with a high accuracy and a low current consumption, capable of measuring both pressure and temperature. The internal signal processor converts the output from the pressure and temperature sensor elements to 24 bit results. Each unit is individually calibrated, the calibration coefficients calculated during this process are stored in the calibration registers. The available raw data of the sensor can be calibrated by using the pre-calibrated coefficients as they are used in the application to convert the measurement results to high accuracy pressure and temperature values. - -Sensor measurements and calibration coefficients are available through the serial I2C or SPI interface. - -### Key Features and Applications -* Supply voltage range 1.7V to 3.6V -* Operation range 300hPa – 1200hPa -* Sensor’s precision 0.005hPa -* Relative accuracy ±0.06hPa -* Pressure temperature sensitivity of 0.5Pa/K -* Temperature accuracy ±0.5C° -* Applications - * Wearable applications, sport and fitness activities tracking - * Drones automatic pilot, fix point flying - * Indoor navigation, altitude metering - -## Installation - -### Integration of Library - -The master branch is always release ready; therefore, you can just download this library by downloading it from GitHub directly: - -Please download this repository from GitHub by clicking on the above button `Clone or download` of this repository: - -![Download Library](https://raw.githubusercontent.com/Infineon/Assets/master/Pictures/Download_Repo.png) - -To install the DPS3xx pressure sensor library in the Arduino IDE, please go now to **Sketch** > **Include Library** > **Add .ZIP Library...** in the Arduino IDE and navigate to the downloaded .ZIP file of this repository. The library will be installed in your Arduino sketch folder in libraries and you can select as well as include this one to your project under **Sketch** > **Include Library** > **arduino-xensiv-dps3xx**. - -![Install Library](https://raw.githubusercontent.com/infineon/assets/master/Pictures/Library_Install_ZIP.png) - -## Usage -Please see the example sketches in the `/examples` directory in this library to learn more about the usage of the library. Especially, take care of the respective SPI and I²C configuration of the sensor. -For more information, please consult the datasheet of DPS368 [here](https://www.infineon.com/dgdl/Infineon-DPS3xx-DS-v01_00-EN.pdf?fileId=5546d46269e1c019016a0c45105d4b40) and DPS310 [here](https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf?fileId=5546d462576f34750157750826c42242) - -Currently, there exists the DPS3xx Pressure Shield2Go evaluation board as a break out board: - -* [DPS368 Pressure Shield2Go](https://www.infineon.com/cms/en/product/evaluation-boards/s2go-pressure-dps368) -* [DPS310 Pressure Shield2Go](https://www.infineon.com/cms/en/product/evaluation-boards/s2go-pressure-dps368) - - -### DPS3xx Pressure Shield2Go -The DPS3xx Pressure Shield2Go is a standalone break out board with Infineon's Shield2Go formfactor and pin out. You can connect it easily to any microcontroller of your choice which is Arduino compatible and has 3.3 V logic level (please note that the Arduino UNO has 5 V logic level and cannot be used without level shifting). -Please consult the [wiki](https://github.com/Infineon/DPS3xx-Library-Arduino/wiki) for additional details about the board. - -Each sensor can only work either SPI or I2C. To convert from SPI to I2C, for example, you have to re-solder the resistors on the Shield2Go. Please take care that every Shield2Go for the DPS3xx is shipped as I2C configuration right now. - -* [Link](https://github.com/Infineon/DPS3xx-Library-Arduino/wiki) to the wiki with more information - - -However, every Shield2Go is directly compatible with Infineon's XMC2Go and the recommended quick start is to use an XMC2Go for evaluation. Therefore, please install (if not already done) also the [XMC-for-Arduino](https://github.com/Infineon/XMC-for-Arduino) implementation and choose afterwards **XMC1100 XMC2Go** from the **Tools**>**Board** menu in the Arduino IDE if working with this evaluation board. To use it, please plug the DPS3xx Pressure Shield2Go onto the XMC2Go as shown below. - - - -### Additional Information -Please find the datasheet of the DPS368 [here](https://www.infineon.com/dgdl/Infineon-DPS368-DS-v01_00-EN.pdf?fileId=5546d46269e1c019016a0c45105d4b40) and DPS310 [here](https://www.infineon.com/dgdl/Infineon-DPS310-DS-v01_00-EN.pdf?fileId=5546d462576f34750157750826c42242). It depends on the evaluation board which you are using or the respective configuration of the sensor on your PCB which communication protocol as well as addresses you need to use for communicating with the sensor. +# XENSIV™ Digital Pressure Sensor Arduino Library + +Arduino library of Infineon's [**XENSIV™ Digital Pressure Sensors (DPS)**](https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/). + + + +## Supported Products + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
products
XENSIV™ DPS310XENSIV™ DPS368
shield2go
XENSIV™ DPS310 Shield2GoXENSIV™ DPS368 Shield2Go
kit2go
XENSIV™ DPS310 Kit 2GoXENSIV™ DPS368 Kit 2Go
+ +## Getting Started + +### Installation + +To install the digital pressure sensor library in the Arduino IDE, please go to **Sketch** > **Include Library** > **Manage Libraries...** search for the ```DigitalPressureSensor``` library by Infineon 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. + +## License + +See the [LICENSE](LICENSE.md) file for more details. \ No newline at end of file diff --git a/docs/img/dps310-kit2go.png b/docs/img/dps310-kit2go.png new file mode 100644 index 0000000..b0d6773 Binary files /dev/null and b/docs/img/dps310-kit2go.png differ diff --git a/docs/img/dps310-shield2go.png b/docs/img/dps310-shield2go.png new file mode 100644 index 0000000..afd17f5 Binary files /dev/null and b/docs/img/dps310-shield2go.png differ diff --git a/docs/img/dps310.png b/docs/img/dps310.png new file mode 100644 index 0000000..5cbb69e Binary files /dev/null and b/docs/img/dps310.png differ diff --git a/docs/img/dps368-kit2go.png b/docs/img/dps368-kit2go.png new file mode 100644 index 0000000..38e4da0 Binary files /dev/null and b/docs/img/dps368-kit2go.png differ diff --git a/docs/img/dps368-shield2go.png b/docs/img/dps368-shield2go.png new file mode 100644 index 0000000..4e0b5f0 Binary files /dev/null and b/docs/img/dps368-shield2go.png differ diff --git a/docs/img/dps368.png b/docs/img/dps368.png new file mode 100644 index 0000000..f55ea4a Binary files /dev/null and b/docs/img/dps368.png differ diff --git a/examples/i2c_background/i2c_background.ino b/examples/i2c_background/i2c_background.ino index 1657458..14ae871 100644 --- a/examples/i2c_background/i2c_background.ino +++ b/examples/i2c_background/i2c_background.ino @@ -1,42 +1,67 @@ #include +/** + * @details This example shows how to read several results for the temperature + * and the pressure from the DPS3xx buffer. The DPS3xx can hold up + * to 32 value inside the buffer. If this value is reach no further + * values are stored. + */ -// Dps3xx Opject + +// Dps3xx Object Dps3xx Dps3xxPressureSensor = Dps3xx(); void setup() { Serial.begin(9600); - while (!Serial); + while (!Serial) + ; - //Call begin to initialize Dps3xxPressureSensor - //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. - //Dps3xxPressureSensor.begin(Wire, 0x76); - //Use the line below instead to use the default I2C address. + /* + * Call begin to initialize Dps3xxPressureSensor + * The parameter 0x76 is the bus address. The default address is 0x77 + * and does not need to be given. Dps3xxPressureSensor.begin(Wire, 0x76); + * Use the line below instead to use the default I2C address. + */ Dps3xxPressureSensor.begin(Wire); - //temperature measure rate (value from 0 to 7) - //2^temp_mr temperature measurement results per second + /* + * temperature measure rate (value from 0 to 7) + * 2^temp_mr temperature measurement results per second + */ int16_t temp_mr = 2; - //temperature oversampling rate (value from 0 to 7) - //2^temp_osr internal temperature measurements per result - //A higher value increases precision + + /* + * temperature oversampling rate (value from 0 to 7) + * 2^temp_osr internal temperature measurements per result + * A higher value increases precision + */ int16_t temp_osr = 2; - //pressure measure rate (value from 0 to 7) - //2^prs_mr pressure measurement results per second + + /* + * pressure measure rate (value from 0 to 7) + * 2^prs_mr pressure measurement results per second + */ int16_t prs_mr = 2; - //pressure oversampling rate (value from 0 to 7) - //2^prs_osr internal pressure measurements per result - //A higher value increases precision + + /* + * pressure oversampling rate (value from 0 to 7) + * 2^prs_osr internal pressure measurements per result + * A higher value increases precision + */ int16_t prs_osr = 2; - //startMeasureBothCont enables background mode - //temperature and pressure ar measured automatically - //High precision and hgh measure rates at the same time are not available. - //Consult Datasheet (or trial and error) for more information - int16_t ret = Dps3xxPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); - //Use one of the commented lines below instead to measure only temperature or pressure - //int16_t ret = Dps3xxPressureSensor.startMeasureTempCont(temp_mr, temp_osr); - //int16_t ret = Dps3xxPressureSensor.startMeasurePressureCont(prs_mr, prs_osr); + /* + * startMeasureBothCont enables background mode + * temperature and pressure ar measured automatically + * High precision and hgh measure rates at the same time are not available. + * Consult Datasheet (or trial and error) for more information + */ + int16_t ret = Dps3xxPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); + /* + * Use one of the commented lines below instead to measure only temperature or pressure + * int16_t ret = Dps3xxPressureSensor.startMeasureTempCont(temp_mr, temp_osr); + * int16_t ret = Dps3xxPressureSensor.startMeasurePressureCont(prs_mr, prs_osr); + */ if (ret != 0) { @@ -49,19 +74,19 @@ void setup() } } - - void loop() { uint8_t pressureCount = 20; float pressure[pressureCount]; uint8_t temperatureCount = 20; - float temperature[temperatureCount]; + float temperature[temperatureCount]; - //This function writes the results of continuous measurements to the arrays given as parameters - //The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called - //After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays - //Note: The Dps3xx cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results + /* + * This function writes the results of continuous measurements to the arrays given as parameters + * The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called + * After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays + * Note: The Dps3xx cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results + */ int16_t ret = Dps3xxPressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); if (ret != 0) @@ -93,6 +118,6 @@ void loop() } } - //Wait some time, so that the Dps3xx can refill its buffer + // Wait some time, so that the Dps3xx can refill its buffer delay(10000); } diff --git a/examples/i2c_command/i2c_command.ino b/examples/i2c_command/i2c_command.ino index de736ff..c6be7ee 100644 --- a/examples/i2c_command/i2c_command.ino +++ b/examples/i2c_command/i2c_command.ino @@ -1,26 +1,33 @@ #include +/** + * @details This example shows how to read temperature and pressure in a loop with a + * high oversampling rate. + * The oversampling rate can be set between 0 and 7 the higher the value the + * more precise the value is. + */ -// Dps3xx Opject + +// Dps3xx Object Dps3xx Dps3xxPressureSensor = Dps3xx(); void setup() { Serial.begin(9600); - while (!Serial); - + while (!Serial) + ; - //Call begin to initialize Dps3xxPressureSensor - //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. - //Dps3xxPressureSensor.begin(Wire, 0x76); - //Use the line below instead of the one above to use the default I2C address. - //if you are using the Pressure 3 click Board, you need 0x76 + /* + * Call begin to initialize Dps3xxPressureSensor + * The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + * Dps3xxPressureSensor.begin(Wire, 0x76); + * Use the line below instead of the one above to use the default I2C address. + * if you are using the Pressure 3 click Board, you need 0x76 + */ Dps3xxPressureSensor.begin(Wire); Serial.println("Init complete!"); } - - void loop() { float temperature; @@ -29,19 +36,23 @@ void loop() int16_t ret; Serial.println(); - //lets the Dps3xx perform a Single temperature measurement with the last (or standard) configuration - //The result will be written to the paramerter temperature - //ret = Dps3xxPressureSensor.measureTempOnce(temperature); - //the commented line below does exactly the same as the one above, but you can also config the precision - //oversampling can be a value from 0 to 7 - //the Dps 3xx will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision - //measurements with higher precision take more time, consult datasheet for more information + /* + * lets the Dps3xx perform a Single temperature measurement with the last (or standard) configuration + * The result will be written to the parameter temperature + * ret = Dps3xxPressureSensor.measureTempOnce(temperature); + * the commented line below does exactly the same as the one above, but you can also config the precision + * oversampling can be a value from 0 to 7 + * the Dps 3xx will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision + * measurements with higher precision take more time, consult datasheet for more information + */ ret = Dps3xxPressureSensor.measureTempOnce(temperature, oversampling); if (ret != 0) { - //Something went wrong. - //Look at the library code for more information about return codes + /* + * Something went wrong. + * Look at the library code for more information about return codes + */ Serial.print("FAIL! ret = "); Serial.println(ret); } @@ -52,13 +63,15 @@ void loop() Serial.println(" degrees of Celsius"); } - //Pressure measurement behaves like temperature measurement - //ret = Dps3xxPressureSensor.measurePressureOnce(pressure); + /* + * Pressure measurement behaves like temperature measurement + * ret = Dps3xxPressureSensor.measurePressureOnce(pressure); + */ ret = Dps3xxPressureSensor.measurePressureOnce(pressure, oversampling); if (ret != 0) { - //Something went wrong. - //Look at the library code for more information about return codes + // Something went wrong. + // Look at the library code for more information about return codes Serial.print("FAIL! ret = "); Serial.println(ret); } @@ -69,6 +82,6 @@ void loop() Serial.println(" Pascal"); } - //Wait some time + // Wait some time delay(500); } diff --git a/examples/i2c_interrupt/i2c_interrupt.ino b/examples/i2c_interrupt/i2c_interrupt.ino index 0f98707..5f4d4a9 100644 --- a/examples/i2c_interrupt/i2c_interrupt.ino +++ b/examples/i2c_interrupt/i2c_interrupt.ino @@ -1,52 +1,73 @@ #include - -// Dps3xx Opject +/** + * @details This example shows how to read temperature and pressure in a loop with a + * high oversampling rate. + * The oversampling rate can be set between 0 and 7 the higher the value the + * more precise the value is. + */ + +// Dps3xx Object Dps3xx Dps3xxPressureSensor = Dps3xx(); void onFifoFull(); - void setup() { Serial.begin(9600); - while (!Serial); - - //Call begin to initialize Dps3xxPressureSensor - //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. - //Dps3xxPressureSensor.begin(Wire, 0x76); - //Use the commented line below instead to use the default I2C address. - - Dps3xxPressureSensor.begin(Wire); + while (!Serial) + ; + + /* + * Call begin to initialize Dps3xxPressureSensor + * The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + * Dps3xxPressureSensor.begin(Wire, 0x76); + * Use the commented line below instead to use the default I2C address. + */ + + Dps3xxPressureSensor.begin(Wire); int16_t val = Dps3xxPressureSensor.setInterruptSources(4, 0); - //clear interrupt flag by reading + // clear interrupt flag by reading Dps3xxPressureSensor.getIntStatusFifoFull(); - //initialization of Interrupt for Controller unit - //SDO pin of Dps3xx has to be connected with interrupt pin + /* + * initialization of Interrupt for Controller unit + * SDO pin of Dps3xx has to be connected with interrupt pin + */ int16_t interruptPin = 9; pinMode(interruptPin, INPUT); attachInterrupt(digitalPinToInterrupt(interruptPin), onFifoFull, RISING); - - - //temperature measure rate (value from 0 to 7) - //2^temp_mr temperature measurement results per second + /* + * temperature measure rate (value from 0 to 7) + * 2^temp_mr temperature measurement results per second + */ int16_t temp_mr = 5; - //temperature oversampling rate (value from 0 to 7) - //2^temp_osr internal temperature measurements per result - //A higher value increases precision + + /* + * temperature oversampling rate (value from 0 to 7) + * 2^temp_osr internal temperature measurements per result + * A higher value increases precision + */ int16_t temp_osr = 1; - //pressure measure rate (value from 0 to 7) - //2^prs_mr pressure measurement results per second + + /* + * pressure measure rate (value from 0 to 7) + * 2^prs_mr pressure measurement results per second + */ int16_t prs_mr = 5; - //pressure oversampling rate (value from 0 to 7) - //2^prs_osr internal pressure measurements per result - //A higher value increases precision + + /* + * pressure oversampling rate (value from 0 to 7) + * 2^prs_osr internal pressure measurements per result + * A higher value increases precision + */ int16_t prs_osr = 1; - //startMeasureBothCont enables background mode - //temperature and pressure ar measured automatically - //High precision and hgh measure rates at the same time are not available. - //Consult Datasheet (or trial and error) for more information - + + /* + * startMeasureBothCont enables background mode + * temperature and pressure are measured automatically + * High precision and high measure rates at the same time are not available. + * Consult Datasheet (or trial and error) for more information + */ int16_t ret = Dps3xxPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); if (ret != 0) @@ -66,17 +87,18 @@ void loop() float pressure[pressureCount]; uint8_t temperatureCount = 20; float temperature[temperatureCount]; - - int16_t val = Dps3xxPressureSensor.getIntStatusFifoFull(); + int16_t val = Dps3xxPressureSensor.getIntStatusFifoFull(); - //This function writes the results of continuous measurements to the arrays given as parameters - //The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called - //After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays - //Note: The Dps3xx cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results - int16_t ret = Dps3xxPressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); + /* + * This function writes the results of continuous measurements to the arrays given as parameters + * The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called + * After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays + * Note: The Dps3xx cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results + */ + int16_t ret = Dps3xxPressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); - if (ret != 0) + if (ret != 0) { Serial.println(); Serial.println(); @@ -105,14 +127,13 @@ void loop() } } - //Wait some time, so that the Dps3xx can refill its buffer + // Wait some time, so that the Dps3xx can refill its buffer delay(10000); } void onFifoFull() { - //message for debugging + // message for debugging Serial.println("Interrupt handler called"); Dps3xxPressureSensor.getIntStatusFifoFull(); - } diff --git a/library.json b/library.json index 9f91f1a..0a0cbdd 100644 --- a/library.json +++ b/library.json @@ -1,13 +1,13 @@ { - "name": "Digital-Pressure-Sensor", + "name": "XENSIV Digital Pressure Sensor", "keywords": "barometric, pressure, temperature, sensor, shield2go", - "description": "Library of Infineon's highly sensitive DPS3xx sensor.", + "description": "Arduino library for Infineon's Digital Pressure Sensor (DPS3xx) series.", "repository": { "type": "git", - "url": "https://github.com/Infineon/DPS3xx-Library-Arduino" + "url": "https://github.com/Infineon/arduino-xensiv-dps3xx" }, - "version": "1.0.6", + "version": "1.0.0", "frameworks": "arduino", "platforms": "infineonxmc" } diff --git a/library.properties b/library.properties index 831e409..db0277e 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,8 @@ -name=DPS3xx Barometric Pressure Sensor +name=XENSIV Digital Pressure Sensor version=1.0.0 author=Infineon Technologies maintainer=Infineon Technologies -sentence=This library provides an interface for Infineon's DPS3xx pressure sensor. -paragraph=The DPS series are highly-sensitive pressure sensors (with temperature compensation) that can be connected via SPI or I2C. +sentence=Arduino library for the Infineon XENSIV(TM) Digital Pressure Sensors (DPS3xx). +paragraph=The XENSIV(TM) barometric pressure sensor series (DPS3xx) offers excellent pressure noise performance and high stability over temperature. category=Sensors -url=https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps368/ -url=https://www.infineon.com/cms/en/product/sensor/pressure-sensors/pressure-sensors-for-iot/dps310/ - +url=https://github.com/Infineon/arduino-xensiv-dps3xx \ No newline at end of file diff --git a/src/Dps3xx.cpp b/src/Dps3xx.cpp index d481287..a043e1f 100644 --- a/src/Dps3xx.cpp +++ b/src/Dps3xx.cpp @@ -4,187 +4,187 @@ using namespace dps; using namespace dps3xx; int16_t Dps3xx::getContResults(float *tempBuffer, - uint8_t &tempCount, - float *prsBuffer, - uint8_t &prsCount) + uint8_t &tempCount, + float *prsBuffer, + uint8_t &prsCount) { - return DpsClass::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); + return DpsClass::getContResults(tempBuffer, tempCount, prsBuffer, prsCount, registers[FIFO_EMPTY]); } #ifndef DPS_DISABLESPI int16_t Dps3xx::setInterruptSources(uint8_t intr_source, uint8_t polarity) { - //Interrupts are not supported with 4 Wire SPI - if (!m_SpiI2c & !m_threeWire) - { - return DPS__FAIL_UNKNOWN; - } - return writeByteBitfield(intr_source, registers[INT_SEL]) || writeByteBitfield(polarity, registers[INT_HL]); + // Interrupts are not supported with 4 Wire SPI + if (!m_SpiI2c & !m_threeWire) + { + return DPS__FAIL_UNKNOWN; + } + return writeByteBitfield(intr_source, registers[INT_SEL]) || writeByteBitfield(polarity, registers[INT_HL]); } #endif 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 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); - - //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; + // TODO: remove magic number + uint8_t buffer[18]; + // read COEF registers to buffer + int16_t ret = readBlock(coeffBlock, buffer); + + // 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 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; + 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; + float temp = raw; - //scale temperature according to scaling table and oversampling - temp /= scaling_facts[m_tempOsr]; + // 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; + // update last measured temperature + // it will be used for pressure compensation + m_lastTempScal = temp; - //Calculate compensated temperature - temp = m_c0Half + m_c1 * temp; + // Calculate compensated temperature + temp = m_c0Half + m_c1 * temp; - return temp; + return temp; } float Dps3xx::calcPressure(int32_t raw) { - float prs = raw; + float prs = raw; - //scale pressure according to scaling table and oversampling - prs /= scaling_facts[m_prsOsr]; + // 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)); + // 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; + // return pressure + return prs; } int16_t Dps3xx::flushFIFO() { - return writeByteBitfield(1U, registers[FIFO_FL]); + return writeByteBitfield(1U, registers[FIFO_FL]); } diff --git a/src/Dps3xx.h b/src/Dps3xx.h index d5508bc..048775f 100644 --- a/src/Dps3xx.h +++ b/src/Dps3xx.h @@ -7,33 +7,33 @@ class Dps3xx : public DpsClass { public: - int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); + 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); + /** + * @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; + uint8_t m_tempSensor; - //compensation coefficients - int32_t m_c0Half; - int32_t m_c1; + // compensation coefficients + int32_t m_c0Half; + int32_t m_c1; - /////// implement pure virtual functions /////// + /////// 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); + 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 \ No newline at end of file diff --git a/src/DpsClass.cpp b/src/DpsClass.cpp index 3994d7d..89231d1 100644 --- a/src/DpsClass.cpp +++ b/src/DpsClass.cpp @@ -3,801 +3,804 @@ using namespace dps; const int32_t DpsClass::scaling_facts[DPS__NUM_OF_SCAL_FACTS] = {524288, 1572864, 3670016, 7864320, 253952, 516096, 1040384, 2088960}; -//////// Constructor, Destructor, begin, end //////// +//////// Constructor, Destructor, begin, end //////// DpsClass::DpsClass(void) { - //assume that initialization has failed before it has been done - m_initFail = 1U; + // assume that initialization has failed before it has been done + m_initFail = 1U; } DpsClass::~DpsClass(void) { - end(); + end(); } void DpsClass::begin(TwoWire &bus) { - begin(bus, DPS__STD_SLAVE_ADDRESS); + begin(bus, DPS__STD_SLAVE_ADDRESS); } void DpsClass::begin(TwoWire &bus, uint8_t slaveAddress) { - //this flag will show if the initialization was successful - m_initFail = 0U; + // this flag will show if the initialization was successful + m_initFail = 0U; - //Set I2C bus connection - m_SpiI2c = 1U; - m_i2cbus = &bus; - m_slaveAddress = slaveAddress; + // Set I2C bus connection + m_SpiI2c = 1U; + m_i2cbus = &bus; + m_slaveAddress = slaveAddress; - // Init bus - m_i2cbus->begin(); + // Init bus + m_i2cbus->begin(); - delay(50); //startup time of Dps3xx + delay(50); // startup time of Dps3xx - init(); + init(); } #ifndef DPS_DISABLESPI void DpsClass::begin(SPIClass &bus, int32_t chipSelect) { - begin(bus, chipSelect, 0U); + begin(bus, chipSelect, 0U); } #endif #ifndef DPS_DISABLESPI void DpsClass::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) { - //this flag will show if the initialization was successful - m_initFail = 0U; + // this flag will show if the initialization was successful + m_initFail = 0U; - //Set SPI bus connection - m_SpiI2c = 0U; - m_spibus = &bus; - m_chipSelect = chipSelect; + // Set SPI bus connection + m_SpiI2c = 0U; + m_spibus = &bus; + m_chipSelect = chipSelect; - // Init bus - m_spibus->begin(); - m_spibus->setDataMode(SPI_MODE3); + // Init bus + m_spibus->begin(); + m_spibus->setDataMode(SPI_MODE3); - pinMode(m_chipSelect, OUTPUT); - digitalWrite(m_chipSelect, HIGH); + pinMode(m_chipSelect, OUTPUT); + digitalWrite(m_chipSelect, HIGH); - delay(50); //startup time of Dps3xx + delay(50); // startup time of Dps3xx - //switch to 3-wire mode if necessary - //do not use writeByteBitfield or check option to set SPI mode! - //Reading is not possible until SPI-mode is valid - if (threeWire) - { - m_threeWire = 1U; - if (writeByte(DPS3xx__REG_ADR_SPI3W, DPS3xx__REG_CONTENT_SPI3W)) - { - m_initFail = 1U; - return; - } - } + // switch to 3-wire mode if necessary + // do not use writeByteBitfield or check option to set SPI mode! + // Reading is not possible until SPI-mode is valid + if (threeWire) + { + m_threeWire = 1U; + if (writeByte(DPS3xx__REG_ADR_SPI3W, DPS3xx__REG_CONTENT_SPI3W)) + { + m_initFail = 1U; + return; + } + } - init(); + init(); } #endif void DpsClass::end(void) { - standby(); + standby(); } -//////// Declaration of other public functions starts here //////// +//////// Declaration of other public functions starts here //////// uint8_t DpsClass::getProductId(void) { - return m_productID; + return m_productID; } uint8_t DpsClass::getRevisionId(void) { - return m_revisionID; + return m_revisionID; } int16_t DpsClass::getContResults(float *tempBuffer, - uint8_t &tempCount, - float *prsBuffer, - uint8_t &prsCount, RegMask_t fifo_empty_reg) -{ - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //abort if device is not in background mode - if (!(m_opMode & 0x04)) - { - return DPS__FAIL_TOOBUSY; - } - - if (!tempBuffer || !prsBuffer) - { - return DPS__FAIL_UNKNOWN; - } - tempCount = 0U; - prsCount = 0U; - - //while FIFO is not empty - while (readByteBitfield(fifo_empty_reg) == 0) - { - int32_t raw_result; - float result; - //read next result from FIFO - int16_t type = getFIFOvalue(&raw_result); - switch (type) - { - case 0: //temperature - if (tempCount < DPS__FIFO_SIZE) - { - result = calcTemp(raw_result); - tempBuffer[tempCount++] = result; - } - break; - case 1: //pressure - if (prsCount < DPS__FIFO_SIZE) - { - result = calcPressure(raw_result); - prsBuffer[prsCount++] = result; - } - break; - case -1: //read failed - break; - } - } - return DPS__SUCCEEDED; + uint8_t &tempCount, + float *prsBuffer, + uint8_t &prsCount, RegMask_t fifo_empty_reg) +{ + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // abort if device is not in background mode + if (!(m_opMode & 0x04)) + { + return DPS__FAIL_TOOBUSY; + } + + if (!tempBuffer || !prsBuffer) + { + return DPS__FAIL_UNKNOWN; + } + tempCount = 0U; + prsCount = 0U; + + // while FIFO is not empty + while (readByteBitfield(fifo_empty_reg) == 0) + { + int32_t raw_result; + float result; + // read next result from FIFO + int16_t type = getFIFOvalue(&raw_result); + switch (type) + { + case 0: // temperature + if (tempCount < DPS__FIFO_SIZE) + { + result = calcTemp(raw_result); + tempBuffer[tempCount++] = result; + } + break; + case 1: // pressure + if (prsCount < DPS__FIFO_SIZE) + { + result = calcPressure(raw_result); + prsBuffer[prsCount++] = result; + } + break; + case -1: // read failed + break; + } + } + return DPS__SUCCEEDED; } int16_t DpsClass::getSingleResult(float &result) { - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - - //read finished bit for current opMode - int16_t rdy; - switch (m_opMode) - { - case CMD_TEMP: //temperature - rdy = readByteBitfield(config_registers[TEMP_RDY]); - break; - case CMD_PRS: //pressure - rdy = readByteBitfield(config_registers[PRS_RDY]); - break; - default: //DPS3xx not in command mode - return DPS__FAIL_TOOBUSY; - } - //read new measurement result - switch (rdy) - { - case DPS__FAIL_UNKNOWN: //could not read ready flag - return DPS__FAIL_UNKNOWN; - case 0: //ready flag not set, measurement still in progress - return DPS__FAIL_UNFINISHED; - case 1: //measurement ready, expected case - Mode oldMode = m_opMode; - m_opMode = IDLE; //opcode was automatically reseted by DPS3xx - int32_t raw_val; - switch (oldMode) - { - case CMD_TEMP: //temperature - getRawResult(&raw_val, registerBlocks[TEMP]); - result = calcTemp(raw_val); - return DPS__SUCCEEDED; // TODO - case CMD_PRS: //pressure - getRawResult(&raw_val, registerBlocks[PRS]); - result = calcPressure(raw_val); - return DPS__SUCCEEDED; // TODO - default: - return DPS__FAIL_UNKNOWN; //should already be filtered above - } - } - return DPS__FAIL_UNKNOWN; + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + + // read finished bit for current opMode + int16_t rdy; + switch (m_opMode) + { + case CMD_TEMP: // temperature + rdy = readByteBitfield(config_registers[TEMP_RDY]); + break; + case CMD_PRS: // pressure + rdy = readByteBitfield(config_registers[PRS_RDY]); + break; + default: // DPS3xx not in command mode + return DPS__FAIL_TOOBUSY; + } + // read new measurement result + switch (rdy) + { + case DPS__FAIL_UNKNOWN: // could not read ready flag + return DPS__FAIL_UNKNOWN; + case 0: // ready flag not set, measurement still in progress + return DPS__FAIL_UNFINISHED; + case 1: // measurement ready, expected case + Mode oldMode = m_opMode; + m_opMode = IDLE; // opcode was automatically reset by DPS3xx + int32_t raw_val; + switch (oldMode) + { + case CMD_TEMP: // temperature + getRawResult(&raw_val, registerBlocks[TEMP]); + result = calcTemp(raw_val); + return DPS__SUCCEEDED; // TODO + case CMD_PRS: // pressure + getRawResult(&raw_val, registerBlocks[PRS]); + result = calcPressure(raw_val); + return DPS__SUCCEEDED; // TODO + default: + return DPS__FAIL_UNKNOWN; // should already be filtered above + } + } + return DPS__FAIL_UNKNOWN; } int16_t DpsClass::measureTempOnce(float &result) { - return measureTempOnce(result, m_tempOsr); + return measureTempOnce(result, m_tempOsr); } int16_t DpsClass::measureTempOnce(float &result, uint8_t oversamplingRate) { - //Start measurement - int16_t ret = startMeasureTempOnce(oversamplingRate); - if (ret != DPS__SUCCEEDED) - { - return ret; - } + // Start measurement + int16_t ret = startMeasureTempOnce(oversamplingRate); + if (ret != DPS__SUCCEEDED) + { + return ret; + } - //wait until measurement is finished - delay(calcBusyTime(0U, m_tempOsr) / DPS__BUSYTIME_SCALING); - delay(DPS3xx__BUSYTIME_FAILSAFE); + // wait until measurement is finished + delay(calcBusyTime(0U, m_tempOsr) / DPS__BUSYTIME_SCALING); + delay(DPS3xx__BUSYTIME_FAILSAFE); - ret = getSingleResult(result); - if (ret != DPS__SUCCEEDED) - { - standby(); - } - return ret; + ret = getSingleResult(result); + if (ret != DPS__SUCCEEDED) + { + standby(); + } + return ret; } int16_t DpsClass::startMeasureTempOnce(void) { - return startMeasureTempOnce(m_tempOsr); + return startMeasureTempOnce(m_tempOsr); } int16_t DpsClass::startMeasureTempOnce(uint8_t oversamplingRate) { - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //abort if device is not in idling mode - if (m_opMode != IDLE) - { - return DPS__FAIL_TOOBUSY; - } - - if (oversamplingRate != m_tempOsr) - { - //configuration of oversampling rate - if (configTemp(0U, oversamplingRate) != DPS__SUCCEEDED) - { - return DPS__FAIL_UNKNOWN; - } - } - - //set device to temperature measuring mode - return setOpMode(CMD_TEMP); + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + + if (oversamplingRate != m_tempOsr) + { + // configuration of oversampling rate + if (configTemp(0U, oversamplingRate) != DPS__SUCCEEDED) + { + return DPS__FAIL_UNKNOWN; + } + } + + // set device to temperature measuring mode + return setOpMode(CMD_TEMP); } int16_t DpsClass::measurePressureOnce(float &result) { - return measurePressureOnce(result, m_prsOsr); + return measurePressureOnce(result, m_prsOsr); } int16_t DpsClass::measurePressureOnce(float &result, uint8_t oversamplingRate) { - //start the measurement - int16_t ret = startMeasurePressureOnce(oversamplingRate); - if (ret != DPS__SUCCEEDED) - { - return ret; - } + // start the measurement + int16_t ret = startMeasurePressureOnce(oversamplingRate); + if (ret != DPS__SUCCEEDED) + { + return ret; + } - //wait until measurement is finished - delay(calcBusyTime(0U, m_prsOsr) / DPS__BUSYTIME_SCALING); - delay(DPS3xx__BUSYTIME_FAILSAFE); + // wait until measurement is finished + delay(calcBusyTime(0U, m_prsOsr) / DPS__BUSYTIME_SCALING); + delay(DPS3xx__BUSYTIME_FAILSAFE); - ret = getSingleResult(result); - if (ret != DPS__SUCCEEDED) - { - standby(); - } - return ret; + ret = getSingleResult(result); + if (ret != DPS__SUCCEEDED) + { + standby(); + } + return ret; } int16_t DpsClass::startMeasurePressureOnce(void) { - return startMeasurePressureOnce(m_prsOsr); + return startMeasurePressureOnce(m_prsOsr); } int16_t DpsClass::startMeasurePressureOnce(uint8_t oversamplingRate) { - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //abort if device is not in idling mode - if (m_opMode != IDLE) - { - return DPS__FAIL_TOOBUSY; - } - //configuration of oversampling rate, lowest measure rate to avoid conflicts - if (oversamplingRate != m_prsOsr) - { - if (configPressure(0U, oversamplingRate)) - { - return DPS__FAIL_UNKNOWN; - } - } - //set device to pressure measuring mode - return setOpMode(CMD_PRS); + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + // configuration of oversampling rate, lowest measure rate to avoid conflicts + if (oversamplingRate != m_prsOsr) + { + if (configPressure(0U, oversamplingRate)) + { + return DPS__FAIL_UNKNOWN; + } + } + // set device to pressure measuring mode + return setOpMode(CMD_PRS); } int16_t DpsClass::startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate) { - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //abort if device is not in idling mode - if (m_opMode != IDLE) - { - return DPS__FAIL_TOOBUSY; - } - //abort if speed and precision are too high - if (calcBusyTime(measureRate, oversamplingRate) >= DPS3xx__MAX_BUSYTIME) - { - return DPS__FAIL_UNFINISHED; - } - //update precision and measuring rate - if (configTemp(measureRate, oversamplingRate)) - { - return DPS__FAIL_UNKNOWN; - } - - if (enableFIFO()) - { - return DPS__FAIL_UNKNOWN; - } - //Start measuring in background mode - if (DpsClass::setOpMode(CONT_TMP)) - { - return DPS__FAIL_UNKNOWN; - } - return DPS__SUCCEEDED; + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + // abort if speed and precision are too high + if (calcBusyTime(measureRate, oversamplingRate) >= DPS3xx__MAX_BUSYTIME) + { + return DPS__FAIL_UNFINISHED; + } + // update precision and measuring rate + if (configTemp(measureRate, oversamplingRate)) + { + return DPS__FAIL_UNKNOWN; + } + + if (enableFIFO()) + { + return DPS__FAIL_UNKNOWN; + } + // Start measuring in background mode + if (DpsClass::setOpMode(CONT_TMP)) + { + return DPS__FAIL_UNKNOWN; + } + return DPS__SUCCEEDED; } int16_t DpsClass::startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate) { - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //abort if device is not in idling mode - if (m_opMode != IDLE) - { - return DPS__FAIL_TOOBUSY; - } - //abort if speed and precision are too high - if (calcBusyTime(measureRate, oversamplingRate) >= DPS3xx__MAX_BUSYTIME) - { - return DPS__FAIL_UNFINISHED; - } - //update precision and measuring rate - if (configPressure(measureRate, oversamplingRate)) - return DPS__FAIL_UNKNOWN; - //enable result FIFO - if (enableFIFO()) - { - return DPS__FAIL_UNKNOWN; - } - //Start measuring in background mode - if (DpsClass::setOpMode(CONT_PRS)) - { - return DPS__FAIL_UNKNOWN; - } - return DPS__SUCCEEDED; + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + // abort if speed and precision are too high + if (calcBusyTime(measureRate, oversamplingRate) >= DPS3xx__MAX_BUSYTIME) + { + return DPS__FAIL_UNFINISHED; + } + // update precision and measuring rate + if (configPressure(measureRate, oversamplingRate)) + return DPS__FAIL_UNKNOWN; + // enable result FIFO + if (enableFIFO()) + { + return DPS__FAIL_UNKNOWN; + } + // Start measuring in background mode + if (DpsClass::setOpMode(CONT_PRS)) + { + return DPS__FAIL_UNKNOWN; + } + return DPS__SUCCEEDED; } int16_t DpsClass::startMeasureBothCont(uint8_t tempMr, - uint8_t tempOsr, - uint8_t prsMr, - uint8_t prsOsr) -{ - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //abort if device is not in idling mode - if (m_opMode != IDLE) - { - return DPS__FAIL_TOOBUSY; - } - //abort if speed and precision are too high - if (calcBusyTime(tempMr, tempOsr) + calcBusyTime(prsMr, prsOsr) >= DPS3xx__MAX_BUSYTIME) - { - return DPS__FAIL_UNFINISHED; - } - //update precision and measuring rate - if (configTemp(tempMr, tempOsr)) - { - return DPS__FAIL_UNKNOWN; - } - //update precision and measuring rate - if (configPressure(prsMr, prsOsr)) - return DPS__FAIL_UNKNOWN; - //enable result FIFO - if (enableFIFO()) - { - return DPS__FAIL_UNKNOWN; - } - //Start measuring in background mode - if (setOpMode(CONT_BOTH)) - { - return DPS__FAIL_UNKNOWN; - } - return DPS__SUCCEEDED; + uint8_t tempOsr, + uint8_t prsMr, + uint8_t prsOsr) +{ + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // abort if device is not in idling mode + if (m_opMode != IDLE) + { + return DPS__FAIL_TOOBUSY; + } + // abort if speed and precision are too high + if (calcBusyTime(tempMr, tempOsr) + calcBusyTime(prsMr, prsOsr) >= DPS3xx__MAX_BUSYTIME) + { + return DPS__FAIL_UNFINISHED; + } + // update precision and measuring rate + if (configTemp(tempMr, tempOsr)) + { + return DPS__FAIL_UNKNOWN; + } + // update precision and measuring rate + if (configPressure(prsMr, prsOsr)) + return DPS__FAIL_UNKNOWN; + // enable result FIFO + if (enableFIFO()) + { + return DPS__FAIL_UNKNOWN; + } + // Start measuring in background mode + if (setOpMode(CONT_BOTH)) + { + return DPS__FAIL_UNKNOWN; + } + return DPS__SUCCEEDED; } int16_t DpsClass::standby(void) { - //abort if initialization failed - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - //set device to idling mode - int16_t ret = setOpMode(IDLE); - if (ret != DPS__SUCCEEDED) - { - return ret; - } - ret = disableFIFO(); - return ret; + // abort if initialization failed + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + // set device to idling mode + int16_t ret = setOpMode(IDLE); + if (ret != DPS__SUCCEEDED) + { + return ret; + } + ret = disableFIFO(); + return ret; } int16_t DpsClass::correctTemp(void) { - if (m_initFail) - { - return DPS__FAIL_INIT_FAILED; - } - writeByte(0x0E, 0xA5); - writeByte(0x0F, 0x96); - writeByte(0x62, 0x02); - writeByte(0x0E, 0x00); - writeByte(0x0F, 0x00); + if (m_initFail) + { + return DPS__FAIL_INIT_FAILED; + } + writeByte(0x0E, 0xA5); + writeByte(0x0F, 0x96); + writeByte(0x62, 0x02); + writeByte(0x0E, 0x00); + writeByte(0x0F, 0x00); - //perform a first temperature measurement (again) - //the most recent temperature will be saved internally - //and used for compensation when calculating pressure - float trash; - measureTempOnce(trash); + // perform a first temperature measurement (again) + // the most recent temperature will be saved internally + // and used for compensation when calculating pressure + float trash; + measureTempOnce(trash); - return DPS__SUCCEEDED; + return DPS__SUCCEEDED; } int16_t DpsClass::getIntStatusFifoFull(void) { - return readByteBitfield(config_registers[INT_FLAG_FIFO]); + return readByteBitfield(config_registers[INT_FLAG_FIFO]); } int16_t DpsClass::getIntStatusTempReady(void) { - return readByteBitfield(config_registers[INT_FLAG_TEMP]); + return readByteBitfield(config_registers[INT_FLAG_TEMP]); } int16_t DpsClass::getIntStatusPrsReady(void) { - return readByteBitfield(config_registers[INT_FLAG_PRS]); + return readByteBitfield(config_registers[INT_FLAG_PRS]); } -//////// Declaration of private functions starts here //////// +//////// Declaration of private functions starts here //////// int16_t DpsClass::setOpMode(uint8_t opMode) { - if (writeByteBitfield(opMode, config_registers[MSR_CTRL]) == -1) - { - return DPS__FAIL_UNKNOWN; - } - m_opMode = (Mode)opMode; - return DPS__SUCCEEDED; + if (writeByteBitfield(opMode, config_registers[MSR_CTRL]) == -1) + { + return DPS__FAIL_UNKNOWN; + } + m_opMode = (Mode)opMode; + return DPS__SUCCEEDED; } int16_t DpsClass::configTemp(uint8_t tempMr, uint8_t tempOsr) { - tempMr &= 0x07; - tempOsr &= 0x07; - // two accesses to the same register; for readability - int16_t ret = writeByteBitfield(tempMr, config_registers[TEMP_MR]); - ret = writeByteBitfield(tempOsr, config_registers[TEMP_OSR]); + tempMr &= 0x07; + tempOsr &= 0x07; + // two accesses to the same register; for readability + int16_t ret = writeByteBitfield(tempMr, config_registers[TEMP_MR]); + ret = writeByteBitfield(tempOsr, config_registers[TEMP_OSR]); - //abort immediately on fail - if (ret != DPS__SUCCEEDED) - { - return DPS__FAIL_UNKNOWN; - } - m_tempMr = tempMr; - m_tempOsr = tempOsr; + // abort immediately on fail + if (ret != DPS__SUCCEEDED) + { + return DPS__FAIL_UNKNOWN; + } + m_tempMr = tempMr; + m_tempOsr = tempOsr; + return DPS__SUCCEEDED; } int16_t DpsClass::configPressure(uint8_t prsMr, uint8_t prsOsr) { - prsMr &= 0x07; - prsOsr &= 0x07; - int16_t ret = writeByteBitfield(prsMr, config_registers[PRS_MR]); - ret = writeByteBitfield(prsOsr, config_registers[PRS_OSR]); + prsMr &= 0x07; + prsOsr &= 0x07; + int16_t ret = writeByteBitfield(prsMr, config_registers[PRS_MR]); + ret = writeByteBitfield(prsOsr, config_registers[PRS_OSR]); + + // abort immediately on fail + if (ret != DPS__SUCCEEDED) + { + return DPS__FAIL_UNKNOWN; + } + m_prsMr = prsMr; + m_prsOsr = prsOsr; + return DPS__SUCCEEDED; - //abort immediately on fail - if (ret != DPS__SUCCEEDED) - { - return DPS__FAIL_UNKNOWN; - } - m_prsMr = prsMr; - m_prsOsr = prsOsr; } int16_t DpsClass::enableFIFO() { - return writeByteBitfield(1U, config_registers[FIFO_EN]); + return writeByteBitfield(1U, config_registers[FIFO_EN]); } int16_t DpsClass::disableFIFO() { - int16_t ret = flushFIFO(); - ret = writeByteBitfield(0U, config_registers[FIFO_EN]); - return ret; + int16_t ret = flushFIFO(); + ret = writeByteBitfield(0U, config_registers[FIFO_EN]); + return ret; } uint16_t DpsClass::calcBusyTime(uint16_t mr, uint16_t osr) { - //formula from datasheet (optimized) - return ((uint32_t)20U << mr) + ((uint32_t)16U << (osr + mr)); + // formula from datasheet (optimized) + return ((uint32_t)20U << mr) + ((uint32_t)16U << (osr + mr)); } int16_t DpsClass::getFIFOvalue(int32_t *value) { - uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; + uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; - //abort on invalid argument or failed block reading - if (value == NULL || readBlock(registerBlocks[PRS], buffer) != DPS__RESULT_BLOCK_LENGTH) - return DPS__FAIL_UNKNOWN; - *value = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; - getTwosComplement(value, 24); - return buffer[2] & 0x01; + // abort on invalid argument or failed block reading + if (value == NULL || readBlock(registerBlocks[PRS], buffer) != DPS__RESULT_BLOCK_LENGTH) + return DPS__FAIL_UNKNOWN; + *value = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; + getTwosComplement(value, 24); + return buffer[2] & 0x01; } int16_t DpsClass::readByte(uint8_t regAddress) { - #ifndef DPS_DISABLESPI - //delegate to specialized function if Dps3xx is connected via SPI - if (m_SpiI2c == 0) - { - return readByteSPI(regAddress); - } - #endif - - m_i2cbus->beginTransmission(m_slaveAddress); - m_i2cbus->write(regAddress); - m_i2cbus->endTransmission(false); - //request 1 byte from slave - if (m_i2cbus->requestFrom(m_slaveAddress, 1U, 1U) > 0) - { - return m_i2cbus->read(); //return this byte on success - } - else - { - return DPS__FAIL_UNKNOWN; //if 0 bytes were read successfully - } +#ifndef DPS_DISABLESPI + // delegate to specialized function if Dps3xx is connected via SPI + if (m_SpiI2c == 0) + { + return readByteSPI(regAddress); + } +#endif + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); + m_i2cbus->endTransmission(false); + // request 1 byte from slave + if (m_i2cbus->requestFrom(m_slaveAddress, 1U, 1U) > 0) + { + return m_i2cbus->read(); // return this byte on success + } + else + { + return DPS__FAIL_UNKNOWN; // if 0 bytes were read successfully + } } #ifndef DPS_DISABLESPI int16_t DpsClass::readByteSPI(uint8_t regAddress) { - //this function is only made for communication via SPI - if (m_SpiI2c != 0) - { - return DPS__FAIL_UNKNOWN; - } - //mask regAddress - regAddress &= ~DPS3xx__SPI_RW_MASK; - //reserve and initialize bus - m_spibus->beginTransaction(SPISettings(DPS3xx__SPI_MAX_FREQ, - MSBFIRST, - SPI_MODE3)); - //enable ChipSelect for Dps3xx - digitalWrite(m_chipSelect, LOW); - //send address with read command to Dps3xx - m_spibus->transfer(regAddress | DPS3xx__SPI_READ_CMD); - //receive register content from Dps3xx - uint8_t ret = m_spibus->transfer(0xFF); //send a dummy byte while receiving - //disable ChipSelect for Dps3xx - digitalWrite(m_chipSelect, HIGH); - //close current SPI transaction - m_spibus->endTransaction(); - //return received data - return ret; + // this function is only made for communication via SPI + if (m_SpiI2c != 0) + { + return DPS__FAIL_UNKNOWN; + } + // mask regAddress + regAddress &= ~DPS3xx__SPI_RW_MASK; + // reserve and initialize bus + m_spibus->beginTransaction(SPISettings(DPS3xx__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + // enable ChipSelect for Dps3xx + digitalWrite(m_chipSelect, LOW); + // send address with read command to Dps3xx + m_spibus->transfer(regAddress | DPS3xx__SPI_READ_CMD); + // receive register content from Dps3xx + uint8_t ret = m_spibus->transfer(0xFF); // send a dummy byte while receiving + // disable ChipSelect for Dps3xx + digitalWrite(m_chipSelect, HIGH); + // close current SPI transaction + m_spibus->endTransaction(); + // return received data + return ret; } #endif #ifndef DPS_DISABLESPI int16_t DpsClass::readBlockSPI(RegBlock_t regBlock, uint8_t *buffer) { - //this function is only made for communication via SPI - if (m_SpiI2c != 0) - { - return DPS__FAIL_UNKNOWN; - } - //do not read if there is no buffer - if (buffer == NULL) - { - return 0; //0 bytes were read successfully - } - //mask regAddress - regBlock.regAddress &= ~DPS3xx__SPI_RW_MASK; - //reserve and initialize bus - m_spibus->beginTransaction(SPISettings(DPS3xx__SPI_MAX_FREQ, - MSBFIRST, - SPI_MODE3)); - //enable ChipSelect for Dps3xx - digitalWrite(m_chipSelect, LOW); - //send address with read command to Dps3xx - m_spibus->transfer(regBlock.regAddress | DPS3xx__SPI_READ_CMD); - - //receive register contents from Dps3xx - for (uint8_t count = 0; count < regBlock.length; count++) - { - buffer[count] = m_spibus->transfer(0xFF); //send a dummy byte while receiving - } - - //disable ChipSelect for Dps3xx - digitalWrite(m_chipSelect, HIGH); - //close current SPI transaction - m_spibus->endTransaction(); - //return received data - return regBlock.length; + // this function is only made for communication via SPI + if (m_SpiI2c != 0) + { + return DPS__FAIL_UNKNOWN; + } + // do not read if there is no buffer + if (buffer == NULL) + { + return 0; // 0 bytes were read successfully + } + // mask regAddress + regBlock.regAddress &= ~DPS3xx__SPI_RW_MASK; + // reserve and initialize bus + m_spibus->beginTransaction(SPISettings(DPS3xx__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + // enable ChipSelect for Dps3xx + digitalWrite(m_chipSelect, LOW); + // send address with read command to Dps3xx + m_spibus->transfer(regBlock.regAddress | DPS3xx__SPI_READ_CMD); + + // receive register contents from Dps3xx + for (uint8_t count = 0; count < regBlock.length; count++) + { + buffer[count] = m_spibus->transfer(0xFF); // send a dummy byte while receiving + } + + // disable ChipSelect for Dps3xx + digitalWrite(m_chipSelect, HIGH); + // close current SPI transaction + m_spibus->endTransaction(); + // return received data + return regBlock.length; } #endif int16_t DpsClass::writeByte(uint8_t regAddress, uint8_t data) { - return writeByte(regAddress, data, 0U); + return writeByte(regAddress, data, 0U); } int16_t DpsClass::writeByte(uint8_t regAddress, uint8_t data, uint8_t check) { - #ifndef DPS_DISABLESPI - //delegate to specialized function if Dps3xx is connected via SPI - if (m_SpiI2c == 0) - { - return writeByteSpi(regAddress, data, check); - } - #endif - m_i2cbus->beginTransmission(m_slaveAddress); - m_i2cbus->write(regAddress); //Write Register number to buffer - m_i2cbus->write(data); //Write data to buffer - if (m_i2cbus->endTransmission() != 0) //Send buffer content to slave - { - return DPS__FAIL_UNKNOWN; - } - else - { - if (check == 0) - return 0; //no checking - if (readByte(regAddress) == data) //check if desired by calling function - { - return DPS__SUCCEEDED; - } - else - { - return DPS__FAIL_UNKNOWN; - } - } +#ifndef DPS_DISABLESPI + // delegate to specialized function if Dps3xx is connected via SPI + if (m_SpiI2c == 0) + { + return writeByteSpi(regAddress, data, check); + } +#endif + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); // Write Register number to buffer + m_i2cbus->write(data); // Write data to buffer + if (m_i2cbus->endTransmission() != 0) // Send buffer content to slave + { + return DPS__FAIL_UNKNOWN; + } + else + { + if (check == 0) + return 0; // no checking + if (readByte(regAddress) == data) // check if desired by calling function + { + return DPS__SUCCEEDED; + } + else + { + return DPS__FAIL_UNKNOWN; + } + } } #ifndef DPS_DISABLESPI int16_t DpsClass::writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check) { - //this function is only made for communication via SPI - if (m_SpiI2c != 0) - { - return DPS__FAIL_UNKNOWN; - } - //mask regAddress - regAddress &= ~DPS3xx__SPI_RW_MASK; - //reserve and initialize bus - m_spibus->beginTransaction(SPISettings(DPS3xx__SPI_MAX_FREQ, - MSBFIRST, - SPI_MODE3)); - //enable ChipSelect for Dps3xx - digitalWrite(m_chipSelect, LOW); - //send address with read command to Dps3xx - m_spibus->transfer(regAddress | DPS3xx__SPI_WRITE_CMD); - - //write register content from Dps3xx - m_spibus->transfer(data); - - //disable ChipSelect for Dps3xx - digitalWrite(m_chipSelect, HIGH); - //close current SPI transaction - m_spibus->endTransaction(); - - //check if necessary - if (check == 0) - { - //no checking necessary - return DPS__SUCCEEDED; - } - //checking necessary - if (readByte(regAddress) == data) - { - //check passed - return DPS__SUCCEEDED; - } - else - { - //check failed - return DPS__FAIL_UNKNOWN; - } + // this function is only made for communication via SPI + if (m_SpiI2c != 0) + { + return DPS__FAIL_UNKNOWN; + } + // mask regAddress + regAddress &= ~DPS3xx__SPI_RW_MASK; + // reserve and initialize bus + m_spibus->beginTransaction(SPISettings(DPS3xx__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + // enable ChipSelect for Dps3xx + digitalWrite(m_chipSelect, LOW); + // send address with read command to Dps3xx + m_spibus->transfer(regAddress | DPS3xx__SPI_WRITE_CMD); + + // write register content from Dps3xx + m_spibus->transfer(data); + + // disable ChipSelect for Dps3xx + digitalWrite(m_chipSelect, HIGH); + // close current SPI transaction + m_spibus->endTransaction(); + + // check if necessary + if (check == 0) + { + // no checking necessary + return DPS__SUCCEEDED; + } + // checking necessary + if (readByte(regAddress) == data) + { + // check passed + return DPS__SUCCEEDED; + } + else + { + // check failed + return DPS__FAIL_UNKNOWN; + } } #endif int16_t DpsClass::writeByteBitfield(uint8_t data, RegMask_t regMask) { - return writeByteBitfield(data, regMask.regAddress, regMask.mask, regMask.shift, 0U); + return writeByteBitfield(data, regMask.regAddress, regMask.mask, regMask.shift, 0U); } int16_t DpsClass::writeByteBitfield(uint8_t data, - uint8_t regAddress, - uint8_t mask, - uint8_t shift, - uint8_t check) + uint8_t regAddress, + uint8_t mask, + uint8_t shift, + uint8_t check) { - int16_t old = readByte(regAddress); - if (old < 0) - { - //fail while reading - return old; - } - return writeByte(regAddress, ((uint8_t)old & ~mask) | ((data << shift) & mask), check); + int16_t old = readByte(regAddress); + if (old < 0) + { + // fail while reading + return old; + } + return writeByte(regAddress, ((uint8_t)old & ~mask) | ((data << shift) & mask), check); } int16_t DpsClass::readByteBitfield(RegMask_t regMask) { - int16_t ret = readByte(regMask.regAddress); - if (ret < 0) - { - return ret; - } - return (((uint8_t)ret) & regMask.mask) >> regMask.shift; + int16_t ret = readByte(regMask.regAddress); + if (ret < 0) + { + return ret; + } + return (((uint8_t)ret) & regMask.mask) >> regMask.shift; } int16_t DpsClass::readBlock(RegBlock_t regBlock, uint8_t *buffer) { - #ifndef DPS_DISABLESPI - //delegate to specialized function if Dps3xx is connected via SPI - if (m_SpiI2c == 0) - { - return readBlockSPI(regBlock, buffer); - } - #endif - //do not read if there is no buffer - if (buffer == NULL) - { - return 0; //0 bytes read successfully - } - - m_i2cbus->beginTransmission(m_slaveAddress); - m_i2cbus->write(regBlock.regAddress); - m_i2cbus->endTransmission(false); - //request length bytes from slave - int16_t ret = m_i2cbus->requestFrom(m_slaveAddress, regBlock.length, 1U); - //read all received bytes to buffer - for (int16_t count = 0; count < ret; count++) - { - buffer[count] = m_i2cbus->read(); - } - return ret; +#ifndef DPS_DISABLESPI + // delegate to specialized function if Dps3xx is connected via SPI + if (m_SpiI2c == 0) + { + return readBlockSPI(regBlock, buffer); + } +#endif + // do not read if there is no buffer + if (buffer == NULL) + { + return 0; // 0 bytes read successfully + } + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regBlock.regAddress); + m_i2cbus->endTransmission(false); + // request length bytes from slave + int16_t ret = m_i2cbus->requestFrom(m_slaveAddress, regBlock.length, 1U); + // read all received bytes to buffer + for (int16_t count = 0; count < ret; count++) + { + buffer[count] = m_i2cbus->read(); + } + return ret; } void DpsClass::getTwosComplement(int32_t *raw, uint8_t length) { - if (*raw & ((uint32_t)1 << (length - 1))) - { - *raw -= (uint32_t)1 << length; - } + if (*raw & ((uint32_t)1 << (length - 1))) + { + *raw -= (uint32_t)1 << length; + } } int16_t DpsClass::getRawResult(int32_t *raw, RegBlock_t reg) { - uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; - if (readBlock(reg, buffer) != DPS__RESULT_BLOCK_LENGTH) - return DPS__FAIL_UNKNOWN; + uint8_t buffer[DPS__RESULT_BLOCK_LENGTH] = {0}; + if (readBlock(reg, buffer) != DPS__RESULT_BLOCK_LENGTH) + return DPS__FAIL_UNKNOWN; - *raw = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; - getTwosComplement(raw, 24); - return DPS__SUCCEEDED; + *raw = (uint32_t)buffer[0] << 16 | (uint32_t)buffer[1] << 8 | (uint32_t)buffer[2]; + getTwosComplement(raw, 24); + return DPS__SUCCEEDED; } diff --git a/src/DpsClass.h b/src/DpsClass.h index 65dcfd9..8d68b55 100644 --- a/src/DpsClass.h +++ b/src/DpsClass.h @@ -1,14 +1,14 @@ /** * Arduino library to control Dps3xx * - * "Dps3xx" represents Infineon's high-sensetive pressure and temperature sensor. - * It measures in ranges of 300 - 1200 hPa and -40 and 85 °C. - * The sensor can be connected via SPI or I2C. + * "Dps3xx" represents Infineon's high-sensitive pressure and temperature sensor. + * It measures in ranges of 300 - 1200 hPa and -40 and 85 °C. + * The sensor can be connected via SPI or I2C. * It is able to perform single measurements - * or to perform continuous measurements of temperature and pressure at the same time, - * and stores the results in a FIFO to reduce bus communication. + * or to perform continuous measurements of temperature and pressure at the same time, + * and stores the results in a FIFO to reduce bus communication. * - * Have a look at the datasheet for more information. + * Have a look at the datasheet for more information. */ #ifndef DPSCLASS_H_INCLUDED @@ -23,463 +23,471 @@ class DpsClass { - public: - //constructor - DpsClass(void); - //destructor - ~DpsClass(void); - - /** - * I2C begin function with standard address - */ - void begin(TwoWire &bus); - - /** - * Standard I2C begin function - * - * @param &bus: I2CBus which connects MC to the sensor - * @param slaveAddress: I2C address of the sensor (0x77 or 0x76) - */ - void begin(TwoWire &bus, uint8_t slaveAddress); +public: + // constructor + DpsClass(void); + // destructor + ~DpsClass(void); + + /** + * I2C begin function with standard address + */ + void begin(TwoWire &bus); + + /** + * Standard I2C begin function + * + * @param &bus: I2CBus which connects MC to the sensor + * @param slaveAddress: I2C address of the sensor (0x77 or 0x76) + */ + void begin(TwoWire &bus, uint8_t slaveAddress); #ifndef DPS_DISABLESPI - /** - * SPI begin function for Dps3xx with 4-wire SPI - */ - void begin(SPIClass &bus, int32_t chipSelect); + /** + * SPI begin function for Dps3xx with 4-wire SPI + */ + void begin(SPIClass &bus, int32_t chipSelect); #endif #ifndef DPS_DISABLESPI - /** - * Standard SPI begin function - * - * @param &bus: SPI bus which connects MC to Dps3xx - * @param chipSelect: Number of the CS line for the Dps3xx - * @param threeWire: 1 if Dps3xx is connected with 3-wire SPI - * 0 if Dps3xx is connected with 4-wire SPI (standard) - */ - void begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); + /** + * Standard SPI begin function + * + * @param &bus: SPI bus which connects MC to Dps3xx + * @param chipSelect: Number of the CS line for the Dps3xx + * @param threeWire: 1 if Dps3xx is connected with 3-wire SPI + * 0 if Dps3xx is connected with 4-wire SPI (standard) + */ + void begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); #endif - /** - * End function for Dps3xx - * Sets the sensor to idle mode - */ - void end(void); - - /** - * returns the Product ID of the connected Dps3xx sensor - */ - uint8_t getProductId(void); - - /** - * returns the Revision ID of the connected Dps3xx sensor - */ - uint8_t getRevisionId(void); - - /** - * Sets the Dps3xx to standby mode - * - * @return status code - */ - int16_t standby(void); - - /** - * performs one temperature measurement - * - * @param &result: reference to a float value where the result will be written - * @return status code - */ - int16_t measureTempOnce(float &result); - - /** - * performs one temperature measurement with specified oversamplingRate - * - * @param &result: reference to a float where the result will be written - * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 - * The number of measurements equals to 2^n, if the value written to the register field is n. 2^n internal measurements are combined to return a more exact measurement - * @return status code - */ - int16_t measureTempOnce(float &result, uint8_t oversamplingRate); - - /** - * starts a single temperature measurement - * - * @return status code - */ - int16_t startMeasureTempOnce(void); - - /** - * starts a single temperature measurement with specified oversamplingRate - * - * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 - * @return status code - */ - int16_t startMeasureTempOnce(uint8_t oversamplingRate); - - /** - * performs one pressure measurement - * - * @param &result: reference to a float value where the result will be written - * @return status code - */ - int16_t measurePressureOnce(float &result); - - /** - * performs one pressure measurement with specified oversamplingRate - * - * @param &result: reference to a float where the result will be written - * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * @return status code - */ - int16_t measurePressureOnce(float &result, uint8_t oversamplingRate); - - /** - * starts a single pressure measurement - * - * @return status code - */ - int16_t startMeasurePressureOnce(void); - - /** - * starts a single pressure measurement with specified oversamplingRate - * - * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * @return status code - */ - int16_t startMeasurePressureOnce(uint8_t oversamplingRate); - - /** - * gets the result a single temperature or pressure measurement in °C or Pa - * - * @param &result: reference to a float value where the result will be written - * @return status code - */ - int16_t getSingleResult(float &result); - - /** - * starts a continuous temperature measurement with specified measurement rate and oversampling rate - * If measure rate is n and oversampling rate is m, the DPS3xx performs 2^(n+m) internal measurements per second. - * The DPS3xx cannot operate with high precision and high speed at the same time. Consult the datasheet for more information. - * - * @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 - * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * - * @return status code - * - */ - int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); - - /** - * starts a continuous temperature measurement with specified measurement rate and oversampling rate - * - * @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 - * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * @return status code - */ - int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); - - /** - * starts a continuous temperature and pressure measurement with specified measurement rate and oversampling rate for temperature and pressure measurement respectvely. - * - * @param tempMr measure rate for temperature - * @param tempOsr oversampling rate for temperature - * @param prsMr measure rate for pressure - * @param prsOsr oversampling rate for pressure - * @return status code - */ - int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); - - /** - * Gets the interrupt status flag of the FIFO - * - * @return 1 if the FIFO is full and caused an interrupt - * 0 if the FIFO is not full or FIFO interrupt is disabled - * -1 on fail - */ - int16_t getIntStatusFifoFull(void); - - /** - * Gets the interrupt status flag that indicates a finished temperature measurement - * - * @return 1 if a finished temperature measurement caused an interrupt; - * 0 if there is no finished temperature measurement or interrupts are disabled; - * -1 on fail. - */ - int16_t getIntStatusTempReady(void); - - /** - * Gets the interrupt status flag that indicates a finished pressure measurement - * - * @return 1 if a finished pressure measurement caused an interrupt; - * 0 if there is no finished pressure measurement or interrupts are disabled; - * -1 on fail. - */ - int16_t getIntStatusPrsReady(void); - - /** - * Function to fix a hardware problem on some devices - * You have this problem if you measure a temperature which is too high (e.g. 60°C when temperature is around 20°C) - * Call correctTemp() directly after begin() to fix this issue - */ - int16_t correctTemp(void); - - protected: - //scaling factor table - static const int32_t scaling_facts[DPS__NUM_OF_SCAL_FACTS]; - - dps::Mode m_opMode; - - //flags - uint8_t m_initFail; - - uint8_t m_productID; - uint8_t m_revisionID; - - //settings - uint8_t m_tempMr; - uint8_t m_tempOsr; - uint8_t m_prsMr; - uint8_t m_prsOsr; - - // compensation coefficients for both dps3xx and dps422 - int32_t m_c00; - int32_t m_c10; - int32_t m_c01; - int32_t m_c11; - int32_t m_c20; - int32_t m_c21; - int32_t m_c30; - - // last measured scaled temperature (necessary for pressure compensation) - float m_lastTempScal; - - //bus specific - uint8_t m_SpiI2c; //0=SPI, 1=I2C - - //used for I2C - TwoWire *m_i2cbus; - uint8_t m_slaveAddress; + /** + * End function for Dps3xx + * Sets the sensor to idle mode + */ + void end(void); + + /** + * returns the Product ID of the connected Dps3xx sensor + */ + uint8_t getProductId(void); + + /** + * returns the Revision ID of the connected Dps3xx sensor + */ + uint8_t getRevisionId(void); + + /** + * Sets the Dps3xx to standby mode + * + * @return status code + */ + int16_t standby(void); + + /** + * performs one temperature measurement + * + * @param &result: reference to a float value where the result will be written + * @return status code + */ + int16_t measureTempOnce(float &result); + + /** + * performs one temperature measurement with specified oversamplingRate + * + * @param &result: reference to a float where the result will be written + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, + * DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, + * which are defined as integers 0 - 7 + * The number of measurements equals to 2^n, if the value written to + * the register field is n. 2^n internal measurements are combined to + * return a more exact measurement + * @return status code + */ + int16_t measureTempOnce(float &result, uint8_t oversamplingRate); + + /** + * starts a single temperature measurement + * + * @return status code + */ + int16_t startMeasureTempOnce(void); + + /** + * starts a single temperature measurement with specified oversamplingRate + * + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, + * DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128, which are defined as integers 0 - 7 + * @return status code + */ + int16_t startMeasureTempOnce(uint8_t oversamplingRate); + + /** + * performs one pressure measurement + * + * @param &result: reference to a float value where the result will be written + * @return status code + */ + int16_t measurePressureOnce(float &result); + + /** + * performs one pressure measurement with specified oversamplingRate + * + * @param &result: reference to a float where the result will be written + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, + * DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return status code + */ + int16_t measurePressureOnce(float &result, uint8_t oversamplingRate); + + /** + * starts a single pressure measurement + * + * @return status code + */ + int16_t startMeasurePressureOnce(void); + + /** + * starts a single pressure measurement with specified oversamplingRate + * + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, + * DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return status code + */ + int16_t startMeasurePressureOnce(uint8_t oversamplingRate); + + /** + * gets the result a single temperature or pressure measurement in °C or Pa + * + * @param &result: reference to a float value where the result will be written + * @return status code + */ + int16_t getSingleResult(float &result); + + /** + * starts a continuous temperature measurement with specified measurement rate and oversampling rate + * If measure rate is n and oversampling rate is m, the DPS3xx performs 2^(n+m) internal measurements per second. + * The DPS3xx cannot operate with high precision and high speed at the same time. Consult the datasheet for more information. + * + * @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * + * @return status code + * + */ + int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); + + /** + * starts a continuous temperature measurement with specified measurement rate and oversampling rate + * + * @param measureRate: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param oversamplingRate: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return status code + */ + int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); + + /** + * starts a continuous temperature and pressure measurement with specified measurement rate and oversampling rate for temperature and pressure measurement respectively. + * + * @param tempMr: measure rate for temperature + * @param tempOsr: oversampling rate for temperature + * @param prsMr: measure rate for pressure + * @param prsOsr: oversampling rate for pressure + * @return status code + */ + int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); + + /** + * Gets the interrupt status flag of the FIFO + * + * @return 1 if the FIFO is full and caused an interrupt + * 0 if the FIFO is not full or FIFO interrupt is disabled + * -1 on fail + */ + int16_t getIntStatusFifoFull(void); + + /** + * Gets the interrupt status flag that indicates a finished temperature measurement + * + * @return 1 if a finished temperature measurement caused an interrupt; + * 0 if there is no finished temperature measurement or interrupts are disabled; + * -1 on fail. + */ + int16_t getIntStatusTempReady(void); + + /** + * Gets the interrupt status flag that indicates a finished pressure measurement + * + * @return 1 if a finished pressure measurement caused an interrupt; + * 0 if there is no finished pressure measurement or interrupts are disabled; + * -1 on fail. + */ + int16_t getIntStatusPrsReady(void); + + /** + * Function to fix a hardware problem on some devices + * You have this problem if you measure a temperature which is too high (e.g. 60°C when temperature is around 20°C) + * Call correctTemp() directly after begin() to fix this issue + */ + int16_t correctTemp(void); + +protected: + // scaling factor table + static const int32_t scaling_facts[DPS__NUM_OF_SCAL_FACTS]; + + dps::Mode m_opMode; + + // flags + uint8_t m_initFail; + + uint8_t m_productID; + uint8_t m_revisionID; + + // settings + uint8_t m_tempMr; + uint8_t m_tempOsr; + uint8_t m_prsMr; + uint8_t m_prsOsr; + + // compensation coefficients for both dps3xx and dps422 + int32_t m_c00; + int32_t m_c10; + int32_t m_c01; + int32_t m_c11; + int32_t m_c20; + int32_t m_c21; + int32_t m_c30; + + // last measured scaled temperature (necessary for pressure compensation) + float m_lastTempScal; + + // bus specific + uint8_t m_SpiI2c; // 0=SPI, 1=I2C + + // used for I2C + TwoWire *m_i2cbus; + uint8_t m_slaveAddress; #ifndef DPS_DISABLESPI - //used for SPI - SPIClass *m_spibus; - int32_t m_chipSelect; - uint8_t m_threeWire; + // used for SPI + SPIClass *m_spibus; + int32_t m_chipSelect; + uint8_t m_threeWire; #endif - /** - * Initializes the sensor. - * This function has to be called from begin() - * and requires a valid bus initialization. - */ - virtual void init(void) = 0; - - /** - * reads the compensation coefficients from the sensor - * this is called once from init(), which is called from begin() - * - * @return 0 on success, -1 on fail - */ - virtual int16_t readcoeffs(void) = 0; - - /** - * Sets the Operation Mode of the sensor - * - * @param opMode: the new OpMode as defined by dps::Mode; CMD_BOTH should not be used for DPS3xx - * @return 0 on success, -1 on fail - */ - int16_t setOpMode(uint8_t opMode); - - /** - * Configures temperature measurement - * - * @param temp_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 - * @param temp_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * - * @return 0 normally or -1 on fail - */ - virtual int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); - - /** - * Configures pressure measurement - * - * @param prs_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 - * @param prs_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * @return 0 normally or -1 on fail - */ - virtual int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); - - virtual int16_t flushFIFO() = 0; - - virtual float calcTemp(int32_t raw) = 0; - - virtual float calcPressure(int32_t raw) = 0; - - int16_t enableFIFO(); - - int16_t disableFIFO(); - - /** - * calculates the time that the sensor needs for 2^mr measurements with an oversampling rate of 2^osr (see table "pressure measurement time (ms) versus oversampling rate") - * Note that the total measurement time for temperature and pressure must not be more than 1 second. - * Timing behavior of pressure and temperature sensors can be considered the same. - * - * @param mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 - * @param osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 - * @return time that the sensor needs for this measurement - */ - uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); - - /** - * reads the next raw value from the FIFO - * - * @param value: the raw pressure or temperature value read from the pressure register blocks, where the LSB of PRS_B0 marks wheather the value is a temperatur or a pressure. - * - * @return -1 on fail - * 0 if result is a temperature raw value - * 1 if result is a pressure raw value - */ - int16_t getFIFOvalue(int32_t *value); - - /** - * Gets the results from continuous measurements and writes them to given arrays - * - * @param *tempBuffer: The start address of the buffer where the temperature results are written - * If this is NULL, no temperature results will be written out - * @param &tempCount: The size of the buffer for temperature results. - * When the function ends, it will contain the number of bytes written to the buffer. - * @param *prsBuffer: The start address of the buffer where the pressure results are written - * If this is NULL, no pressure results will be written out - * @param &prsCount: The size of the buffer for pressure results. - * When the function ends, it will contain the number of bytes written to the buffer. - * @param reg The FIFO empty register field; needed since this field is different for each sensor - * @return status code - */ - int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount, RegMask_t reg); - - /** - * reads a byte from the sensor - * - * @param regAdress: Address that has to be read - * @return register content or -1 on fail - */ - int16_t readByte(uint8_t regAddress); + /** + * Initializes the sensor. + * This function has to be called from begin() + * and requires a valid bus initialization. + */ + virtual void init(void) = 0; + + /** + * reads the compensation coefficients from the sensor + * this is called once from init(), which is called from begin() + * + * @return 0 on success, -1 on fail + */ + virtual int16_t readcoeffs(void) = 0; + + /** + * Sets the Operation Mode of the sensor + * + * @param opMode: the new OpMode as defined by dps::Mode; CMD_BOTH should not be used for DPS3xx + * @return 0 on success, + * -1 on fail + */ + int16_t setOpMode(uint8_t opMode); + + /** + * Configures temperature measurement + * + * @param temp_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param temp_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * + * @return 0 normally or -1 on fail + */ + virtual int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); + + /** + * Configures pressure measurement + * + * @param prs_mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param prs_osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return 0 normally or + * -1 on fail + */ + virtual int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); + + virtual int16_t flushFIFO() = 0; + + virtual float calcTemp(int32_t raw) = 0; + + virtual float calcPressure(int32_t raw) = 0; + + int16_t enableFIFO(); + + int16_t disableFIFO(); + + /** + * calculates the time that the sensor needs for 2^mr measurements with an oversampling rate of 2^osr (see table "pressure measurement time (ms) versus oversampling rate") + * Note that the total measurement time for temperature and pressure must not be more than 1 second. + * Timing behavior of pressure and temperature sensors can be considered the same. + * + * @param mr: DPS__MEASUREMENT_RATE_1, DPS__MEASUREMENT_RATE_2,DPS__MEASUREMENT_RATE_4 ... DPS__MEASUREMENT_RATE_128 + * @param osr: DPS__OVERSAMPLING_RATE_1, DPS__OVERSAMPLING_RATE_2, DPS__OVERSAMPLING_RATE_4 ... DPS__OVERSAMPLING_RATE_128 + * @return time that the sensor needs for this measurement + */ + uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); + + /** + * reads the next raw value from the FIFO + * + * @param value: the raw pressure or temperature value read from the pressure register blocks, where the LSB of PRS_B0 marks whether the value is a temperature or a pressure. + * + * @return -1 on fail + * 0 if result is a temperature raw value + * 1 if result is a pressure raw value + */ + int16_t getFIFOvalue(int32_t *value); + + /** + * Gets the results from continuous measurements and writes them to given arrays + * + * @param *tempBuffer: The start address of the buffer where the temperature results are written + * If this is NULL, no temperature results will be written out + * @param &tempCount: The size of the buffer for temperature results. + * When the function ends, it will contain the number of bytes written to the buffer. + * @param *prsBuffer: The start address of the buffer where the pressure results are written + * If this is NULL, no pressure results will be written out + * @param &prsCount: The size of the buffer for pressure results. + * When the function ends, it will contain the number of bytes written to the buffer. + * @param reg The FIFO empty register field; needed since this field is different for each sensor + * @return status code + */ + int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount, RegMask_t reg); + + /** + * reads a byte from the sensor + * + * @param regAddress: Address that has to be read + * @return register content or -1 on fail + */ + int16_t readByte(uint8_t regAddress); #ifndef DPS_DISABLESPI - /** - * reads a byte from the sensor via SPI - * this function is automatically called by readByte - * if the sensor is connected via SPI - * - * @param regAdress: Address that has to be read - * @return register content or -1 on fail - */ - int16_t readByteSPI(uint8_t regAddress); + /** + * reads a byte from the sensor via SPI + * this function is automatically called by readByte + * if the sensor is connected via SPI + * + * @param regAddress: Address that has to be read + * @return register content or -1 on fail + */ + int16_t readByteSPI(uint8_t regAddress); #endif - /** - * reads a block from the sensor - * - * @param regAdress: Address that has to be read - * @param length: Length of data block - * @param buffer: Buffer where data will be stored - * @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. - */ - int16_t readBlock(RegBlock_t regBlock, uint8_t *buffer); + /** + * reads a block from the sensor + * + * @param regAddress: Address that has to be read + * @param length: Length of data block + * @param buffer: Buffer where data will be stored + * @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. + */ + int16_t readBlock(RegBlock_t regBlock, uint8_t *buffer); #ifndef DPS_DISABLESPI - /** - * reads a block from the sensor via SPI - * - * @param regAdress: Address that has to be read - * @param length: Length of data block - * @param readbuffer: Buffer where data will be stored - * @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. - */ - int16_t readBlockSPI(RegBlock_t regBlock, uint8_t *readbuffer); + /** + * reads a block from the sensor via SPI + * + * @param regAddress: Address that has to be read + * @param length: Length of data block + * @param readBuffer: Buffer where data will be stored + * @return number of bytes that have been read successfully, which might not always equal to length due to rx-Buffer overflow etc. + */ + int16_t readBlockSPI(RegBlock_t regBlock, uint8_t *readBuffer); #endif - /** - * writes a byte to a given register of the sensor without checking - * - * @param regAdress: Address of the register that has to be updated - * @param data: Byte that will be written to the register - * @return 0 if byte was written successfully - * or -1 on fail - */ - int16_t writeByte(uint8_t regAddress, uint8_t data); - - /** - * writes a byte to a register of the sensor - * - * @param regAdress: Address of the register that has to be updated - * @param data: Byte that will be written to the register - * @param check: If this is true, register content will be read after writing - * to check if update was successful - * @return 0 if byte was written successfully - * or -1 on fail - */ - int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check); + /** + * writes a byte to a given register of the sensor without checking + * + * @param regAddress: Address of the register that has to be updated + * @param data: Byte that will be written to the register + * @return 0 if byte was written successfully or + * -1 on fail + */ + int16_t writeByte(uint8_t regAddress, uint8_t data); + + /** + * writes a byte to a register of the sensor + * + * @param regAddress: Address of the register that has to be updated + * @param data: Byte that will be written to the register + * @param check: If this is true, register content will be read after writing + * to check if update was successful + * @return 0 if byte was written successfully or + * -1 on fail + */ + int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check); #ifndef DPS_DISABLESPI - /** - * writes a byte to a register of the sensor via SPI - * - * @param regAdress: Address of the register that has to be updated - * @param data: Byte that will be written to the register - * @param check: If this is true, register content will be read after writing - * to check if update was successful - * @return 0 if byte was written successfully - * or -1 on fail - */ - int16_t writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check); + /** + * writes a byte to a register of the sensor via SPI + * + * @param regAddress: Address of the register that has to be updated + * @param data: Byte that will be written to the register + * @param check: If this is true, register content will be read after writing + * to check if update was successful + * @return 0 if byte was written successfully or + * -1 on fail + */ + int16_t writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check); #endif - /** - * updates a bit field of the sensor without checking - * - * @param regMask: Mask of the register that has to be updated - * @param data: BitValues that will be written to the register - * @return 0 if byte was written successfully - * or -1 on fail - */ - int16_t writeByteBitfield(uint8_t data, RegMask_t regMask); - - /** - * updates a bit field of the sensor - * - * regMask: Mask of the register that has to be updated - * data: BitValues that will be written to the register - * check: enables/disables check after writing; 0 disables check. - * if check fails, -1 will be returned - * @return 0 if byte was written successfully - * or -1 on fail - */ - int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check); - - /** - * reads a bit field from the sensor - * regMask: Mask of the register that has to be updated - * data: BitValues that will be written to the register - * @return read and processed bits - * or -1 on fail - */ - int16_t readByteBitfield(RegMask_t regMask); - - /** - * @brief converts non-32-bit negative numbers to 32-bit negative numbers with 2's complement - * - * @param raw The raw number of less than 32 bits - * @param length The bit length - */ - void getTwosComplement(int32_t *raw, uint8_t length); - - /** - * @brief Get a raw result from a given register block - * - * @param raw The address where the raw value is to be written - * @param reg The register block to be read from - * @return status code - */ - int16_t getRawResult(int32_t *raw, RegBlock_t reg); + /** + * updates a bit field of the sensor without checking + * + * @param regMask: Mask of the register that has to be updated + * @param data: BitValues that will be written to the register + * @return 0 if byte was written successfully or + * -1 on fail + */ + int16_t writeByteBitfield(uint8_t data, RegMask_t regMask); + + /** + * updates a bit field of the sensor + * + * regMask: Mask of the register that has to be updated + * data: BitValues that will be written to the register + * check: enables/disables check after writing; 0 disables check. + * if check fails, -1 will be returned + * @return 0 if byte was written successfully or + * -1 on fail + */ + int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check); + + /** + * reads a bit field from the sensor + * regMask: Mask of the register that has to be updated + * data: BitValues that will be written to the register + * @return read and processed bits or -1 on fail + */ + int16_t readByteBitfield(RegMask_t regMask); + + /** + * @brief converts non-32-bit negative numbers to 32-bit negative numbers with 2's complement + * + * @param raw The raw number of less than 32 bits + * @param length The bit length + */ + void getTwosComplement(int32_t *raw, uint8_t length); + + /** + * @brief Get a raw result from a given register block + * + * @param raw The address where the raw value is to be written + * @param reg The register block to be read from + * @return status code + */ + int16_t getRawResult(int32_t *raw, RegBlock_t reg); }; -#endif //DPSCLASS_H_INCLUDED +#endif // DPSCLASS_H_INCLUDED diff --git a/src/util/dps3xx_config.h b/src/util/dps3xx_config.h index 934a62b..9dd93b8 100644 --- a/src/util/dps3xx_config.h +++ b/src/util/dps3xx_config.h @@ -15,35 +15,35 @@ enum Interrupt_source_3xx_e namespace dps3xx { -enum Registers_e -{ - PROD_ID = 0, - REV_ID, - TEMP_SENSOR, // internal vs external - TEMP_SENSORREC, //temperature sensor recommendation - TEMP_SE, //temperature shift enable (if temp_osr>3) - PRS_SE, //pressure shift enable (if prs_osr>3) - FIFO_FL, //FIFO flush - FIFO_EMPTY, //FIFO empty - FIFO_FULL, //FIFO full - INT_HL, - INT_SEL, //interrupt select -}; + enum Registers_e + { + PROD_ID = 0, + REV_ID, + TEMP_SENSOR, // internal vs external + TEMP_SENSORREC, // temperature sensor recommendation + TEMP_SE, // temperature shift enable (if temp_osr>3) + PRS_SE, // pressure shift enable (if prs_osr>3) + FIFO_FL, // FIFO flush + FIFO_EMPTY, // FIFO empty + FIFO_FULL, // FIFO full + INT_HL, + INT_SEL, // interrupt select + }; -const RegMask_t registers[DPS3xx_NUM_OF_REGMASKS] = { - {0x0D, 0x0F, 0}, // PROD_ID - {0x0D, 0xF0, 4}, // REV_ID - {0x07, 0x80, 7}, // TEMP_SENSOR - {0x28, 0x80, 7}, // TEMP_SENSORREC - {0x09, 0x08, 3}, // TEMP_SE - {0x09, 0x04, 2}, // PRS_SE - {0x0C, 0x80, 7}, // FIFO_FL - {0x0B, 0x01, 0}, // FIFO_EMPTY - {0x0B, 0x02, 1}, // FIFO_FULL - {0x09, 0x80, 7}, // INT_HL - {0x09, 0x70, 4}, // INT_SEL -}; + const RegMask_t registers[DPS3xx_NUM_OF_REGMASKS] = { + {0x0D, 0x0F, 0}, // PROD_ID + {0x0D, 0xF0, 4}, // REV_ID + {0x07, 0x80, 7}, // TEMP_SENSOR + {0x28, 0x80, 7}, // TEMP_SENSORREC + {0x09, 0x08, 3}, // TEMP_SE + {0x09, 0x04, 2}, // PRS_SE + {0x0C, 0x80, 7}, // FIFO_FL + {0x0B, 0x01, 0}, // FIFO_EMPTY + {0x0B, 0x02, 1}, // FIFO_FULL + {0x09, 0x80, 7}, // INT_HL + {0x09, 0x70, 4}, // INT_SEL + }; -const RegBlock_t coeffBlock = {0x10, 18}; + const RegBlock_t coeffBlock = {0x10, 18}; } // namespace dps3xx #endif \ No newline at end of file diff --git a/src/util/dps_config.h b/src/util/dps_config.h index 34ec033..75e0c0c 100644 --- a/src/util/dps_config.h +++ b/src/util/dps_config.h @@ -47,7 +47,7 @@ #define DPS__OVERSAMPLING_RATE_64 DPS__MEASUREMENT_RATE_64 #define DPS__OVERSAMPLING_RATE_128 DPS__MEASUREMENT_RATE_128 -//we use 0.1 ms units for time calculations, so 10 units are one millisecond +// we use 0.1 ms units for time calculations, so 10 units are one millisecond #define DPS__BUSYTIME_SCALING 10U #define DPS__NUM_OF_SCAL_FACTS 8 @@ -62,66 +62,66 @@ namespace dps { -/** - * @brief Operating mode. - * - */ -enum Mode -{ - IDLE = 0x00, - CMD_PRS = 0x01, - CMD_TEMP = 0x02, - CMD_BOTH = 0x03, // only for DPS422 - CONT_PRS = 0x05, - CONT_TMP = 0x06, - CONT_BOTH = 0x07 -}; - -enum RegisterBlocks_e -{ - PRS = 0, // pressure value - TEMP, // temperature value -}; - -const RegBlock_t registerBlocks[2] = { - {0x00, 3}, - {0x03, 3}, -}; - -/** - * @brief registers for configuration and flags; these are the same for both 3xx and 422, might need to be adapted for future sensors - * - */ -enum Config_Registers_e -{ - TEMP_MR = 0, // temperature measure rate - TEMP_OSR, // temperature measurement resolution - PRS_MR, // pressure measure rate - PRS_OSR, // pressure measurement resolution - MSR_CTRL, // measurement control - FIFO_EN, - - TEMP_RDY, - PRS_RDY, - INT_FLAG_FIFO, - INT_FLAG_TEMP, - INT_FLAG_PRS, -}; - -const RegMask_t config_registers[NUM_OF_COMMON_REGMASKS] = { - {0x07, 0x70, 4}, // TEMP_MR - {0x07, 0x07, 0}, // TEMP_OSR - {0x06, 0x70, 4}, // PRS_MR - {0x06, 0x07, 0}, // PRS_OSR - {0x08, 0x07, 0}, // MSR_CTRL - {0x09, 0x02, 1}, // FIFO_EN - - {0x08, 0x20, 5}, // TEMP_RDY - {0x08, 0x10, 4}, // PRS_RDY - {0x0A, 0x04, 2}, // INT_FLAG_FIFO - {0x0A, 0x02, 1}, // INT_FLAG_TEMP - {0x0A, 0x01, 0}, // INT_FLAG_PRS -}; + /** + * @brief Operating mode. + * + */ + enum Mode + { + IDLE = 0x00, + CMD_PRS = 0x01, + CMD_TEMP = 0x02, + CMD_BOTH = 0x03, // only for DPS422 + CONT_PRS = 0x05, + CONT_TMP = 0x06, + CONT_BOTH = 0x07 + }; + + enum RegisterBlocks_e + { + PRS = 0, // pressure value + TEMP, // temperature value + }; + + const RegBlock_t registerBlocks[2] = { + {0x00, 3}, + {0x03, 3}, + }; + + /** + * @brief registers for configuration and flags; these are the same for both 3xx and 422, might need to be adapted for future sensors + * + */ + enum Config_Registers_e + { + TEMP_MR = 0, // temperature measure rate + TEMP_OSR, // temperature measurement resolution + PRS_MR, // pressure measure rate + PRS_OSR, // pressure measurement resolution + MSR_CTRL, // measurement control + FIFO_EN, + + TEMP_RDY, + PRS_RDY, + INT_FLAG_FIFO, + INT_FLAG_TEMP, + INT_FLAG_PRS, + }; + + const RegMask_t config_registers[NUM_OF_COMMON_REGMASKS] = { + {0x07, 0x70, 4}, // TEMP_MR + {0x07, 0x07, 0}, // TEMP_OSR + {0x06, 0x70, 4}, // PRS_MR + {0x06, 0x07, 0}, // PRS_OSR + {0x08, 0x07, 0}, // MSR_CTRL + {0x09, 0x02, 1}, // FIFO_EN + + {0x08, 0x20, 5}, // TEMP_RDY + {0x08, 0x10, 4}, // PRS_RDY + {0x0A, 0x04, 2}, // INT_FLAG_FIFO + {0x0A, 0x02, 1}, // INT_FLAG_TEMP + {0x0A, 0x01, 0}, // INT_FLAG_PRS + }; } // namespace dps #endif /* DPS_CONSTS_H_ */