-
Notifications
You must be signed in to change notification settings - Fork 148
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
10 changed files
with
693 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
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,53 @@ | ||
/* | ||
* Copyright (c) 2023, 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_MATH_BCD_HPP | ||
#define MODM_MATH_BCD_HPP | ||
|
||
#include <stdint.h> | ||
|
||
namespace modm | ||
{ | ||
|
||
/// @ingroup modm_math_utils | ||
/// @{ | ||
|
||
constexpr uint32_t | ||
fromBcd(uint32_t bcd) | ||
{ | ||
uint32_t decimal = 0; | ||
for (uint16_t multiplier = 1; bcd != 0; multiplier *= 10) | ||
{ | ||
decimal += (bcd & 0b1111) * multiplier; | ||
bcd >>= 4; | ||
} | ||
return decimal; | ||
} | ||
|
||
constexpr uint32_t | ||
toBcd(uint32_t decimal) | ||
{ | ||
uint32_t bcd = 0; | ||
uint16_t remainder = decimal % 10; | ||
for (uint16_t shift = 0; decimal != 0; shift += 4) | ||
{ | ||
bcd |= remainder << shift; | ||
decimal = (decimal - remainder) / 10; | ||
remainder = decimal % 10; | ||
} | ||
return bcd; | ||
} | ||
|
||
/// @} | ||
|
||
} // namespace modm | ||
|
||
#endif // MODM_MATH_BCD_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
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,35 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (c) 2023, 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 = ":platform:rtc" | ||
module.description = "Real Time Clock (RTC)" | ||
|
||
def prepare(module, options): | ||
device = options[":target"] | ||
if not device.has_driver("rtc:stm32*"): | ||
return False | ||
|
||
module.depends( | ||
":cmsis:device", | ||
":platform:rcc", | ||
":architecture:register", | ||
":math:utils", | ||
":math:units" | ||
) | ||
|
||
return True | ||
|
||
def build(env): | ||
env.outbasepath = "modm/src/modm/platform/rtc" | ||
env.copy("rtc.hpp") | ||
env.copy("rtc_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,202 @@ | ||
/* | ||
* Copyright (c) 2023, 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_STM32_RTC_HPP | ||
#define MODM_STM32_RTC_HPP | ||
|
||
#include <chrono> | ||
#include <ctime> | ||
|
||
#include <modm/architecture/interface/clock.hpp> | ||
#include <modm/architecture/interface/register.hpp> | ||
|
||
namespace modm::platform | ||
{ | ||
|
||
/** | ||
* Real Time Clock (RTC) control for STM32 devices | ||
* | ||
* @author Rasmus Kleist Hørlyck Sørensen | ||
* @ingroup modm_platform_rtc | ||
*/ | ||
class Rtc | ||
{ | ||
static constexpr uint16_t century{2000}; | ||
static constexpr uint32_t seconds_per_day{24*60*60}; | ||
static constexpr uint32_t seconds_per_year{365*seconds_per_day}; | ||
// Unix time starts in 1970, so we need to add 7 leap days until 2000 | ||
static constexpr uint32_t seconds_since_base{30*seconds_per_year + 7*seconds_per_day}; | ||
static constexpr uint16_t m2d[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; | ||
|
||
public: | ||
using duration = std::chrono::duration<int64_t, std::milli>; | ||
using rep = duration::rep; | ||
using period = duration::period; | ||
using time_point = std::chrono::time_point<Rtc, duration>; | ||
static constexpr bool is_steady = true; | ||
|
||
/// Efficient representation of a date and time direct from the RTC | ||
class DateTime | ||
{ | ||
friend class Rtc; | ||
uint8_t _year; | ||
uint8_t _month; | ||
uint8_t _day; | ||
uint8_t _weekday; | ||
|
||
uint8_t _hour; | ||
uint8_t _minute; | ||
uint8_t _second; | ||
bool _isDST; | ||
|
||
uint16_t _subseconds; | ||
uint16_t _subfractions; | ||
|
||
public: | ||
std::chrono::year inline year() const { return std::chrono::year{_year + century}; } | ||
std::chrono::month inline month() const { return std::chrono::month{_month}; } | ||
std::chrono::day inline day() const { return std::chrono::day{_day}; } | ||
std::chrono::weekday inline weekday() const { return std::chrono::weekday{_weekday}; } | ||
|
||
std::chrono::hours inline hour() const { return std::chrono::hours{_hour}; } | ||
std::chrono::minutes inline minute() const { return std::chrono::minutes{_minute}; } | ||
std::chrono::seconds inline second() const { return std::chrono::seconds{_second}; } | ||
|
||
float inline | ||
subsecond() const | ||
{ return float(_subfractions - _subseconds) / (_subfractions + 1); } | ||
|
||
std::chrono::milliseconds inline | ||
millisecond() const | ||
{ return std::chrono::milliseconds{(_subfractions - _subseconds) * 1'000ul / (_subfractions + 1)}; } | ||
|
||
bool inline isDST() const { return _isDST; } | ||
|
||
std::chrono::days inline | ||
day_of_year() const | ||
{ | ||
uint16_t yday = m2d[_month] + _day; | ||
if (_month > 2 and year().is_leap()) yday++; | ||
return std::chrono::days{yday}; | ||
} | ||
|
||
std::tm tm() const; | ||
|
||
std::time_t time() const; | ||
|
||
time_point inline | ||
now() const noexcept | ||
{ return time_point{duration{time()*1000ull + millisecond().count()}}; } | ||
}; | ||
friend class DateTime; | ||
|
||
public: | ||
static time_point | ||
now() noexcept | ||
{ return dateTime().now(); } | ||
|
||
public: | ||
static void | ||
enable(); | ||
|
||
static void | ||
disable(); | ||
|
||
template< class SystemClock > | ||
static bool | ||
initialize(); | ||
|
||
static const DateTime& | ||
dateTime(); | ||
|
||
template< class DateTimeClass > | ||
static void | ||
setDateTime(const DateTimeClass &dateTime); | ||
|
||
/** | ||
* Synchronized to a remote clock with a high degree of precision | ||
* | ||
* @tparam Rep | ||
* an arithmetic type representing the number of ticks | ||
* @tparam Period | ||
* a std::ratio representing the tick period (i.e. the number of second's fractions per tick) | ||
* | ||
* @param delay The amount of time to delay (or advance) the | ||
* @param waitCycle Number of cycles to wait for the INITF bit to be set. (default = 2048) | ||
* | ||
* @return True on success | ||
*/ | ||
template< typename Rep, typename Period > | ||
static bool | ||
synchronize(std::chrono::duration<Rep, Period> delay, uint32_t waitCycles = 2048); | ||
|
||
public: | ||
|
||
enum class | ||
Interrupt : uint32_t | ||
{ | ||
InternalTimestamp = RTC_CR_ITSE, | ||
Timestamp = RTC_CR_TSIE, | ||
WakeupTimer = RTC_CR_WUTIE, | ||
AlarmB = RTC_CR_ALRBIE, | ||
AlarmA = RTC_CR_ALRAIE, | ||
}; | ||
MODM_FLAGS32(Interrupt); | ||
|
||
enum class | ||
InterruptFlag : uint32_t | ||
{ | ||
InternalTimestamp = RTC_SR_ITSF, | ||
TimestampOverflow = RTC_SR_TSOVF, | ||
Timestamp = RTC_SR_TSF, | ||
WakeupTimer = RTC_SR_WUTF, | ||
AlarmB = RTC_SR_ALRBF, | ||
AlarmA = RTC_SR_ALRAF, | ||
}; | ||
MODM_FLAGS32(InterruptFlag); | ||
|
||
static void | ||
enableInterruptVector(bool enable, uint32_t priority); | ||
|
||
static void | ||
enableInterrupt(Interrupt_t interrupt); | ||
|
||
static void | ||
disableInterrupt(Interrupt_t interrupt); | ||
|
||
static InterruptFlag_t | ||
getInterruptFlags(); | ||
|
||
/** | ||
* | ||
* | ||
* @warning Not all InterruptFlags can be cleared this way. | ||
*/ | ||
static void | ||
acknowledgeInterruptFlag(InterruptFlag_t flags); | ||
|
||
private: | ||
/// Unlock RTC register write protection | ||
static void | ||
unlock(); | ||
|
||
/// Lock RTC register write protection | ||
static void | ||
lock(); | ||
|
||
static inline DateTime idt{}; | ||
}; | ||
|
||
} // namespace modm::platform | ||
|
||
#include "rtc_impl.hpp" | ||
|
||
#endif // MODM_STM32_RTC_HPP |
Oops, something went wrong.