-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
597 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// coding: utf-8 | ||
// ---------------------------------------------------------------------------- | ||
/* | ||
* Copyright (c) 2023, Vivien Henry | ||
* Based on the ms5837, courtesy of Rasmus Kleist Hørlyck Sørensen | ||
* | ||
* This file is part of the modm project. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#ifndef MODM_MS5837_HPP | ||
#define MODM_MS5837_HPP | ||
|
||
#include "ms5837_data.hpp" | ||
|
||
#include <modm/processing/resumable.hpp> | ||
#include <modm/architecture/interface/i2c_device.hpp> | ||
#include <modm/architecture/interface/register.hpp> | ||
#include <modm/processing/timer.hpp> | ||
|
||
|
||
namespace modm | ||
{ | ||
|
||
/// @ingroup modm_driver_ms5837 | ||
struct ms5837 | ||
{ | ||
|
||
using Prom = modm::ms5837data::Prom; | ||
using Data = modm::ms5837data::Data; | ||
using DataBase = modm::ms5837data::DataBase; | ||
|
||
protected: | ||
/// @cond | ||
enum class | ||
Command : uint8_t | ||
{ | ||
Reset = 0x1E, | ||
Convert = 0x40, | ||
AdcRead = 0x00, | ||
PromRead = 0xA0, | ||
}; | ||
|
||
enum class | ||
Conversion : uint8_t | ||
{ | ||
Pressure = 0x00, | ||
Temperature = 0x10, | ||
}; | ||
/// @endcond | ||
|
||
public: | ||
enum class | ||
OversamplingRatio : uint8_t | ||
{ | ||
Osr256 = 0x00, | ||
Osr512 = 0x02, | ||
Osr1024 = 0x04, | ||
Osr2048 = 0x06, | ||
Osr4096 = 0x08, | ||
}; | ||
|
||
protected: | ||
/// @cond | ||
static constexpr uint8_t | ||
i(Command cmd) { return uint8_t(cmd); } | ||
static constexpr uint8_t | ||
i(Conversion conv) { return uint8_t(conv); } | ||
static constexpr uint8_t | ||
i(OversamplingRatio osr) { return uint8_t(osr); } | ||
/// @endcond | ||
}; | ||
|
||
/** | ||
* @tparam I2cMaster I2C interface | ||
* | ||
* @author Vivien Henry | ||
* @ingroup modm_driver_ms5837 | ||
*/ | ||
template < typename I2cMaster > | ||
class Ms5837 : public ms5837, public modm::I2cDevice<I2cMaster, 2> | ||
{ | ||
public: | ||
/** | ||
* @param data pointer to buffer of the internal data of type Data | ||
*/ | ||
Ms5837(DataBase &data, uint8_t address=0x76); | ||
|
||
/// Call this function before using the device to read the factory calibration | ||
/// @warning calls to this function resets the device | ||
modm::ResumableResult<bool> | ||
initialize(); | ||
|
||
/// Do a readout sequence to convert and read temperature and then pressure from sensor | ||
modm::ResumableResult<bool> | ||
readout(OversamplingRatio osrPressure = OversamplingRatio::Osr256, | ||
OversamplingRatio osrTemperature = OversamplingRatio::Osr256); | ||
|
||
public: | ||
/// Get the data object for this sensor | ||
inline DataBase& | ||
getData() { return data; } | ||
|
||
private: | ||
/// Read the PROM register at the address | ||
modm::ResumableResult<uint16_t> | ||
readProm(uint8_t addr); | ||
|
||
private: | ||
DataBase &data; | ||
modm::ShortTimeout timeout; | ||
|
||
/** | ||
* Conversion time of the Analog Digital Convert for different oversampling ratios | ||
* The conversion times are taken from the application note AN520 | ||
*/ | ||
static constexpr uint8_t conversionDelay[] = {1, 3, 4, 6, 10}; | ||
|
||
/// Command buffer for writing to and reading from the device | ||
uint8_t buffer[2]; | ||
|
||
uint8_t factory_crc; | ||
}; | ||
|
||
} // modm namespace | ||
|
||
#include "ms5837_impl.hpp" | ||
|
||
#endif // MODM_MS5837_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (c) 2023, Vivien Henry, | ||
# Based on the ms5611, courtesy of Rasmus Kleist Hørlyck Sørensen | ||
# | ||
# This file is part of the modm project. | ||
# | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
# ----------------------------------------------------------------------------- | ||
|
||
def init(module): | ||
module.name = ":driver:ms5837" | ||
module.description = """\ | ||
# MS5837 Pressure Sensor | ||
This sensor is optimized for water depth measurement systems with a resolution of 0.2cm. | ||
""" | ||
|
||
def prepare(module, options): | ||
module.depends( | ||
":architecture:i2c.device", | ||
":architecture:register", | ||
":math:utils", | ||
":processing:resumable", | ||
":processing:timer") | ||
return True | ||
|
||
def build(env): | ||
env.outbasepath = "modm/src/modm/driver/pressure" | ||
env.copy("ms5837.hpp") | ||
env.copy("ms5837_impl.hpp") | ||
env.copy("ms5837_data.hpp") | ||
env.copy("ms5837_data_impl.hpp") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
// coding: utf-8 | ||
// ---------------------------------------------------------------------------- | ||
/* | ||
* Copyright (c) 2023, Vivien Henry | ||
* Based on the ms5837, courtesy of Rasmus Kleist Hørlyck Sørensen | ||
* | ||
* This file is part of the modm project. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#ifndef MODM_MS5837_DATA_HPP | ||
#define MODM_MS5837_DATA_HPP | ||
|
||
namespace modm | ||
{ | ||
|
||
// Forward declaration of the driver class | ||
template < typename I2cMaster > | ||
class Ms5837; | ||
|
||
namespace ms5837data | ||
{ | ||
|
||
/** | ||
* @brief Holds the factory calibration data from the PROM. | ||
* Upon initialization the driver automatically reads the calibration values from the PROM | ||
*/ | ||
/// @ingroup modm_driver_ms5837 | ||
struct modm_packed | ||
Prom | ||
{ | ||
uint8_t | ||
calculateCrc() | ||
{ | ||
uint32_t n_rem = 0; // crc remainder | ||
data[0] = ((data[0]) & 0x0FFF); // CRC byte is replaced by 0 | ||
data[7] = 0; // Subsidiary value, set to 0 | ||
for (int cnt = 0; cnt < 16; cnt++) // operation is performed on bytes | ||
{ // choose LSB or MSB | ||
if (cnt % 2==1) n_rem ^= uint16_t((data[cnt>>1]) & 0x00FF); | ||
else n_rem ^= uint16_t(data[cnt>>1] >> 8); | ||
|
||
for (uint8_t n_bit = 8; n_bit > 0; n_bit--) | ||
{ | ||
if (n_rem & (0x8000)) n_rem = (n_rem << 1) ^ 0x3000; | ||
else n_rem = (n_rem << 1); | ||
} | ||
} | ||
n_rem = ((n_rem >> 12) & 0x000F); // final 4-bit remainder is CRC code | ||
return n_rem; | ||
} | ||
|
||
/** | ||
* prom[0] Factory data and CRC | ||
* prom[1] C1 / Pressure sensitivity | ||
* prom[2] C2 / Pressure offset | ||
* prom[3] C3 / Temperature coefficient of pressure sensitivity | ||
* prom[4] C4 / Temperature coefficient of pressure offset | ||
* prom[5] C5 / Reference temperature | ||
* prom[6] C6 / Temperature coefficient of the temperature | ||
* prom[7] Subsidiary value (not read, used internally for calculation) | ||
*/ | ||
uint16_t data[8]{}; | ||
}; | ||
|
||
/// @ingroup modm_driver_ms5837 | ||
class modm_packed | ||
DataBase | ||
{ | ||
template < typename I2cMaster > | ||
friend class ::modm::Ms5837; | ||
|
||
public: | ||
inline | ||
DataBase() : meta(0) {} | ||
|
||
inline Prom& | ||
getProm() { return prom; } | ||
|
||
public: | ||
/// Notify the data class about changed buffer of raw pressure data (D1). | ||
void rawPressureTouched() { meta &= ~PRESSURE_CALCULATED; } | ||
|
||
/// Notify the data class about changed buffer of raw temperature data (D2). | ||
void rawTemperatureTouched() { meta &= ~TEMPERATURE_CALCULATED; } | ||
|
||
protected: | ||
Prom prom; | ||
|
||
protected: | ||
// The raw data read from the ADC register | ||
// 0 .. 2 pressure data (D1) | ||
// 3 .. 5 temperature data (D2) | ||
uint8_t raw[6]{}; | ||
|
||
// Bit 1: Temperature calculated | ||
// Bit 0: Pressure calculated | ||
uint8_t meta = 0; | ||
|
||
enum | ||
{ | ||
/// Remember if the raw data has been converted to pressure | ||
PRESSURE_CALCULATED = modm::Bit0, | ||
/// Remember if the raw data has been converted to temperature | ||
TEMPERATURE_CALCULATED = modm::Bit1, | ||
}; | ||
}; | ||
|
||
/// @ingroup modm_driver_ms5837 | ||
class modm_packed | ||
Data : public DataBase | ||
{ | ||
public: | ||
|
||
/** | ||
* @brief Get the calibrated pressure data with 0.25 mbar resolution (in tenth of mbar (10^-4 bar)) | ||
* @attention No I2C transaction | ||
* | ||
* @return int32_t | ||
*/ | ||
int32_t inline | ||
getPressure(); | ||
|
||
void inline | ||
getPressure(int32_t &pres) { pres = getPressure(); } | ||
|
||
/** | ||
* @brief Get the calibrated pressure data with 0.25 mbar resolution (in mbar) | ||
* @attention No I2C transaction | ||
* @return void | ||
*/ | ||
void inline | ||
getPressure(float &pres) { pres = float(getPressure()) / 10.0f; } | ||
|
||
/** | ||
* @brief Get the calibrated temperature data with 0.01 degrees Centigrade resolution (2501 = 25.01°C) | ||
* @attention No I2C transaction | ||
* | ||
* @return int32_t | ||
*/ | ||
int32_t inline | ||
getTemperature(); | ||
|
||
void inline | ||
getTemperature(int32_t &temp) { temp = getTemperature(); } | ||
|
||
/** | ||
* @brief Get the calibrated temperature data with 0.01 degrees Centigrade resolution, in °C | ||
* @attention No I2C transaction | ||
* | ||
* @return void | ||
*/ | ||
void inline | ||
getTemperature(float &temp) { temp = float(getTemperature()) / 100.0f; } | ||
|
||
|
||
inline uint32_t getRawC1() { return uint32_t(raw[0] << 16 | raw[1] << 8 | raw[2]); } | ||
inline uint32_t getRawC2() { return uint32_t(raw[3] << 16 | raw[4] << 8 | raw[5]); } | ||
|
||
protected: | ||
void inline | ||
calculateCalibratedValues(); | ||
|
||
private: | ||
int32_t calibratedPressure; | ||
int32_t calibratedTemperature; | ||
}; | ||
|
||
} // ms5837data namespace | ||
|
||
} // modm namespace | ||
|
||
#include "ms5837_data_impl.hpp" | ||
|
||
#endif // MODM_MS5837_DATA_HPP |
Oops, something went wrong.