1#![no_std]
2#![deny(unsafe_code)]
3#![deny(missing_docs)]
4#![doc = include_str!("../README.md")]
5#![doc(issue_tracker_base_url = "https://github.com/imxrt-rs/imxrt-uart-panic/issues")]
6#![cfg_attr(docsrs, feature(doc_cfg))]
7
8#[doc(hidden)]
9pub mod _deps {
10 pub use cortex_m;
11 pub use embedded_io;
12 pub use imxrt_hal;
13 pub use imxrt_ral;
14}
15
16#[macro_export]
27macro_rules! register {
28 ($uart: ident, $tx_pin: ident, $rx_pin: ident, $baud: expr, $idle_func: expr) => {
29 #[panic_handler]
30 fn panic(info: &::core::panic::PanicInfo) -> ! {
31 use ::core::fmt::Write as _;
32
33 use $crate::_deps::embedded_io::Write as _;
34 use $crate::_deps::imxrt_hal as hal;
35 use $crate::_deps::imxrt_ral as ral;
36
37 use hal::ccm;
38 use hal::lpuart::{Baud, Direction, Lpuart, Pins, Watermark};
39
40 const UART_DIVIDER: u32 = 3;
42 pub const UART_FREQUENCY: u32 = hal::ccm::XTAL_OSCILLATOR_HZ / UART_DIVIDER;
43 let mut ccm = unsafe { ral::ccm::CCM::instance() };
44 ccm::clock_gate::UART_CLOCK_GATES
45 .iter()
46 .for_each(|locator| locator.set(&mut ccm, ccm::clock_gate::OFF));
47 ccm::uart_clk::set_selection(&mut ccm, ccm::uart_clk::Selection::Oscillator);
48 ccm::uart_clk::set_divider(&mut ccm, UART_DIVIDER);
49 ccm::clock_gate::UART_CLOCK_GATES
50 .iter()
51 .for_each(|locator| locator.set(&mut ccm, ccm::clock_gate::ON));
52
53 let registers = unsafe { ral::lpuart::$uart::instance() };
55 let pins = Pins {
56 tx: unsafe { $tx_pin::new() },
57 rx: unsafe { $rx_pin::new() },
58 };
59 let mut uart = Lpuart::new(registers, pins);
60
61 const BAUD: Baud = Baud::compute(UART_FREQUENCY, $baud);
63 uart.disable(|uart| {
64 uart.set_baud(&BAUD);
65 uart.enable_fifo(Watermark::tx(4));
66 uart.disable_fifo(Direction::Rx);
67 });
68
69 struct UartWriter<P, const N: u8> {
70 uart: hal::lpuart::Lpuart<P, N>,
71 }
72 impl<P, const N: u8> ::core::fmt::Write for UartWriter<P, N> {
73 fn write_str(&mut self, s: &str) -> ::core::fmt::Result {
74 for &b in s.as_bytes() {
75 if b == b'\n' {
76 let _ = self.uart.write_all(b"\r");
77 }
78 let _ = self.uart.write_all(core::slice::from_ref(&b));
79 }
80 Ok(())
81 }
82 }
83
84 let mut uart = UartWriter { uart };
85
86 ::core::writeln!(uart).ok();
87 ::core::writeln!(uart, "{}", info).ok();
88 ::core::writeln!(uart).ok();
89
90 let _ = uart.uart.flush();
91
92 $idle_func();
93 }
94 };
95 ($uart: ident, $tx_pin: ident, $rx_pin: ident, $baud: expr) => {
96 $crate::register!(
97 $uart,
98 $tx_pin,
99 $rx_pin,
100 $baud,
101 $crate::_deps::cortex_m::asm::udf
102 );
103 };
104}