Skip to content

Commit

Permalink
Adding MS5837 Driver
Browse files Browse the repository at this point in the history
  • Loading branch information
lukh authored and salkinium committed Feb 5, 2023
1 parent afdb5ba commit 1957994
Show file tree
Hide file tree
Showing 6 changed files with 597 additions and 5 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -725,39 +725,40 @@ you specific needs.
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mmc5603">MMC5603</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ms5611">MS5611</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ms5837">MS5837</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nokia5110">NOKIA5110</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nrf24">NRF24</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-parallel_tft_display">TFT-DISPLAY</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pat9125el">PAT9125EL</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pat9125el">PAT9125EL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca8574">PCA8574</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9535">PCA9535</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9548a">PCA9548A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9685">PCA9685</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sh1106">SH1106</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s65">SIEMENS-S65</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s65">SIEMENS-S65</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s75">SIEMENS-S75</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sk6812">SK6812</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sk9822">SK9822</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ssd1306">SSD1306</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-st7586s">ST7586S</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-st7789">ST7789</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-st7789">ST7789</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-stts22h">STTS22H</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-stusb4500">STUSB4500</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sx1276">SX1276</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3414">TCS3414</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3472">TCS3472</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tlc594x">TLC594x</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tlc594x">TLC594x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp102">TMP102</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp12x">TMP12x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp175">TMP175</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-touch2046">TOUCH2046</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl53l0">VL53L0</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl6180">VL6180</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl6180">VL6180</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ws2812">WS2812</a></td>
</tr>
</table>
Expand Down
133 changes: 133 additions & 0 deletions src/modm/driver/pressure/ms5837.hpp
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
36 changes: 36 additions & 0 deletions src/modm/driver/pressure/ms5837.lb
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")
179 changes: 179 additions & 0 deletions src/modm/driver/pressure/ms5837_data.hpp
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
Loading

0 comments on commit 1957994

Please sign in to comment.