diff options
Diffstat (limited to 'crates/imxrt1170evk/src/lib.rs')
| -rw-r--r-- | crates/imxrt1170evk/src/lib.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/crates/imxrt1170evk/src/lib.rs b/crates/imxrt1170evk/src/lib.rs new file mode 100644 index 0000000..b626843 --- /dev/null +++ b/crates/imxrt1170evk/src/lib.rs @@ -0,0 +1,117 @@ +#![no_std] +#![feature(rustc_private)] +extern crate fusible; + +use core::pin::Pin; + +use imxrt_ral as ral; +use imxrt_rt as _; +use imxrt1170evk_fcb as _; +use rust_threadx_cortex_m as _; +use rust_threadx_stdio_semihosting as _; + +#[doc(hidden)] +#[unsafe(no_mangle)] +pub unsafe extern "C" fn _tx_initialize_low_level() { + use cortex_m::{ + Peripherals, + peripheral::{scb::SystemHandler, syst::SystClkSource}, + }; + + cortex_m::interrupt::disable(); + + unsafe { + let Peripherals { + mut SYST, mut SCB, .. + } = Peripherals::steal(); + + SCB.set_priority(SystemHandler::SysTick, 0x40); + SCB.set_priority(SystemHandler::PendSV, 0xff); + SCB.set_priority(SystemHandler::SVCall, 0xff); + + SYST.set_clock_source(SystClkSource::External); + SYST.set_reload(100_000 / 100 - 1); + SYST.clear_current(); + SYST.enable_interrupt(); + SYST.enable_counter(); + } + + unsafe { + use ral::ccm; + + let ccm = ccm::CCM::instance(); + let clock_root = &ccm.CLOCK_ROOT[8]; + ral::modify_reg!(ccm::clockroot, clock_root, CLOCK_ROOT_CONTROL, MUX: 1, DIV: 240 - 1); + } + + unsafe { + use ral::iomuxc; + let iomuxc = iomuxc::IOMUXC::instance(); + + ral::write_reg!(iomuxc, iomuxc, SW_MUX_CTL_PAD_GPIO_AD_04, MUX_MODE: 5, SION: 0); + + ral::write_reg!(iomuxc, iomuxc, SW_PAD_CTL_PAD_GPIO_AD_04, PUE: 0); + } + + unsafe { + use ral::gpio; + let gpio3 = gpio::GPIO3::instance(); + + const GPIO3_OUTPUTS: u32 = led::MASK; + + ral::write_reg!(gpio, gpio3, GDIR, GPIO3_OUTPUTS); + } +} + +/// Controls the LED. +pub mod led { + use crate::ral::gpio; + + pub(crate) const MASK: u32 = 1 << 3; + + /// Turn on the LED. + #[inline] + pub fn set() { + unsafe { crate::ral::write_reg!(gpio, gpio::GPIO3, DR_SET, MASK) }; + } + + /// Turn off the LED. + #[inline] + pub fn clear() { + unsafe { crate::ral::write_reg!(gpio, gpio::GPIO3, DR_CLEAR, MASK) }; + } + + /// Toggle the LED. + /// + /// This is achieved in hardware, without reading the current state + /// of the LED. It's usually more efficient. + #[inline] + pub fn toggle() { + unsafe { crate::ral::write_reg!(gpio, gpio::GPIO3, DR_TOGGLE, MASK) }; + } + + /// Drive the LED on or off. + #[inline] + pub fn drive(value: bool) { + if value { set() } else { clear() } + } +} + +use fusible::thread::{StaticStack, Thread, ThreadContext}; +static STACK: StaticStack<512> = StaticStack::new(); +static THREAD: ThreadContext = Thread::context(); + +#[unsafe(no_mangle)] +#[doc(hidden)] +pub extern "C" fn __rust_threadx_app_define() { + Thread::create( + Pin::static_ref(&THREAD), + STACK.take().unwrap(), + &Default::default(), + || loop { + fusible::thread::sleep(25); + led::toggle(); + }, + ) + .unwrap(); +} |
