diff options
Diffstat (limited to 'src/ostimer.rs')
| -rw-r--r-- | src/ostimer.rs | 88 |
1 files changed, 64 insertions, 24 deletions
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}; | |||
| 35 | use crate::clocks::{assert_reset, enable_and_reset, is_reset_released, release_reset, Gate, PoweredClock}; | 35 | use crate::clocks::{assert_reset, enable_and_reset, is_reset_released, release_reset, Gate, PoweredClock}; |
| 36 | use crate::interrupt::InterruptExt; | 36 | use crate::interrupt::InterruptExt; |
| 37 | use crate::pac; | 37 | use crate::pac; |
| 38 | use crate::peripherals::OSTIMER0; | ||
| 39 | 38 | ||
| 40 | // PAC defines the shared RegisterBlock under `ostimer0`. | 39 | // PAC defines the shared RegisterBlock under `ostimer0`. |
| 41 | type Regs = pac::ostimer0::RegisterBlock; | 40 | type 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"))] |
| 494 | pub type Ostimer0 = crate::peripherals::OSTIMER0; | ||
| 495 | |||
| 496 | impl Instance for crate::peripherals::OSTIMER0 { | 493 | impl 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)] |
| 512 | fn bin_to_gray(x: u64) -> u64 { | 501 | fn 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")] | ||
| 526 | pub mod time_driver { | 516 | pub 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; | 738 | use 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 | } | 743 | fn OS_EVENT() { |
| 744 | time_driver::on_interrupt() | ||
| 705 | } | 745 | } |
