Skip to content

Commit

Permalink
[driver] MCP7941X: Make use of std::optional
Browse files Browse the repository at this point in the history
  • Loading branch information
rleh committed Dec 19, 2021
1 parent 19cc41f commit a14d12a
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 74 deletions.
46 changes: 22 additions & 24 deletions examples/nucleo_f429zi/rtc_mcp7941x/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <modm/driver/rtc/mcp7941x.hpp>
#include <modm/processing/protothread.hpp>
#include <modm/processing/timer.hpp>
#include <optional>

using MyI2cMaster = modm::platform::I2cMaster1;
using I2cScl = modm::platform::GpioB8;
Expand All @@ -22,10 +23,6 @@ using I2cSda = modm::platform::GpioB9;
class RtcThread : public modm::pt::Protothread
{
public:
RtcThread() : data{}, rtc{data}
{
}

bool
update()
{
Expand Down Expand Up @@ -63,15 +60,14 @@ class RtcThread : public modm::pt::Protothread

while (true)
{
while(not PT_CALL(rtc.getDateTime())){
dateTime2 = PT_CALL(rtc.getDateTime());
if(dateTime2.has_value()) {
MODM_LOG_INFO.printf("%02u.%02u.%02u ", dateTime2->days, dateTime2->months, dateTime2->years);
MODM_LOG_INFO.printf("%02u:%02u.%02uh\n", dateTime2->hours, dateTime2->minutes, dateTime2->seconds);
}
else {
MODM_LOG_ERROR << "Unable to read from RTC." << modm::endl;
timeout.restart(500ms);
PT_WAIT_UNTIL(timeout.isExpired());
}
MODM_LOG_INFO << "Date and time read from RTC: ";
dateTime = rtc.getData().getDateTime();
MODM_LOG_INFO.printf("%02u.%02u.%02u ", dateTime.days, dateTime.months, dateTime.years);
MODM_LOG_INFO.printf("%02u:%02u.%02uh\n", dateTime.hours, dateTime.minutes, dateTime.seconds);

timeout.restart(2500ms);
PT_WAIT_UNTIL(timeout.isExpired());
Expand All @@ -81,9 +77,9 @@ class RtcThread : public modm::pt::Protothread
}

private:
modm::Mcp7941x<MyI2cMaster> rtc{};
modm::mcp7941x::DateTime dateTime{};
modm::mcp7941x::Data data{};
modm::Mcp7941x<MyI2cMaster> rtc{data};
std::optional<modm::mcp7941x::DateTime> dateTime2{};
modm::ShortTimeout timeout;
};

Expand All @@ -102,19 +98,21 @@ main()
MODM_LOG_INFO << "RTC MCP7941x Example on Nucleo-F429ZI" << modm::endl;

modm::Mcp7941xEeprom<MyI2cMaster> eeprom{};
while(not RF_CALL_BLOCKING(eeprom.getUniqueID())) {
if (auto data = RF_CALL_BLOCKING(eeprom.getUniqueId())) {
MODM_LOG_INFO << "Unique ID (EUI-48/64): ";
MODM_LOG_INFO << modm::hex << (*data)[0] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[1] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[2] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[3] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[4] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[5] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[6] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << (*data)[7] << modm::ascii << modm::endl;
}
else {
MODM_LOG_ERROR << "Unable to read unique ID from RTC." << modm::endl;
modm::delay(500ms);
}
MODM_LOG_INFO << "Unique ID (EUI-48/64): ";
MODM_LOG_INFO << modm::hex << eeprom.getData()[0] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[1] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[2] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[3] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[4] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[5] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[6] << modm::ascii << ":";
MODM_LOG_INFO << modm::hex << eeprom.getData()[7] << modm::ascii << modm::endl;
modm::delay(500ms);

RtcThread rtcThread;

Expand Down
43 changes: 18 additions & 25 deletions src/modm/driver/rtc/mcp7941x.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define MODM_MCP7941X_HPP

#include <array>
#include <optional>

#include <modm/architecture/interface/register.hpp>
#include <modm/architecture/interface/i2c_device.hpp>
Expand All @@ -30,11 +31,8 @@ class Mcp7941x;
/// @ingroup modm_driver_mcp7941
struct mcp7941x
{

public:

//see datasheet section 4 for more information on format
struct
/// days, months, etc. are decoded (BCD) in this struct
struct modm_packed
DateTime{
uint8_t days;
uint8_t months;
Expand All @@ -44,22 +42,24 @@ struct mcp7941x
uint8_t hours;
};

/*
struct modm_packed
Data
{
template < class I2cMaster >
friend class Mcp7941x;
public:
constexpr DateTime getDateTime(){
constexpr DateTime
getDateTime()
{
return date_time;
}
uint8_t unique_id[8];
private:
DateTime date_time;
};
uint8_t scratch[8];

*/

protected:
constexpr inline uint8_t
Expand All @@ -85,23 +85,20 @@ class Mcp7941x : public mcp7941x,
public modm::I2cDevice<I2cMaster, 2>
{
public:
/// Constructor, requires a mcp7941x::Data object,
Mcp7941x(Data &data, uint8_t address = 0x6f);
Mcp7941x(uint8_t address = 0x6f);

inline Data&
getData();

inline modm::ResumableResult<bool>
modm::ResumableResult<std::optional<mcp7941x::DateTime>>
getDateTime();

inline modm::ResumableResult<bool>
modm::ResumableResult<bool>
setDateTime(DateTime);

inline modm::ResumableResult<bool>
modm::ResumableResult<bool>
oscillatorRunning();

private:
mcp7941x::Data &data;
DateTime dateTime;

//address definition for registers of the MCP7941x
const uint8_t addr_seconds = 0x00;
Expand All @@ -111,6 +108,8 @@ class Mcp7941x : public mcp7941x,
const uint8_t addr_days = 0x04;
const uint8_t addr_months = 0x05;
const uint8_t addr_years = 0x06;

uint8_t scratch[8];
};

/**
Expand All @@ -123,14 +122,8 @@ class Mcp7941xEeprom : public modm::I2cDevice<I2cMaster, 2>
public:
Mcp7941xEeprom(uint8_t address = 0x57);

inline std::array<uint8_t, 8>&
getData()
{
return data;
}

inline modm::ResumableResult<bool>
getUniqueID();
modm::ResumableResult<std::optional<std::array<uint8_t, 8>>>
getUniqueId();

private:
const uint8_t addr_unique_id = 0xF0;
Expand Down
47 changes: 22 additions & 25 deletions src/modm/driver/rtc/mcp7941x_impl.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2021, Odin Holmes
* Copyright (c) 2021, Raphael Lehmann
*
* This file is part of the modm project.
*
Expand All @@ -15,35 +16,27 @@

// ----------------------------------------------------------------------------
template < typename I2cMaster >
modm::Mcp7941x<I2cMaster>::Mcp7941x(Data &data, uint8_t address)
: I2cDevice<I2cMaster, 2>(address), data(data)
modm::Mcp7941x<I2cMaster>::Mcp7941x(uint8_t address)
: I2cDevice<I2cMaster, 2>(address), dateTime{}
{

}

template < typename I2cMaster >
modm::mcp7941x::Data&
modm::Mcp7941x<I2cMaster>::getData()
{
return this->data;
}

template < typename I2cMaster >
inline modm::ResumableResult<bool>
inline modm::ResumableResult<std::optional<modm::mcp7941x::DateTime>>
modm::Mcp7941x<I2cMaster>::getDateTime(){
RF_BEGIN();
this->transaction.configureWriteRead(&addr_seconds, 1, scratch, 7);
if(RF_CALL(this->runTransaction())){
data.date_time.seconds = decodeBcd(scratch[0] & 0b0111'1111);
data.date_time.minutes = decodeBcd(scratch[1]);
data.date_time.hours = decodeBcd(scratch[2] & 0b0011'1111);
if (RF_CALL(this->runTransaction())) {
dateTime.seconds = decodeBcd(scratch[0] & 0b0111'1111);
dateTime.minutes = decodeBcd(scratch[1]);
dateTime.hours = decodeBcd(scratch[2] & 0b0011'1111);
//no need for day of the week
data.date_time.days = decodeBcd(scratch[4]);
data.date_time.months = decodeBcd(scratch[5] & 0b0001'1111);
data.date_time.years = decodeBcd(scratch[6]);
RF_RETURN(true);
dateTime.days = decodeBcd(scratch[4]);
dateTime.months = decodeBcd(scratch[5] & 0b0001'1111);
dateTime.years = decodeBcd(scratch[6]);
RF_RETURN(dateTime);
}
RF_END_RETURN(false);
RF_END_RETURN(std::nullopt);
}

template < typename I2cMaster >
Expand All @@ -59,7 +52,7 @@ modm::Mcp7941x<I2cMaster>::setDateTime(mcp7941x::DateTime dt){
scratch[6] = encodeBcd(dt.months);
scratch[7] = encodeBcd(dt.years);
this->transaction.configureWrite(scratch, 8);
if(not RF_CALL(this->runTransaction())){
if (not RF_CALL(this->runTransaction())) {
RF_RETURN(false);
}
scratch[0] = addr_seconds;
Expand All @@ -73,7 +66,7 @@ inline modm::ResumableResult<bool>
modm::Mcp7941x<I2cMaster>::oscillatorRunning(){
RF_BEGIN();
this->transaction.configureWriteRead(&addr_weekday, 1, scratch, 1);
if(RF_CALL(this->runTransaction())){
if (RF_CALL(this->runTransaction())) {
RF_RETURN((scratch[0] | 0b0010'0000 /* OSCRUN bit */) > 0);
}
RF_END_RETURN(false);
Expand All @@ -87,9 +80,13 @@ modm::Mcp7941xEeprom<I2cMaster>::Mcp7941xEeprom(uint8_t address)
}

template < typename I2cMaster >
inline modm::ResumableResult<bool>
modm::Mcp7941xEeprom<I2cMaster>::getUniqueID(){
inline modm::ResumableResult<std::optional<std::array<uint8_t, 8>>>
modm::Mcp7941xEeprom<I2cMaster>::getUniqueId(){
RF_BEGIN();
this->transaction.configureWriteRead(&addr_unique_id, 1, data.data(), 8);
RF_END_RETURN_CALL(this->runTransaction());
//RF_END_RETURN_CALL(this->runTransaction());
if (not RF_CALL(this->runTransaction())) {
RF_RETURN(std::nullopt);
}
RF_END_RETURN(data);
}

0 comments on commit a14d12a

Please sign in to comment.