Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[driver] Add driver for STTS22H temperature sensor #544

Merged
merged 2 commits into from
May 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -588,18 +588,20 @@ you specific needs.
<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>
</tr><tr>
<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>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp102">TMP102</a></td>
</tr><tr>
<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-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>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ws2812">WS2812</a></td>
</tr><tr>
</tr>
</table>
<!--/drivertable-->
Expand Down
55 changes: 55 additions & 0 deletions examples/nucleo_f103rb/stts22h/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2021, Christopher Durand
*
* 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/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/processing.hpp>
#include <modm/driver/temperature/stts22h.hpp>

using namespace Board;
using namespace std::literals;

using I2cMaster = I2cMaster1;

int
main()
{
Board::initialize();
LedD13::setOutput();

I2cMaster::connect<GpioB7::Sda, GpioB6::Scl>();
I2cMaster::initialize<Board::SystemClock, 100_kHz>();

MODM_LOG_INFO << "Welcome to STTS22H Test" << modm::endl;

modm::stts22h::Data data{};
modm::Stts22h<I2cMaster> sensor{data, 0x3f};

bool success = RF_CALL_BLOCKING(sensor.initialize());
if(!success)
{
MODM_LOG_ERROR << "Initialization failed" << modm::endl;
}

modm::PeriodicTimer timer{500ms};
while (true)
{
if (timer.execute())
{
LedD13::toggle();

RF_CALL_BLOCKING(sensor.readTemperature());
MODM_LOG_INFO << "temperature: " << data.getTemperatureFractional();
MODM_LOG_INFO << " [1/100th °C]" << modm::endl;
}
}

return 0;
}
12 changes: 12 additions & 0 deletions examples/nucleo_f103rb/stts22h/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<library>
<extends>modm:nucleo-f103rb</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_f103rb/stts22h</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:processing:timer</module>
<module>modm:platform:i2c:1</module>
<module>modm:driver:stts22h</module>
</modules>
</library>
148 changes: 148 additions & 0 deletions src/modm/driver/temperature/stts22h.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright (c) 2021, Christopher Durand
*
* 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_STTS22H_HPP
#define MODM_STTS22H_HPP

#include <modm/architecture/interface/register.hpp>
#include <modm/architecture/interface/i2c_device.hpp>
#include <array>

namespace modm
{

/// @ingroup modm_driver_stts22h
struct stts22h
{
protected:
/// @cond
enum class
Register : uint8_t
{
WhoAmI = 0x01,
TempHLimit = 0x02,
TempLLimit = 0x03,
Ctrl = 0x04,
Status = 0x05,
TempLOut = 0x06,
TempHOut = 0x07,
SoftwareReset = 0x0C
};

enum class
Ctrl : uint8_t
{
LowOdrStart = Bit7,
Bdu = Bit6,
Avg1 = Bit5,
Avg0 = Bit4,
IfAddInc = Bit3,
FreeRun = Bit2,
TimeOutDis = Bit1,
OneShot = Bit0
};
MODM_FLAGS8(Ctrl);

enum class
SoftwareReset : uint8_t
{
LowOdrEnable = Bit6,
SwReset = Bit1
};
MODM_FLAGS8(SoftwareReset);

using RegisterValue = modm::FlagsGroup<Ctrl_t, SoftwareReset_t>;

enum class
Status : uint8_t
{
UnderThl = Bit2,
OverThh = Bit1,
Busy = Bit0
};
MODM_FLAGS8(Status);
/// @endcond
public:
struct modm_packed
Data
{
uint8_t data[2];

/// @return temperature in 1/100th °C
constexpr int16_t
salkinium marked this conversation as resolved.
Show resolved Hide resolved
getTemperatureFractional()
{
return (int16_t(data[1]) << 8) | data[0];
}

/// @return temperature as float in °C
constexpr float
getTemperature()
{
return getTemperatureFractional() / 100.0f;
}
};
};

/**
* Simple driver for STTS22H I2C temperature sensor.
*
* Only 'free-run' mode is supported.
*
* @ingroup modm_driver_stts22h
*
* @author Christopher Durand
*/
template <class I2cMaster>
class Stts22h : public stts22h, public I2cDevice<I2cMaster, 3>
{
public:
/// \param address I2C address, selectable on device between 0x38 and 0x3f
Stts22h(Data& data, uint8_t address = 0x3f);

/// Initialize sensor
modm::ResumableResult<bool>
initialize();

/// Detect sensor
modm::ResumableResult<bool>
ping();

/// Read temperature from device
/// \pre sensor is succesfully initialized
modm::ResumableResult<bool>
readTemperature();

inline Data&
getData()
{ return data_; }

private:
static constexpr inline uint8_t DeviceId{0xA0};

modm::ResumableResult<bool>
write(Register reg, RegisterValue value);

modm::ResumableResult<bool>
read(Register reg, uint8_t& value);

modm::ResumableResult<bool>
read(Register reg, uint8_t* buffer, uint8_t length);

Data& data_;
std::array<uint8_t, 2> buffer_;
};

} // namespace modm

