diff options
Diffstat (limited to 'embassy-imxrt/src/lib.rs')
| -rw-r--r-- | embassy-imxrt/src/lib.rs | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/embassy-imxrt/src/lib.rs b/embassy-imxrt/src/lib.rs new file mode 100644 index 000000000..d56d993c3 --- /dev/null +++ b/embassy-imxrt/src/lib.rs | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![allow(async_fn_in_trait)] | ||
| 3 | #![doc = include_str!("../README.md")] | ||
| 4 | #![warn(missing_docs)] | ||
| 5 | |||
| 6 | //! ## Feature flags | ||
| 7 | #![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)] | ||
| 8 | |||
| 9 | #[cfg(not(any(feature = "mimxrt633s", feature = "mimxrt685s",)))] | ||
| 10 | compile_error!( | ||
| 11 | "No chip feature activated. You must activate exactly one of the following features: | ||
| 12 | mimxrt633s, | ||
| 13 | mimxrt685s, | ||
| 14 | " | ||
| 15 | ); | ||
| 16 | |||
| 17 | // This mod MUST go first, so that the others see its macros. | ||
| 18 | pub(crate) mod fmt; | ||
| 19 | |||
| 20 | pub mod clocks; | ||
| 21 | pub mod gpio; | ||
| 22 | pub mod iopctl; | ||
| 23 | |||
| 24 | // This mod MUST go last, so that it sees all the `impl_foo!' macros | ||
| 25 | #[cfg_attr(feature = "mimxrt633s", path = "chips/mimxrt633s.rs")] | ||
| 26 | #[cfg_attr(feature = "mimxrt685s", path = "chips/mimxrt685s.rs")] | ||
| 27 | mod chip; | ||
| 28 | |||
| 29 | // Reexports | ||
| 30 | pub use chip::interrupts::*; | ||
| 31 | #[cfg(feature = "unstable-pac")] | ||
| 32 | pub use chip::pac; | ||
| 33 | #[cfg(not(feature = "unstable-pac"))] | ||
| 34 | pub(crate) use chip::pac; | ||
| 35 | pub use chip::{peripherals, Peripherals}; | ||
| 36 | pub use embassy_hal_internal::{Peri, PeripheralType}; | ||
| 37 | |||
| 38 | #[cfg(feature = "rt")] | ||
| 39 | pub use crate::pac::NVIC_PRIO_BITS; | ||
| 40 | |||
| 41 | /// Macro to bind interrupts to handlers. | ||
| 42 | /// | ||
| 43 | /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) | ||
| 44 | /// and implements the right \[`Binding`\]s for it. You can pass this struct to drivers to | ||
| 45 | /// prove at compile-time that the right interrupts have been bound. | ||
| 46 | /// | ||
| 47 | /// Example of how to bind one interrupt: | ||
| 48 | /// | ||
| 49 | /// ```rust,ignore | ||
| 50 | /// use embassy_imxrt::{bind_interrupts, flexspi, peripherals}; | ||
| 51 | /// | ||
| 52 | /// bind_interrupts!(struct Irqs { | ||
| 53 | /// FLEXSPI_IRQ => flexspi::InterruptHandler<peripherals::FLEXSPI>; | ||
| 54 | /// }); | ||
| 55 | /// ``` | ||
| 56 | /// | ||
| 57 | // developer note: this macro can't be in `embassy-hal-internal` due to the use of `$crate`. | ||
| 58 | #[macro_export] | ||
| 59 | macro_rules! bind_interrupts { | ||
| 60 | ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { | ||
| 61 | #[derive(Copy, Clone)] | ||
| 62 | $vis struct $name; | ||
| 63 | |||
| 64 | $( | ||
| 65 | #[allow(non_snake_case)] | ||
| 66 | #[no_mangle] | ||
| 67 | unsafe extern "C" fn $irq() { | ||
| 68 | $( | ||
| 69 | <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt(); | ||
| 70 | )* | ||
| 71 | } | ||
| 72 | |||
| 73 | $( | ||
| 74 | unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {} | ||
| 75 | )* | ||
| 76 | )* | ||
| 77 | }; | ||
| 78 | } | ||
| 79 | |||
| 80 | /// HAL configuration for iMX RT600. | ||
| 81 | pub mod config { | ||
| 82 | use crate::clocks::ClockConfig; | ||
| 83 | |||
| 84 | /// HAL configuration passed when initializing. | ||
| 85 | #[non_exhaustive] | ||
| 86 | pub struct Config { | ||
| 87 | /// Clock configuration. | ||
| 88 | pub clocks: ClockConfig, | ||
| 89 | } | ||
| 90 | |||
| 91 | impl Default for Config { | ||
| 92 | fn default() -> Self { | ||
| 93 | Self { | ||
| 94 | clocks: ClockConfig::crystal(), | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | impl Config { | ||
| 100 | /// Create a new configuration with the provided clock config. | ||
| 101 | pub fn new(clocks: ClockConfig) -> Self { | ||
| 102 | Self { clocks } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | /// Initialize the `embassy-imxrt` HAL with the provided configuration. | ||
| 108 | /// | ||
| 109 | /// This returns the peripheral singletons that can be used for creating drivers. | ||
| 110 | /// | ||
| 111 | /// This should only be called once at startup, otherwise it panics. | ||
| 112 | pub fn init(config: config::Config) -> Peripherals { | ||
| 113 | // Do this first, so that it panics if user is calling `init` a second time | ||
| 114 | // before doing anything important. | ||
| 115 | let peripherals = Peripherals::take(); | ||
| 116 | |||
| 117 | unsafe { | ||
| 118 | if let Err(e) = clocks::init(config.clocks) { | ||
| 119 | error!("unable to initialize Clocks for reason: {:?}", e); | ||
| 120 | // Panic here? | ||
| 121 | } | ||
| 122 | gpio::init(); | ||
| 123 | } | ||
| 124 | |||
| 125 | peripherals | ||
| 126 | } | ||
| 127 | |||
| 128 | pub(crate) mod sealed { | ||
| 129 | pub trait Sealed {} | ||
| 130 | } | ||
