lpc55s6x_hal/
lib.rs

1#![no_std]
2
3//! This HAL takes a layered approach.
4//!
5//! 1. raw PAC peripherals
6//! 1. HAL peripheral wrappers (under `peripherals`)
7//! 1. HAL drivers (under `drivers`, typically take ownership of one or more peripherals)
8//!
9//! The middle layer is quite thin, notably we model pins and the clock tree
10//! as drivers.
11//!
12//! In as much as possible, it is a goal for this HAL that drivers implement
13//! general interfaces (under `traits`).
14//!
15//! The main intended use case of this HAL is in the context of RTFM.
16//!
17//! To get started without RTFM, try something like:
18//! ```
19//! let hal = hal::new(); // layer 2
20//! let pins = hal::Pins::take().unwrap(); // layer 3
21//!
22//! let mut syscon = hal.syscon;
23//! let mut gpio = hal.gpio.enabled(&mut syscon);
24//! let mut iocon = hal.iocon.enabled(&mut syscon);
25//!
26//! let mut red_led = pins.pio1_6
27//!     .into_gpio_pin(&mut iocon, &mut gpio)
28//!     .into_output(Level::High);
29//!
30//! loop {
31//!     red.set_low().unwrap();
32//!     hal::wait_at_least(300_000);
33//!     red.set_high().unwrap();
34//!     hal::wait_at_least(300_000);
35//! }
36//! ```
37
38pub extern crate lpc55s6x_pac as raw;
39
40pub mod prelude;
41
42#[macro_use]
43pub mod macros;
44
45pub mod time;
46pub mod traits;
47pub mod typestates;
48
49pub mod peripherals;
50pub use peripherals::{
51    anactrl::Anactrl,
52    casper::Casper,
53    flash::Flash,
54    flexcomm::Flexcomm,
55    gpio::Gpio,
56    iocon::Iocon,
57    pmc::Pmc,
58    rng::Rng,
59    syscon::Syscon,
60    usbfs::Usbfs,
61    utick::Utick,
62};
63
64pub mod drivers;
65pub use drivers::{
66    ClockRequirements,
67    // Flash,
68    I2cMaster,
69    SpiMaster,
70    Pin,
71    Pins,
72    UsbBus,
73};
74
75
76/// This is the main (monolithic) entry point to the HAL for non-RTFM applications.
77/// For RTFM, use `hal::<Peripheral>::from(<raw_peripheral>)` as needed.
78pub fn new() -> Peripherals {
79    Peripherals::from((
80        raw::Peripherals::take().expect("raw device peripherals already taken elsewhere"),
81        raw::CorePeripherals::take().expect("raw core peripherals already taken elsewhere"),
82    ))
83}
84
85/// This is the entry point to the HAL API.
86///
87/// Before you can do anything else, you need to get an instance of this struct,
88/// via `hal::new` or `hal::steal`.
89#[allow(non_snake_case)]
90pub struct Peripherals {
91    /// Analog control
92    pub anactrl: Anactrl,
93
94    /// Cryptographic Accelerator and Signal Processing Engine with RAM sharing
95    pub casper: Casper,
96
97    /// Flash
98    pub flash: Flash,
99
100    /// Flexcomm Interface Serial Communication
101    pub flexcomm: Flexcomm,
102
103    /// General-purpose I/O (GPIO)
104    pub gpio: Gpio,
105
106    /// I/O configuration
107    pub iocon: Iocon,
108
109    /// Power configuration
110    pub pmc: Pmc,
111
112    /// System configuration
113    pub syscon: Syscon,
114
115    /// USB full-speed device or, not implemented, host
116    pub usbfs: Usbfs,
117
118    /// Micro-Tick Timer
119    pub utick: Utick,
120
121    /// Analog-to-Digital Converter (ADC) - not HAL-ified.
122    pub ADC0: raw::ADC0,
123
124    /// CRC engine - not HAL-ified.
125    pub CRC_ENGINE: raw::CRC_ENGINE,
126
127    /// Standard counter/timer (CTIMER) - not HAL-ified.
128    pub CTIMER0: raw::CTIMER0,
129
130    /// Stateful counter/timer (SCTIMER) - not HAL-ified.
131    pub SCT0: raw::SCT0,
132
133    /// CPUID - core peripheral
134    pub CPUID: raw::CPUID,
135
136    /// Debug Control Block (DCB) - core peripheral
137    pub DCB: raw::DCB,
138
139    /// Data Watchpoint and Trace unit (DWT) - core peripheral
140    pub DWT: raw::DWT,
141
142    /// Memory Protection Unit (MPU) - core peripheral
143    pub MPU: raw::MPU,
144
145    /// Nested Vector Interrupt Controller (NVIC) - core peripheral
146    pub NVIC: raw::NVIC,
147
148    /// System Control Block (SCB) - core peripheral
149    pub SCB: raw::SCB,
150
151    /// SysTick: System Timer - core peripheral
152    pub SYST: raw::SYST,
153}
154
155impl Peripherals {
156    fn new(p: raw::Peripherals, cp: raw::CorePeripherals) -> Self {
157        Peripherals {
158            // HAL peripherals
159            anactrl: Anactrl::from(p.ANACTRL),
160            casper: Casper::from(p.CASPER),
161            flash: Flash::from(p.FLASH),
162            flexcomm: (
163                peripherals::flexcomm::Flexcomm0::from((p.FLEXCOMM0, p.I2C0, p.I2S0, p.SPI0, p.USART0)),
164                peripherals::flexcomm::Flexcomm1::from((p.FLEXCOMM1, p.I2C1, p.I2S1, p.SPI1, p.USART1)),
165                peripherals::flexcomm::Flexcomm2::from((p.FLEXCOMM2, p.I2C2, p.I2S2, p.SPI2, p.USART2)),
166                peripherals::flexcomm::Flexcomm3::from((p.FLEXCOMM3, p.I2C3, p.I2S3, p.SPI3, p.USART3)),
167                peripherals::flexcomm::Flexcomm4::from((p.FLEXCOMM4, p.I2C4, p.I2S4, p.SPI4, p.USART4)),
168                peripherals::flexcomm::Flexcomm5::from((p.FLEXCOMM5, p.I2C5, p.I2S5, p.SPI5, p.USART5)),
169                peripherals::flexcomm::Flexcomm6::from((p.FLEXCOMM6, p.I2C6, p.I2S6, p.SPI6, p.USART6)),
170                peripherals::flexcomm::Flexcomm7::from((p.FLEXCOMM7, p.I2C7, p.I2S7, p.SPI7, p.USART7)),
171                peripherals::flexcomm::Flexcomm8::from((p.FLEXCOMM8, p.SPI8)),
172            ),
173            gpio: Gpio::from(p.GPIO),
174            iocon: Iocon::from(p.IOCON),
175            pmc: Pmc::from(p.PMC),
176            syscon: Syscon::from(p.SYSCON),
177            usbfs: Usbfs::from((p.USB0, p.USBFSH)),
178            utick: Utick::from(p.UTICK0),
179
180            // Raw peripherals
181            ADC0: p.ADC0,
182            CRC_ENGINE: p.CRC_ENGINE,
183            CTIMER0: p.CTIMER0,
184            SCT0: p.SCT0,
185
186            // Core peripherals
187            CPUID: cp.CPUID,
188            DCB: cp.DCB,
189            DWT: cp.DWT,
190            MPU: cp.MPU,
191            NVIC: cp.NVIC,
192            SCB: cp.SCB,
193            SYST: cp.SYST,
194        }
195    }
196
197    pub fn take() -> Option<Self> {
198        Some(Self::new(
199            raw::Peripherals::take()?,
200            raw::CorePeripherals::take()?,
201        ))
202    }
203
204    pub unsafe fn steal() -> Self {
205        Self::new(raw::Peripherals::steal(), raw::CorePeripherals::steal())
206    }
207
208}
209
210impl From<(raw::Peripherals, raw::CorePeripherals)> for Peripherals {
211    fn from(raw: (raw::Peripherals, raw::CorePeripherals)) -> Self {
212        Peripherals::new(raw.0, raw.1)
213    }
214}
215
216pub fn enable_cycle_counter() {
217    unsafe { &mut raw::CorePeripherals::steal().DWT }.enable_cycle_counter();
218}
219
220pub fn get_cycle_count() -> u32 {
221    raw::DWT::get_cycle_count()
222}
223
224/// Delay of last resort :-))
225pub fn wait_at_least(delay_usecs: u32) {
226    enable_cycle_counter();
227    let max_cpu_speed = 150_000_000; // via PLL
228    let period = max_cpu_speed / 1_000_000;
229
230    let current = get_cycle_count() as u64;
231    let mut target = current + period as u64 * delay_usecs as u64;
232    if target > 0xFFFF_FFFF {
233        // wait for wraparound
234        target -= 0xFFFF_FFFF;
235        while target < get_cycle_count() as u64 { continue; }
236    }
237    while target > get_cycle_count() as u64 { continue; }
238}