diff --git a/examples/teensy4_blinky/Cargo.lock b/examples/teensy4_blinky/Cargo.lock index 48d0e3db617e..8253a71bbd0f 100644 --- a/examples/teensy4_blinky/Cargo.lock +++ b/examples/teensy4_blinky/Cargo.lock @@ -193,6 +193,9 @@ name = "imxrt-blinky" version = "0.1.0" dependencies = [ "embedded-hal 0.2.7", + "imxrt-log", + "log", + "nb 1.1.0", "rtic", "rtic-monotonics", "teensy4-bsp", @@ -248,6 +251,7 @@ dependencies = [ "bbqueue", "critical-section", "defmt", + "imxrt-hal", "imxrt-usbd", "log", "usb-device", @@ -430,6 +434,7 @@ dependencies = [ "embedded-hal 1.0.0-rc.1", "fugit", "imxrt-ral", + "log", "rtic-time", ] diff --git a/examples/teensy4_blinky/Cargo.toml b/examples/teensy4_blinky/Cargo.toml index c25c4867a5f6..b032f4d5800f 100644 --- a/examples/teensy4_blinky/Cargo.toml +++ b/examples/teensy4_blinky/Cargo.toml @@ -19,12 +19,20 @@ features = ["imxrt_gpt1"] [dependencies] embedded-hal = "0.2.7" -teensy4-panic = "0.2.3" +teensy4-panic = { version = "0.2.3", default-features = false } [dependencies.teensy4-bsp] features = ["rt"] version = "0.4.4" +[dev-dependencies] +nb = "1.1.0" # Async +imxrt-log = { version = "0.1.1", default-features = false, features = [ + "log", + "lpuart", +] } +log = "0.4.20" + # this lets you use `cargo fix`! [[bin]] name = "imxrt-blinky" diff --git a/examples/teensy4_blinky/examples/common/mod.rs b/examples/teensy4_blinky/examples/common/mod.rs new file mode 100644 index 000000000000..9851feab1cda --- /dev/null +++ b/examples/teensy4_blinky/examples/common/mod.rs @@ -0,0 +1,42 @@ +macro_rules! uart_panic_handler { + ($uart: ident, $tx_pin: ident, $rx_pin: ident, $baud: expr) => { + #[panic_handler] + fn panic(info: &::core::panic::PanicInfo) -> ! { + use ::core::fmt::Write as _; + use ::embedded_hal::serial::Write as _; + + let ::teensy4_bsp::board::Resources { + $uart: uart, pins, .. + } = ::teensy4_bsp::board::t40(unsafe { ::teensy4_bsp::ral::Instances::instances() }); + + let uart = ::teensy4_bsp::board::lpuart(uart, pins.$tx_pin, pins.$rx_pin, $baud); + + struct UartWriter { + uart: ::teensy4_bsp::hal::lpuart::Lpuart, + } + impl ::core::fmt::Write for UartWriter { + fn write_str(&mut self, s: &str) -> ::core::fmt::Result { + for &b in s.as_bytes() { + if b == b'\n' { + let _ = ::nb::block!(self.uart.write(b'\r')); + } + let _ = ::nb::block!(self.uart.write(b)); + } + Ok(()) + } + } + + let mut uart = UartWriter { uart }; + + ::core::writeln!(uart).ok(); + ::core::writeln!(uart, "{}", info).ok(); + ::core::writeln!(uart).ok(); + + let _ = ::nb::block!(uart.uart.flush()); + + ::teensy4_panic::sos() + } + }; +} + +pub(crate) use uart_panic_handler; diff --git a/examples/teensy4_blinky/examples/with_logs.rs b/examples/teensy4_blinky/examples/with_logs.rs new file mode 100644 index 000000000000..e7e57c3e1365 --- /dev/null +++ b/examples/teensy4_blinky/examples/with_logs.rs @@ -0,0 +1,113 @@ +#![deny(warnings)] +#![no_main] +#![no_std] +#![feature(type_alias_impl_trait)] + +mod common; +common::uart_panic_handler!(lpuart6, p1, p0, 115200); + +use teensy4_bsp as bsp; + +use bsp::board; +use bsp::hal; +use bsp::logging; + +use embedded_hal::serial::Write; + +use rtic_monotonics::imxrt::Gpt1 as Mono; +use rtic_monotonics::imxrt::*; +use rtic_monotonics::Monotonic; + +#[rtic::app(device = teensy4_bsp, dispatchers = [LPSPI1])] +mod app { + use super::*; + + const LOG_POLL_INTERVAL: u32 = board::PERCLK_FREQUENCY / 100; + const LOG_DMA_CHANNEL: usize = 0; + + #[shared] + struct Shared {} + + #[local] + struct Local { + led: board::Led, + poll_log: hal::pit::Pit<3>, + log_poller: logging::Poller, + } + + #[init] + fn init(cx: init::Context) -> (Shared, Local) { + let board::Resources { + mut dma, + pit: (_, _, _, mut poll_log), + pins, + lpuart6, + mut gpio2, + mut gpt1, + .. + } = board::t40(cx.device); + + // Logging + let log_dma = dma[LOG_DMA_CHANNEL].take().unwrap(); + let mut log_uart = board::lpuart(lpuart6, pins.p1, pins.p0, 115200); + for &ch in "\r\n===== Teensy4 Rtic Blinky =====\r\n\r\n".as_bytes() { + nb::block!(log_uart.write(ch)).unwrap(); + } + nb::block!(log_uart.flush()).unwrap(); + let log_poller = + logging::log::lpuart(log_uart, log_dma, logging::Interrupts::Enabled).unwrap(); + poll_log.set_interrupt_enable(true); + poll_log.set_load_timer_value(LOG_POLL_INTERVAL); + poll_log.enable(); + + // Initialize the systick interrupt & obtain the token to prove that we did + gpt1.set_clock_source(hal::gpt::ClockSource::PeripheralClock); + let gpt1_mono_token = rtic_monotonics::create_imxrt_gpt1_token!(); + Mono::start(board::PERCLK_FREQUENCY, gpt1.release(), gpt1_mono_token); + + // Setup LED + let led = board::led(&mut gpio2, pins.p13); + led.set(); + + // Schedule the blinking task + blink::spawn().ok(); + + ( + Shared {}, + Local { + log_poller, + poll_log, + led, + }, + ) + } + + #[task(local = [led])] + async fn blink(cx: blink::Context) { + let blink::LocalResources { led, .. } = cx.local; + + let mut next_update = Mono::now(); + + loop { + led.toggle(); + log::info!("Time: {:?}", Mono::now()); + next_update += 1000.millis(); + Mono::delay_until(next_update).await; + } + } + + #[task(binds = PIT, priority = 1, local = [poll_log, log_poller])] + fn logger(cx: logger::Context) { + let logger::LocalResources { + poll_log, + log_poller, + .. + } = cx.local; + + if poll_log.is_elapsed() { + poll_log.clear_elapsed(); + + log_poller.poll(); + } + } +} diff --git a/examples/teensy4_blinky/src/main.rs b/examples/teensy4_blinky/src/main.rs index 37d8aa5db69f..1b95e7b082a6 100644 --- a/examples/teensy4_blinky/src/main.rs +++ b/examples/teensy4_blinky/src/main.rs @@ -4,8 +4,12 @@ #![no_std] #![feature(type_alias_impl_trait)] +#[panic_handler] +fn panic(_: &::core::panic::PanicInfo) -> ! { + ::teensy4_panic::sos() +} + use teensy4_bsp::{board, hal}; -use teensy4_panic as _; use rtic_monotonics::imxrt::Gpt1 as Mono; use rtic_monotonics::imxrt::*;