aboutsummaryrefslogtreecommitdiff
path: root/embassy-nxp
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nxp')
-rw-r--r--embassy-nxp/src/time_driver/rtc.rs76
1 files changed, 41 insertions, 35 deletions
diff --git a/embassy-nxp/src/time_driver/rtc.rs b/embassy-nxp/src/time_driver/rtc.rs
index 94272e9c2..fb6de6a5e 100644
--- a/embassy-nxp/src/time_driver/rtc.rs
+++ b/embassy-nxp/src/time_driver/rtc.rs
@@ -6,7 +6,9 @@ use embassy_hal_internal::interrupt::{InterruptExt, Priority};
6use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; 6use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex;
7use embassy_time_driver::{time_driver_impl, Driver}; 7use embassy_time_driver::{time_driver_impl, Driver};
8use embassy_time_queue_utils::Queue; 8use embassy_time_queue_utils::Queue;
9use lpc55_pac::{interrupt, PMC, RTC, SYSCON}; 9
10use crate::pac::{interrupt, pmc, rtc, PMC, RTC, SYSCON};
11
10struct AlarmState { 12struct AlarmState {
11 timestamp: Cell<u64>, 13 timestamp: Cell<u64>,
12} 14}
@@ -32,33 +34,32 @@ time_driver_impl!(static DRIVER: RtcDriver = RtcDriver {
32}); 34});
33impl RtcDriver { 35impl RtcDriver {
34 fn init(&'static self) { 36 fn init(&'static self) {
35 let syscon = unsafe { &*SYSCON::ptr() }; 37 let syscon = SYSCON;
36 let pmc = unsafe { &*PMC::ptr() }; 38 let pmc = PMC;
37 let rtc = unsafe { &*RTC::ptr() }; 39 let rtc = RTC;
38 40
39 syscon.ahbclkctrl0.modify(|_, w| w.rtc().enable()); 41 syscon.ahbclkctrl0().modify(|w| w.set_rtc(true));
40 42
41 // By default the RTC enters software reset. If for some reason it is 43 // By default the RTC enters software reset. If for some reason it is
42 // not in reset, we enter and them promptly leave.q 44 // not in reset, we enter and them promptly leave.q
43 rtc.ctrl.modify(|_, w| w.swreset().set_bit()); 45 rtc.ctrl().modify(|w| w.set_swreset(true));
44 rtc.ctrl.modify(|_, w| w.swreset().clear_bit()); 46 rtc.ctrl().modify(|w| w.set_swreset(false));
45 47
46 // Select clock source - either XTAL or FRO 48 // Select clock source - either XTAL or FRO
47 // pmc.rtcosc32k.write(|w| w.sel().xtal32k()); 49 // pmc.rtcosc32k().write(|w| w.set_sel(pmc::vals::Sel::XTAL32K));
48 pmc.rtcosc32k.write(|w| w.sel().fro32k()); 50 pmc.rtcosc32k().write(|w| w.set_sel(pmc::vals::Sel::FRO32K));
49 51
50 // Start the RTC peripheral 52 // Start the RTC peripheral
51 rtc.ctrl.modify(|_, w| w.rtc_osc_pd().power_up()); 53 rtc.ctrl().modify(|w| w.set_rtc_osc_pd(rtc::vals::RtcOscPd::POWER_UP));
52
53 // rtc.ctrl.modify(|_, w| w.rtc_en().clear_bit()); // EXTRA
54 54
55 //reset/clear(?) counter 55 //reset/clear(?) counter
56 rtc.count.reset(); 56 rtc.count().modify(|w| w.set_val(0));
57 //en rtc main counter 57 //en rtc main counter
58 rtc.ctrl.modify(|_, w| w.rtc_en().set_bit()); 58 rtc.ctrl().modify(|w| w.set_rtc_en(true));
59 rtc.ctrl.modify(|_, w| w.rtc1khz_en().set_bit()); 59 rtc.ctrl().modify(|w| w.set_rtc1khz_en(true));
60 // subsec counter enable 60 // subsec counter enable
61 rtc.ctrl.modify(|_, w| w.rtc_subsec_ena().set_bit()); 61 rtc.ctrl()
62 .modify(|w| w.set_rtc_subsec_ena(rtc::vals::RtcSubsecEna::POWER_UP));
62 63
63 // enable irq 64 // enable irq
64 unsafe { 65 unsafe {
@@ -68,7 +69,7 @@ impl RtcDriver {
68 } 69 }
69 70
70 fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { 71 fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool {
71 let rtc = unsafe { &*RTC::ptr() }; 72 let rtc = RTC;
72 let alarm = &self.alarms.borrow(cs); 73 let alarm = &self.alarms.borrow(cs);
73 alarm.timestamp.set(timestamp); 74 alarm.timestamp.set(timestamp);
74 let now = self.now(); 75 let now = self.now();
@@ -83,33 +84,38 @@ impl RtcDriver {
83 let sec = (diff / 32768) as u32; 84 let sec = (diff / 32768) as u32;
84 let subsec = (diff % 32768) as u32; 85 let subsec = (diff % 32768) as u32;
85 86
86 let current_sec = rtc.count.read().val().bits(); 87 let current_sec = rtc.count().read().val();
87 let target_sec = current_sec.wrapping_add(sec as u32); 88 let target_sec = current_sec.wrapping_add(sec as u32);
88 89
89 rtc.match_.write(|w| unsafe { w.matval().bits(target_sec) }); 90 rtc.match_().write(|w| w.set_matval(target_sec));
90 rtc.wake.write(|w| unsafe { 91 rtc.wake().write(|w| {
91 let ms = (subsec * 1000) / 32768; 92 let ms = (subsec * 1000) / 32768;
92 w.val().bits(ms as u16) 93 w.set_val(ms as u16)
93 }); 94 });
95
94 if subsec > 0 { 96 if subsec > 0 {
95 let ms = (subsec * 1000) / 32768; 97 let ms = (subsec * 1000) / 32768;
96 rtc.wake.write(|w| unsafe { w.val().bits(ms as u16) }); 98 rtc.wake().write(|w| w.set_val(ms as u16));
97 } 99 }
98 rtc.ctrl.modify(|_, w| w.alarm1hz().clear_bit().wake1khz().clear_bit()); 100
101 rtc.ctrl().modify(|w| {
102 w.set_alarm1hz(false);
103 w.set_wake1khz(rtc::vals::Wake1khz::RUN)
104 });
99 true 105 true
100 } 106 }
101 107
102 fn on_interrupt(&self) { 108 fn on_interrupt(&self) {
103 critical_section::with(|cs| { 109 critical_section::with(|cs| {
104 let rtc = unsafe { &*RTC::ptr() }; 110 let rtc = RTC;
105 let flags = rtc.ctrl.read(); 111 let flags = rtc.ctrl().read();
106 if flags.alarm1hz().bit_is_clear() { 112 if flags.alarm1hz() == false {
107 rtc.ctrl.modify(|_, w| w.alarm1hz().set_bit()); 113 rtc.ctrl().modify(|w| w.set_alarm1hz(true));
108 self.trigger_alarm(cs); 114 self.trigger_alarm(cs);
109 } 115 }
110 116
111 if flags.wake1khz().bit_is_clear() { 117 if flags.wake1khz() == rtc::vals::Wake1khz::RUN {
112 rtc.ctrl.modify(|_, w| w.wake1khz().set_bit()); 118 rtc.ctrl().modify(|w| w.set_wake1khz(rtc::vals::Wake1khz::TIMEOUT));
113 self.trigger_alarm(cs); 119 self.trigger_alarm(cs);
114 } 120 }
115 }); 121 });
@@ -135,13 +141,13 @@ impl RtcDriver {
135 141
136impl Driver for RtcDriver { 142impl Driver for RtcDriver {
137 fn now(&self) -> u64 { 143 fn now(&self) -> u64 {
138 let rtc = unsafe { &*RTC::ptr() }; 144 let rtc = RTC;
139 145
140 loop { 146 loop {
141 let sec1 = rtc.count.read().val().bits() as u64; 147 let sec1 = rtc.count().read().val() as u64;
142 let sub1 = rtc.subsec.read().subsec().bits() as u64; 148 let sub1 = rtc.subsec().read().subsec() as u64;
143 let sec2 = rtc.count.read().val().bits() as u64; 149 let sec2 = rtc.count().read().val() as u64;
144 let sub2 = rtc.subsec.read().subsec().bits() as u64; 150 let sub2 = rtc.subsec().read().subsec() as u64;
145 151
146 if sec1 == sec2 && sub1 == sub2 { 152 if sec1 == sec2 && sub1 == sub2 {
147 return sec1 * 32768 + sub1; 153 return sec1 * 32768 + sub1;
@@ -162,7 +168,7 @@ impl Driver for RtcDriver {
162 }) 168 })
163 } 169 }
164} 170}
165#[cortex_m_rt::interrupt] 171#[interrupt]
166fn RTC() { 172fn RTC() {
167 DRIVER.on_interrupt(); 173 DRIVER.on_interrupt();
168} 174}