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#[cfg(not(feature = "rtic-peripherals"))]
79pub fn from(raw: (raw::Peripherals, raw::CorePeripherals)) -> Peripherals {
80 Peripherals::from(raw)
81}
82
83#[cfg(feature = "rtic-peripherals")]
84pub fn from(raw: (raw::Peripherals, rtic::Peripherals)) -> Peripherals {
85 Peripherals::from(raw)
86}
87
88#[allow(non_snake_case)]
93pub struct Peripherals {
94 pub adc: Adc,
96
97 pub anactrl: Anactrl,
99
100 pub casper: Casper,
102
103 pub ctimer: Ctimers,
105
106 pub dma: Dma,
108
109 pub flash: Flash,
111
112 pub flexcomm: Flexcomm,
114
115 pub gint: Gint,
117
118 pub gpio: Gpio,
120
121 pub hashcrypt: Hashcrypt,
123
124 pub inputmux: InputMux,
126
127 pub iocon: Iocon,
129
130 pub pint: Pint,
132
133 pub pfr: Pfr,
135
136 pub pmc: Pmc,
138
139 pub prince: Prince,
141
142 pub puf: Puf,
144
145 pub rng: Rng,
147
148 pub rtc: Rtc,
150
151 pub syscon: Syscon,
153
154 pub usbfs: Usbfs,
156
157 pub usbhs: Usbhs,
159
160 pub utick: Utick,
162
163 pub CRC_ENGINE: raw::CRC_ENGINE,
165
166 pub FLASH_CMPA: raw::FLASH_CMPA,
167 pub FLASH_CFPA0: raw::FLASH_CFPA0,
168
169 pub SCT0: raw::SCT0,
171
172 pub SAU: raw::SAU,
174
175 pub AHB_SECURE_CTRL: raw::AHB_SECURE_CTRL,
177
178 pub CPUID: raw::CPUID,
180
181 pub DCB: raw::DCB,
183
184 pub DWT: raw::DWT,
186
187 pub MPU: raw::MPU,
189
190 pub NVIC: raw::NVIC,
192
193 pub SCB: raw::SCB,
195
196 pub wwdt: raw::WWDT,
198
199 #[cfg(not(feature = "rtic-peripherals"))]
200 #[cfg(not(feature = "rtic-peripherals"))]
202 pub SYST: raw::SYST,
203}
204
205#[cfg(feature = "rtic-peripherals")]
206impl From<(raw::Peripherals, rtic::Peripherals)> for Peripherals {
207 fn from(raw: (raw::Peripherals, rtic::Peripherals)) -> Self {
208 let cp = raw.1;
209 let p = raw.0;
210 Peripherals {
211 adc: Adc::from(p.ADC0),
213 anactrl: Anactrl::from(p.ANACTRL),
214 casper: Casper::from(p.CASPER),
215 ctimer: (
216 peripherals::ctimer::Ctimer0::from(p.CTIMER0),
217 peripherals::ctimer::Ctimer1::from(p.CTIMER1),
218 peripherals::ctimer::Ctimer2::from(p.CTIMER2),
219 peripherals::ctimer::Ctimer3::from(p.CTIMER3),
220 peripherals::ctimer::Ctimer4::from(p.CTIMER4),
221 ),
222 dma: Dma::from(p.DMA0),
223 flash: Flash::from(p.FLASH),
224 flexcomm: (
225 peripherals::flexcomm::Flexcomm0::from((
226 p.FLEXCOMM0,
227 p.I2C0,
228 p.I2S0,
229 p.SPI0,
230 p.USART0,
231 )),
232 peripherals::flexcomm::Flexcomm1::from((
233 p.FLEXCOMM1,
234 p.I2C1,
235 p.I2S1,
236 p.SPI1,
237 p.USART1,
238 )),
239 peripherals::flexcomm::Flexcomm2::from((
240 p.FLEXCOMM2,
241 p.I2C2,
242 p.I2S2,
243 p.SPI2,
244 p.USART2,
245 )),
246 peripherals::flexcomm::Flexcomm3::from((
247 p.FLEXCOMM3,
248 p.I2C3,
249 p.I2S3,
250 p.SPI3,
251 p.USART3,
252 )),
253 peripherals::flexcomm::Flexcomm4::from((
254 p.FLEXCOMM4,
255 p.I2C4,
256 p.I2S4,
257 p.SPI4,
258 p.USART4,
259 )),
260 peripherals::flexcomm::Flexcomm5::from((
261 p.FLEXCOMM5,
262 p.I2C5,
263 p.I2S5,
264 p.SPI5,
265 p.USART5,
266 )),
267 peripherals::flexcomm::Flexcomm6::from((
268 p.FLEXCOMM6,
269 p.I2C6,
270 p.I2S6,
271 p.SPI6,
272 p.USART6,
273 )),
274 peripherals::flexcomm::Flexcomm7::from((
275 p.FLEXCOMM7,
276 p.I2C7,
277 p.I2S7,
278 p.SPI7,
279 p.USART7,
280 )),
281 peripherals::flexcomm::Flexcomm8::from((p.FLEXCOMM8, p.SPI8)),
282 ),
283 gint: Gint::from((p.GINT0, p.GINT1)),
284 gpio: Gpio::from(p.GPIO),
285 hashcrypt: Hashcrypt::from(p.HASHCRYPT),
286 inputmux: InputMux::from(p.INPUTMUX),
287 iocon: Iocon::from(p.IOCON),
288 pint: Pint::from(p.PINT),
289 pfr: Pfr::new(),
290 pmc: Pmc::from(p.PMC),
291 prince: Prince::from(p.PRINCE),
292 puf: Puf::from(p.PUF),
293 rng: Rng::from(p.RNG),
294 rtc: Rtc::from(p.RTC),
295 syscon: Syscon::from(p.SYSCON),
296 usbfs: Usbfs::from((p.USB0, p.USBFSH)),
297 usbhs: Usbhs::from((p.USBPHY, p.USB1, p.USBHSH)),
298 utick: Utick::from(p.UTICK0),
299
300 AHB_SECURE_CTRL: p.AHB_SECURE_CTRL,
302 CRC_ENGINE: p.CRC_ENGINE,
303 FLASH_CMPA: p.FLASH_CMPA,
304 FLASH_CFPA0: p.FLASH_CFPA0,
305 SAU: p.SAU,
306 SCT0: p.SCT0,
307
308 CPUID: cp.CPUID,
310 DCB: cp.DCB,
311 DWT: cp.DWT,
312 MPU: cp.MPU,
313 NVIC: cp.NVIC,
314 SCB: cp.SCB,
315 }
316 }
317}
318
319impl From<(raw::Peripherals, raw::CorePeripherals)> for Peripherals {
320 fn from(raw: (raw::Peripherals, raw::CorePeripherals)) -> Self {
321 let cp = raw.1;
322 let p = raw.0;
323 Peripherals {
324 adc: Adc::from(p.ADC0),
326 anactrl: Anactrl::from(p.ANACTRL),
327 casper: Casper::from(p.CASPER),
328
329 ctimer: (
330 peripherals::ctimer::Ctimer0::from(p.CTIMER0),
331 peripherals::ctimer::Ctimer1::from(p.CTIMER1),
332 peripherals::ctimer::Ctimer2::from(p.CTIMER2),
333 peripherals::ctimer::Ctimer3::from(p.CTIMER3),
334 peripherals::ctimer::Ctimer4::from(p.CTIMER4),
335 ),
336 dma: Dma::from(p.DMA0),
337 flash: Flash::from(p.FLASH),
338 flexcomm: (
339 peripherals::flexcomm::Flexcomm0::from((
340 p.FLEXCOMM0,
341 p.I2C0,
342 p.I2S0,
343 p.SPI0,
344 p.USART0,
345 )),
346 peripherals::flexcomm::Flexcomm1::from((
347 p.FLEXCOMM1,
348 p.I2C1,
349 p.I2S1,
350 p.SPI1,
351 p.USART1,
352 )),
353 peripherals::flexcomm::Flexcomm2::from((
354 p.FLEXCOMM2,
355 p.I2C2,
356 p.I2S2,
357 p.SPI2,
358 p.USART2,
359 )),
360 peripherals::flexcomm::Flexcomm3::from((
361 p.FLEXCOMM3,
362 p.I2C3,
363 p.I2S3,
364 p.SPI3,
365 p.USART3,
366 )),
367 peripherals::flexcomm::Flexcomm4::from((
368 p.FLEXCOMM4,
369 p.I2C4,
370 p.I2S4,
371 p.SPI4,
372 p.USART4,
373 )),
374 peripherals::flexcomm::Flexcomm5::from((
375 p.FLEXCOMM5,
376 p.I2C5,
377 p.I2S5,
378 p.SPI5,
379 p.USART5,
380 )),
381 peripherals::flexcomm::Flexcomm6::from((
382 p.FLEXCOMM6,
383 p.I2C6,
384 p.I2S6,
385 p.SPI6,
386 p.USART6,
387 )),
388 peripherals::flexcomm::Flexcomm7::from((
389 p.FLEXCOMM7,
390 p.I2C7,
391 p.I2S7,
392 p.SPI7,
393 p.USART7,
394 )),
395 peripherals::flexcomm::Flexcomm8::from((p.FLEXCOMM8, p.SPI8)),
396 ),
397 gint: Gint::from((p.GINT0, p.GINT1)),
398 gpio: Gpio::from(p.GPIO),
399 hashcrypt: Hashcrypt::from(p.HASHCRYPT),
400 inputmux: InputMux::from(p.INPUTMUX),
401 iocon: Iocon::from(p.IOCON),
402 pint: Pint::from(p.PINT),
403 pfr: Pfr::new(),
404 pmc: Pmc::from(p.PMC),
405 prince: Prince::from(p.PRINCE),
406 puf: Puf::from(p.PUF),
407 rng: Rng::from(p.RNG),
408 rtc: Rtc::from(p.RTC),
409 syscon: Syscon::from(p.SYSCON),
410 usbfs: Usbfs::from((p.USB0, p.USBFSH)),
411 usbhs: Usbhs::from((p.USBPHY, p.USB1, p.USBHSH)),
412 utick: Utick::from(p.UTICK0),
413
414 AHB_SECURE_CTRL: p.AHB_SECURE_CTRL,
416 CRC_ENGINE: p.CRC_ENGINE,
417 FLASH_CMPA: p.FLASH_CMPA,
418 FLASH_CFPA0: p.FLASH_CFPA0,
419 SAU: p.SAU,
420 SCT0: p.SCT0,
421 wwdt: p.WWDT,
422
423 CPUID: cp.CPUID,
425 DCB: cp.DCB,
426 DWT: cp.DWT,
427 MPU: cp.MPU,
428 NVIC: cp.NVIC,
429 SCB: cp.SCB,
430 #[cfg(not(feature = "rtic-peripherals"))]
431 SYST: cp.SYST,
432 }
433 }
434}
435
436impl Peripherals {
437 #[cfg(not(feature = "rtic-peripherals"))]
438 pub fn take() -> Option<Self> {
439 Some(Self::from((
440 raw::Peripherals::take()?,
441 raw::CorePeripherals::take()?,
442 )))
443 }
444
445 #[cfg(not(feature = "rtic-peripherals"))]
456 pub unsafe fn steal() -> Self {
461 Self::from((raw::Peripherals::steal(), raw::CorePeripherals::steal()))
462 }
463}
464
465pub fn enable_cycle_counter() {
466 unsafe { &mut raw::CorePeripherals::steal().DWT }.enable_cycle_counter();
467}
468
469pub fn get_cycle_count() -> u32 {
470 raw::DWT::cycle_count()
471}
472
473pub fn count_cycles<Output>(f: impl FnOnce() -> Output) -> (u32, Output) {
474 let before = get_cycle_count();
475 let outcome = f();
476 let after = get_cycle_count();
477 (after - before, outcome)
478}
479
480pub fn wait_at_least(delay_usecs: u32) {
482 enable_cycle_counter();
483 let max_cpu_speed = 150_000_000; let period = max_cpu_speed / 1_000_000;
485
486 let current = get_cycle_count() as u64;
487 let mut target = current + period as u64 * delay_usecs as u64;
488 if target > 0xFFFF_FFFF {
489 target -= 0xFFFF_FFFF;
491 while target < get_cycle_count() as u64 {
492 continue;
493 }
494 }
495 while target > get_cycle_count() as u64 {
496 continue;
497 }
498}
499
500pub fn chip_revision() -> &'static str {
504 const DIEID: *const u8 = 0x5000_0FFC as _;
505 let rev_id: u8 = 0xFu8 & unsafe { core::ptr::read_volatile(DIEID) };
506 match rev_id {
507 0 => "0A",
508 1 => "1B",
509 _ => "unknown",
510 }
511}
512
513pub fn uuid() -> [u8; 16] {
514 const UUID: *const u8 = 0x0009_FC70 as _;
515 let mut uuid: [u8; 16] = [0; 16];
516 unsafe {
517 copy_nonoverlapping(UUID, uuid.as_mut_ptr(), 16);
518 }
519 uuid
520}
521
522pub fn boot_to_bootrom() -> ! {
533 cortex_m::interrupt::disable();
535 let core_peripherals = unsafe { cortex_m::peripheral::Peripherals::steal() };
536 unsafe {
537 core_peripherals.NVIC.icer[0].write(0xFFFF_FFFFu32);
538 core_peripherals.NVIC.icer[1].write(0xFFFF_FFFFu32);
539 cortex_m::interrupt::enable();
540 }
541
542 let mut syscon = unsafe { Syscon::reset_all_noncritical_peripherals() };
544
545 let iocon = unsafe { Iocon::steal() }.enabled(&mut syscon).release();
547 iocon
548 .pio0_5
549 .modify(|_, w| w.invert().set_bit().digimode().digital());
550
551 unsafe { cortex_m::asm::bootload(0x03000000 as *const u32) }
553}