Skip to content

Commit

Permalink
[driver] max31865 removed blocking RF calls, added pt(100) config struct
Browse files Browse the repository at this point in the history
  • Loading branch information
hshose committed Apr 9, 2023
1 parent 12b5e3b commit 8e0a8dd
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 61 deletions.
4 changes: 2 additions & 2 deletions examples/stm32f469_discovery/max31865/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class ThermocoupleThread : public modm::pt::Protothread
while (true)
{
MODM_LOG_INFO << "\nNew readout:" << modm::endl;
RF_CALL_BLOCKING(pt100.readout());
PT_CALL(pt100.readout());

MODM_LOG_INFO << " resistance : " << data.getResistance() << " Ohm"
<< modm::endl;
Expand All @@ -53,7 +53,7 @@ class ThermocoupleThread : public modm::pt::Protothread
}

private:
modm::max31865pt100::Data data;
modm::max31865<modm::pt100>::Data data;
modm::Max31865<SpiMaster, Cs> pt100;

modm::ShortTimeout timeout;
Expand Down
59 changes: 38 additions & 21 deletions src/modm/driver/temperature/max31865.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,34 @@
#include <modm/architecture/interface/register.hpp>
#include <modm/architecture/interface/spi_device.hpp>
#include <modm/processing/resumable.hpp>
#include <modm/processing/timer.hpp>

namespace modm
{

struct Pt
{
float R0;
float Rref;
float alpha;
double a;
double b;
double c;
};

/// Standard values for IEC 751 (PT100) with 430 Ohm reference
constexpr Pt pt100{
.R0 = 100.f,
.Rref = 430.f,
.alpha = 3.85055e-3f,
.a = double{3.90830e-3},
.b = double{-5.77500e-7},
.c = double{-4.18301e-12},
};

/// @ingroup modm_driver_max31865
// Standard values for IEC 751 (PT100) with 400 Ohm reference
template<float R0 = 100.f, float Rref = 430.f, float alpha = 3.85055e-3f,
double a = double{3.90830e-3}, double b = double{-5.77500e-7},
double c = double{-4.18301e-12}>
template<Pt pt>
struct max31865
{

Expand Down Expand Up @@ -117,15 +136,15 @@ struct max31865
getResistance() const
{
const uint16_t adccode = data >> 1;
return adccode / 32768.f * Rref;
return adccode / 32768.f * pt.Rref;
}

/// @return fast temperature in degrees celsius, about 0.3 degrees error between 0 and 100
/// degrees celsius
constexpr float
getTemperatureFast() const
{
return (getResistance() - R0) / alpha / 100.f;
return (getResistance() - pt.R0) / pt.alpha / 100.f;
}

/// @return slow but accurate temperature in degrees celsius
Expand All @@ -134,18 +153,19 @@ struct max31865
{
const double res = getResistance();
double T = getTemperatureFast();
const double c0 = T <= 0 ? c : 0;
const double c0 = T <= 0 ? pt.c : 0;

// Do some fixed number of newton steps for root finding
// on Callendar Van Dusen equation:
// R = R0*(1+a*T+b*T*T+c*(T-100)*T*T*T)
// Newton seems to need double precision to achieve 1.e-10 residual?!
for (int i = 0; i < 10; i++)
{
const double R =
double{R0} * (1 + (a * T) + (b * T * T) + (c0 * (T - 100) * T * T * T)) - res;
const double R = double{pt.R0} * (1 + (pt.a * T) + (pt.b * T * T) +
(c0 * (T - 100) * T * T * T)) -
res;
const double Rdash =
double{R0} * (a + (2 * b * T) + c0 * (((4 * T) - 300) * T * T));
double{pt.R0} * (pt.a + (2 * pt.b * T) + c0 * (((4 * T) - 300) * T * T));
T -= R / Rdash;
if (std::abs(R) <= 1.e-10) { break; }
}
Expand All @@ -157,25 +177,23 @@ struct max31865
};
}; // struct max31865

using max31865pt100 = max31865<>;

/**
* @tparam SpiMaster
* @tparam Cs
*
* @author Henrik Hose
* @ingroup modm_driver_max31865
*/
template<typename SpiMaster, typename Cs>
class Max31865 : public max31865pt100,
template<typename SpiMaster, typename Cs, Pt pt = pt100>
class Max31865 : public max31865<pt>,
public modm::SpiDevice<SpiMaster>,
protected modm::NestedResumable<3>
{
public:
/**
* @param data pointer to buffer of the internal data of type Data
*/
Max31865(Data &data);
Max31865(max31865<pt>::Data &data);

/// Call this function once before using the device
void
Expand All @@ -185,29 +203,28 @@ class Max31865 : public max31865pt100,
modm::ResumableResult<void>
readout();

public:
/// Get the data object for this sensor
inline Data &
inline max31865<pt>::Data &
getData()
{
return data;
}

private:
Data &data;
max31865<pt>::Data &data;
std::array<uint8_t, 2> buffer;
Config_t config;
max31865<pt>::Config_t config;

modm::ShortTimeout timeout;

modm::ResumableResult<void>
writeSingleRegister(Register address, uint8_t data);
writeSingleRegister(max31865<pt>::Register address, uint8_t data);

modm::ResumableResult<uint8_t>
readSingleRegister(Register address);
readSingleRegister(max31865<pt>::Register address);

modm::ResumableResult<uint16_t>
readTwoRegisters(Register address);
readTwoRegisters(max31865<pt>::Register address);
};

} // namespace modm
Expand Down
3 changes: 2 additions & 1 deletion src/modm/driver/temperature/max31865.lb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def prepare(module, options):
module.depends(
":architecture:gpio",
":architecture:spi.device",
":processing:resumable")
":processing:resumable",
":processing:timer")
return True

