diff options
| author | Ulf Lilleengen <[email protected]> | 2025-05-09 12:39:11 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-05-09 12:39:11 +0200 |
| commit | 4dbaa018703f0362d1d20de30817f80d1dbdea35 (patch) | |
| tree | 30bcd47701931dea52a27ac47414817da494303a | |
| parent | 8b80195843b6f67eed8dcf6ecb21873ed3aaa6d4 (diff) | |
| parent | 42c62ba8999df08ad34d566f30f0a7199dbae083 (diff) | |
Merge pull request #4175 from felipebalbi/imxrt-rtos-timer
iMXRT OS timer
| -rw-r--r-- | embassy-imxrt/Cargo.toml | 9 | ||||
| -rw-r--r-- | embassy-imxrt/src/clocks.rs | 72 | ||||
| -rw-r--r-- | embassy-imxrt/src/lib.rs | 8 | ||||
| -rw-r--r-- | embassy-imxrt/src/time_driver.rs (renamed from embassy-imxrt/src/rtc.rs) | 196 | ||||
| -rw-r--r-- | examples/mimxrt6/Cargo.toml | 4 |
5 files changed, 209 insertions, 80 deletions
diff --git a/embassy-imxrt/Cargo.toml b/embassy-imxrt/Cargo.toml index d58de6353..f16002a8d 100644 --- a/embassy-imxrt/Cargo.toml +++ b/embassy-imxrt/Cargo.toml | |||
| @@ -12,7 +12,7 @@ documentation = "https://docs.embassy.dev/embassy-imxrt" | |||
| 12 | [package.metadata.embassy_docs] | 12 | [package.metadata.embassy_docs] |
| 13 | src_base = "https://github.com/embassy-rs/embassy/blob/embassy-imxrt-v$VERSION/embassy-imxrt/src/" | 13 | src_base = "https://github.com/embassy-rs/embassy/blob/embassy-imxrt-v$VERSION/embassy-imxrt/src/" |
| 14 | src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-imxrt/src/" | 14 | src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-imxrt/src/" |
| 15 | features = ["defmt", "unstable-pac", "time", "time-driver"] | 15 | features = ["defmt", "unstable-pac", "time", "time-driver-os-timer"] |
| 16 | flavors = [ | 16 | flavors = [ |
| 17 | { regex_feature = "mimxrt6.*", target = "thumbv8m.main-none-eabihf" } | 17 | { regex_feature = "mimxrt6.*", target = "thumbv8m.main-none-eabihf" } |
| 18 | ] | 18 | ] |
| @@ -37,9 +37,12 @@ defmt = ["dep:defmt", "embassy-hal-internal/defmt", "embassy-sync/defmt", "mimxr | |||
| 37 | time = ["dep:embassy-time", "embassy-embedded-hal/time"] | 37 | time = ["dep:embassy-time", "embassy-embedded-hal/time"] |
| 38 | 38 | ||
| 39 | ## Enable custom embassy time-driver implementation, using 32KHz RTC | 39 | ## Enable custom embassy time-driver implementation, using 32KHz RTC |
| 40 | time-driver-rtc = ["_time-driver"] | 40 | time-driver-rtc = ["_time-driver", "embassy-time-driver?/tick-hz-1_000"] |
| 41 | 41 | ||
| 42 | _time-driver = ["dep:embassy-time-driver", "embassy-time-driver?/tick-hz-1_000", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] | 42 | ## Enable custom embassy time-driver implementation, using 1MHz OS Timer |
| 43 | time-driver-os-timer = ["_time-driver", "embassy-time-driver?/tick-hz-1_000_000"] | ||
| 44 | |||
| 45 | _time-driver = ["dep:embassy-time-driver", "dep:embassy-time-queue-utils", "embassy-embedded-hal/time"] | ||
| 43 | 46 | ||
| 44 | ## Reexport the PAC for the currently enabled chip at `embassy_imxrt::pac` (unstable) | 47 | ## Reexport the PAC for the currently enabled chip at `embassy_imxrt::pac` (unstable) |
| 45 | unstable-pac = [] | 48 | unstable-pac = [] |
diff --git a/embassy-imxrt/src/clocks.rs b/embassy-imxrt/src/clocks.rs index 1d36fb142..39c3e6238 100644 --- a/embassy-imxrt/src/clocks.rs +++ b/embassy-imxrt/src/clocks.rs | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | //! Clock configuration for the `RT6xx` | 1 | //! Clock configuration for the `RT6xx` |
| 2 | use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; | 2 | use core::sync::atomic::{AtomicU32, AtomicU8, Ordering}; |
| 3 | 3 | ||
| 4 | #[cfg(feature = "defmt")] | ||
| 5 | use defmt; | ||
| 6 | use paste::paste; | 4 | use paste::paste; |
| 7 | 5 | ||
| 8 | use crate::pac; | 6 | use crate::pac; |
| @@ -503,7 +501,6 @@ impl ConfigurableClock for LposcConfig { | |||
| 503 | } | 501 | } |
| 504 | } | 502 | } |
| 505 | } else { | 503 | } else { |
| 506 | error!("failed to convert desired clock rate, {:#}, to LPOSC Freq", freq); | ||
| 507 | Err(ClockError::InvalidFrequency) | 504 | Err(ClockError::InvalidFrequency) |
| 508 | } | 505 | } |
| 509 | } | 506 | } |
| @@ -549,7 +546,6 @@ impl ConfigurableClock for FfroConfig { | |||
| 549 | Ok(()) | 546 | Ok(()) |
| 550 | } | 547 | } |
| 551 | fn get_clock_rate(&self) -> Result<u32, ClockError> { | 548 | fn get_clock_rate(&self) -> Result<u32, ClockError> { |
| 552 | trace!("getting ffro clock rate"); | ||
| 553 | Ok(self.freq.load(Ordering::Relaxed)) | 549 | Ok(self.freq.load(Ordering::Relaxed)) |
| 554 | } | 550 | } |
| 555 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { | 551 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { |
| @@ -616,7 +612,6 @@ impl ConfigurableClock for SfroConfig { | |||
| 616 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { | 612 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { |
| 617 | if self.state == State::Enabled { | 613 | if self.state == State::Enabled { |
| 618 | if freq == SFRO_FREQ { | 614 | if freq == SFRO_FREQ { |
| 619 | trace!("Sfro frequency is already set at 16MHz"); | ||
| 620 | Ok(()) | 615 | Ok(()) |
| 621 | } else { | 616 | } else { |
| 622 | Err(ClockError::InvalidFrequency) | 617 | Err(ClockError::InvalidFrequency) |
| @@ -677,7 +672,6 @@ impl MultiSourceClock for MainPllClkConfig { | |||
| 677 | } | 672 | } |
| 678 | MainPllClkSrc::SFRO => { | 673 | MainPllClkSrc::SFRO => { |
| 679 | if !clock_src_config.is_enabled() { | 674 | if !clock_src_config.is_enabled() { |
| 680 | error!("Can't set SFRO as source for MainPll as it's not enabled"); | ||
| 681 | return Err(ClockError::ClockNotEnabled); | 675 | return Err(ClockError::ClockNotEnabled); |
| 682 | } | 676 | } |
| 683 | // check if desired frequency is a valid multiple of 16m SFRO clock | 677 | // check if desired frequency is a valid multiple of 16m SFRO clock |
| @@ -703,7 +697,6 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 703 | } | 697 | } |
| 704 | fn disable(&self) -> Result<(), ClockError> { | 698 | fn disable(&self) -> Result<(), ClockError> { |
| 705 | if self.is_enabled() { | 699 | if self.is_enabled() { |
| 706 | error!("Attempting to reset the Main Pll Clock, should be resetting its source"); | ||
| 707 | Err(ClockError::ClockNotSupported) | 700 | Err(ClockError::ClockNotSupported) |
| 708 | } else { | 701 | } else { |
| 709 | Err(ClockError::ClockNotEnabled) | 702 | Err(ClockError::ClockNotEnabled) |
| @@ -719,7 +712,6 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 719 | } | 712 | } |
| 720 | fn set_clock_rate(&mut self, div: u8, mult: u8, freq: u32) -> Result<(), ClockError> { | 713 | fn set_clock_rate(&mut self, div: u8, mult: u8, freq: u32) -> Result<(), ClockError> { |
| 721 | if self.is_enabled() { | 714 | if self.is_enabled() { |
| 722 | trace!("attempting to set main pll clock rate"); | ||
| 723 | // SAFETY: unsafe needed to take pointers to Sysctl0 and Clkctl0 | 715 | // SAFETY: unsafe needed to take pointers to Sysctl0 and Clkctl0 |
| 724 | let clkctl0 = unsafe { crate::pac::Clkctl0::steal() }; | 716 | let clkctl0 = unsafe { crate::pac::Clkctl0::steal() }; |
| 725 | let sysctl0 = unsafe { crate::pac::Sysctl0::steal() }; | 717 | let sysctl0 = unsafe { crate::pac::Sysctl0::steal() }; |
| @@ -741,15 +733,12 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 741 | base_rate = r; | 733 | base_rate = r; |
| 742 | } | 734 | } |
| 743 | MainPllClkSrc::FFRO => { | 735 | MainPllClkSrc::FFRO => { |
| 744 | trace!("found FFRO as source, wait a bit"); | ||
| 745 | delay_loop_clocks(1000, desired_freq); | 736 | delay_loop_clocks(1000, desired_freq); |
| 746 | match clkctl0.ffroctl0().read().trim_range().is_ffro_48mhz() { | 737 | match clkctl0.ffroctl0().read().trim_range().is_ffro_48mhz() { |
| 747 | true => base_rate = Into::into(FfroFreq::Ffro48m), | 738 | true => base_rate = Into::into(FfroFreq::Ffro48m), |
| 748 | false => base_rate = Into::into(FfroFreq::Ffro60m), | 739 | false => base_rate = Into::into(FfroFreq::Ffro60m), |
| 749 | } | 740 | } |
| 750 | trace!("found ffro rate to be: {:#}", base_rate); | ||
| 751 | if div == 2 { | 741 | if div == 2 { |
| 752 | trace!("dividing FFRO rate by 2"); | ||
| 753 | clkctl0.syspll0clksel().write(|w| w.sel().ffro_div_2()); | 742 | clkctl0.syspll0clksel().write(|w| w.sel().ffro_div_2()); |
| 754 | delay_loop_clocks(150, desired_freq); | 743 | delay_loop_clocks(150, desired_freq); |
| 755 | base_rate /= 2; | 744 | base_rate /= 2; |
| @@ -763,10 +752,8 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 763 | } | 752 | } |
| 764 | }; | 753 | }; |
| 765 | base_rate *= u32::from(mult); | 754 | base_rate *= u32::from(mult); |
| 766 | trace!("calculated base rate at: {:#}", base_rate); | ||
| 767 | if base_rate != freq { | 755 | if base_rate != freq { |
| 768 | // make sure to power syspll back up before returning the error | 756 | // make sure to power syspll back up before returning the error |
| 769 | error!("invalid frequency found, powering syspll back up before returning error. Check div and mult"); | ||
| 770 | // Clear System PLL reset | 757 | // Clear System PLL reset |
| 771 | clkctl0.syspll0ctl0().write(|w| w.reset().normal()); | 758 | clkctl0.syspll0ctl0().write(|w| w.reset().normal()); |
| 772 | // Power up SYSPLL | 759 | // Power up SYSPLL |
| @@ -775,13 +762,11 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 775 | .write(|w| w.syspllana_pd().clr_pdruncfg0().syspllldo_pd().clr_pdruncfg0()); | 762 | .write(|w| w.syspllana_pd().clr_pdruncfg0().syspllldo_pd().clr_pdruncfg0()); |
| 776 | return Err(ClockError::InvalidFrequency); | 763 | return Err(ClockError::InvalidFrequency); |
| 777 | } | 764 | } |
| 778 | trace!("setting default num and denom"); | ||
| 779 | // SAFETY: unsafe needed to write the bits for the num and demon fields | 765 | // SAFETY: unsafe needed to write the bits for the num and demon fields |
| 780 | clkctl0.syspll0num().write(|w| unsafe { w.num().bits(0b0) }); | 766 | clkctl0.syspll0num().write(|w| unsafe { w.num().bits(0b0) }); |
| 781 | clkctl0.syspll0denom().write(|w| unsafe { w.denom().bits(0b1) }); | 767 | clkctl0.syspll0denom().write(|w| unsafe { w.denom().bits(0b1) }); |
| 782 | delay_loop_clocks(30, desired_freq); | 768 | delay_loop_clocks(30, desired_freq); |
| 783 | self.mult.store(mult, Ordering::Relaxed); | 769 | self.mult.store(mult, Ordering::Relaxed); |
| 784 | trace!("setting self.mult as: {:#}", mult); | ||
| 785 | match mult { | 770 | match mult { |
| 786 | 16 => { | 771 | 16 => { |
| 787 | clkctl0.syspll0ctl0().modify(|_r, w| w.mult().div_16()); | 772 | clkctl0.syspll0ctl0().modify(|_r, w| w.mult().div_16()); |
| @@ -803,7 +788,6 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 803 | } | 788 | } |
| 804 | _ => return Err(ClockError::InvalidMult), | 789 | _ => return Err(ClockError::InvalidMult), |
| 805 | } | 790 | } |
| 806 | trace!("clear syspll reset"); | ||
| 807 | // Clear System PLL reset | 791 | // Clear System PLL reset |
| 808 | clkctl0.syspll0ctl0().modify(|_r, w| w.reset().normal()); | 792 | clkctl0.syspll0ctl0().modify(|_r, w| w.reset().normal()); |
| 809 | // Power up SYSPLL | 793 | // Power up SYSPLL |
| @@ -819,7 +803,6 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 819 | clkctl0.syspll0ctl0().modify(|_, w| w.holdringoff_ena().dsiable()); | 803 | clkctl0.syspll0ctl0().modify(|_, w| w.holdringoff_ena().dsiable()); |
| 820 | delay_loop_clocks(15, desired_freq); | 804 | delay_loop_clocks(15, desired_freq); |
| 821 | 805 | ||
| 822 | trace!("setting new PFD0 bits"); | ||
| 823 | // gate the output and clear bits. | 806 | // gate the output and clear bits. |
| 824 | // SAFETY: unsafe needed to write the bits for pfd0 | 807 | // SAFETY: unsafe needed to write the bits for pfd0 |
| 825 | clkctl0 | 808 | clkctl0 |
| @@ -833,7 +816,6 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 833 | .modify(|_r, w| unsafe { w.pfd0_clkgate().not_gated().pfd0().bits(0x12) }); | 816 | .modify(|_r, w| unsafe { w.pfd0_clkgate().not_gated().pfd0().bits(0x12) }); |
| 834 | // wait for ready bit to be set | 817 | // wait for ready bit to be set |
| 835 | delay_loop_clocks(50, desired_freq); | 818 | delay_loop_clocks(50, desired_freq); |
| 836 | trace!("waiting for mainpll clock to be ready"); | ||
| 837 | while clkctl0.syspll0pfd().read().pfd0_clkrdy().bit_is_clear() {} | 819 | while clkctl0.syspll0pfd().read().pfd0_clkrdy().bit_is_clear() {} |
| 838 | // clear by writing a 1 | 820 | // clear by writing a 1 |
| 839 | clkctl0.syspll0pfd().modify(|_, w| w.pfd0_clkrdy().set_bit()); | 821 | clkctl0.syspll0pfd().modify(|_, w| w.pfd0_clkrdy().set_bit()); |
| @@ -854,11 +836,9 @@ impl ConfigurableClock for MainPllClkConfig { | |||
| 854 | impl MainPllClkConfig { | 836 | impl MainPllClkConfig { |
| 855 | /// Calculate the mult value of a desired frequency, return error if invalid | 837 | /// Calculate the mult value of a desired frequency, return error if invalid |
| 856 | pub(self) fn calc_mult(rate: u32, base_freq: u32) -> Result<u8, ClockError> { | 838 | pub(self) fn calc_mult(rate: u32, base_freq: u32) -> Result<u8, ClockError> { |
| 857 | trace!("calculating mult for {:#} / {:#}", rate, base_freq); | ||
| 858 | const VALIDMULTS: [u8; 6] = [16, 17, 20, 22, 27, 33]; | 839 | const VALIDMULTS: [u8; 6] = [16, 17, 20, 22, 27, 33]; |
| 859 | if rate > base_freq && rate % base_freq == 0 { | 840 | if rate > base_freq && rate % base_freq == 0 { |
| 860 | let mult = (rate / base_freq) as u8; | 841 | let mult = (rate / base_freq) as u8; |
| 861 | trace!("verifying that calculated mult {:#} is a valid one", mult); | ||
| 862 | if VALIDMULTS.into_iter().any(|i| i == mult) { | 842 | if VALIDMULTS.into_iter().any(|i| i == mult) { |
| 863 | Ok(mult) | 843 | Ok(mult) |
| 864 | } else { | 844 | } else { |
| @@ -1112,7 +1092,6 @@ impl ConfigurableClock for MainClkConfig { | |||
| 1112 | Ok(()) | 1092 | Ok(()) |
| 1113 | } | 1093 | } |
| 1114 | fn disable(&self) -> Result<(), ClockError> { | 1094 | fn disable(&self) -> Result<(), ClockError> { |
| 1115 | error!("Attempting to reset the main clock, should NOT happen during runtime"); | ||
| 1116 | Err(ClockError::ClockNotSupported) | 1095 | Err(ClockError::ClockNotSupported) |
| 1117 | } | 1096 | } |
| 1118 | fn get_clock_rate(&self) -> Result<u32, ClockError> { | 1097 | fn get_clock_rate(&self) -> Result<u32, ClockError> { |
| @@ -1120,7 +1099,6 @@ impl ConfigurableClock for MainClkConfig { | |||
| 1120 | Ok(rate) | 1099 | Ok(rate) |
| 1121 | } | 1100 | } |
| 1122 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, _freq: u32) -> Result<(), ClockError> { | 1101 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, _freq: u32) -> Result<(), ClockError> { |
| 1123 | error!("The multi-source set_clock_rate_and_source method should be used instead of set_clock_rate"); | ||
| 1124 | Err(ClockError::ClockNotSupported) | 1102 | Err(ClockError::ClockNotSupported) |
| 1125 | } | 1103 | } |
| 1126 | fn is_enabled(&self) -> bool { | 1104 | fn is_enabled(&self) -> bool { |
| @@ -1145,7 +1123,6 @@ impl ConfigurableClock for ClkInConfig { | |||
| 1145 | } | 1123 | } |
| 1146 | } | 1124 | } |
| 1147 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { | 1125 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { |
| 1148 | trace!("Setting value of clk in config, this won't change the clock itself"); | ||
| 1149 | self.freq.as_ref().unwrap().store(freq, Ordering::Relaxed); | 1126 | self.freq.as_ref().unwrap().store(freq, Ordering::Relaxed); |
| 1150 | Ok(()) | 1127 | Ok(()) |
| 1151 | } | 1128 | } |
| @@ -1188,7 +1165,6 @@ impl ConfigurableClock for RtcClkConfig { | |||
| 1188 | Ok(()) | 1165 | Ok(()) |
| 1189 | } | 1166 | } |
| 1190 | fn disable(&self) -> Result<(), ClockError> { | 1167 | fn disable(&self) -> Result<(), ClockError> { |
| 1191 | error!("Resetting the RTC clock, this should NOT happen during runtime"); | ||
| 1192 | Err(ClockError::ClockNotSupported) | 1168 | Err(ClockError::ClockNotSupported) |
| 1193 | } | 1169 | } |
| 1194 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { | 1170 | fn set_clock_rate(&mut self, _div: u8, _mult: u8, freq: u32) -> Result<(), ClockError> { |
| @@ -1199,7 +1175,6 @@ impl ConfigurableClock for RtcClkConfig { | |||
| 1199 | match r { | 1175 | match r { |
| 1200 | RtcFreq::Default1Hz => { | 1176 | RtcFreq::Default1Hz => { |
| 1201 | if rtc.ctrl().read().rtc_en().is_enable() { | 1177 | if rtc.ctrl().read().rtc_en().is_enable() { |
| 1202 | trace!("Attempting to enable an already enabled clock, RTC 1Hz"); | ||
| 1203 | } else { | 1178 | } else { |
| 1204 | rtc.ctrl().modify(|_r, w| w.rtc_en().enable()); | 1179 | rtc.ctrl().modify(|_r, w| w.rtc_en().enable()); |
| 1205 | } | 1180 | } |
| @@ -1207,7 +1182,6 @@ impl ConfigurableClock for RtcClkConfig { | |||
| 1207 | } | 1182 | } |
| 1208 | RtcFreq::HighResolution1khz => { | 1183 | RtcFreq::HighResolution1khz => { |
| 1209 | if rtc.ctrl().read().rtc1khz_en().is_enable() { | 1184 | if rtc.ctrl().read().rtc1khz_en().is_enable() { |
| 1210 | trace!("Attempting to enable an already enabled clock, RTC 1Hz"); | ||
| 1211 | } else { | 1185 | } else { |
| 1212 | rtc.ctrl().modify(|_r, w| w.rtc1khz_en().enable()); | 1186 | rtc.ctrl().modify(|_r, w| w.rtc1khz_en().enable()); |
| 1213 | } | 1187 | } |
| @@ -1215,7 +1189,6 @@ impl ConfigurableClock for RtcClkConfig { | |||
| 1215 | } | 1189 | } |
| 1216 | RtcFreq::SubSecond32kHz => { | 1190 | RtcFreq::SubSecond32kHz => { |
| 1217 | if rtc.ctrl().read().rtc_subsec_ena().is_enable() { | 1191 | if rtc.ctrl().read().rtc_subsec_ena().is_enable() { |
| 1218 | trace!("Attempting to enable an already enabled clock, RTC 1Hz"); | ||
| 1219 | } else { | 1192 | } else { |
| 1220 | rtc.ctrl().modify(|_r, w| w.rtc_subsec_ena().enable()); | 1193 | rtc.ctrl().modify(|_r, w| w.rtc_subsec_ena().enable()); |
| 1221 | } | 1194 | } |
| @@ -1245,18 +1218,12 @@ impl ConfigurableClock for RtcClkConfig { | |||
| 1245 | 1218 | ||
| 1246 | impl SysClkConfig { | 1219 | impl SysClkConfig { |
| 1247 | /// Updates the system core clock frequency, SW concept used for systick | 1220 | /// Updates the system core clock frequency, SW concept used for systick |
| 1248 | fn update_sys_core_clock(&self) { | 1221 | fn update_sys_core_clock(&self) {} |
| 1249 | trace!( | ||
| 1250 | "System core clock has been updated to {:?}, this involves no HW reg writes", | ||
| 1251 | self.sysclkfreq.load(Ordering::Relaxed) | ||
| 1252 | ); | ||
| 1253 | } | ||
| 1254 | } | 1222 | } |
| 1255 | 1223 | ||
| 1256 | impl ConfigurableClock for SysOscConfig { | 1224 | impl ConfigurableClock for SysOscConfig { |
| 1257 | fn enable_and_reset(&self) -> Result<(), ClockError> { | 1225 | fn enable_and_reset(&self) -> Result<(), ClockError> { |
| 1258 | if self.state == State::Enabled { | 1226 | if self.state == State::Enabled { |
| 1259 | trace!("SysOsc was already enabled"); | ||
| 1260 | return Ok(()); | 1227 | return Ok(()); |
| 1261 | } | 1228 | } |
| 1262 | 1229 | ||
| @@ -1498,32 +1465,26 @@ impl ClockOutConfig { | |||
| 1498 | /// Using the config, enables all desired clocks to desired clock rates | 1465 | /// Using the config, enables all desired clocks to desired clock rates |
| 1499 | fn init_clock_hw(config: ClockConfig) -> Result<(), ClockError> { | 1466 | fn init_clock_hw(config: ClockConfig) -> Result<(), ClockError> { |
| 1500 | if let Err(e) = config.rtc.enable_and_reset() { | 1467 | if let Err(e) = config.rtc.enable_and_reset() { |
| 1501 | error!("couldn't Power on OSC for RTC, result: {:?}", e); | ||
| 1502 | return Err(e); | 1468 | return Err(e); |
| 1503 | } | 1469 | } |
| 1504 | 1470 | ||
| 1505 | if let Err(e) = config.lposc.enable_and_reset() { | 1471 | if let Err(e) = config.lposc.enable_and_reset() { |
| 1506 | error!("couldn't Power on LPOSC, result: {:?}", e); | ||
| 1507 | return Err(e); | 1472 | return Err(e); |
| 1508 | } | 1473 | } |
| 1509 | 1474 | ||
| 1510 | if let Err(e) = config.ffro.enable_and_reset() { | 1475 | if let Err(e) = config.ffro.enable_and_reset() { |
| 1511 | error!("couldn't Power on FFRO, result: {:?}", e); | ||
| 1512 | return Err(e); | 1476 | return Err(e); |
| 1513 | } | 1477 | } |
| 1514 | 1478 | ||
| 1515 | if let Err(e) = config.sfro.enable_and_reset() { | 1479 | if let Err(e) = config.sfro.enable_and_reset() { |
| 1516 | error!("couldn't Power on SFRO, result: {:?}", e); | ||
| 1517 | return Err(e); | 1480 | return Err(e); |
| 1518 | } | 1481 | } |
| 1519 | 1482 | ||
| 1520 | if let Err(e) = config.sys_osc.enable_and_reset() { | 1483 | if let Err(e) = config.sys_osc.enable_and_reset() { |
| 1521 | error!("Couldn't enable sys oscillator {:?}", e); | ||
| 1522 | return Err(e); | 1484 | return Err(e); |
| 1523 | } | 1485 | } |
| 1524 | 1486 | ||
| 1525 | if let Err(e) = config.main_pll_clk.enable_and_reset() { | 1487 | if let Err(e) = config.main_pll_clk.enable_and_reset() { |
| 1526 | error!("Couldn't enable main pll clock {:?}", e); | ||
| 1527 | return Err(e); | 1488 | return Err(e); |
| 1528 | } | 1489 | } |
| 1529 | 1490 | ||
| @@ -1542,7 +1503,6 @@ fn init_clock_hw(config: ClockConfig) -> Result<(), ClockError> { | |||
| 1542 | init_syscpuahb_clk(); | 1503 | init_syscpuahb_clk(); |
| 1543 | 1504 | ||
| 1544 | if let Err(e) = config.main_clk.enable_and_reset() { | 1505 | if let Err(e) = config.main_clk.enable_and_reset() { |
| 1545 | error!("Couldn't enable main clock {:?}", e); | ||
| 1546 | return Err(e); | 1506 | return Err(e); |
| 1547 | } | 1507 | } |
| 1548 | 1508 | ||
| @@ -1561,7 +1521,8 @@ pub(crate) unsafe fn init(config: ClockConfig) -> Result<(), ClockError> { | |||
| 1561 | 1521 | ||
| 1562 | ///Trait to expose perph clocks | 1522 | ///Trait to expose perph clocks |
| 1563 | trait SealedSysconPeripheral { | 1523 | trait SealedSysconPeripheral { |
| 1564 | fn enable_and_reset_perph_clock(); | 1524 | fn enable_perph_clock(); |
| 1525 | fn reset_perph(); | ||
| 1565 | fn disable_perph_clock(); | 1526 | fn disable_perph_clock(); |
| 1566 | } | 1527 | } |
| 1567 | 1528 | ||
| @@ -1574,7 +1535,18 @@ pub trait SysconPeripheral: SealedSysconPeripheral + 'static {} | |||
| 1574 | /// | 1535 | /// |
| 1575 | /// Peripheral must not be in use. | 1536 | /// Peripheral must not be in use. |
| 1576 | pub fn enable_and_reset<T: SysconPeripheral>() { | 1537 | pub fn enable_and_reset<T: SysconPeripheral>() { |
| 1577 | T::enable_and_reset_perph_clock(); | 1538 | T::enable_perph_clock(); |
| 1539 | T::reset_perph(); | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | /// Enables peripheral `T`. | ||
| 1543 | pub fn enable<T: SysconPeripheral>() { | ||
| 1544 | T::enable_perph_clock(); | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | /// Reset peripheral `T`. | ||
| 1548 | pub fn reset<T: SysconPeripheral>() { | ||
| 1549 | T::reset_perph(); | ||
| 1578 | } | 1550 | } |
| 1579 | 1551 | ||
| 1580 | /// Disables peripheral `T`. | 1552 | /// Disables peripheral `T`. |
| @@ -1588,15 +1560,21 @@ pub fn disable<T: SysconPeripheral>() { | |||
| 1588 | macro_rules! impl_perph_clk { | 1560 | macro_rules! impl_perph_clk { |
| 1589 | ($peripheral:ident, $clkctl:ident, $clkreg:ident, $rstctl:ident, $rstreg:ident, $bit:expr) => { | 1561 | ($peripheral:ident, $clkctl:ident, $clkreg:ident, $rstctl:ident, $rstreg:ident, $bit:expr) => { |
| 1590 | impl SealedSysconPeripheral for crate::peripherals::$peripheral { | 1562 | impl SealedSysconPeripheral for crate::peripherals::$peripheral { |
| 1591 | fn enable_and_reset_perph_clock() { | 1563 | fn enable_perph_clock() { |
| 1592 | // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 | 1564 | // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 |
| 1593 | let cc1 = unsafe { pac::$clkctl::steal() }; | 1565 | let cc1 = unsafe { pac::$clkctl::steal() }; |
| 1594 | let rc1 = unsafe { pac::$rstctl::steal() }; | ||
| 1595 | 1566 | ||
| 1596 | paste! { | 1567 | paste! { |
| 1597 | // SAFETY: unsafe due to the use of bits() | 1568 | // SAFETY: unsafe due to the use of bits() |
| 1598 | cc1.[<$clkreg _set>]().write(|w| unsafe { w.bits(1 << $bit) }); | 1569 | cc1.[<$clkreg _set>]().write(|w| unsafe { w.bits(1 << $bit) }); |
| 1570 | } | ||
| 1571 | } | ||
| 1599 | 1572 | ||
| 1573 | fn reset_perph() { | ||
| 1574 | // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 | ||
| 1575 | let rc1 = unsafe { pac::$rstctl::steal() }; | ||
| 1576 | |||
| 1577 | paste! { | ||
| 1600 | // SAFETY: unsafe due to the use of bits() | 1578 | // SAFETY: unsafe due to the use of bits() |
| 1601 | rc1.[<$rstreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); | 1579 | rc1.[<$rstreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); |
| 1602 | } | 1580 | } |
| @@ -1605,13 +1583,9 @@ macro_rules! impl_perph_clk { | |||
| 1605 | fn disable_perph_clock() { | 1583 | fn disable_perph_clock() { |
| 1606 | // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 | 1584 | // SAFETY: unsafe needed to take pointers to Rstctl1 and Clkctl1 |
| 1607 | let cc1 = unsafe { pac::$clkctl::steal() }; | 1585 | let cc1 = unsafe { pac::$clkctl::steal() }; |
| 1608 | let rc1 = unsafe { pac::$rstctl::steal() }; | ||
| 1609 | 1586 | ||
| 1610 | paste! { | 1587 | paste! { |
| 1611 | // SAFETY: unsafe due to the use of bits() | 1588 | // SAFETY: unsafe due to the use of bits() |
| 1612 | rc1.[<$rstreg _set>]().write(|w| unsafe { w.bits(1 << $bit) }); | ||
| 1613 | |||
| 1614 | // SAFETY: unsafe due to the use of bits() | ||
| 1615 | cc1.[<$clkreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); | 1589 | cc1.[<$clkreg _clr>]().write(|w| unsafe { w.bits(1 << $bit) }); |
| 1616 | } | 1590 | } |
| 1617 | } | 1591 | } |
diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs index 5fbf3244b..ad9f81e88 100644 --- a/embassy-imxrt/src/lib.rs +++ b/embassy-imxrt/src/lib.rs | |||
| @@ -22,7 +22,7 @@ pub mod gpio; | |||
| 22 | pub mod iopctl; | 22 | pub mod iopctl; |
| 23 | 23 | ||
| 24 | #[cfg(feature = "_time-driver")] | 24 | #[cfg(feature = "_time-driver")] |
| 25 | pub mod rtc; | 25 | pub mod time_driver; |
| 26 | 26 | ||
| 27 | // This mod MUST go last, so that it sees all the `impl_foo!' macros | 27 | // This mod MUST go last, so that it sees all the `impl_foo!' macros |
| 28 | #[cfg_attr(feature = "mimxrt633s", path = "chips/mimxrt633s.rs")] | 28 | #[cfg_attr(feature = "mimxrt633s", path = "chips/mimxrt633s.rs")] |
| @@ -132,12 +132,10 @@ pub fn init(config: config::Config) -> Peripherals { | |||
| 132 | error!("unable to initialize Clocks for reason: {:?}", e); | 132 | error!("unable to initialize Clocks for reason: {:?}", e); |
| 133 | // Panic here? | 133 | // Panic here? |
| 134 | } | 134 | } |
| 135 | gpio::init(); | ||
| 136 | } | 135 | } |
| 137 | |||
| 138 | // init RTC time driver | ||
| 139 | #[cfg(feature = "_time-driver")] | 136 | #[cfg(feature = "_time-driver")] |
| 140 | rtc::init(config.time_interrupt_priority); | 137 | time_driver::init(config.time_interrupt_priority); |
| 138 | gpio::init(); | ||
| 141 | 139 | ||
| 142 | peripherals | 140 | peripherals |
| 143 | } | 141 | } |
diff --git a/embassy-imxrt/src/rtc.rs b/embassy-imxrt/src/time_driver.rs index 56a8f7397..c68679d3e 100644 --- a/embassy-imxrt/src/rtc.rs +++ b/embassy-imxrt/src/time_driver.rs | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | //! RTC Time Driver. | 1 | //! Time Driver. |
| 2 | use core::cell::{Cell, RefCell}; | 2 | use core::cell::{Cell, RefCell}; |
| 3 | #[cfg(feature = "time-driver-rtc")] | ||
| 3 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; | 4 | use core::sync::atomic::{compiler_fence, AtomicU32, Ordering}; |
| 4 | 5 | ||
| 5 | use critical_section::CriticalSection; | 6 | use critical_section::CriticalSection; |
| @@ -8,9 +9,26 @@ use embassy_sync::blocking_mutex::Mutex; | |||
| 8 | use embassy_time_driver::Driver; | 9 | use embassy_time_driver::Driver; |
| 9 | use embassy_time_queue_utils::Queue; | 10 | use embassy_time_queue_utils::Queue; |
| 10 | 11 | ||
| 12 | #[cfg(feature = "time-driver-os-timer")] | ||
| 13 | use crate::clocks::enable; | ||
| 11 | use crate::interrupt::InterruptExt; | 14 | use crate::interrupt::InterruptExt; |
| 12 | use crate::{interrupt, pac}; | 15 | use crate::{interrupt, pac}; |
| 13 | 16 | ||
| 17 | struct AlarmState { | ||
| 18 | timestamp: Cell<u64>, | ||
| 19 | } | ||
| 20 | |||
| 21 | unsafe impl Send for AlarmState {} | ||
| 22 | |||
| 23 | impl AlarmState { | ||
| 24 | const fn new() -> Self { | ||
| 25 | Self { | ||
| 26 | timestamp: Cell::new(u64::MAX), | ||
| 27 | } | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | #[cfg(feature = "time-driver-rtc")] | ||
| 14 | fn rtc() -> &'static pac::rtc::RegisterBlock { | 32 | fn rtc() -> &'static pac::rtc::RegisterBlock { |
| 15 | unsafe { &*pac::Rtc::ptr() } | 33 | unsafe { &*pac::Rtc::ptr() } |
| 16 | } | 34 | } |
| @@ -25,24 +43,19 @@ fn rtc() -> &'static pac::rtc::RegisterBlock { | |||
| 25 | /// the 1kHz RTC counter is 16 bits and RTC doesn't have separate compare channels, | 43 | /// the 1kHz RTC counter is 16 bits and RTC doesn't have separate compare channels, |
| 26 | /// so using a 32 bit GPREG0-2 as counter, compare, and int_en | 44 | /// so using a 32 bit GPREG0-2 as counter, compare, and int_en |
| 27 | /// `period` is a 32bit integer, gpreg 'counter' is 31 bits plus the parity bit for overflow detection | 45 | /// `period` is a 32bit integer, gpreg 'counter' is 31 bits plus the parity bit for overflow detection |
| 46 | #[cfg(feature = "time-driver-rtc")] | ||
| 28 | fn calc_now(period: u32, counter: u32) -> u64 { | 47 | fn calc_now(period: u32, counter: u32) -> u64 { |
| 29 | ((period as u64) << 31) + ((counter ^ ((period & 1) << 31)) as u64) | 48 | ((period as u64) << 31) + ((counter ^ ((period & 1) << 31)) as u64) |
| 30 | } | 49 | } |
| 31 | 50 | ||
| 32 | struct AlarmState { | 51 | #[cfg(feature = "time-driver-rtc")] |
| 33 | timestamp: Cell<u64>, | 52 | embassy_time_driver::time_driver_impl!(static DRIVER: Rtc = Rtc { |
| 34 | } | 53 | period: AtomicU32::new(0), |
| 35 | 54 | alarms: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), | |
| 36 | unsafe impl Send for AlarmState {} | 55 | queue: Mutex::new(RefCell::new(Queue::new())), |
| 37 | 56 | }); | |
| 38 | impl AlarmState { | ||
| 39 | const fn new() -> Self { | ||
| 40 | Self { | ||
| 41 | timestamp: Cell::new(u64::MAX), | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | 57 | ||
| 58 | #[cfg(feature = "time-driver-rtc")] | ||
| 46 | struct Rtc { | 59 | struct Rtc { |
| 47 | /// Number of 2^31 periods elapsed since boot. | 60 | /// Number of 2^31 periods elapsed since boot. |
| 48 | period: AtomicU32, | 61 | period: AtomicU32, |
| @@ -51,12 +64,7 @@ struct Rtc { | |||
| 51 | queue: Mutex<CriticalSectionRawMutex, RefCell<Queue>>, | 64 | queue: Mutex<CriticalSectionRawMutex, RefCell<Queue>>, |
| 52 | } | 65 | } |
| 53 | 66 | ||
| 54 | embassy_time_driver::time_driver_impl!(static DRIVER: Rtc = Rtc { | 67 | #[cfg(feature = "time-driver-rtc")] |
| 55 | period: AtomicU32::new(0), | ||
| 56 | alarms: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), | ||
| 57 | queue: Mutex::new(RefCell::new(Queue::new())), | ||
| 58 | }); | ||
| 59 | |||
| 60 | impl Rtc { | 68 | impl Rtc { |
| 61 | /// Access the GPREG0 register to use it as a 31-bit counter. | 69 | /// Access the GPREG0 register to use it as a 31-bit counter. |
| 62 | #[inline] | 70 | #[inline] |
| @@ -219,6 +227,7 @@ impl Rtc { | |||
| 219 | } | 227 | } |
| 220 | } | 228 | } |
| 221 | 229 | ||
| 230 | #[cfg(feature = "time-driver-rtc")] | ||
| 222 | impl Driver for Rtc { | 231 | impl Driver for Rtc { |
| 223 | fn now(&self) -> u64 { | 232 | fn now(&self) -> u64 { |
| 224 | // `period` MUST be read before `counter`, see comment at the top for details. | 233 | // `period` MUST be read before `counter`, see comment at the top for details. |
| @@ -242,13 +251,158 @@ impl Driver for Rtc { | |||
| 242 | } | 251 | } |
| 243 | } | 252 | } |
| 244 | 253 | ||
| 245 | #[cfg(feature = "rt")] | 254 | #[cfg(all(feature = "rt", feature = "time-driver-rtc"))] |
| 246 | #[allow(non_snake_case)] | 255 | #[allow(non_snake_case)] |
| 247 | #[interrupt] | 256 | #[interrupt] |
| 248 | fn RTC() { | 257 | fn RTC() { |
| 249 | DRIVER.on_interrupt() | 258 | DRIVER.on_interrupt() |
| 250 | } | 259 | } |
| 251 | 260 | ||
| 261 | #[cfg(feature = "time-driver-os-timer")] | ||
| 262 | fn os() -> &'static pac::ostimer0::RegisterBlock { | ||
| 263 | unsafe { &*pac::Ostimer0::ptr() } | ||
| 264 | } | ||
| 265 | |||
| 266 | /// Convert gray to decimal | ||
| 267 | /// | ||
| 268 | /// Os Event provides a 64-bit timestamp gray-encoded. All we have to | ||
| 269 | /// do here is read both 32-bit halves of the register and convert | ||
| 270 | /// from gray to regular binary. | ||
| 271 | #[cfg(feature = "time-driver-os-timer")] | ||
| 272 | fn gray_to_dec(gray: u64) -> u64 { | ||
| 273 | let mut dec = gray; | ||
| 274 | |||
| 275 | dec ^= dec >> 1; | ||
| 276 | dec ^= dec >> 2; | ||
| 277 | dec ^= dec >> 4; | ||
| 278 | dec ^= dec >> 8; | ||
| 279 | dec ^= dec >> 16; | ||
| 280 | dec ^= dec >> 32; | ||
| 281 | |||
| 282 | dec | ||
| 283 | } | ||
| 284 | |||
| 285 | /// Convert decimal to gray | ||
| 286 | /// | ||
| 287 | /// Before writing match value to the target register, we must convert | ||
| 288 | /// it back into gray code. | ||
| 289 | #[cfg(feature = "time-driver-os-timer")] | ||
| 290 | fn dec_to_gray(dec: u64) -> u64 { | ||
| 291 | let gray = dec; | ||
| 292 | gray ^ (gray >> 1) | ||
| 293 | } | ||
| 294 | |||
| 295 | #[cfg(feature = "time-driver-os-timer")] | ||
| 296 | embassy_time_driver::time_driver_impl!(static DRIVER: OsTimer = OsTimer { | ||
| 297 | alarms: Mutex::const_new(CriticalSectionRawMutex::new(), AlarmState::new()), | ||
| 298 | queue: Mutex::new(RefCell::new(Queue::new())), | ||
| 299 | }); | ||
| 300 | |||
| 301 | #[cfg(feature = "time-driver-os-timer")] | ||
| 302 | struct OsTimer { | ||
| 303 | /// Timestamp at which to fire alarm. u64::MAX if no alarm is scheduled. | ||
| 304 | alarms: Mutex<CriticalSectionRawMutex, AlarmState>, | ||
| 305 | queue: Mutex<CriticalSectionRawMutex, RefCell<Queue>>, | ||
| 306 | } | ||
| 307 | |||
| 308 | #[cfg(feature = "time-driver-os-timer")] | ||
| 309 | impl OsTimer { | ||
| 310 | fn init(&'static self, irq_prio: crate::interrupt::Priority) { | ||
| 311 | // init alarms | ||
| 312 | critical_section::with(|cs| { | ||
| 313 | let alarm = DRIVER.alarms.borrow(cs); | ||
| 314 | alarm.timestamp.set(u64::MAX); | ||
| 315 | }); | ||
| 316 | |||
| 317 | // Enable clocks. Documentation advises AGAINST resetting this | ||
| 318 | // peripheral. | ||
| 319 | enable::<crate::peripherals::OS_EVENT>(); | ||
| 320 | |||
| 321 | interrupt::OS_EVENT.disable(); | ||
| 322 | |||
| 323 | // Make sure interrupt is masked | ||
| 324 | os().osevent_ctrl().modify(|_, w| w.ostimer_intena().clear_bit()); | ||
| 325 | |||
| 326 | // Default to the end of time | ||
| 327 | os().match_l().write(|w| unsafe { w.bits(0xffff_ffff) }); | ||
| 328 | os().match_h().write(|w| unsafe { w.bits(0xffff_ffff) }); | ||
| 329 | |||
| 330 | interrupt::OS_EVENT.unpend(); | ||
| 331 | interrupt::OS_EVENT.set_priority(irq_prio); | ||
| 332 | unsafe { interrupt::OS_EVENT.enable() }; | ||
| 333 | } | ||
| 334 | |||
| 335 | fn set_alarm(&self, cs: CriticalSection, timestamp: u64) -> bool { | ||
| 336 | let alarm = self.alarms.borrow(cs); | ||
| 337 | alarm.timestamp.set(timestamp); | ||
| 338 | |||
| 339 | let t = self.now(); | ||
| 340 | if timestamp <= t { | ||
| 341 | os().osevent_ctrl().modify(|_, w| w.ostimer_intena().clear_bit()); | ||
| 342 | alarm.timestamp.set(u64::MAX); | ||
| 343 | return false; | ||
| 344 | } | ||
| 345 | |||
| 346 | let gray_timestamp = dec_to_gray(timestamp); | ||
| 347 | |||
| 348 | os().match_l() | ||
| 349 | .write(|w| unsafe { w.bits(gray_timestamp as u32 & 0xffff_ffff) }); | ||
| 350 | os().match_h() | ||
| 351 | .write(|w| unsafe { w.bits((gray_timestamp >> 32) as u32) }); | ||
| 352 | os().osevent_ctrl().modify(|_, w| w.ostimer_intena().set_bit()); | ||
| 353 | |||
| 354 | true | ||
| 355 | } | ||
| 356 | |||
| 357 | #[cfg(feature = "rt")] | ||
| 358 | fn trigger_alarm(&self, cs: CriticalSection) { | ||
| 359 | let mut next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now()); | ||
| 360 | while !self.set_alarm(cs, next) { | ||
| 361 | next = self.queue.borrow(cs).borrow_mut().next_expiration(self.now()); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | |||
| 365 | #[cfg(feature = "rt")] | ||
| 366 | fn on_interrupt(&self) { | ||
| 367 | critical_section::with(|cs| { | ||
| 368 | if os().osevent_ctrl().read().ostimer_intrflag().bit_is_set() { | ||
| 369 | os().osevent_ctrl().modify(|_, w| w.ostimer_intena().clear_bit()); | ||
| 370 | self.trigger_alarm(cs); | ||
| 371 | } | ||
| 372 | }); | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | #[cfg(feature = "time-driver-os-timer")] | ||
| 377 | impl Driver for OsTimer { | ||
| 378 | fn now(&self) -> u64 { | ||
| 379 | let mut t = os().evtimerh().read().bits() as u64; | ||
| 380 | t <<= 32; | ||
| 381 | t |= os().evtimerl().read().bits() as u64; | ||
| 382 | gray_to_dec(t) | ||
| 383 | } | ||
| 384 | |||
| 385 | fn schedule_wake(&self, at: u64, waker: &core::task::Waker) { | ||
| 386 | critical_section::with(|cs| { | ||
| 387 | let mut queue = self.queue.borrow(cs).borrow_mut(); | ||
| 388 | |||
| 389 | if queue.schedule_wake(at, waker) { | ||
| 390 | let mut next = queue.next_expiration(self.now()); | ||
| 391 | while !self.set_alarm(cs, next) { | ||
| 392 | next = queue.next_expiration(self.now()); | ||
| 393 | } | ||
| 394 | } | ||
| 395 | }) | ||
| 396 | } | ||
| 397 | } | ||
| 398 | |||
| 399 | #[cfg(all(feature = "rt", feature = "time-driver-os-timer"))] | ||
| 400 | #[allow(non_snake_case)] | ||
| 401 | #[interrupt] | ||
| 402 | fn OS_EVENT() { | ||
| 403 | DRIVER.on_interrupt() | ||
| 404 | } | ||
| 405 | |||
| 252 | pub(crate) fn init(irq_prio: crate::interrupt::Priority) { | 406 | pub(crate) fn init(irq_prio: crate::interrupt::Priority) { |
| 253 | DRIVER.init(irq_prio) | 407 | DRIVER.init(irq_prio) |
| 254 | } | 408 | } |
diff --git a/examples/mimxrt6/Cargo.toml b/examples/mimxrt6/Cargo.toml index 8fc510c47..b0c56f003 100644 --- a/examples/mimxrt6/Cargo.toml +++ b/examples/mimxrt6/Cargo.toml | |||
| @@ -12,8 +12,8 @@ defmt-rtt = "1.0" | |||
| 12 | 12 | ||
| 13 | embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } | 13 | embassy-executor = { version = "0.7.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } |
| 14 | embassy-futures = { version = "0.1.1", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.1", path = "../../embassy-futures" } |
| 15 | embassy-imxrt = { version = "0.1.0", path = "../../embassy-imxrt", features = ["defmt", "mimxrt685s", "unstable-pac", "time", "time-driver-rtc"] } | 15 | embassy-imxrt = { version = "0.1.0", path = "../../embassy-imxrt", features = ["defmt", "mimxrt685s", "unstable-pac", "time", "time-driver-os-timer"] } |
| 16 | embassy-time = { version = "0.4", path = "../../embassy-time" } | 16 | embassy-time = { version = "0.4", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 17 | embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } | 17 | embassy-sync = { version = "0.6.2", path = "../../embassy-sync", features = ["defmt"] } |
| 18 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | 18 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 19 | embedded-hal-async = "1.0.0" | 19 | embedded-hal-async = "1.0.0" |