#include "stts22h_impl.hpp"

#endif // MODM_STTS22H_HPP
30 changes: 30 additions & 0 deletions src/modm/driver/temperature/stts22h.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2018, Niklas Hauser
# Copyright (c) 2021, Christopher Durand
#
# 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:stts22h"
module.description = """\
Simple driver for STTS22H I2c temperature sensor
"""

def prepare(module, options):
module.depends(
":architecture:i2c.device",
":architecture:register")
return True

def build(env):
env.outbasepath = "modm/src/modm/driver/temperature"
env.copy("stts22h.hpp")
env.copy("stts22h_impl.hpp")
95 changes: 95 additions & 0 deletions src/modm/driver/temperature/stts22h_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2021, Christopher Durand
*
* 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_STTS22H_HPP
#error "Don't include this file directly, use 'stts22h.hpp' instead!"
#endif

namespace modm
{

template < typename I2cMaster >
Stts22h<I2cMaster>::Stts22h(Data &data, uint8_t address) :
I2cDevice<I2cMaster, 3>{address}, data_{data}
{
}

template<class I2cMaster>
ResumableResult<bool>
Stts22h<I2cMaster>::write(Register reg, RegisterValue value)
{
RF_BEGIN();

buffer_[0] = static_cast<uint8_t>(reg);
buffer_[1] = value.value;

this->transaction.configureWrite(&buffer_[0], 2);

RF_END_RETURN_CALL(this->runTransaction());
}

template<class I2cMaster>
ResumableResult<bool>
Stts22h<I2cMaster>::read(Register reg, uint8_t& value)
{
return read(reg, &value, 1);
}

template<class I2cMaster>
ResumableResult<bool>
Stts22h<I2cMaster>::read(Register reg, uint8_t* data, uint8_t length)
{
RF_BEGIN();

buffer_[0] = static_cast<uint8_t>(reg);
this->transaction.configureWriteRead(&buffer_[0], 1, data, length);

RF_END_RETURN_CALL(this->runTransaction());
}

template<class I2cMaster>
ResumableResult<bool>
Stts22h<I2cMaster>::initialize()
{
RF_BEGIN();
if (!RF_CALL(this->ping())) {
RF_RETURN(false);
}
if (!RF_CALL(write(Register::SoftwareReset, SoftwareReset::SwReset))) {
RF_RETURN(false);
}
if (!RF_CALL(write(Register::SoftwareReset, SoftwareReset{}))) {
RF_RETURN(false);
}
RF_END_RETURN_CALL(write(Register::Ctrl, Ctrl::FreeRun | Ctrl::IfAddInc));
}

template<class I2cMaster>
ResumableResult<bool>
Stts22h<I2cMaster>::ping()
{
RF_BEGIN();
// It's ok here to use buffer_[1] as temporary storage
// since read() only uses buffer_[0]
if (!RF_CALL(read(Register::WhoAmI, buffer_[1]))) {
RF_RETURN(false);
}
RF_END_RETURN(buffer_[1] == DeviceId);
}

template<class I2cMaster>
ResumableResult<bool>
Stts22h<I2cMaster>::readTemperature()
{
return read(Register::TempLOut, data_.data, 2);
}

} // namespace modm