def build(env):
Expand Down
72 changes: 35 additions & 37 deletions src/modm/driver/temperature/max31865_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,9 @@
namespace modm
{

template<typename SpiMaster, typename Cs>
Max31865<SpiMaster, Cs>::Max31865(Data &data) : data(data)
{}

template<typename SpiMaster, typename Cs>
void
Max31865<SpiMaster, Cs>::initialize()
template<typename SpiMaster, typename Cs, Pt pt>
Max31865<SpiMaster, Cs, pt>::Max31865(max31865<pt>::Data &data) : data(data)
{

this->attachConfigurationHandler([]() {
static_assert(std::is_same_v<SpiMaster, modm::platform::SpiMaster2>);
SPI2->CR1 &= ~SPI_CR1_SPE;
Expand All @@ -35,78 +29,82 @@ Max31865<SpiMaster, Cs>::initialize()
SPI2->CR1 |= SPI_CR1_SPE;
__DSB();
});

Cs::setOutput(modm::Gpio::High);
}

template<typename SpiMaster, typename Cs, Pt pt>
void
Max31865<SpiMaster, Cs, pt>::initialize()
{

config = Config();
config.set(Config::FaultStatusClear);
config.set(Rejection_t(Rejection::Rejection50Hz));
RF_CALL_BLOCKING(writeSingleRegister(Register::WriteConfiguration, config.value));
config = Config_t(RF_CALL_BLOCKING(readSingleRegister(Register::ReadConfiguration)));
config = typename max31865<pt>::Config();
config.set(max31865<pt>::Config::FaultStatusClear);
config.set(typename max31865<pt>::Rejection_t(max31865<pt>::Rejection::Rejection50Hz));
RF_CALL_BLOCKING(writeSingleRegister(max31865<pt>::Register::WriteConfiguration, config.value));
config = typename max31865<pt>::Config_t(
RF_CALL_BLOCKING(readSingleRegister(max31865<pt>::Register::ReadConfiguration)));
}

template<typename SpiMaster, typename Cs>
template<typename SpiMaster, typename Cs, Pt pt>
modm::ResumableResult<void>
Max31865<SpiMaster, Cs>::readout()
Max31865<SpiMaster, Cs, pt>::readout()
{
RF_BEGIN();
config.set(Config::VBias);
RF_CALL(writeSingleRegister(Register::WriteConfiguration, config.value));
timeout.restart(std::chrono::milliseconds(10));
config.set(max31865<pt>::Config::VBias);
RF_CALL(writeSingleRegister(max31865<pt>::Register::WriteConfiguration, config.value));
timeout.restart(10ms);
RF_WAIT_UNTIL(timeout.isExpired());

config.set(Config::OneShot);
RF_CALL(writeSingleRegister(Register::WriteConfiguration, config.value));
timeout.restart(std::chrono::milliseconds(65));
config.set(max31865<pt>::Config::OneShot);
RF_CALL(writeSingleRegister(max31865<pt>::Register::WriteConfiguration, config.value));
timeout.restart(65ms);
RF_WAIT_UNTIL(timeout.isExpired());

data.data = RF_CALL(readTwoRegisters(Register::ReadRtdMsb));
data.data = RF_CALL(readTwoRegisters(max31865<pt>::Register::ReadRtdMsb));

config.reset(Config::VBias);
RF_CALL(writeSingleRegister(Register::WriteConfiguration, config.value));
config.reset(max31865<pt>::Config::VBias);
RF_CALL(writeSingleRegister(max31865<pt>::Register::WriteConfiguration, config.value));

RF_END();
}

template<typename SpiMaster, typename Cs>
template<typename SpiMaster, typename Cs, Pt pt>
modm::ResumableResult<uint8_t>
Max31865<SpiMaster, Cs>::readSingleRegister(Register address)
Max31865<SpiMaster, Cs, pt>::readSingleRegister(max31865<pt>::Register address)
{
RF_BEGIN();
RF_WAIT_UNTIL(this->acquireMaster());

Cs::reset();
buffer[0] = uint8_t(address);
RF_CALL_BLOCKING(SpiMaster::transfer(buffer.data(), nullptr, 1));
RF_CALL_BLOCKING(SpiMaster::transfer(nullptr, buffer.data(), 1));
RF_CALL(SpiMaster::transfer(buffer.data(), nullptr, 1));
RF_CALL(SpiMaster::transfer(nullptr, buffer.data(), 1));

if (this->releaseMaster()) { Cs::set(); }
modm::delay(100ms);

RF_END_RETURN(buffer[0]);
}

template<typename SpiMaster, typename Cs>
template<typename SpiMaster, typename Cs, Pt pt>
modm::ResumableResult<uint16_t>
Max31865<SpiMaster, Cs>::readTwoRegisters(Register address)
Max31865<SpiMaster, Cs, pt>::readTwoRegisters(max31865<pt>::Register address)
{
RF_BEGIN();
RF_WAIT_UNTIL(this->acquireMaster());

Cs::reset();
buffer[0] = uint8_t(address);
RF_CALL_BLOCKING(SpiMaster::transfer(buffer.data(), nullptr, 1));
RF_CALL_BLOCKING(SpiMaster::transfer(nullptr, buffer.data(), 2));
RF_CALL(SpiMaster::transfer(buffer.data(), nullptr, 1));
RF_CALL(SpiMaster::transfer(nullptr, buffer.data(), 2));

if (this->releaseMaster()) { Cs::set(); }
modm::delay(100ms);

RF_END_RETURN(static_cast<uint16_t>(buffer[0] << 8 | buffer[1]));
}

template<typename SpiMaster, typename Cs>
template<typename SpiMaster, typename Cs, Pt pt>
modm::ResumableResult<void>
Max31865<SpiMaster, Cs>::writeSingleRegister(Register address, uint8_t data)
Max31865<SpiMaster, Cs, pt>::writeSingleRegister(max31865<pt>::Register address, uint8_t data)
{
RF_BEGIN();
RF_WAIT_UNTIL(this->acquireMaster());
Expand Down

0 comments on commit 8e0a8dd

Please sign in to comment.