Skip to content

Commit 603c3c1

Browse files
committed
[stm32] Add RTC peripheral
1 parent 464516d commit 603c3c1

File tree

7 files changed

+480
-5
lines changed

7 files changed

+480
-5
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,31 @@ Please [discover modm's peripheral drivers for your specific device][discover].
458458
<td align="center">✕</td>
459459
<td align="center">✕</td>
460460
</tr><tr>
461+
<td align="left">RTC</td>
462+
<td align="center">✅</td>
463+
<td align="center">✅</td>
464+
<td align="center">○</td>
465+
<td align="center">✅</td>
466+
<td align="center">✅</td>
467+
<td align="center">✅</td>
468+
<td align="center">✅</td>
469+
<td align="center">✅</td>
470+
<td align="center">✅</td>
471+
<td align="center">✅</td>
472+
<td align="center">✅</td>
473+
<td align="center">✅</td>
474+
<td align="center">✅</td>
475+
<td align="center">✅</td>
476+
<td align="center">✅</td>
477+
<td align="center">○</td>
478+
<td align="center">○</td>
479+
<td align="center">○</td>
480+
<td align="center">○</td>
481+
<td align="center">○</td>
482+
<td align="center">✕</td>
483+
<td align="center">✕</td>
484+
<td align="center">✕</td>
485+
</tr><tr>
461486
<td align="left">SPI</td>
462487
<td align="center">✅</td>
463488
<td align="center">✅</td>

src/modm/platform/clock/stm32/module.lb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ def build(env):
187187
nper = "DSI"
188188
if "Eth" in all_peripherals and per == "ETHMAC":
189189
per = "Eth"
190+
if "Rtc" in all_peripherals and per == "RTCAPB":
191+
per = "RTC"
192+
nper = "RTCAPB"
190193
# Fix USBOTG OTG
191194
if target.family == "u5" and per == "OTG":
192195
per = "Usbotgfs"
@@ -200,7 +203,9 @@ def build(env):
200203
if per.capitalize() not in all_peripherals:
201204
continue
202205
if "EN" in mode:
203-
rcc_enable[per.capitalize()] = (nper, mode["EN"])
206+
kw = per.capitalize()
207+
if kw not in rcc_enable:
208+
rcc_enable[kw] = (nper, mode["EN"])
204209
if "RST" in mode:
205210
rcc_reset[per.capitalize()] = (nper, mode["RST"])
206211

src/modm/platform/core/stm32/startup_platform.c.in

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,17 @@ __modm_initialize_platform(void)
6161
// Enable Data Tighly Coupled Memory (DTCM) and backup SRAM (BKPSRAM)
6262
RCC->AHB1ENR |= RCC_AHB1ENR_DTCMRAMEN | RCC_AHB1ENR_BKPSRAMEN;
6363
%% elif target.family in ["g0", "g4", "l4", "l5"]
64-
%% if target.family in ["l4", "g4"]
64+
%% if target.family in ["l4", "g4"]
6565
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
66-
%% elif target.family != "g0"
67-
#ifdef PWR_CR2_IOSV
66+
%% elif target.family in ["g0"]
67+
RCC->APBENR1 |= RCC_APBENR1_PWREN;
68+
%% else
69+
#ifdef RCC_APB1ENR1_PWREN
6870
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
6971
#endif
70-
%% endif
72+
%% endif
73+
// Enable access to RTC and Backup registers
74+
PWR->CR1 |= PWR_CR1_DBP;
7175

7276
#ifdef PWR_CR2_IOSV
7377
// Enable VDDIO2

src/modm/platform/rtc/stm32/module.lb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (c) 2023, Rasmus Kleist Hørlyck Sørensen
5+
#
6+
# This file is part of the modm project.
7+
#
8+
# This Source Code Form is subject to the terms of the Mozilla Public
9+
# License, v. 2.0. If a copy of the MPL was not distributed with this
10+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
11+
# -----------------------------------------------------------------------------
12+
13+
def init(module):
14+
module.name = ":platform:rtc"
15+
module.description = "Real Time Clock (RTC)"
16+
17+
def prepare(module, options):
18+
device = options[":target"]
19+
if not device.has_driver("rtc:stm32*") or device.identifier.family in ["f1"]:
20+
return False
21+
22+
module.depends(
23+
":cmsis:device",
24+
":platform:rcc",
25+
":architecture:register",
26+
":math:calendar",
27+
)
28+
29+
return True
30+
31+
def build(env):
32+
env.outbasepath = "modm/src/modm/platform/rtc"
33+
# $ cd modm/ext/st/stm32
34+
# $ rg "RTC_ICSR_RSF" -l | rg "stm32(.*?)xx/" -or "\$1" | sort | uniq
35+
# $ rg "RTC_ISR_RSF" -l | rg "stm32(.*?)xx/" -or "\$1" | sort | uniq
36+
has_isr = env[":target"].identifier.family in ["f0", "f2", "f3", "f4", "f7", "h7", "l0", "l1", "l4", "wb"]
37+
env.substitutions = {"icsr": "ISR" if has_isr else "ICSR"}
38+
env.copy("rtc.hpp")
39+
env.template("rtc_impl.hpp.in")
40+
# env.copy("rtc.cpp")

src/modm/platform/rtc/stm32/rtc.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2024, Niklas Hauser
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include "rtc.hpp"
13+
#include <sys/time.h>
14+
15+
/*
16+
extern "C" int
17+
_gettimeofday(struct timeval *tp, void *)
18+
{
19+
const auto milliseconds = Rtc::read();
20+
Rtc::update_cache();
21+
tp->tv_sec = cache_time_seconds;
22+
tp->tv_usec = milliseconds * 1000ul;
23+
return 0;
24+
}
25+
*/

src/modm/platform/rtc/stm32/rtc.hpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* Copyright (c) 2023, Rasmus Kleist Hørlyck Sørensen
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#ifndef MODM_STM32_RTC_HPP
13+
#define MODM_STM32_RTC_HPP
14+
15+
#include <chrono>
16+
#include <ctime>
17+
18+
#include <modm/architecture.hpp>
19+
#include <modm/math/calendar/date_time.hpp>
20+
21+
namespace modm::platform
22+
{
23+
24+
/**
25+
* Real Time Clock (RTC) control for STM32 devices
26+
*
27+
* @author Niklas Hauser
28+
* @author Rasmus Kleist Hørlyck Sørensen
29+
* @ingroup modm_platform_rtc
30+
*/
31+
class Rtc : public modm::PeripheralDriver
32+
{
33+
public:
34+
using duration = std::chrono::milliseconds;
35+
using rep = duration::rep;
36+
using period = duration::period;
37+
using time_point = std::chrono::time_point<Rtc, duration>;
38+
static constexpr bool is_steady = true;
39+
40+
static time_point
41+
now() noexcept;
42+
43+
static std::time_t
44+
to_time_t(const time_point& t) noexcept
45+
{
46+
return std::time_t(duration_cast<std::chrono::seconds>(t.time_since_epoch()).count());
47+
}
48+
49+
static time_point
50+
from_time_t(std::time_t t) noexcept
51+
{
52+
using from_t = std::chrono::time_point<Rtc, std::chrono::seconds>;
53+
return time_point_cast<duration>(from_t(std::chrono::seconds(t)));
54+
}
55+
56+
public:
57+
// Optimized version that returns seconds since epoch
58+
static std::time_t
59+
time_t();
60+
61+
static modm::DateTime
62+
dateTime();
63+
64+
static void
65+
setDateTime(const modm::DateTime &dt);
66+
67+
public:
68+
static void
69+
enable();
70+
71+
static void
72+
disable();
73+
74+
template< class SystemClock >
75+
static bool
76+
initialize();
77+
78+
/**
79+
* Synchronized to a remote clock with a high degree of precision
80+
*
81+
* @tparam Rep
82+
* an arithmetic type representing the number of ticks
83+
* @tparam Period
84+
* a std::ratio representing the tick period (i.e. the number of second's fractions per tick)
85+
*
86+
* @param delay The amount of time to delay (or advance) the
87+
* @param waitCycle Number of cycles to wait for the INITF bit to be set. (default = 2048)
88+
*
89+
* @return True on success
90+
*/
91+
// template< typename Rep, typename Period >
92+
// static bool
93+
// synchronize(std::chrono::duration<Rep, Period> delay, uint32_t waitCycles = 2048);
94+
95+
protected:
96+
/// Unlock RTC register write protection
97+
static void
98+
unlock();
99+
100+
/// Lock RTC register write protection
101+
static void
102+
lock();
103+
104+
static uint16_t
105+
read();
106+
107+
static void
108+
update_cache();
109+
110+
struct Data
111+
{
112+
union
113+
{
114+
struct
115+
{
116+
uint8_t second;
117+
uint8_t minute;
118+
uint8_t hour;
119+
} modm_packed;
120+
uint32_t time32;
121+
};
122+
union
123+
{
124+
struct
125+
{
126+
uint8_t weekday;
127+
uint8_t day;
128+
uint8_t month;
129+
uint8_t year;
130+
} modm_packed;
131+
uint32_t date32;
132+
};
133+
};
134+
135+
static inline Data data{};
136+
137+
static inline uint64_t cache_time_milliseconds{};
138+
static inline uint32_t cache_time_seconds{};
139+
static inline uint32_t cache_date_seconds{};
140+
static inline uint32_t cache_time{};
141+
static inline uint32_t cache_date{};
142+
143+
static inline uint32_t (*t2ms)(uint32_t) = [](uint32_t) { return 0ul; };
144+
static inline uint32_t (*ms2t)(uint32_t) = [](uint32_t) { return 0ul; };
145+
146+
static constexpr uint16_t epoch{1970};
147+
};
148+
149+
} // namespace modm::platform
150+
151+
#include "rtc_impl.hpp"
152+
153+
#endif // MODM_STM32_RTC_HPP

0 commit comments

Comments
 (0)