diff options
| author | Ian McIntyre <ianpmcintyre@gmail.com> | 2022-08-02 06:21:12 -0400 |
|---|---|---|
| committer | Ian McIntyre <ianpmcintyre@gmail.com> | 2022-12-01 20:21:05 -0500 |
| commit | c7a9b9f3d4b9e71303c7b988d2bd916c2e4df9bc (patch) | |
| tree | 6d41ea7e433cac328fa165d45d1bc0cd71a1bf8f /board/src/lib.rs | |
First commit
Diffstat (limited to 'board/src/lib.rs')
| -rw-r--r-- | board/src/lib.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/board/src/lib.rs b/board/src/lib.rs new file mode 100644 index 0000000..24d746a --- /dev/null +++ b/board/src/lib.rs @@ -0,0 +1,107 @@ +//! A very simple, multi-board BSP for imxrt-rt-support examples. +#![no_std] + +use imxrt_ral as ral; + +cfg_if::cfg_if! { + if #[cfg(feature = "teensy4")] { + mod shared { pub mod imxrt10xx; } + use shared::imxrt10xx::prepare_pit; + + mod teensy4; + pub use teensy4::*; + } else if #[cfg(feature = "imxrt1010evk")] { + mod shared { pub mod imxrt10xx; } + use shared::imxrt10xx::prepare_pit; + + mod imxrt1010evk; + pub use imxrt1010evk::*; + } else if #[cfg(feature = "imxrt1170evk-cm7")] { + mod shared { pub mod imxrt11xx; } + use shared::imxrt11xx::prepare_pit; + + mod imxrt1170evk_cm7; + pub use imxrt1170evk_cm7::*; + } else { + compile_error!("No board feature selected!"); + } +} + +pub struct Pit(&'static ral::pit::RegisterBlock); + +impl Pit { + fn new(pit: &ral::pit::RegisterBlock, timer_delay_microseconds: u32) -> Self { + // Disable the PIT, just in case it was used by the boot ROM + ral::write_reg!(ral::pit, pit, MCR, MDIS: 1); + let timer = &pit.TIMER[0]; + // Reset channel 0 control; we'll use channel 0 for our timer + ral::write_reg!(ral::pit::timer, timer, TCTRL, 0); + // Set the counter value + ral::write_reg!(ral::pit::timer, timer, LDVAL, timer_delay_microseconds); + // Enable the PIT timer + ral::modify_reg!(ral::pit, pit, MCR, MDIS: 0); + Self(unsafe { core::mem::transmute(pit) }) + } + pub fn blocking_delay(&mut self) { + let timer = &self.0.TIMER[0]; + // Start counting! + ral::write_reg!(ral::pit::timer, timer, TCTRL, TEN: 1); + // Are we done? + while ral::read_reg!(ral::pit::timer, timer, TFLG, TIF == 0) {} + // We're done; clear the flag + ral::write_reg!(ral::pit::timer, timer, TFLG, TIF: 1); + // Turn off the timer + ral::write_reg!(ral::pit::timer, timer, TCTRL, TEN: 0); + } + pub fn loop_with_interrupts(&mut self) { + let timer = &self.0.TIMER[0]; + // Enable interrupts and start counting + ral::write_reg!(ral::pit::timer, timer, TCTRL, TIE: 1); + ral::modify_reg!(ral::pit::timer, timer, TCTRL, TEN: 1); + } + pub fn clear_interrupts(&mut self) { + let timer = &self.0.TIMER[0]; + while ral::read_reg!(ral::pit::timer, timer, TFLG, TIF == 1) { + ral::write_reg!(ral::pit::timer, timer, TFLG, TIF: 1); + } + } +} + +unsafe impl Send for Pit {} + +pub struct Led { + offset: u32, + port: &'static ral::gpio::RegisterBlock, +} + +impl Led { + fn new(offset: u32, port: &ral::gpio::RegisterBlock) -> Self { + let led = Led { + offset, + port: unsafe { core::mem::transmute(port) }, + }; + ral::modify_reg!(ral::gpio, port, GDIR, |gdir| gdir | led.mask()); + led + } + fn mask(&self) -> u32 { + 1 << self.offset + } + pub fn set(&self) { + ral::write_reg!(ral::gpio, self.port, DR_SET, self.mask()); + } + + pub fn clear(&self) { + ral::write_reg!(ral::gpio, self.port, DR_CLEAR, self.mask()); + } + + pub fn toggle(&self) { + ral::write_reg!(ral::gpio, self.port, DR_TOGGLE, self.mask()); + } +} + +unsafe impl Send for Led {} + +pub struct Resources { + pub led: crate::Led, + pub pit: crate::Pit, +} |
