1#![no_std]
2#![allow(static_mut_refs)]
3
4pub extern crate lpc55_pac as raw;
40
41pub mod prelude;
42
43pub mod macros;
45
46pub mod time;
47pub mod traits;
48
49pub mod typestates;
50use core::ptr::copy_nonoverlapping;
51
52pub use typestates::init_state::Enabled;
53
54pub mod peripherals;
55pub use peripherals::{
56 adc::Adc, anactrl::Anactrl, casper::Casper, ctimer::Ctimers, dma::Dma, flash::Flash,
57 flexcomm::Flexcomm, gint::Gint, gpio::Gpio, hashcrypt::Hashcrypt, inputmux::InputMux,
58 iocon::Iocon, pfr::Pfr, pint::Pint, pmc::Pmc, prince::Prince, puf::Puf, rng::Rng, rtc::Rtc,
59 syscon::Syscon, usbfs::Usbfs, usbhs::Usbhs, utick::Utick,
60};
61
62pub mod drivers;
63pub use drivers::{ClockRequirements, FlashGordon, I2cMaster, Pin, Pins, SpiMaster, UsbBus};
64
65pub fn new() -> Peripherals {
66 take().unwrap()
67}
68
69pub fn take() -> Option<Peripherals> {
72 Some(Peripherals::from((
73 raw::Peripherals::take()?, raw::CorePeripherals::take()?, )))
76}
77
78#[allow(non_snake_case)]
83pub struct Peripherals {
84 pub adc: Adc,
86
87 pub anactrl: Anactrl,
89
90 pub casper: Casper,
92
93 pub ctimer: Ctimers,
95
96 pub dma: Dma,
98
99 pub flash: Flash,
101
102 pub flexcomm: Flexcomm,
104
105 pub gint: Gint,
107
108 pub gpio: Gpio,
110
111 pub hashcrypt: Hashcrypt,
113
114 pub inputmux: InputMux,
116
117 pub iocon: Iocon,
119
120 pub pint: Pint,
122
123 pub pfr: Pfr,
125
126 pub pmc: Pmc,
128
129 pub prince: Prince,
131
132 pub puf: Puf,
134
135 pub rng: Rng,
137
138 pub rtc: Rtc,
140
141 pub syscon: Syscon,
143
144 pub usbfs: Usbfs,
146
147 pub usbhs: Usbhs,
149
150 pub utick: Utick,
152
153 pub CRC_ENGINE: raw::CRC_ENGINE,
155
156 pub FLASH_CMPA: raw::FLASH_CMPA,
157 pub FLASH_CFPA0: raw::FLASH_CFPA0,
158
159 pub SCT0: raw::SCT0,
161
162 pub SAU: raw::SAU,
164
165 pub AHB_SECURE_CTRL: raw::AHB_SECURE_CTRL,
167
168 pub CPUID: raw::CPUID,
170
171 pub DCB: raw::DCB,
173
174 pub DWT: raw::DWT,
176
177 pub MPU: raw::MPU,
179
180 pub NVIC: raw::NVIC,
182
183 pub SCB: raw::SCB,
185
186 pub wwdt: raw::WWDT,
188
189 pub SYST: raw::SYST,
191}
192
193impl From<(raw::Peripherals, raw::CorePeripherals)> for Peripherals {
194 fn from(raw: (raw::Peripherals, raw::CorePeripherals)) -> Self {
195 let cp = raw.1;
196 let p = raw.0;
197 Peripherals {
198 adc: Adc::from(p.ADC0),
200 anactrl: Anactrl::from(p.ANACTRL),
201 casper: Casper::from(p.CASPER),
202
203 ctimer: (
204 peripherals::ctimer::Ctimer0::from(p.CTIMER0),
205 peripherals::ctimer::Ctimer1::from(p.CTIMER1),
206 peripherals::ctimer::Ctimer2::from(p.CTIMER2),
207 peripherals::ctimer::Ctimer3::from(p.CTIMER3),
208 peripherals::ctimer::Ctimer4::from(p.CTIMER4),
209 ),
210 dma: Dma::from(p.DMA0),
211 flash: Flash::from(p.FLASH),
212 flexcomm: (
213 peripherals::flexcomm::Flexcomm0::from((
214 p.FLEXCOMM0,
215 p.I2C0,
216 p.I2S0,
217 p.SPI0,
218 p.USART0,
219 )),
220 peripherals::flexcomm::Flexcomm1::from((
221 p.FLEXCOMM1,
222 p.I2C1,
223 p.I2S1,
224 p.SPI1,
225 p.USART1,
226 )),
227 peripherals::flexcomm::Flexcomm2::from((
228 p.FLEXCOMM2,
229 p.I2C2,
230 p.I2S2,
231 p.SPI2,
232 p.USART2,
233 )),
234 peripherals::flexcomm::Flexcomm3::from((
235 p.FLEXCOMM3,
236 p.I2C3,
237 p.I2S3,
238 p.SPI3,
239 p.USART3,
240 )),
241 peripherals::flexcomm::Flexcomm4::from((
242 p.FLEXCOMM4,
243 p.I2C4,
244 p.I2S4,
245 p.SPI4,
246 p.USART4,
247 )),
248 peripherals::flexcomm::Flexcomm5::from((
249 p.FLEXCOMM5,
250 p.I2C5,
251 p.I2S5,
252 p.SPI5,
253 p.USART5,
254 )),
255 peripherals::flexcomm::Flexcomm6::from((
256 p.FLEXCOMM6,
257 p.I2C6,
258 p.I2S6,
259 p.SPI6,
260 p.USART6,
261 )),
262 peripherals::flexcomm::Flexcomm7::from((
263 p.FLEXCOMM7,
264 p.I2C7,
265 p.I2S7,
266 p.SPI7,
267 p.USART7,
268 )),
269 peripherals::flexcomm::Flexcomm8::from((p.FLEXCOMM8, p.SPI8)),
270 ),
271 gint: Gint::from((p.GINT0, p.GINT1)),
272 gpio: Gpio::from(p.GPIO),
273 hashcrypt: Hashcrypt::from(p.HASHCRYPT),
274 inputmux: InputMux::from(p.INPUTMUX),
275 iocon: Iocon::from(p.IOCON),
276 pint: Pint::from(p.PINT),
277 pfr: Pfr::new(),
278 pmc: Pmc::from(p.PMC),
279 prince: Prince::from(p.PRINCE),
280 puf: Puf::from(p.PUF),
281 rng: Rng::from(p.RNG),
282 rtc: Rtc::from(p.RTC),
283 syscon: Syscon::from(p.SYSCON),
284 usbfs: Usbfs::from((p.USB0, p.USBFSH)),
285 usbhs: Usbhs::from((p.USBPHY, p.USB1, p.USBHSH)),
286 utick: Utick::from(p.UTICK0),
287
288 AHB_SECURE_CTRL: p.AHB_SECURE_CTRL,
290 CRC_ENGINE: p.CRC_ENGINE,
291 FLASH_CMPA: p.FLASH_CMPA,
292 FLASH_CFPA0: p.FLASH_CFPA0,
293 SAU: p.SAU,
294 SCT0: p.SCT0,
295 wwdt: p.WWDT,
296
297 CPUID: cp.CPUID,
299 DCB: cp.DCB,
300 DWT: cp.DWT,
301 MPU: cp.MPU,
302 NVIC: cp.NVIC,
303 SCB: cp.SCB,
304 SYST: cp.SYST,
305 }
306 }
307}
308
309impl Peripherals {
310 pub fn take() -> Option<Self> {
311 Some(Self::from((
312 raw::Peripherals::take()?,
313 raw::CorePeripherals::take()?,
314 )))
315 }
316
317 pub unsafe fn steal() -> Self {
322 Self::from((raw::Peripherals::steal(), raw::CorePeripherals::steal()))
323 }
324}
325
326pub fn enable_cycle_counter() {
327 unsafe { &mut raw::CorePeripherals::steal().DWT }.enable_cycle_counter();
328}
329
330pub fn get_cycle_count() -> u32 {
331 raw::DWT::cycle_count()
332}
333
334pub fn count_cycles<Output>(f: impl FnOnce() -> Output) -> (u32, Output) {
335 let before = get_cycle_count();
336 let outcome = f();
337 let after = get_cycle_count();
338 (after - before, outcome)
339}
340
341pub fn wait_at_least(delay_usecs: u32) {
343 enable_cycle_counter();
344 let max_cpu_speed = 150_000_000; let period = max_cpu_speed / 1_000_000;
346
347 let current = get_cycle_count() as u64;
348 let mut target = current + period as u64 * delay_usecs as u64;
349 if target > 0xFFFF_FFFF {
350 target -= 0xFFFF_FFFF;
352 while target < get_cycle_count() as u64 {
353 continue;
354 }
355 }
356 while target > get_cycle_count() as u64 {
357 continue;
358 }
359}
360
361pub fn chip_revision() -> &'static str {
365 const DIEID: *const u8 = 0x5000_0FFC as _;
366 let rev_id: u8 = 0xFu8 & unsafe { core::ptr::read_volatile(DIEID) };
367 match rev_id {
368 0 => "0A",
369 1 => "1B",
370 _ => "unknown",
371 }
372}
373
374pub fn uuid() -> [u8; 16] {
375 const UUID: *const u8 = 0x0009_FC70 as _;
376 let mut uuid: [u8; 16] = [0; 16];
377 unsafe {
378 copy_nonoverlapping(UUID, uuid.as_mut_ptr(), 16);
379 }
380 uuid
381}
382
383pub fn boot_to_bootrom() -> ! {
394 cortex_m::interrupt::disable();
396 let core_peripherals = unsafe { cortex_m::peripheral::Peripherals::steal() };
397 unsafe {
398 core_peripherals.NVIC.icer[0].write(0xFFFF_FFFFu32);
399 core_peripherals.NVIC.icer[1].write(0xFFFF_FFFFu32);
400 cortex_m::interrupt::enable();
401 }
402
403 let mut syscon = unsafe { Syscon::reset_all_noncritical_peripherals() };
405
406 let iocon = unsafe { Iocon::steal() }.enabled(&mut syscon).release();
408 iocon
409 .pio0_5
410 .modify(|_, w| w.invert().set_bit().digimode().digital());
411
412 unsafe { cortex_m::asm::bootload(0x03000000 as *const u32) }
414}