-
Notifications
You must be signed in to change notification settings - Fork 132
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
[stm32] Adding Real Time Clock (RTC) for STM32G4 #1055
base: develop
Are you sure you want to change the base?
Changes from all commits
899449d
1ca42f9
56659d9
e10b4cb
7ca32fe
ce50925
aca50d1
bc4ccc0
36e0264
a4ac17f
1014ce4
67897b2
f9a6be8
3481389
0944588
8d8571f
3c8ee1d
b6422b5
5f88163
0723beb
963d6f5
208cd65
0c0169c
df92454
3d9f95b
1309b12
6478700
0a63653
25f651d
9cadadc
c627c1d
ef6755e
a93ef7b
15fa5cb
fe5ccbc
a815277
d044e5d
5776001
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// 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/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#include <modm/board.hpp> | ||
#include <modm/debug/logger.hpp> | ||
#include <modm/platform.hpp> | ||
#include <modm/processing.hpp> | ||
|
||
using namespace modm::literals; | ||
|
||
// Set the log level | ||
#undef MODM_LOG_LEVEL | ||
#define MODM_LOG_LEVEL modm::log::INFO | ||
|
||
static constexpr Rtc::DateTime datetime = { | ||
.year = 0, | ||
.month = 12, | ||
.date = 31, | ||
.weekday = 1, | ||
.hour = 23, | ||
.minute = 59, | ||
.second = 30, | ||
}; | ||
|
||
int | ||
main() | ||
{ | ||
Board::initialize(); | ||
|
||
modm::PeriodicTimer timer(std::chrono::milliseconds(1000)); | ||
|
||
Rtc::initialize<Board::SystemClock>(); | ||
while (true) | ||
{ | ||
if (timer.execute()) | ||
{ | ||
float ss; | ||
Rtc::DateTime dt; | ||
if (Rtc::getSubSecond(ss) && Rtc::getDateTime(dt)) | ||
{ | ||
MODM_LOG_INFO << "Date: " << dt.date << "-" << dt.month << "-" << dt.year << modm::endl; | ||
MODM_LOG_INFO << "Weekday: " << dt.weekday << modm::endl; | ||
MODM_LOG_INFO << "Time: " << dt.hour << ":" << dt.minute << ":" << dt.second << modm::endl; | ||
MODM_LOG_INFO << "Sub Second: " << ss << modm::endl; | ||
} | ||
else | ||
{ | ||
MODM_LOG_INFO << "Error: Unable to get Date Time and Sub Second" << modm::endl; | ||
} | ||
} | ||
} | ||
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<library> | ||
<extends>modm:nucleo-g474re</extends> | ||
<options> | ||
<option name="modm:build:build.path">../../../build/nucleo_g474re/rtc</option> | ||
</options> | ||
<modules> | ||
<module>modm:debug</module> | ||
<module>modm:platform:rtc</module> | ||
<module>modm:processing:timer</module> | ||
<module>modm:build:scons</module> | ||
</modules> | ||
</library> |
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -167,4 +167,4 @@ Rcc::isEnabled() | |
%% endfor | ||
} | ||
|
||
} // namespace modm::platform | ||
} // namespace modm::platform | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#!/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 device.identifier.family not in ["g4"]: | ||
return False | ||
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): | ||
target = env[":target"].identifier | ||
|
||
env.outbasepath = "modm/src/modm/platform/rtc" | ||
env.template("rtc_impl.hpp.in") | ||
env.template("rtc.cpp.in") | ||
env.template("rtc.hpp.in") |
rasmuskleist marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* 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/. | ||
*/ | ||
// ---------------------------------------------------------------------------- | ||
|
||
#include "rtc.hpp" | ||
|
||
#include <modm/math/utils.hpp> | ||
|
||
namespace modm::platform | ||
{ | ||
|
||
// ---------------------------------------------------------------------------- | ||
|
||
bool | ||
Rtc::getDateTime(DateTime &dateTime, uint32_t waitCycles) | ||
{ | ||
/// TODO: Determine if ABP1 frequency is less than seven times RTC frequency | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You would write this information to a |
||
/// TODO: Determine if BYPSHAD control bit is set or cleared in the RTC_CR register | ||
|
||
// After initialization, synchronization software must wait until RSF is set | ||
while (!(RTC->ICSR & RTC_ICSR_RSF)) | ||
if (--waitCycles == 0) return false; | ||
|
||
dateTime.hour = fromBcd((RTC->TR & (RTC_TR_HT_Msk | RTC_TR_HU_Msk)) >> RTC_TR_HU_Pos); | ||
dateTime.minute = fromBcd((RTC->TR & (RTC_TR_MNT_Msk | RTC_TR_MNU_Msk)) >> RTC_TR_MNU_Pos); | ||
dateTime.second = fromBcd((RTC->TR & (RTC_TR_ST_Msk | RTC_TR_SU_Msk)) >> RTC_TR_SU_Pos); | ||
|
||
dateTime.year = fromBcd((RTC->DR & (RTC_DR_YT_Msk | RTC_DR_YU_Msk)) >> RTC_DR_YU_Pos); | ||
dateTime.month = fromBcd((RTC->DR & (RTC_DR_MT_Msk | RTC_DR_MU_Msk)) >> RTC_DR_MU_Pos); | ||
dateTime.date = fromBcd((RTC->DR & (RTC_DR_DT_Msk | RTC_DR_DU_Msk)) >> RTC_DR_DU_Pos); | ||
dateTime.weekday = ((RTC->DR & RTC_DR_WDU_Msk) >> RTC_DR_WDU_Pos); | ||
|
||
return true; | ||
} | ||
|
||
// ---------------------------------------------------------------------------- | ||
|
||
bool | ||
Rtc::getSubSecond(float &subsecond, uint32_t waitCycles) | ||
{ | ||
// After initialization, synchronization software must wait until RSF is set | ||
while (!(RTC->ICSR & RTC_ICSR_RSF)) | ||
if (--waitCycles == 0) return false; | ||
|
||
/* | ||
uint32_t predivS = getSynchronousPrescaler(); | ||
uint32_t ss = (RTC->SSR & RTC_SSR_SS_Msk) >> RTC_SSR_SS_Pos; | ||
subsecond = float(predivS - ss) / float(predivS + 1); | ||
/// TODO: Handle case when ss > predivS | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. meh, why not integer math based on milli- or microseconds? |
||
*/ | ||
return true; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
best to change your editor to add a newline at the end of file, otherwise there'll be a lot of these changes in the modm code base ;-P