diff --git a/src/shared/sensors/ND015X/ND015D.cpp b/src/shared/sensors/ND015X/ND015D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d20d7b66464d6167cde23d0496341dcae74facb8 --- /dev/null +++ b/src/shared/sensors/ND015X/ND015D.cpp @@ -0,0 +1,142 @@ +/* Copyright (c) 2025 Skyward Experimental Rocketry + * Author: Pietro Bortolus + * + * 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 "ND015D.h" + +#include <drivers/timer/TimestampTimer.h> +#include <math.h> + +namespace Boardcore +{ +ND015D::ND015D(SPIBusInterface& bus, miosix::GpioPin cs, SPIBusConfig spiConfig) + : slave(bus, cs, spiConfig) +{ +} + +bool ND015D::init() +{ + uint8_t data[10]; + + SPITransaction spi(slave); + + spi.read(data, sizeof(data)); + + // the following monstrosity is needed to check if the model number read + // from the SPI is correct, the numbers are the ASCII encoding of "ND015D" + + if (data[9] == 0x44 && data[8] == 0x35 && data[7] == 0x31 && + data[6] == 0x30 && data[5] == 0x44 && data[4] == 0x4E) + { + return true; + } + else + { + LOG_ERR(logger, "sensor model number did not match"); + return false; + } +} + +bool ND015D::selfTest() { return true; } + +void ND015D::setOutputDataRate(uint8_t odr) +{ + if (odr < 0x100) + { + rateByte = odr; + } + else + { + LOG_ERR(logger, "odr setting not valid, using default value (0x1C)"); + rateByte = 0x1C; + } +} + +void ND015D::setFullScaleRange(FullScaleRange fs) +{ + modeByte = (modeByte & ~FS_MASK) | fs; + + switch (fs) + { + case FS_1: + range = 1; + break; + + case FS_2: + range = 2; + break; + + case FS_4: + range = 4; + break; + + case FS_5: + range = 5; + break; + + case FS_10: + range = 10; + break; + + case FS_15: + range = 15; + break; + + default: + break; + } +} + +void ND015D::setIOWatchdog(IOWatchdogEnable iow) +{ + modeByte = (modeByte & ~IO_WATCHDOG_MASK) | iow; +} + +void ND015D::setBWLimitFilter(BWLimitFilter bwl) +{ + modeByte = (modeByte & ~BW_LIMIT_MASK) | bwl; +} + +void ND015D::setNotch(NotchEnable ntc) +{ + modeByte = (modeByte & ~NOTCH_MASK) | ntc; +} + +ND015XData ND015D::sampleImpl() +{ + ND015XData data; + SPIDataOut = (modeByte << 8) | rateByte; + + SPITransaction spi(slave); + + spi.transfer16(SPIDataOut); // we need to make an SPI transaction before + // reading the data to make sure the proper + // settings are used + + SPIDataIn = spi.transfer16(SPIDataOut); + + data.pressure = (short)SPIDataIn / (0.9 * pow(2, 15)) * range; + data.pressureTimestamp = TimestampTimer::getTimestamp(); + + return data; +} + +} // namespace Boardcore diff --git a/src/shared/sensors/ND015X/ND015D.h b/src/shared/sensors/ND015X/ND015D.h new file mode 100644 index 0000000000000000000000000000000000000000..693222009f94d02e04f2a3ac47302b3577b19e03 --- /dev/null +++ b/src/shared/sensors/ND015X/ND015D.h @@ -0,0 +1,132 @@ +/* Copyright (c) 2025 Skyward Experimental Rocketry + * Author: Pietro Bortolus + * + * 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 <sensors/Sensor.h> + +#include "ND015XData.h" + +namespace Boardcore +{ + +class ND015D : public Sensor<ND015XData> +{ +public: + /** + * The datasheet is unclear about the unit of measure, + * it could be either psi or inH2O but I believe it's the latter + */ + enum FullScaleRange : uint8_t + { + FS_1 = 0x02, // 1.0 psi + FS_2 = 0x03, // 2.0 psi + FS_4 = 0x04, // 4.0 psi + FS_5 = 0x05, // 5.0 psi + FS_10 = 0x06, // 10.0 psi + FS_15 = 0x07, // 15.0 psi + }; + + enum BWLimitFilter : uint8_t + { + BWL_1 = 0x00, // 1.0 Hz + BWL_2 = 0x10, // 2.0 Hz + BWL_5 = 0x20, // 5.0 Hz + BWL_10 = 0x30, // 10 Hz + BWL_20 = 0x40, // 20 Hz + BWL_50 = 0x50, // 50 Hz + BWL_100 = 0x60, // 100 Hz + BWL_200 = 0x70, // 200 Hz + }; + + enum IOWatchdogEnable : uint8_t + { + DISABLED = 0x00, + ENABLED = 0x08, + }; + + enum NotchEnable : uint8_t + { + DISABLED = 0x00, + ENABLED = 0x80, + }; + + ND015D(SPIBusInterface& bus, miosix::GpioPin cs, SPIBusConfig spiConfig); + + bool init() override; + + bool selfTest() override; + + /** + * @brief function to set the output data rate + * + * @param odr output data rate for the sensor, + * the actual odr is calculated as + * 444Hz / odr + */ + void setOutputDataRate(u_int8_t odr); + + /** + * @brief function to set the fullscale range + * + * @param fs fullscale range, default is + * 2.0 psi + */ + void setFullScaleRange(FullScaleRange fs); + + /** + * @brief function to enable the IO watchdog + * + * @param iow setting + */ + void setIOWatchdog(IOWatchdogEnable iow); + + void setBWLimitFilter(BWLimitFilter bwl); + + void setNotch(NotchEnable ntc); + +protected: + ND015XData sampleImpl() override; + +private: + SPISlave slave; + uint8_t modeByte = 0xF3; // settings for the mode control register + uint8_t rateByte = 0x1C; // settings for the rate control register + uint16_t SPIDataIn; + uint16_t SPIDataOut; + short range = 1; + + enum RegisterMask : uint8_t + { + FS_MASK = 0x07, + IO_WATCHDOG_MASK = 0x08, + BW_LIMIT_MASK = 0x70, + NOTCH_MASK = 0x80, + }; + + PrintLogger logger = Logging::getLogger("nd015d"); +}; + +} // namespace Boardcore +