aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clocks/mod.rs6
-rw-r--r--src/config.rs2
-rw-r--r--src/lib.rs11
-rw-r--r--src/ostimer.rs88
4 files changed, 81 insertions, 26 deletions
diff --git a/src/clocks/mod.rs b/src/clocks/mod.rs
index 558fb0278..a12e125c6 100644
--- a/src/clocks/mod.rs
+++ b/src/clocks/mod.rs
@@ -867,7 +867,9 @@ macro_rules! impl_cc_gate {
867/// This module contains implementations of MRCC APIs, specifically of the [`Gate`] trait, 867/// This module contains implementations of MRCC APIs, specifically of the [`Gate`] trait,
868/// for various low level peripherals. 868/// for various low level peripherals.
869pub(crate) mod gate { 869pub(crate) mod gate {
870 use super::periph_helpers::{AdcConfig, LpuartConfig, NoConfig, OsTimerConfig}; 870 #[cfg(not(feature = "time"))]
871 use super::periph_helpers::OsTimerConfig;
872 use super::periph_helpers::{AdcConfig, LpuartConfig, NoConfig};
871 use super::*; 873 use super::*;
872 874
873 // These peripherals have no additional upstream clocks or configuration required 875 // These peripherals have no additional upstream clocks or configuration required
@@ -888,7 +890,9 @@ pub(crate) mod gate {
888 890
889 // These peripherals DO have meaningful configuration, and could fail if the system 891 // These peripherals DO have meaningful configuration, and could fail if the system
890 // clocks do not match their needs. 892 // clocks do not match their needs.
893 #[cfg(not(feature = "time"))]
891 impl_cc_gate!(OSTIMER0, mrcc_glb_cc1, mrcc_glb_rst1, ostimer0, OsTimerConfig); 894 impl_cc_gate!(OSTIMER0, mrcc_glb_cc1, mrcc_glb_rst1, ostimer0, OsTimerConfig);
895
892 impl_cc_gate!(LPUART2, mrcc_glb_cc0, mrcc_glb_rst0, lpuart2, LpuartConfig); 896 impl_cc_gate!(LPUART2, mrcc_glb_cc0, mrcc_glb_rst0, lpuart2, LpuartConfig);
893 impl_cc_gate!(ADC1, mrcc_glb_cc1, mrcc_glb_rst1, adc1, AdcConfig); 897 impl_cc_gate!(ADC1, mrcc_glb_cc1, mrcc_glb_rst1, adc1, AdcConfig);
894} 898}
diff --git a/src/config.rs b/src/config.rs
index 0939c11f1..9c0d47ecb 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,6 +5,7 @@ use crate::interrupt::Priority;
5 5
6#[non_exhaustive] 6#[non_exhaustive]
7pub struct Config { 7pub struct Config {
8 #[cfg(feature = "time")]
8 pub time_interrupt_priority: Priority, 9 pub time_interrupt_priority: Priority,
9 pub rtc_interrupt_priority: Priority, 10 pub rtc_interrupt_priority: Priority,
10 pub adc_interrupt_priority: Priority, 11 pub adc_interrupt_priority: Priority,
@@ -14,6 +15,7 @@ pub struct Config {
14impl Default for Config { 15impl Default for Config {
15 fn default() -> Self { 16 fn default() -> Self {
16 Self { 17 Self {
18 #[cfg(feature = "time")]
17 time_interrupt_priority: Priority::from(0), 19 time_interrupt_priority: Priority::from(0),
18 rtc_interrupt_priority: Priority::from(0), 20 rtc_interrupt_priority: Priority::from(0),
19 adc_interrupt_priority: Priority::from(0), 21 adc_interrupt_priority: Priority::from(0),
diff --git a/src/lib.rs b/src/lib.rs
index c885ecc50..e93ff61a6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,9 @@ pub mod lpuart;
14pub mod ostimer; 14pub mod ostimer;
15pub mod rtc; 15pub mod rtc;
16 16
17#[cfg(feature = "rt")]
18pub use crate::pac::NVIC_PRIO_BITS;
19
17#[rustfmt::skip] 20#[rustfmt::skip]
18embassy_hal_internal::peripherals!( 21embassy_hal_internal::peripherals!(
19 ADC0, 22 ADC0,
@@ -83,6 +86,8 @@ embassy_hal_internal::peripherals!(
83 MBC0, 86 MBC0,
84 MRCC0, 87 MRCC0,
85 OPAMP0, 88 OPAMP0,
89
90 #[cfg(not(feature = "time"))]
86 OSTIMER0, 91 OSTIMER0,
87 92
88 P0_0, 93 P0_0,
@@ -335,7 +340,6 @@ pub use interrupt::InterruptExt;
335pub use mcxa_pac as pac; 340pub use mcxa_pac as pac;
336#[cfg(not(feature = "unstable-pac"))] 341#[cfg(not(feature = "unstable-pac"))]
337pub(crate) use mcxa_pac as pac; 342pub(crate) use mcxa_pac as pac;
338pub use ostimer::Ostimer0 as Ostimer0Token;
339pub use rtc::Rtc0 as Rtc0Token; 343pub use rtc::Rtc0 as Rtc0Token;
340 344
341/// Initialize HAL with configuration (mirrors embassy-imxrt style). Minimal: just take peripherals. 345/// Initialize HAL with configuration (mirrors embassy-imxrt style). Minimal: just take peripherals.
@@ -343,6 +347,7 @@ pub use rtc::Rtc0 as Rtc0Token;
343pub fn init(cfg: crate::config::Config) -> Peripherals { 347pub fn init(cfg: crate::config::Config) -> Peripherals {
344 let peripherals = Peripherals::take(); 348 let peripherals = Peripherals::take();
345 // Apply user-configured priority early; enabling is left to examples/apps 349 // Apply user-configured priority early; enabling is left to examples/apps
350 #[cfg(feature = "time")]
346 crate::interrupt::OS_EVENT.set_priority(cfg.time_interrupt_priority); 351 crate::interrupt::OS_EVENT.set_priority(cfg.time_interrupt_priority);
347 // Apply user-configured priority early; enabling is left to examples/apps 352 // Apply user-configured priority early; enabling is left to examples/apps
348 crate::interrupt::RTC.set_priority(cfg.rtc_interrupt_priority); 353 crate::interrupt::RTC.set_priority(cfg.rtc_interrupt_priority);
@@ -352,6 +357,10 @@ pub fn init(cfg: crate::config::Config) -> Peripherals {
352 // Configure clocks 357 // Configure clocks
353 crate::clocks::init(cfg.clock_cfg).unwrap(); 358 crate::clocks::init(cfg.clock_cfg).unwrap();
354 359
360 // Initialize embassy-time global driver backed by OSTIMER0
361 #[cfg(feature = "time")]
362 crate::ostimer::time_driver::init(crate::config::Config::default().time_interrupt_priority, 1_000_000);
363
355 // Enable GPIO clocks 364 // Enable GPIO clocks
356 unsafe { 365 unsafe {
357 _ = crate::clocks::enable_and_reset::<crate::peripherals::PORT0>(&crate::clocks::periph_helpers::NoConfig); 366 _ = crate::clocks::enable_and_reset::<crate::peripherals::PORT0>(&crate::clocks::periph_helpers::NoConfig);
diff --git a/src/ostimer.rs b/src/ostimer.rs
index cd5451b53..c51812e3d 100644
--- a/src/ostimer.rs
+++ b/src/ostimer.rs
@@ -35,7 +35,6 @@ use crate::clocks::periph_helpers::{OsTimerConfig, OstimerClockSel};
35use crate::clocks::{assert_reset, enable_and_reset, is_reset_released, release_reset, Gate, PoweredClock}; 35use crate::clocks::{assert_reset, enable_and_reset, is_reset_released, release_reset, Gate, PoweredClock};
36use crate::interrupt::InterruptExt; 36use crate::interrupt::InterruptExt;
37use crate::pac; 37use crate::pac;
38use crate::peripherals::OSTIMER0;
39 38
40// PAC defines the shared RegisterBlock under `ostimer0`. 39// PAC defines the shared RegisterBlock under `ostimer0`.
41type Regs = pac::ostimer0::RegisterBlock; 40type Regs = pac::ostimer0::RegisterBlock;
@@ -283,15 +282,15 @@ impl<'d, I: Instance> Ostimer<'d, I> {
283 .write(|w| w.ostimer_intrflag().clear_bit_by_one().ostimer_intena().clear_bit()); 282 .write(|w| w.ostimer_intrflag().clear_bit_by_one().ostimer_intena().clear_bit());
284 283
285 unsafe { 284 unsafe {
286 assert_reset::<OSTIMER0>(); 285 assert_reset::<I>();
287 286
288 for _ in 0..RESET_STABILIZE_SPINS { 287 for _ in 0..RESET_STABILIZE_SPINS {
289 cortex_m::asm::nop(); 288 cortex_m::asm::nop();
290 } 289 }
291 290
292 release_reset::<OSTIMER0>(); 291 release_reset::<I>();
293 292
294 while !is_reset_released::<OSTIMER0>() { 293 while !is_reset_released::<I>() {
295 cortex_m::asm::nop(); 294 cortex_m::asm::nop();
296 } 295 }
297 } 296 }
@@ -490,9 +489,7 @@ pub trait Instance: Gate<MrccPeriphConfig = OsTimerConfig> + PeripheralType {
490 fn ptr() -> *const Regs; 489 fn ptr() -> *const Regs;
491} 490}
492 491
493// Token for OSTIMER0 provided by embassy-hal-internal peripherals macro. 492#[cfg(not(feature = "time"))]
494pub type Ostimer0 = crate::peripherals::OSTIMER0;
495
496impl Instance for crate::peripherals::OSTIMER0 { 493impl Instance for crate::peripherals::OSTIMER0 {
497 #[inline(always)] 494 #[inline(always)]
498 fn ptr() -> *const Regs { 495 fn ptr() -> *const Regs {
@@ -500,14 +497,6 @@ impl Instance for crate::peripherals::OSTIMER0 {
500 } 497 }
501} 498}
502 499
503// Also implement Instance for the Peri wrapper type
504// impl Instance for embassy_hal_internal::Peri<'_, crate::peripherals::OSTIMER0> {
505// #[inline(always)]
506// fn ptr() -> *const Regs {
507// pac::Ostimer0::ptr()
508// }
509// }
510
511#[inline(always)] 500#[inline(always)]
512fn bin_to_gray(x: u64) -> u64 { 501fn bin_to_gray(x: u64) -> u64 {
513 x ^ (x >> 1) 502 x ^ (x >> 1)
@@ -523,6 +512,7 @@ fn gray_to_bin(gray: u64) -> u64 {
523 bin 512 bin
524} 513}
525 514
515#[cfg(feature = "time")]
526pub mod time_driver { 516pub mod time_driver {
527 use core::sync::atomic::Ordering; 517 use core::sync::atomic::Ordering;
528 use core::task::Waker; 518 use core::task::Waker;
@@ -537,7 +527,55 @@ pub mod time_driver {
537 use crate::clocks::periph_helpers::{OsTimerConfig, OstimerClockSel}; 527 use crate::clocks::periph_helpers::{OsTimerConfig, OstimerClockSel};
538 use crate::clocks::{enable_and_reset, PoweredClock}; 528 use crate::clocks::{enable_and_reset, PoweredClock};
539 use crate::pac; 529 use crate::pac;
540 use crate::peripherals::OSTIMER0; 530
531 #[allow(non_camel_case_types)]
532 pub(crate) struct _OSTIMER0_TIME_DRIVER {
533 _x: (),
534 }
535
536 // #[cfg(feature = "time")]
537 // impl_cc_gate!(_OSTIMER0_TIME_DRIVER, mrcc_glb_cc1, mrcc_glb_rst1, ostimer0, OsTimerConfig);
538
539 impl crate::clocks::Gate for _OSTIMER0_TIME_DRIVER {
540 type MrccPeriphConfig = crate::clocks::periph_helpers::OsTimerConfig;
541
542 #[inline]
543 unsafe fn enable_clock() {
544 let mrcc = unsafe { pac::Mrcc0::steal() };
545 mrcc.mrcc_glb_cc1().modify(|_, w| w.ostimer0().enabled());
546 }
547
548 #[inline]
549 unsafe fn disable_clock() {
550 let mrcc = unsafe { pac::Mrcc0::steal() };
551 mrcc.mrcc_glb_cc1().modify(|_r, w| w.ostimer0().disabled());
552 }
553
554 #[inline]
555 fn is_clock_enabled() -> bool {
556 let mrcc = unsafe { pac::Mrcc0::steal() };
557 mrcc.mrcc_glb_cc1().read().ostimer0().is_enabled()
558 }
559
560 #[inline]
561 unsafe fn release_reset() {
562 let mrcc = unsafe { pac::Mrcc0::steal() };
563 mrcc.mrcc_glb_rst1().modify(|_, w| w.ostimer0().enabled());
564 }
565
566 #[inline]
567 unsafe fn assert_reset() {
568 let mrcc = unsafe { pac::Mrcc0::steal() };
569 mrcc.mrcc_glb_rst1().modify(|_, w| w.ostimer0().disabled());
570 }
571
572 #[inline]
573 fn is_reset_released() -> bool {
574 let mrcc = unsafe { pac::Mrcc0::steal() };
575 mrcc.mrcc_glb_rst1().read().ostimer0().is_enabled()
576 }
577 }
578
541 pub struct Driver; 579 pub struct Driver;
542 static TIMER_WAKER: AtomicWaker = AtomicWaker::new(); 580 static TIMER_WAKER: AtomicWaker = AtomicWaker::new();
543 581
@@ -625,7 +663,7 @@ pub mod time_driver {
625 /// The embassy_time_driver macro handles driver registration automatically. 663 /// The embassy_time_driver macro handles driver registration automatically.
626 pub fn init(priority: crate::interrupt::Priority, frequency_hz: u64) { 664 pub fn init(priority: crate::interrupt::Priority, frequency_hz: u64) {
627 let _clock_freq = unsafe { 665 let _clock_freq = unsafe {
628 enable_and_reset::<OSTIMER0>(&OsTimerConfig { 666 enable_and_reset::<_OSTIMER0_TIME_DRIVER>(&OsTimerConfig {
629 power: PoweredClock::AlwaysEnabled, 667 power: PoweredClock::AlwaysEnabled,
630 source: OstimerClockSel::Clk1M, 668 source: OstimerClockSel::Clk1M,
631 }) 669 })
@@ -694,12 +732,14 @@ pub mod time_driver {
694 } 732 }
695 }); 733 });
696 } 734 }
735}
697 736
698 /// Type-level handler to be used with bind_interrupts! for OS_EVENT. 737#[cfg(feature = "time")]
699 pub struct OsEventHandler; 738use crate::pac::interrupt;
700 impl crate::interrupt::typelevel::Handler<crate::interrupt::typelevel::OS_EVENT> for OsEventHandler { 739
701 unsafe fn on_interrupt() { 740#[cfg(feature = "time")]
702 on_interrupt(); 741#[allow(non_snake_case)]
703 } 742#[interrupt]
704 } 743fn OS_EVENT() {
744 time_driver::on_interrupt()
705} 745}