1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! A Rust board support package (BSP) for the Teensy 4. Supports the Teensy 4.0 and
//! 4.1 boards.
//!
//! Peripherals are re-exported from the [`imxrt-hal`](imxrt_hal)
//! hardware abstraction layer. See the HAL's documentation for more information on creating
//! and using peripherals.
//!
//! # Runtime
//!
//! The `teensy4-bsp` use the [`cortex-m-rt`] crate to provide a runtime. Enable runtime support using
//! the `"rt"` feature. To properly link your program, you **must link with the `t4link.x` linker
//! script**.
//!
//! [`cortex-m-rt`]: https://crates.io/crates/cortex-m-rt
//!
//! The `teensy4-bsp` emits a `cortex-m-rt`-compatible linker script. The layout supports the i.MX RT's boot requirements
//! and advanced memory features. Specifically, the layout includes the image vector table (IVT) and boot data
//! that's necessary for i.MX RT processors. Additionally, the layout specifies the FlexSPI configuration block's (FCB)
//! FLASH location. Finally, the linker script places all instructions in ITCM, and all data in DTCM.
//!
//! The `teensy4-bsp` provides its own reset hander. The custom reset handler
//!
//! - initalizes TCM regions
//! - copies instructions into ITCM
//! - copies the vector table into DTCM, and sets VTOR
//! - set's the CCM's low-power setting
//!
//! The reset handler then calls the `cortex-m-rt` entrypoint to finish memory initialization and invoke your program's
//! `main()`.
//!
//! # Features
//!
//! The `teensy4-bsp` supports these features:
//!
//! | Flag            |         Description                                                   | Default? |
//! | --------------- | --------------------------------------------------------------------- | -------- |
//! | `"usb-logging"` | Adds support for logging over USB with the `log` crate                | ✓        |
//! | `"rt"`          | Adds runtime support using `cortex-m-rt`                              |          |
//! | `"rtic"`        | Adds support for using the BSP peripherals with RTIC                  |          |
//!
//! Proper RTIC support requires that you disable the BSP's default features. You may combine `"rtic"` with
//! either `"rt"` and `"usb-logging"`.
//!
//! ```toml
//! [dependencies.teensy4-bsp]
//! default-features = false
//! features = ["rtic",  "rt"]
//! version = # ...
//! ```
//!
//! # Pins
//!
//! The BSP helps you convert all the i.MX RT processor pads into your Teensy 4's pins.
//! From these pins, you may construct peripherals and perform I/O. See the [`pins`] module
//! for more information.
//!
//! # Examples
//!
//! Turn on a Teensy 4.0's LED:
//!
//! ```no_run
//! use cortex_m::asm::wfi;
//! use teensy4_bsp as bsp;
//!
//! use embedded_hal::digital::v2::OutputPin;
//!
//! let peripherals = bsp::Peripherals::take().unwrap();
//! let pins = bsp::pins::t40::from_pads(peripherals.iomuxc);
//! let mut led = bsp::configure_led(pins.p13);
//!
//! loop {
//!     led.set_high().unwrap();
//!     wfi();
//! }
//! ```
//!
//! See more examples in the project's repository.

#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]

// Need to reference this so that it doesn't get stripped out
#[cfg(target_arch = "arm")]
extern crate teensy4_fcb;

pub use teensy4_pins as pins;

/// Use [`teensy4_bsp::pins::common`](crate::pins::common).
///
/// This module will be removed in the next breaking release.
#[deprecated(since = "0.3.0", note = "Use teensy4_bsp::pins::common")]
pub mod common {
    pub use crate::pins::common::*;
}
/// Use [`teensy4_bsp::pins::t40`](crate::pins::t40).
///
/// This module will be removed in the next breaking release.
#[deprecated(since = "0.3.0", note = "Use teensy4_bsp::pins::t40")]
pub mod t40 {
    pub use crate::pins::t40::*;
}
/// Use [`teensy4_bsp::pins::t41`](crate::pins::t41).
///
/// This module will be removed in the next breaking release.
#[deprecated(since = "0.3.0", note = "Use teensy4_bsp::pins::t41")]
pub mod t41 {
    pub use crate::pins::t41::*;
}

#[cfg(all(target_arch = "arm", feature = "rt"))]
mod rt;
#[cfg(feature = "usb-logging")]
#[cfg_attr(docsrs, doc(cfg(feature = "usb-logging")))]
pub mod usb;

#[cfg(all(target_arch = "arm", feature = "rt"))]
pub use rt::{dtcm_heap_start, heap_len, heap_start};

pub use hal::ral::interrupt;
// `rtic` expects these in the root.
#[doc(hidden)]
#[cfg(feature = "rtic")]
pub use hal::ral::{interrupt as Interrupt, NVIC_PRIO_BITS};

pub use hal::Peripherals;
pub use imxrt_hal as hal;

/// The LED
///
/// See [`configure_led`](configure_led()) to prepare the LED.
pub type Led = hal::gpio::GPIO<common::P13, hal::gpio::Output>;

/// Configure the board's LED
///
/// Returns a GPIO that's physically tied to the LED. Use the returned handle
/// to drive the LED.
pub fn configure_led(pad: common::P13) -> Led {
    let mut led = hal::gpio::GPIO::new(pad);
    led.set_fast(true);
    led.output()
}

/// SYSTICK external clock frequency.
///
/// This represents the frequency (Hz) of the external clock
/// that can supply SYSTICK.
// See Section 12.3.2.1 of the reference manual. The note
// explains that the 24MHz clock is divided down to 100KHz
// before reaching SYSTICK.
pub const EXT_SYSTICK_HZ: u32 = 100_000;