From 3c5fdf2495f20ff7fecd6df72e312fb61f037c38 Mon Sep 17 00:00:00 2001 From: Giulia <giulia.ghirardini@skywarder.eu> Date: Sat, 17 Jun 2023 18:52:55 +0200 Subject: [PATCH] [LPS22DF] Review and standardization with LPS28DFW --- src/shared/sensors/LPS22DF/LPS22DF.cpp | 373 +++++++++++++---------- src/shared/sensors/LPS22DF/LPS22DF.h | 293 +++++++++--------- src/shared/sensors/LPS22DF/LPS22DFData.h | 114 +++---- src/shared/sensors/LPS22DF/LPS22DFDefs.h | 121 ++++++++ src/tests/sensors/test-lps22df.cpp | 6 +- 5 files changed, 540 insertions(+), 367 deletions(-) create mode 100644 src/shared/sensors/LPS22DF/LPS22DFDefs.h diff --git a/src/shared/sensors/LPS22DF/LPS22DF.cpp b/src/shared/sensors/LPS22DF/LPS22DF.cpp index 278060ad5..4cfd455da 100644 --- a/src/shared/sensors/LPS22DF/LPS22DF.cpp +++ b/src/shared/sensors/LPS22DF/LPS22DF.cpp @@ -1,168 +1,205 @@ -/* Copyright (c) 2023 Skyward Experimental Rocketry - * Author: Giulia Ghirardini - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "LPS22DF.h" - -#include <drivers/timer/TimestampTimer.h> -#include <miosix.h> -#include <sensors/calibration/SensorDataExtra/SensorDataExtra.h> -#include <utils/Debug.h> - -#include <iostream> - -using namespace Eigen; - -namespace Boardcore -{ - -static constexpr uint8_t WHO_AM_I_VALUE = 0xb4; -static constexpr uint8_t ENABLE_ONESHOT = (0b01 << 0); - -LPS22DF::LPS22DF(SPIBusInterface& bus, miosix::GpioPin pin) - : slave(bus, pin, getDefaultSPIConfig()) -{ -} - -LPS22DF::LPS22DF(SPIBusInterface& bus, miosix::GpioPin pin, - SPIBusConfig spiConfig, Config config) - : slave(bus, pin, spiConfig), config(config) -{ -} - -SPIBusConfig LPS22DF::getDefaultSPIConfig() -{ - SPIBusConfig spiConfig; - spiConfig.clockDivider = SPI::ClockDivider::DIV_256; - spiConfig.mode = SPI::Mode::MODE_3; - spiConfig.byteOrder = SPI::Order::LSB_FIRST; - return spiConfig; -} - -bool LPS22DF::init() -{ - SPITransaction spi(slave); - - if (isInitialized) - { - LOG_ERR(logger, "Attempted to initialized sensor twice"); - lastError = ALREADY_INIT; - return false; - } - - // Disable I2C and I3C interfaces - spi.writeRegister(IF_CTRL_REG, I2C_I3C_DIS); - - // Setting the actual sensor configurations (Mode, ODR, AVG) - setConfig(config); - - // TODO: Read back registers to check configuration - - isInitialized = true; - return true; -} - -bool LPS22DF::selfTest() -{ - if (!isInitialized) - { - LOG_ERR(logger, "Invoked selfTest() but sensor was uninitialized"); - lastError = NOT_INIT; - return false; - } - - // selfTest procedure does not exist for this sensor. WhoamiValue is checked - // to assure communication. - { - SPITransaction spi(slave); - uint8_t value = spi.readRegister(WHO_AM_I_REG); - - if (value != WHO_AM_I_VALUE) - { - LOG_ERR(logger, "WHO_AM_I: read 0x{:x} but expected 0x{:x}", value, - WHO_AM_I_VALUE); - lastError = INVALID_WHOAMI; - return false; - } - } - - return true; -} - -void LPS22DF::setConfig(const Config& config) -{ - SPITransaction spi(slave); - - setAverage(config.avg); - setOutputDataRate(config.odr); -} - -void LPS22DF::setAverage(AVG avg) -{ - SPITransaction spi(slave); - - spi.writeRegister(CTRL1_REG, avg); - - config.avg = avg; -} - -void LPS22DF::setOutputDataRate(ODR odr) -{ - SPITransaction spi(slave); - - spi.writeRegister(CTRL1_REG, odr); - - config.odr = odr; -} - -LPS22DFData LPS22DF::sampleImpl() -{ - if (!isInitialized) - { - LOG_ERR(logger, "Invoked sampleImpl() but sensor was not initialized"); - lastError = NOT_INIT; - return lastSample; - } - - SPITransaction spi(slave); - LPS22DFData data; - - // TODO: Handle ONE SHOT mode - if (config.odr == ODR::ONE_SHOT) - { - // Trigger sample - spi.writeRegister(CTRL2_REG, ONE_SHOT_TRIGGER); - - // Pool status register until the sample is ready - while ((spi.readRegister16(STATUS_REG) & 0x3) == 0) - ; - } - - data.pressureTimestamp = TimestampTimer::getTimestamp(); - data.temperatureTimestamp = data.pressureTimestamp; - - data.pressure = spi.readRegister24(PRESSURE_OUT_XL_REG) / PRES_SENS; - data.temperature = spi.readRegister16(TEMP_OUT_L_REG) / TEMP_SENS; - - return data; -} - -} // namespace Boardcore +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Giulia Ghirardini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "LPS22DF.h" + +#include <drivers/timer/TimestampTimer.h> +#include <miosix.h> +#include <sensors/calibration/SensorDataExtra/SensorDataExtra.h> +#include <utils/Debug.h> + +#include <iostream> + +using namespace Boardcore::LPS22DFDefs; + +namespace Boardcore +{ + +LPS22DF::LPS22DF(SPIBusInterface& bus, miosix::GpioPin cs) + : slave(bus, cs, getDefaultSPIConfig()) +{ +} + +LPS22DF::LPS22DF(SPIBusInterface& bus, miosix::GpioPin cs, + SPIBusConfig spiConfig, Config config) + : slave(bus, cs, spiConfig), config(config) +{ +} + +SPIBusConfig LPS22DF::getDefaultSPIConfig() +{ + SPIBusConfig spiConfig; + spiConfig.clockDivider = SPI::ClockDivider::DIV_256; + spiConfig.mode = SPI::Mode::MODE_3; + spiConfig.byteOrder = SPI::Order::LSB_FIRST; + return spiConfig; +} + +bool LPS22DF::init() +{ + if (isInitialized) + { + LOG_ERR(logger, "Attempted to initialized sensor twice"); + lastError = ALREADY_INIT; + return false; + } + + { + // Disable I2C and I3C interfaces + SPITransaction spi(slave); + spi.writeRegister(IF_CTRL_addr, IF_CTRL::I2C_I3C_DIS); + } + + // Setting the actual sensor configurations (Mode, ODR, AVG) + setConfig(config); + + lastError = SensorErrors::NO_ERRORS; + isInitialized = true; + return true; +} + +bool LPS22DF::selfTest() +{ + // Since the sensor doesn't provide any self-test feature we just try to + // probe the sensor and read his whoami register. + if (!isInitialized) + { + LOG_ERR(logger, "Invoked selfTest() but sensor was uninitialized"); + lastError = NOT_INIT; + return false; + } + + { + // Reading the whoami value to assure communication + SPITransaction spi(slave); + uint8_t whoamiValue = spi.readRegister(WHO_AM_I_addr); + + // Checking the whoami value to assure correct communication + if (whoamiValue != WHO_AM_I_VALUE) + { + LOG_ERR(logger, "WHO_AM_I: read 0x{:x} but expected 0x{:x}", + whoamiValue, WHO_AM_I_VALUE); + lastError = INVALID_WHOAMI; + return false; + } + } + + return true; +} + +void LPS22DF::setConfig(const Config& config) +{ + setAverage(config.avg); + setOutputDataRate(config.odr); +} + +void LPS22DF::setAverage(AVG avg) +{ + // Since the CTRL_REG1 contains only the AVG and ODR settings, we use + // the internal driver state to set the register with the wanted ODR and + // AVG without previously reading it. This allows to avoid a useless + // transaction. + { + SPITransaction spi(slave); + spi.writeRegister(CTRL_REG1_addr, config.odr | avg); + } + config.avg = avg; +} + +void LPS22DF::setOutputDataRate(ODR odr) +{ + // Since the CTRL_REG1 contains only the AVG and ODR settings, we use + // the internal driver state to set the register with the wanted ODR and + // AVG without previously reading it. This allows to avoid a useless + // transaction. + { + SPITransaction spi(slave); + spi.writeRegister(CTRL_REG1_addr, odr | config.avg); + } + config.odr = odr; +} + +LPS22DFData LPS22DF::sampleImpl() +{ + if (!isInitialized) + { + LOG_ERR(logger, "Invoked sampleImpl() but sensor was not initialized"); + lastError = NOT_INIT; + return lastSample; + } + + LPS22DFData data; + SPITransaction spi(slave); + uint8_t statusValue{0}; + + if (config.odr == ODR::ONE_SHOT) + { + // Reading previous value of Control Register 2 + uint8_t ctrl_reg2_val = spi.readRegister(CTRL_REG2_addr); + + // Trigger sample + spi.writeRegister(CTRL_REG2_addr, + ctrl_reg2_val | CTRL_REG2::ONE_SHOT_START); + + // Pool status register until the sample is ready + do + { + statusValue = spi.readRegister(STATUS_addr); + } while (!(statusValue & (STATUS::P_DA | STATUS::T_DA))); + } + else + { + // read status register value + statusValue = spi.readRegister(STATUS_addr); + } + + auto ts = TimestampTimer::getTimestamp(); + + // Sample pressure if data is available, return last sample otherwise + if (statusValue & STATUS::P_DA) + { + data.pressureTimestamp = ts; + data.pressure = spi.readRegister24(PRESSURE_OUT_XL_addr) / PRES_SENS; + } + else + { + lastError = NO_NEW_DATA; + data.pressureTimestamp = lastSample.pressureTimestamp; + data.pressure = lastSample.pressure; + } + + // Sample temperature if data is available, return last sample otherwise + if (statusValue & STATUS::T_DA) + { + data.temperatureTimestamp = ts; + data.temperature = spi.readRegister16(TEMP_OUT_L_addr) / TEMP_SENS; + } + else + { + data.temperatureTimestamp = lastSample.temperatureTimestamp; + data.temperature = lastSample.temperature; + } + + return data; +} + +} // namespace Boardcore diff --git a/src/shared/sensors/LPS22DF/LPS22DF.h b/src/shared/sensors/LPS22DF/LPS22DF.h index d78174ba5..d42537bab 100644 --- a/src/shared/sensors/LPS22DF/LPS22DF.h +++ b/src/shared/sensors/LPS22DF/LPS22DF.h @@ -1,140 +1,155 @@ -/* Copyright (c) 2023 Skyward Experimental Rocketry - * Author: Giulia Ghirardini - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include <diagnostic/PrintLogger.h> -#include <drivers/spi/SPIDriver.h> -#include <drivers/timer/TimestampTimer.h> -#include <miosix.h> -#include <sensors/Sensor.h> - -#include <Eigen/Core> -#include <array> - -#include "LPS22DFData.h" - -namespace Boardcore -{ - -/** - * @brief Driver for LPS22DF, Low-power and high-precision MEMS pressure sensor. - */ -class LPS22DF : public Sensor<LPS22DFData> -{ -public: - /** - * @brief Constants for Output Data Rate Configuration - * - * ODR configuration is valid for both pressure and temperature. - */ - enum ODR : uint8_t - { - ONE_SHOT = 0b0000 << 3, - ODR_1 = 0b0001 << 3, - ODR_4 = 0b0010 << 3, - ODR_10 = 0b0011 << 3, - ODR_25 = 0b0100 << 3, - ODR_50 = 0b0101 << 3, - ODR_75 = 0b0110 << 3, - ODR_100 = 0b0111 << 3, - ODR_200 = 0b1000 << 3 - }; - - /** - * @brief Averaging of pressure and temperature. - * - * For an AGV value of 512, 128, 64 the maximum ODR values are respectively - * of 25, 75 and 100 Hz. For any other AVG value all ODR configurations are - * possible. - */ - enum AVG : uint8_t - { - AVG_4 = 0b000, - AVG_8 = 0b001, - AVG_16 = 0b010, - AVG_32 = 0b011, - AVG_64 = 0b100, - AVG_128 = 0b101, - AVG_512 = 0b111 - }; - - struct Config - { - ODR odr = ODR::ODR_25; - AVG avg = AVG::AVG_512; - }; - - LPS22DF(SPIBusInterface& bus, miosix::GpioPin pin); - - LPS22DF(SPIBusInterface& bus, miosix::GpioPin pin, SPIBusConfig spiConfig, - Config config); - - static SPIBusConfig getDefaultSPIConfig(); - - bool init() override; - - bool selfTest() override; - - void setConfig(const Config& config); - - void setAverage(AVG avg); - - void setOutputDataRate(ODR odr); - -private: - LPS22DFData sampleImpl() override; - - SPISlave slave; - Config config; - - bool isInitialized = false; - - enum Registers : uint8_t - { - IF_CTRL_REG = 0x0e, - - WHO_AM_I_REG = 0x0f, - - CTRL1_REG = 0x10, - CTRL2_REG = 0x11, - CTRL3_REG = 0x12, - CTRL4_REG = 0x13, - - STATUS_REG = 0x27, - - PRESSURE_OUT_XL_REG = 0x28, - PRESSURE_OUT_L_REG = 0x29, - PRESSURE_OUT_H_REG = 0x2a, - TEMP_OUT_L_REG = 0x2b, - TEMP_OUT_H_REG = 0x2c, - }; - - static constexpr uint32_t WHO_AM_I_VALUE = 0xb4; - static constexpr uint8_t I2C_I3C_DIS = 1 << 6; - static constexpr uint8_t ONE_SHOT_TRIGGER = 1 << 0; - - static constexpr float TEMP_SENS = 100; // LSB / °C - static constexpr float PRES_SENS = 40.96; // LSB / Pa - - PrintLogger logger = Logging::getLogger("lps22df"); -}; - +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Giulia Ghirardini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <diagnostic/PrintLogger.h> +#include <drivers/spi/SPIDriver.h> +#include <drivers/timer/TimestampTimer.h> +#include <miosix.h> +#include <sensors/Sensor.h> + +#include <Eigen/Core> +#include <array> + +#include "LPS22DFData.h" +#include "LPS22DFDefs.h" + +namespace Boardcore +{ + +/** + * @brief Driver for LPS22DF, Low-power and high-precision MEMS pressure sensor. + */ +class LPS22DF : public Sensor<LPS22DFData> +{ +public: + /** + * @brief Enumeration for Output Data Rate Configuration. + * + * Available are One shot (only one sample calculated when signal sent), 1 + * Hz to 200 Hz. ODR configuration is valid for both pressure and + * temperature. + */ + enum ODR : uint8_t + { + ONE_SHOT = 0b0000 << 3, + ODR_1 = 0b0001 << 3, + ODR_4 = 0b0010 << 3, + ODR_10 = 0b0011 << 3, + ODR_25 = 0b0100 << 3, + ODR_50 = 0b0101 << 3, + ODR_75 = 0b0110 << 3, + ODR_100 = 0b0111 << 3, + ODR_200 = 0b1000 << 3 + }; + + /** + * @brief Averaging of pressure and temperature. + * + * For an AGV value of 512, 128, 64 the maximum ODR values are respectively + * of 25, 75 and 100 Hz. For any other AVG value all ODR configurations are + * possible. + */ + enum AVG : uint8_t + { + AVG_4 = 0b000, + AVG_8 = 0b001, + AVG_16 = 0b010, + AVG_32 = 0b011, + AVG_64 = 0b100, + AVG_128 = 0b101, + AVG_512 = 0b111 + }; + + /** + * @brief Struct that sums up all the settings of the sensor. + */ + struct Config + { + ODR odr = ODR::ODR_25; + AVG avg = AVG::AVG_512; + }; + + /** + * @brief Constructor that stores the initial default settings (without + * applying them to the sensor). + * @param bus SPI bus. + * @param cs SPI Chip Select pin. + */ + LPS22DF(SPIBusInterface& bus, miosix::GpioPin cs); + + /** + * @brief Constructor that stores the initial settings (without applying + * them to the sensor). + * @param bus SPI bus. + * @param cs SPI Chip Select pin. + * @param config LPS22DF configuration. + */ + LPS22DF(SPIBusInterface& bus, miosix::GpioPin cs, SPIBusConfig spiConfig, + Config config); + + static SPIBusConfig getDefaultSPIConfig(); + + /** + * @brief Initializes the sensor with the current settings. + * @return true if initialization succeeded, false otherwise. + */ + bool init() override; + + /** + * @brief The self test method returns true if we read the right whoami + * value. We can't make a better self test due to the fact that the sensor + * doesn't support this feature. + * @return true if the right whoami has been read. + */ + bool selfTest() override; + + /** + * @brief Sets and saves the configurations passed on the parameters. + */ + void setConfig(const Config& config); + + /** + * @brief Sets and saves the oversampling on the sensor. + * @return True if setting succeeded, false otherwise. + */ + void setAverage(AVG avg); + + /** + * @brief Sets and saves the output data rate. + * @return True if setting succeeded, false otherwise. + */ + void setOutputDataRate(ODR odr); + +private: + LPS22DFData sampleImpl() override; + + SPISlave slave; + Config config; + + bool isInitialized = false; + + PrintLogger logger = Logging::getLogger("lps22df"); +}; + } // namespace Boardcore \ No newline at end of file diff --git a/src/shared/sensors/LPS22DF/LPS22DFData.h b/src/shared/sensors/LPS22DF/LPS22DFData.h index ae483b0ea..c76cbd245 100644 --- a/src/shared/sensors/LPS22DF/LPS22DFData.h +++ b/src/shared/sensors/LPS22DF/LPS22DFData.h @@ -1,58 +1,58 @@ -/* Copyright (c) 2023 Skyward Experimental Rocketry - * Author: Giulia Ghirardini - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#include <sensors/SensorData.h> - -namespace Boardcore -{ - -struct LPS22DFData : public PressureData, public TemperatureData -{ - LPS22DFData() : PressureData{0, 0.0}, TemperatureData{0, 0.0} {} - - LPS22DFData(uint64_t t, float press, float deg) - : PressureData{t, press}, TemperatureData{t, deg} - - { - } - - LPS22DFData(PressureData pressData, TemperatureData tempData) - : PressureData(pressData), TemperatureData(tempData) - - { - } - - static std::string header() - { - return "pressureTimestamp, press, temperatureTimestamp, temp\n"; - } - - void print(std::ostream& os) const - { - os << pressureTimestamp << "," << pressure << "," - << temperatureTimestamp << "," << temperature << "\n"; - } -}; - +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Giulia Ghirardini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include <sensors/SensorData.h> + +namespace Boardcore +{ + +struct LPS22DFData : public PressureData, public TemperatureData +{ + LPS22DFData() : PressureData{0, 0.0}, TemperatureData{0, 0.0} {} + + LPS22DFData(uint64_t t, float press, float deg) + : PressureData{t, press}, TemperatureData{t, deg} + + { + } + + LPS22DFData(PressureData pressData, TemperatureData tempData) + : PressureData(pressData), TemperatureData(tempData) + + { + } + + static std::string header() + { + return "pressureTimestamp, press, temperatureTimestamp, temp\n"; + } + + void print(std::ostream& os) const + { + os << pressureTimestamp << "," << pressure << "," + << temperatureTimestamp << "," << temperature << "\n"; + } +}; + } // namespace Boardcore \ No newline at end of file diff --git a/src/shared/sensors/LPS22DF/LPS22DFDefs.h b/src/shared/sensors/LPS22DF/LPS22DFDefs.h new file mode 100644 index 000000000..d22788f60 --- /dev/null +++ b/src/shared/sensors/LPS22DF/LPS22DFDefs.h @@ -0,0 +1,121 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Giulia Ghirardini + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +namespace Boardcore +{ +namespace LPS22DFDefs +{ +static constexpr uint32_t WHO_AM_I_VALUE = 0xb4; + +static constexpr float TEMP_SENS = 100; // LSB / °C +static constexpr float PRES_SENS = 40.96; // LSB / Pa + +enum Registers : uint8_t +{ + INTERRUPT_CFG_addr = 0x0b, ///< Interrupt mode for pressure acquisition + + THS_P_L_addr = 0x0c, ///< User-defined threshold LSB register + THS_P_H_addr = 0x0d, ///< User-defined threshold MSB register + + IF_CTRL_addr = 0x0e, ///< Interface control register + + WHO_AM_I_addr = 0x0f, ///< Device Who am I register + + CTRL_REG1_addr = 0x10, ///< Control Register 1 [ODR, AVG] + CTRL_REG2_addr = 0x11, ///< Control Register 2 + CTRL_REG3_addr = 0x12, ///< Control Register 3 + CTRL_REG4_addr = 0x13, ///< Control Register 4 + + FIFO_CTRL_addr = 0x14, ///< FIFO control register + FIFO_WTM_addr = 0x15, ///< FIFO threshold setting register + + REF_P_L_addr = 0x16, ///< Reference pressure LSB data + REF_P_H_addr = 0x17, ///< Reference pressure MSB data + + FIFO_STATUS1_addr = 0x25, ///< FIFO status register 1 + FIFO_STATUS2_addr = 0x26, ///< FIFO status register 2 + + STATUS_addr = 0x27, ///< Status register + + PRESSURE_OUT_XL_addr = 0x28, ///< Pressure output value LSB data + PRESSURE_OUT_L_addr = 0x29, ///< Pressure output value middle data + PRESSURE_OUT_H_addr = 0x2a, ///< Pressure output value MSB data + + TEMP_OUT_L_addr = 0x2b, ///< Temperature output value LSB data + TEMP_OUT_H_addr = 0x2c, ///< Temperature output value MSB data + + FIFO_DATA_OUT_PRESS_XL_addr = 0x78, ///< FIFO pressure output LSB data + FIFO_DATA_OUT_PRESS_L_addr = 0x79, ///< FIFO pressure output middle data + FIFO_DATA_OUT_PRESS_H_addr = 0x7a, ///< FIFO pressure output MSB data +}; + +enum IF_CTRL : uint8_t +{ + CS_PU_DIS = (1 << 1), + INT_PD_DIS = (1 << 2), + SDO_PU_EN = (1 << 3), + SDA_PU_EN = (1 << 4), + SIM = (1 << 5), + I2C_I3C_DIS = (1 << 6), ///< Disable I2C and I3C digital interfaces + INT_EN_I3C = (1 << 7) +}; + +enum CTRL_REG2 : uint8_t +{ + ONE_SHOT_START = (1 << 0), ///< Enable one-shot mode + SWRESET = (1 << 2), ///< Software reset + BDU = (1 << 3), ///< Block data update + EN_LPFP = (1 << 4), ///< Enable low-pass filter on pressure data + LFPF_CFG = (1 << 5), ///< Low-pass filter configuration + FS_MODE = (1 << 6), ///< Full-scale selection + BOOT = (1 << 7) ///< Reboot memory content +}; + +enum CTRL_REG3 : uint8_t +{ + IF_ADD_INC = + (0b1 << 0), ///< Increment register during a multiple byte access + PP_OD = (0b1 << 1), ///< Push-pull/open-drain selection on interrupt pin + INT_H_L = (0b1 << 3) ///< Select interrupt active-high, active-low +}; + +enum CTRL_REG4 : uint8_t +{ + INT_F_OVR = (0b1 << 0), ///< FIFO overrun status on INT_DRDY pin + INT_F_WTM = (0b1 << 1), ///< FIFO threshold status on INT_DRDY pin + INT_F_FULL = (0b1 << 2), ///< FIFO full flag on INT_DRDY pin + INT_EN = (0b1 << 4), ///< Interrupt signal on INT_DRDY pin + DRDY = (0b1 << 5), ///< Date-ready signal on INT_DRDY pin + DRDY_PLS = (0b1 << 6) ///< Data-ready pulsed on INT_DRDY pin +}; + +enum STATUS : uint8_t +{ + P_DA = (0b1 << 0), ///< Pressure data available + T_DA = (0b1 << 1), ///< Temperature data available + P_OR = (0b1 << 4), ///< Pressure data overrun + T_OR = (0b1 << 5) ///< Temperature data overrun +}; +} // namespace LPS22DFDefs +} // namespace Boardcore \ No newline at end of file diff --git a/src/tests/sensors/test-lps22df.cpp b/src/tests/sensors/test-lps22df.cpp index 7be3e9cd9..caad6e697 100644 --- a/src/tests/sensors/test-lps22df.cpp +++ b/src/tests/sensors/test-lps22df.cpp @@ -67,13 +67,13 @@ int main() return 0; } - printf("Trying one shot mode for 10 seconds"); + printf("Trying one shot mode for 10 seconds\n"); for (int i = 0; i < 10 * 10; i++) { sensor.sample(); LPS22DFData data = sensor.getLastSample(); - printf("%.2f° | %.2fPa\n", data.temperature, data.pressure); + printf("%.2f C | %.2f Pa\n", data.temperature, data.pressure); miosix::Thread::sleep(100); } @@ -85,7 +85,7 @@ int main() sensor.sample(); LPS22DFData data = sensor.getLastSample(); - printf("%.2f° | %.2fPa\n", data.temperature, data.pressure); + printf("%.2f C | %.2f Pa\n", data.temperature, data.pressure); miosix::Thread::sleep(100); } -- GitLab