OpenMPTL - STM32F10X
C++ Microprocessor Template Library
rtc.hpp
Go to the documentation of this file.
1 /*
2  * OpenMPTL - C++ Microprocessor Template Library
3  *
4  * Copyright (C) 2012-2017 Axel Burri <axel@tty0.ch>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef ARCH_RTC_HPP_INCLUDED
22 #define ARCH_RTC_HPP_INCLUDED
23 
24 #include <arch/nvic.hpp>
25 #include <arch/pwr.hpp>
26 #include <arch/rcc.hpp>
27 #include <arch/reg/rtc.hpp>
28 
29 namespace mptl {
30 
31 template< freq_t rtcclk_freq = khz(0x8000) > /* LSE clock frequency */
32 class rtc
33 {
34 private:
35  static void enter_config_mode(void) {
36  wait_config_done();
38  }
39  static void exit_config_mode(void) {
41  wait_config_done();
42  }
43  static void wait_config_done(void) {
44  while(RTC::CRL::RTOFF::test() == false);
45  }
46 
47 public:
48 
49  using irq_global = irq::rtc; /**< RTC global Interrupt */
50  using irq_alarm = irq::rtc_alarm; /**< RTC Alarm through EXTI Line Interrupt */
51 
52  static void wait_sync(void) {
54  while(RTC::CRL::RSF::test() == false);
55  }
56 
57  // TODO: enable/disable more than one at once
58  static void enable_overflow_interrupt(void) {
60  }
61  static void enable_alarm_interrupt(void) {
63  }
64  static void enable_second_interrupt(void) {
66  }
67 
68  static void disable_overflow_interrupt(void) {
70  }
71  static void disable_alarm_interrupt(void) {
73  }
74  static void disable_second_interrupt(void) {
76  }
77 
78  static void clear_overflow_flag(void) {
80  }
81  static void clear_alarm_flag(void) {
83  }
84  static void clear_second_flag(void) {
86  }
87 
88  static uint32_t get_counter(void) {
89  return (((uint32_t)RTC::CNTH::load() << 16) | (uint32_t)RTC::CNTL::load());
90  }
91 
92  static void set_counter(uint32_t value) {
93  enter_config_mode();
94  RTC::CNTH::store(value >> 16);
95  RTC::CNTL::store(value & 0xFFFF);
96  exit_config_mode();
97  }
98 
99  static void set_prescaler(uint32_t value) {
100  enter_config_mode();
101  RTC::PRLH::store((value & 0xF0000) >> 16);
102  RTC::PRLL::store(value & 0xFFFF);
103  exit_config_mode();
104  }
105 
106  template< freq_t tr_clk_freq >
107  static void set_time_base(void) {
108  static constexpr unsigned prescaler_value = (rtcclk_freq / tr_clk_freq) - 1;
109  set_prescaler(prescaler_value);
110  }
111 
112  static void set_alarm(uint32_t value) {
113  enter_config_mode();
114  RTC::ALRH::store(value >> 16);
115  RTC::ALRL::store(value & 0xFFFF);
116  exit_config_mode();
117  }
118 
119  static uint32_t get_divider(void) {
120  return ((uint32_t)RTC::DIVH::load() << 16 ) | (uint32_t)RTC::DIVL::load();
121 
122  /* paranoid variant: applies bitmask on high/low register before shifting */
123  // return ((uint32_t)RTC::DIVH::regbits_type::test() << 16 ) | (uint32_t)RTC::DIVL::bits_type::test();
124  }
125 
127 
128  /**
129  * Initialize RTC to run on on LSE clock, with given time base.
130  *
131  * NOTE: resets backup domain and disables write protection
132  */
133  template< freq_t tr_clk_freq = hz(1) >
134  static void init(void) {
137 
138  reglist<
139  typename rcc::lse_enable,
141  typename rcc::rtc_enable
142  >::set();
143 
145  wait_sync();
146 
147  /* set prescaler */
148  set_time_base<tr_clk_freq>();
149  }
150 };
151 
152 } // namespace mptl
153 
154 #endif // ARCH_RTC_HPP_INCLUDED
static void enable_second_interrupt(void)
Definition: rtc.hpp:64
static void clear_overflow_flag(void)
Definition: rtc.hpp:78
static void clear_alarm_flag(void)
Definition: rtc.hpp:81
irq_channel< 3 > rtc
RTC global Interrupt.
Definition: nvic.hpp:31
static void backup_domain_software_reset(void)
Definition: rcc.hpp:74
static void init(void)
Initialize RTC to run on on LSE clock, with given time base.
Definition: rtc.hpp:134
static void enable_alarm_interrupt(void)
Definition: rtc.hpp:61
regval< RCC::BDCR::LSEON, 1 > lse_enable
Enable external low speed oscillator.
Definition: rcc.hpp:52
static void disable_backup_domain_write_protection(void)
Definition: pwr.hpp:32
static void enable_overflow_interrupt(void)
Definition: rtc.hpp:58
static void clear_second_flag(void)
Definition: rtc.hpp:84
typelist< RCC::APB1ENR::PWREN, RCC::APB1ENR::BKPEN > rcc_rtc_clock_resources
Definition: rcc.hpp:228
static void set_time_base(void)
Definition: rtc.hpp:107
static void disable_alarm_interrupt(void)
Definition: rtc.hpp:71
static void disable_overflow_interrupt(void)
Definition: rtc.hpp:68
static uint32_t get_divider(void)
Definition: rtc.hpp:119
static void set_counter(uint32_t value)
Definition: rtc.hpp:92
static void wait_lse_ready(void)
Definition: rcc.hpp:89
Definition: rtc.hpp:32
rcc_rtc_clock_resources resources
Definition: rtc.hpp:126
static uint32_t get_counter(void)
Definition: rtc.hpp:88
RCC::BDCR::RTCSEL::LSE lse
Definition: rcc.hpp:59
static __always_inline void store(Tp const value)
static void wait_sync(void)
Definition: rtc.hpp:52
static void set_prescaler(uint32_t value)
Definition: rtc.hpp:99
static void set_alarm(uint32_t value)
Definition: rtc.hpp:112
static void disable_second_interrupt(void)
Definition: rtc.hpp:74
irq_channel< 41 > rtc_alarm
RTC Alarm through EXTI Line Interrupt.
Definition: nvic.hpp:265