1use crate::datetime::*;
4use crate::rcc::{BDCR, APB1R1};
5use crate::pwr;
6use crate::stm32::{RTC};
7
8pub struct Rtc {
10 rtc: RTC
11}
12
13impl Rtc {
14 pub fn rtc(rtc: RTC, apb1r1: &mut APB1R1, bdcr: &mut BDCR, pwrcr1: &mut pwr::CR1) -> Self {
15 apb1r1.enr().modify(|_, w| w.rtcapben().set_bit());
17 pwrcr1.reg().read(); pwrcr1.reg().modify(|_, w| w.dbp().set_bit());
20 while pwrcr1.reg().read().dbp().bit_is_clear() {}
21
22 bdcr.enr().modify(|_, w| { w.bdrst().set_bit() }); bdcr.enr().modify(|_, w| unsafe {
25 w.rtcsel()
26 .bits(0b10)
33 .rtcen()
34 .set_bit()
35 .bdrst() .clear_bit()
37 });
38
39
40 write_protection(&rtc, false);
41 {
42 init_mode(&rtc, true);
43 {
44 rtc.cr.modify(|_, w| unsafe {
45 w.fmt()
46 .clear_bit() .osel()
48 .bits(0b00)
55 .pol()
56 .clear_bit() });
58
59 rtc.prer.modify(|_, w| unsafe {
60 w.prediv_s()
61 .bits(255)
62 .prediv_a()
63 .bits(127)
64 });
65 }
66 init_mode(&rtc, false);
67
68 rtc.or.modify(|_, w| {
70 w.rtc_alarm_type()
71 .clear_bit()
72 .rtc_out_rmp()
73 .clear_bit()
74 });
75
76 }
77 write_protection(&rtc, true);
78
79 Self {
80 rtc: rtc
81 }
82 }
83
84 pub fn set_time(&self, time: &Time){
85 write_protection(&self.rtc, false);
86 {
87 init_mode(&self.rtc, true);
88 {
89
90 let (ht, hu) = byte_to_bcd2(time.hours as u8);
91 let (mnt, mnu) = byte_to_bcd2(time.minutes as u8);
92 let (st, su) = byte_to_bcd2(time.seconds as u8);
93 self.rtc.tr.write(|w| unsafe {
94 w.ht().bits(ht)
95 .hu().bits(hu)
96 .mnt().bits(mnt)
97 .mnu().bits(mnu)
98 .st().bits(st)
99 .su().bits(su)
100 .pm()
101 .clear_bit()
102
103 });
104
105 self.rtc.cr.modify(|_, w| {
106 w.fmt()
107 .bit(time.daylight_savings)
108
109 });
110 }
111 init_mode(&self.rtc, false);
112 }
113 write_protection(&self.rtc, true);
114 }
115
116 pub fn get_time(&self) -> Time {
117 let time;
118
119 let timer = self.rtc.tr.read();
120 let cr = self.rtc.cr.read();
121 time = Time::new(bcd2_to_byte((timer.ht().bits(), timer.hu().bits())).into(),
122 bcd2_to_byte((timer.mnt().bits(), timer.mnu().bits())).into(),
123 bcd2_to_byte((timer.st().bits(), timer.su().bits())).into(),
124 cr.fmt().bit());
125
126 write_protection(&self.rtc, true);
127
128 time
129 }
130
131 pub fn set_date(&self, date: &Date){
132 write_protection(&self.rtc, false);
133 {
134 init_mode(&self.rtc, true);
135 {
136 let (dt, du) = byte_to_bcd2(date.date as u8);
137 let (mt, mu) = byte_to_bcd2(date.month as u8);
138 let yr = date.year as u16;
139 let yr_offset = (yr - 1970_u16) as u8;
140 let (yt, yu) = byte_to_bcd2(yr_offset);
141
142 self.rtc.dr.write(|w| unsafe {
143 w.dt().bits(dt)
144 .du().bits(du)
145 .mt().bit(mt > 0)
146 .mu().bits(mu)
147 .yt().bits(yt)
148 .yu().bits(yu)
149 .wdu().bits(date.day as u8)
150 });
151
152
153 }
154 init_mode(&self.rtc, false);
155 }
156 write_protection(&self.rtc, true);
157 }
158
159 pub fn get_date(&self) -> Date {
160 let date;
161
162 let dater = self.rtc.dr.read();
163 date = Date::new(dater.wdu().bits().into(),
164 bcd2_to_byte((dater.dt().bits(), dater.du().bits())).into(),
165 bcd2_to_byte((dater.mt().bit() as u8, dater.mu().bits())).into(),
166 (bcd2_to_byte((dater.yt().bits(), dater.yu().bits())) as u16 + 1970_u16).into());
167 date
168 }
169
170}
171
172fn write_protection(rtc: &RTC, enable: bool){
173 if enable {
174 rtc.wpr.write(|w| unsafe {
175 w.bits(0xFF)
176 });
177 } else {
178 rtc.wpr.write(|w| unsafe {
179 w.bits(0xCA)
180 });
181
182 rtc.wpr.write(|w| unsafe {
183 w.bits(0x53)
184 });
185 }
186}
187
188fn init_mode(rtc: &RTC, enabled: bool) {
189 if enabled {
190 let isr = rtc.isr.read();
191 if isr.initf().bit_is_clear() { rtc.isr.write(|w| { w.init().set_bit() });
193 while rtc.isr.read().initf().bit_is_clear() {} }
196 } else {
197 rtc.isr.write(|w| { w.init().clear_bit() }); }
199
200}
201
202fn byte_to_bcd2(byte: u8) -> (u8, u8){
203 let mut bcd_high: u8 = 0;
204 let mut value = byte;
205
206 while value >= 10 {
207 bcd_high += 1;
208 value -= 10;
209 }
210
211 (bcd_high, ((bcd_high << 4) | value) as u8)
212}
213
214fn bcd2_to_byte(bcd: (u8, u8)) -> u8 { let value = bcd.1 | bcd.0 << 4;
216
217 let tmp = ((value & 0xF0) >> 0x4) * 10;
218
219 (tmp + (value & 0x0F))
220}