From 369201efd5d4bf526098a201efd6676daaee0590 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Tue, 7 Jul 2020 17:24:08 -0400 Subject: [PATCH 01/20] Integrate the IOMUXC refactor into the BSP --- Cargo.toml | 10 +++ Makefile | 9 +++ examples/dma_spi.rs | 15 ++-- examples/dma_uart.rs | 14 +--- examples/gpt.rs | 5 +- examples/i2c.rs | 6 +- examples/led.rs | 4 +- examples/pit.rs | 6 +- examples/pwm.rs | 4 +- examples/rtic_blink.rs | 6 +- examples/rtic_dma_uart_log.rs | 10 +-- examples/rtic_led.rs | 4 +- examples/spi.rs | 8 +- examples/systick.rs | 5 +- examples/timer.rs | 2 +- examples/uart.rs | 11 +-- examples/usb.rs | 6 +- src/lib.rs | 147 +++++++++++++++++----------------- 18 files changed, 139 insertions(+), 133 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dc886a4e..2cacda3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,15 @@ teensy4-fcb = { path = "teensy4-fcb" } [dependencies.imxrt-hal] version = "0.3.0" +path = "../imxrt/imxrt/imxrt-hal" features = ["imxrt1062", "rt"] +[dependencies.imxrt-iomuxc] +path = "../imxrt/iomuxc" + +[dependencies.imxrt106x-iomuxc] +path = "../imxrt/iomuxc/imxrt106x-iomuxc" + # Tied to "systick" feature, since # SysTick implements a blocking delay trait [dependencies.embedded-hal] @@ -48,14 +55,17 @@ panic-halt = "0.2.0" name = "rtic_led" path = "examples/rtic_led.rs" required-features = ["rtic"] + [[example]] name = "rtic_blink" path = "examples/rtic_blink.rs" required-features = ["rtic"] + [[example]] name = "rtic_uart_log" path = "examples/rtic_uart_log.rs" required-features = ["rtic"] + [[example]] name = "rtic_dma_uart_log" path = "examples/rtic_dma_uart_log.rs" diff --git a/Makefile b/Makefile index a8582e1a..37b1263d 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ endif # INSTALL_DEPS != 0 TARGET_EXAMPLES := target/thumbv7em-none-eabihf/release/examples EXAMPLES := $(shell ls examples | xargs basename | cut -f 1 -d .) +RTIC_EXAMPLES := $(shell ls examples | grep rtic | xargs basename | cut -f 1 -d .) .PHONY: all all: @@ -44,6 +45,14 @@ all: -- -O ihex $(TARGET_EXAMPLES)/$$example.hex;\ done +# Build all RTIC-related examples +.PHONY: rtic +rtic: + @for example in $(RTIC_EXAMPLES);\ + do cargo build $(MODE) --example $$example \ + --no-default-features --features=rtic;\ + done + .PHONY: example_% example_%: @cargo build \ diff --git a/examples/dma_spi.rs b/examples/dma_spi.rs index b0e91586..4da29373 100644 --- a/examples/dma_spi.rs +++ b/examples/dma_spi.rs @@ -80,7 +80,7 @@ static TX_BUFFER: Mutex>> = Mutex::new(RefCell::new(Non static RX_BUFFER: Mutex>> = Mutex::new(RefCell::new(None)); type SpiDma = - dma::Peripheral, u16, TxBuffer, RxBuffer>; + dma::Peripheral, u16, TxBuffer, RxBuffer>; // TODO types should be Send static mut SPI_DMA: Option = None; @@ -158,7 +158,7 @@ fn rx_buffer_mut R, R>(act: F) -> Option { } // Pin 20 -type HardwareFlag = bsp::hal::gpio::GPIO1IO26; +type HardwareFlag = bsp::hal::gpio::GPIO; static mut HARDWARE_FLAG: Option = None; #[entry] @@ -174,8 +174,7 @@ fn main() -> ! { unsafe { let p20 = peripherals.pins.p20; - use bsp::hal::gpio::IntoGpio; - HARDWARE_FLAG = Some(p20.alt5().into_gpio().output()); + HARDWARE_FLAG = Some(bsp::hal::gpio::GPIO::new(p20).output()); } // @@ -193,11 +192,11 @@ fn main() -> ! { log::info!("Constructing SPI4 peripheral..."); let mut spi4 = spi4_builder.build( - peripherals.pins.p11.alt3(), - peripherals.pins.p12.alt3(), - peripherals.pins.p13.alt3(), + peripherals.pins.p11, + peripherals.pins.p12, + peripherals.pins.p13, ); - spi4.enable_chip_select_0(peripherals.pins.p10.alt3()); + spi4.enable_chip_select_0(peripherals.pins.p10); match spi4.set_clock_speed(bsp::hal::spi::ClockSpeed(SPI_BAUD_RATE_HZ)) { Ok(()) => { diff --git a/examples/dma_uart.rs b/examples/dma_uart.rs index 08e72fe3..2a4f693b 100644 --- a/examples/dma_uart.rs +++ b/examples/dma_uart.rs @@ -18,8 +18,6 @@ use bsp::interrupt; use bsp::rt::entry; use teensy4_bsp as bsp; -use embedded_hal::digital::v2::ToggleableOutputPin; - use core::{ cell::RefCell, sync::atomic::{AtomicBool, Ordering}, @@ -42,7 +40,7 @@ static TX_BUFFER: Mutex>> = Mutex::new(RefCell::new(Non static RX_BUFFER: Mutex>> = Mutex::new(RefCell::new(None)); type DmaUart = bsp::hal::dma::Peripheral< - bsp::hal::uart::UART, + bsp::hal::uart::UART, u8, TxBuffer, RxBuffer, @@ -90,11 +88,7 @@ fn main() -> ! { ); let uart = uarts .uart2 - .init( - peripherals.pins.p14.alt2(), - peripherals.pins.p15.alt2(), - BAUD, - ) + .init(peripherals.pins.p14, peripherals.pins.p15, BAUD) .unwrap(); let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle); @@ -114,7 +108,7 @@ fn main() -> ! { cortex_m::peripheral::NVIC::unmask(interrupt::DMA7_DMA23); DMA_PERIPHERAL.as_mut().unwrap() }; - let mut led = bsp::configure_led(&mut peripherals.gpr, peripherals.pins.p13); + let mut led = bsp::configure_led(peripherals.pins.p13); let rx_buffer = match bsp::hal::dma::Circular::new(&RX_MEM.0) { Ok(circular) => circular, @@ -156,7 +150,7 @@ fn main() -> ! { loop { cortex_m::asm::wfi(); if RX_READY.load(Ordering::Acquire) { - led.toggle().unwrap(); + led.toggle(); RX_READY.store(false, Ordering::Release); let mut rx_buffer = free(|cs| RX_BUFFER.borrow(cs).borrow_mut().take()).unwrap(); let value = match rx_buffer.pop() { diff --git a/examples/gpt.rs b/examples/gpt.rs index a838638d..ed7b0ab0 100644 --- a/examples/gpt.rs +++ b/examples/gpt.rs @@ -11,7 +11,6 @@ extern crate panic_halt; use bsp::hal::gpt; use bsp::interrupt; use bsp::rt::{entry, interrupt}; -use embedded_hal::digital::v2::ToggleableOutputPin; use teensy4_bsp as bsp; use core::time::Duration; @@ -53,13 +52,13 @@ fn main() -> ! { cortex_m::peripheral::NVIC::unmask(interrupt::GPT1); } - let mut led = bsp::configure_led(&mut periphs.gpr, periphs.pins.p13); + let mut led = bsp::configure_led(periphs.pins.p13); loop { let gpt1 = unsafe { TIMER.as_mut().unwrap() }; gpt1.set_enable(false); gpt1.set_output_compare_duration(OCR, Duration::from_millis(400)); gpt1.set_enable(true); cortex_m::asm::wfi(); - led.toggle().unwrap(); + led.toggle(); } } diff --git a/examples/i2c.rs b/examples/i2c.rs index d2ba413d..3da4ba45 100644 --- a/examples/i2c.rs +++ b/examples/i2c.rs @@ -54,7 +54,7 @@ fn main() -> ! { ); log::info!("Constructing I2C3 instance on pins 16 and 17..."); - let mut i2c3 = i2c3_builder.build(peripherals.pins.p16.alt1(), peripherals.pins.p17.alt1()); + let mut i2c3 = i2c3_builder.build(peripherals.pins.p16, peripherals.pins.p17); if let Err(err) = i2c3.set_bus_idle_timeout(core::time::Duration::from_micros(200)) { log::warn!("Error when setting bus idle timeout: {:?}", err); @@ -71,11 +71,13 @@ fn main() -> ! { } log::info!("Starting I/O loop..."); + let mut counter = 0; loop { peripherals.systick.delay(1000); log::info!("Querying WHO_AM_I..."); + counter += 1; match who_am_i(&mut i2c3) { - Ok(who) => log::info!("Received 0x{:X} for WHO_AM_I", who), + Ok(who) => log::info!("Received 0x{:X} for WHO_AM_I (iter = {})", who, counter), Err(err) => { log::warn!("Error reading WHO_AM_I: {:?}", err); continue; diff --git a/examples/led.rs b/examples/led.rs index 07ebe1a6..c20e32d5 100644 --- a/examples/led.rs +++ b/examples/led.rs @@ -15,8 +15,8 @@ use embedded_hal::digital::v2::OutputPin; #[entry] fn main() -> ! { - let mut peripherals = bsp::Peripherals::take().unwrap(); - let mut led = bsp::configure_led(&mut peripherals.gpr, peripherals.pins.p13); + let peripherals = bsp::Peripherals::take().unwrap(); + let mut led = bsp::configure_led(peripherals.pins.p13); loop { led.set_high().unwrap(); diff --git a/examples/pit.rs b/examples/pit.rs index 9d49512a..4bb6c94e 100644 --- a/examples/pit.rs +++ b/examples/pit.rs @@ -13,7 +13,7 @@ extern crate panic_halt; use bsp::hal::pit; use bsp::interrupt; use bsp::rt::{entry, interrupt}; -use embedded_hal::{digital::v2::ToggleableOutputPin, timer::CountDown}; +use embedded_hal::timer::CountDown; use teensy4_bsp as bsp; static mut TIMER: Option> = None; @@ -77,9 +77,9 @@ fn main() -> ! { .start(core::time::Duration::from_millis(250)); cortex_m::peripheral::NVIC::unmask(interrupt::PIT); } - let mut led = bsp::configure_led(&mut periphs.gpr, periphs.pins.p13); + let mut led = bsp::configure_led(periphs.pins.p13); loop { - led.toggle().unwrap(); + led.toggle(); cortex_m::asm::wfi(); } } diff --git a/examples/pwm.rs b/examples/pwm.rs index 71ebc39c..15ff1cfb 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -47,8 +47,8 @@ fn main() -> ! { .sm2 .outputs( &mut pwm2.handle, - p.pins.p6.alt2(), - p.pins.p9.alt2(), + p.pins.p6, + p.pins.p9, bsp::hal::pwm::Timing { clock_select: bsp::hal::ccm::pwm::ClockSelect::IPG(ipg_hz), prescalar: bsp::hal::ccm::pwm::Prescalar::PRSC_5, diff --git a/examples/rtic_blink.rs b/examples/rtic_blink.rs index 57fb6e13..61281740 100644 --- a/examples/rtic_blink.rs +++ b/examples/rtic_blink.rs @@ -10,7 +10,7 @@ #![no_std] #![no_main] -use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; +use embedded_hal::digital::v2::OutputPin; use panic_halt as _; use rtic::cyccnt::U32Ext; use teensy4_bsp as bsp; @@ -54,7 +54,7 @@ const APP: () = { // Schedule the first blink. cx.schedule.blink(cx.start + PERIOD.cycles()).unwrap(); - let mut led = bsp::configure_led(&mut cx.device.gpr, cx.device.pins.p13); + let mut led = bsp::configure_led(cx.device.pins.p13); led.set_high().unwrap(); init::LateResources { led } @@ -62,7 +62,7 @@ const APP: () = { #[task(resources = [led], schedule = [blink])] fn blink(cx: blink::Context) { - cx.resources.led.toggle().unwrap(); + cx.resources.led.toggle(); // Schedule the following blink. cx.schedule.blink(cx.scheduled + PERIOD.cycles()).unwrap(); } diff --git a/examples/rtic_dma_uart_log.rs b/examples/rtic_dma_uart_log.rs index caf79f47..b2027cd1 100644 --- a/examples/rtic_dma_uart_log.rs +++ b/examples/rtic_dma_uart_log.rs @@ -22,7 +22,7 @@ #![no_std] #![no_main] -use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; +use embedded_hal::digital::v2::OutputPin; use embedded_hal::serial::Read; use heapless::consts::U256; use panic_halt as _; @@ -41,7 +41,7 @@ type Producer = heapless::spsc::Producer<'static, Ty, Cap>; type Consumer = heapless::spsc::Consumer<'static, Ty, Cap>; // The UART receiver. -type UartRx = bsp::hal::uart::Rx; +type UartRx = bsp::hal::uart::Rx; #[rtic::app(device = teensy4_bsp, monotonic = rtic::cyccnt::CYCCNT, peripherals = true)] const APP: () = { @@ -78,7 +78,7 @@ const APP: () = { ); let mut uart = uarts .uart2 - .init(cx.device.pins.p14.alt2(), cx.device.pins.p15.alt2(), BAUD) + .init(cx.device.pins.p14, cx.device.pins.p15, BAUD) .unwrap(); uart.set_tx_fifo(core::num::NonZeroU8::new(TX_FIFO_SIZE)); uart.set_rx_fifo(true); @@ -93,7 +93,7 @@ const APP: () = { let (q_tx, q_rx) = unsafe { Q.split() }; // LED setup. - let mut led = bsp::configure_led(&mut cx.device.gpr, cx.device.pins.p13); + let mut led = bsp::configure_led(cx.device.pins.p13); led.set_high().unwrap(); // Schedule the first blink. @@ -132,7 +132,7 @@ const APP: () = { } // Toggle the LED. - cx.resources.led.toggle().unwrap(); + cx.resources.led.toggle(); // Schedule the following blink. cx.schedule.blink(cx.scheduled + PERIOD.cycles()).unwrap(); diff --git a/examples/rtic_led.rs b/examples/rtic_led.rs index 85af5b03..d598f681 100644 --- a/examples/rtic_led.rs +++ b/examples/rtic_led.rs @@ -24,9 +24,9 @@ const APP: () = { let _core: cortex_m::Peripherals = cx.core; // Device-specific peripherals - let mut device: bsp::Peripherals = cx.device; + let device: bsp::Peripherals = cx.device; - let mut led = bsp::configure_led(&mut device.gpr, device.pins.p13); + let mut led = bsp::configure_led(device.pins.p13); led.set_high().unwrap(); } #[idle] diff --git a/examples/spi.rs b/examples/spi.rs index 07cb9b8f..95f45c97 100644 --- a/examples/spi.rs +++ b/examples/spi.rs @@ -52,9 +52,9 @@ fn main() -> ! { log::info!("Constructing SPI4 peripheral..."); let mut spi4 = spi4_builder.build( - peripherals.pins.p11.alt3(), - peripherals.pins.p12.alt3(), - peripherals.pins.p13.alt3(), + peripherals.pins.p11, + peripherals.pins.p12, + peripherals.pins.p13, ); match spi4.set_clock_speed(bsp::hal::spi::ClockSpeed(SPI_BAUD_RATE_HZ)) { @@ -76,7 +76,7 @@ fn main() -> ! { // We're using the SPI's default chip select pin. This uses a // dummy `OutputPin` that does nothing! If you'd rather use any // GPIO, replace this line to construct a GPIO from another pin. - spi4.enable_chip_select_0(peripherals.pins.p10.alt3()); + spi4.enable_chip_select_0(peripherals.pins.p10); struct DummyCS; impl embedded_hal::digital::v2::OutputPin for DummyCS { type Error = core::convert::Infallible; diff --git a/examples/systick.rs b/examples/systick.rs index 85f262ad..bbebb8e9 100644 --- a/examples/systick.rs +++ b/examples/systick.rs @@ -9,7 +9,6 @@ extern crate panic_halt; use bsp::rt; -use embedded_hal::digital::v2::ToggleableOutputPin; use teensy4_bsp as bsp; const LED_PERIOD_MS: u32 = 1_000; @@ -17,10 +16,10 @@ const LED_PERIOD_MS: u32 = 1_000; #[rt::entry] fn main() -> ! { let mut p = bsp::Peripherals::take().unwrap(); - let mut led: bsp::LED = bsp::configure_led(&mut p.gpr, p.pins.p13); + let mut led: bsp::LED = bsp::configure_led(p.pins.p13); loop { p.systick.delay(LED_PERIOD_MS); - led.toggle().unwrap(); + led.toggle(); } } diff --git a/examples/timer.rs b/examples/timer.rs index 6b09b53d..5b8b602a 100644 --- a/examples/timer.rs +++ b/examples/timer.rs @@ -43,7 +43,7 @@ fn main() -> ! { let (timer0, timer1, _, mut timer3) = periphs.pit.clock(&mut cfg); let mut timer = pit::chain(timer0, timer1); - let mut led: bsp::LED = bsp::configure_led(&mut periphs.gpr, periphs.pins.p13); + let mut led: bsp::LED = bsp::configure_led(periphs.pins.p13); let mut systick = periphs.systick; loop { let (_, period) = timer.time(|| { diff --git a/examples/uart.rs b/examples/uart.rs index 6ffb5563..3330b5fe 100644 --- a/examples/uart.rs +++ b/examples/uart.rs @@ -23,7 +23,6 @@ extern crate panic_halt; use bsp::rt::entry; use teensy4_bsp as bsp; -use embedded_hal::digital::v2::ToggleableOutputPin; use embedded_hal::serial::{Read, Write}; const BAUD: u32 = 115_200; @@ -89,11 +88,7 @@ fn main() -> ! { ); let mut uart = uarts .uart2 - .init( - peripherals.pins.p14.alt2(), - peripherals.pins.p15.alt2(), - BAUD, - ) + .init(peripherals.pins.p14, peripherals.pins.p15, BAUD) .unwrap(); let fifo_size = uart.set_tx_fifo(core::num::NonZeroU8::new(TX_FIFO_SIZE)); log::info!("Setting TX FIFO to {}", fifo_size); @@ -102,11 +97,11 @@ fn main() -> ! { uart.set_parity(PARITY); uart.set_rx_inversion(INVERTED); uart.set_tx_inversion(INVERTED); - let mut led = bsp::configure_led(&mut peripherals.gpr, peripherals.pins.p13); + let mut led = bsp::configure_led(peripherals.pins.p13); let (mut tx, mut rx) = uart.split(); loop { peripherals.systick.delay(1_000); - led.toggle().unwrap(); + led.toggle(); let mut buffer = DATA; write(&mut tx, &buffer).unwrap(); peripherals.systick.delay(1); diff --git a/examples/usb.rs b/examples/usb.rs index efa91f21..361ac223 100644 --- a/examples/usb.rs +++ b/examples/usb.rs @@ -13,8 +13,6 @@ extern crate panic_halt; use bsp::rt; use teensy4_bsp as bsp; -use embedded_hal::digital::v2::ToggleableOutputPin; - #[rt::entry] fn main() -> ! { let mut p = bsp::Peripherals::take().unwrap(); @@ -27,7 +25,7 @@ fn main() -> ! { p.ccm .pll1 .set_arm_clock(bsp::hal::ccm::PLL1::ARM_HZ, &mut p.ccm.handle, &mut p.dcdc); - let mut led: bsp::LED = bsp::configure_led(&mut p.gpr, p.pins.p13); + let mut led: bsp::LED = bsp::configure_led(p.pins.p13); let mut buffer = [0; 256]; loop { let bytes_read = usb_reader.read(&mut buffer); @@ -49,7 +47,7 @@ fn main() -> ! { log::info!("It's 31'C outside"); log::debug!("Sleeping for 1 second..."); log::trace!("{} + {} = {}", 3, 2, 3 + 2); - led.toggle().unwrap(); + led.toggle(); p.systick.delay(5000); } } diff --git a/src/lib.rs b/src/lib.rs index 36a40b17..2cd917df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -127,74 +127,77 @@ pub use cortex_m_rt as rt; pub use imxrt_hal as hal; /// The LED in its final configuration -pub type LED = hal::gpio::GPIO2IO03; +pub type LED = hal::gpio::GPIO; + +use imxrt106x_iomuxc as iomuxc; +use imxrt_iomuxc::consts::{U1, U2, U3, U4}; /// Teensy pins that do not yet have a function /// /// Pin 13 can be used for several things; one common usage is for the on-board LED. pub struct Pins { /// Pin 0 - pub p0: hal::iomuxc::gpio::GPIO_AD_B0_03, + pub p0: iomuxc::ad_b0::AD_B0_03, /// Pin 1 - pub p1: hal::iomuxc::gpio::GPIO_AD_B0_02, + pub p1: iomuxc::ad_b0::AD_B0_02, /// Pin 2 - pub p2: hal::iomuxc::gpio::GPIO_EMC_04, + pub p2: iomuxc::emc::EMC_04, /// Pin 3 - pub p3: hal::iomuxc::gpio::GPIO_EMC_05, + pub p3: iomuxc::emc::EMC_05, /// Pin 4 - pub p4: hal::iomuxc::gpio::GPIO_EMC_06, + pub p4: iomuxc::emc::EMC_06, /// Pin 5 - pub p5: hal::iomuxc::gpio::GPIO_EMC_08, + pub p5: iomuxc::emc::EMC_08, /// Pin 6 - pub p6: hal::iomuxc::gpio::GPIO_B0_10, + pub p6: iomuxc::b0::B0_10, /// Pin 7 - pub p7: hal::iomuxc::gpio::GPIO_B1_01, + pub p7: iomuxc::b1::B1_01, /// Pin 8 - pub p8: hal::iomuxc::gpio::GPIO_B1_00, + pub p8: iomuxc::b1::B1_00, /// Pin 9 - pub p9: hal::iomuxc::gpio::GPIO_B0_11, + pub p9: iomuxc::b0::B0_11, /// Pin 10 - pub p10: hal::iomuxc::gpio::GPIO_B0_00, + pub p10: iomuxc::b0::B0_00, /// Pin 11 - pub p11: hal::iomuxc::gpio::GPIO_B0_02, + pub p11: iomuxc::b0::B0_02, /// Pin 12 - pub p12: hal::iomuxc::gpio::GPIO_B0_01, + pub p12: iomuxc::b0::B0_01, /// Pin 13 - pub p13: hal::iomuxc::gpio::GPIO_B0_03, + pub p13: iomuxc::b0::B0_03, /// Pin 14 - pub p14: hal::iomuxc::gpio::GPIO_AD_B1_02, + pub p14: iomuxc::ad_b1::AD_B1_02, /// Pin 15 - pub p15: hal::iomuxc::gpio::GPIO_AD_B1_03, + pub p15: iomuxc::ad_b1::AD_B1_03, /// Pin 16 - pub p16: hal::iomuxc::gpio::GPIO_AD_B1_07, + pub p16: iomuxc::ad_b1::AD_B1_07, /// Pin 17 - pub p17: hal::iomuxc::gpio::GPIO_AD_B1_06, + pub p17: iomuxc::ad_b1::AD_B1_06, /// Pin 18 - pub p18: hal::iomuxc::gpio::GPIO_AD_B1_01, + pub p18: iomuxc::ad_b1::AD_B1_01, /// Pin 19 - pub p19: hal::iomuxc::gpio::GPIO_AD_B1_00, + pub p19: iomuxc::ad_b1::AD_B1_00, /// Pin 20 - pub p20: hal::iomuxc::gpio::GPIO_AD_B1_10, + pub p20: iomuxc::ad_b1::AD_B1_10, /// Pin 21 - pub p21: hal::iomuxc::gpio::GPIO_AD_B1_11, + pub p21: iomuxc::ad_b1::AD_B1_11, /// Pin 22 - pub p22: hal::iomuxc::gpio::GPIO_AD_B1_08, + pub p22: iomuxc::ad_b1::AD_B1_08, /// Pin 23 - pub p23: hal::iomuxc::gpio::GPIO_AD_B1_09, + pub p23: iomuxc::ad_b1::AD_B1_09, /// Pin 24 - pub p24: hal::iomuxc::gpio::GPIO_AD_B0_12, + pub p24: iomuxc::ad_b0::AD_B0_12, /// Pin 25 - pub p25: hal::iomuxc::gpio::GPIO_AD_B0_13, + pub p25: iomuxc::ad_b0::AD_B0_13, /// Pin 28 - pub p28: hal::iomuxc::gpio::GPIO_EMC_32, + pub p28: iomuxc::emc::EMC_32, /// Pin 29 - pub p29: hal::iomuxc::gpio::GPIO_EMC_31, + pub p29: iomuxc::emc::EMC_31, /// Pin 33 - pub p33: hal::iomuxc::gpio::GPIO_EMC_07, + pub p33: iomuxc::emc::EMC_07, /// Pin 36 - pub p36: hal::iomuxc::gpio::GPIO_SD_B0_01, + pub p36: iomuxc::sd_b0::SD_B0_01, /// Pin 37 - pub p37: hal::iomuxc::gpio::GPIO_SD_B0_00, + pub p37: iomuxc::sd_b0::SD_B0_00, } /// All peripherals available on the Teensy4 @@ -217,13 +220,13 @@ pub struct Peripherals { /// DCDC converters pub dcdc: hal::dcdc::DCDC, /// PWM1 controller - pub pwm1: hal::pwm::Unclocked, + pub pwm1: hal::pwm::Unclocked, /// PWM2 controller - pub pwm2: hal::pwm::Unclocked, + pub pwm2: hal::pwm::Unclocked, /// PWM3 controller - pub pwm3: hal::pwm::Unclocked, + pub pwm3: hal::pwm::Unclocked, /// PWM4 controller - pub pwm4: hal::pwm::Unclocked, + pub pwm4: hal::pwm::Unclocked, /// Teensy pins pub pins: Pins, /// Unclocked I2C peripherals @@ -232,8 +235,6 @@ pub struct Peripherals { pub spi: hal::spi::Unclocked, /// Unclocked UART peripherals pub uart: hal::uart::Unclocked, - /// General purpose registers, used when configuring GPIO pins. - pub gpr: hal::iomuxc::GPR, /// General purpose timer 1 pub gpt1: hal::gpt::Unclocked, /// General purpose timer 2 @@ -294,42 +295,41 @@ impl Peripherals { pwm3: p.pwm3, pwm4: p.pwm4, pins: Pins { - p0: p.iomuxc.gpio_ad_b0_03, - p1: p.iomuxc.gpio_ad_b0_02, - p2: p.iomuxc.gpio_emc_04, - p3: p.iomuxc.gpio_emc_05, - p4: p.iomuxc.gpio_emc_06, - p5: p.iomuxc.gpio_emc_08, - p6: p.iomuxc.gpio_b0_10, - p7: p.iomuxc.gpio_b1_01, - p8: p.iomuxc.gpio_b1_00, - p9: p.iomuxc.gpio_b0_11, - p10: p.iomuxc.gpio_b0_00, - p11: p.iomuxc.gpio_b0_02, - p12: p.iomuxc.gpio_b0_01, - p13: p.iomuxc.gpio_b0_03, - p14: p.iomuxc.gpio_ad_b1_02, - p15: p.iomuxc.gpio_ad_b1_03, - p16: p.iomuxc.gpio_ad_b1_07, - p17: p.iomuxc.gpio_ad_b1_06, - p18: p.iomuxc.gpio_ad_b1_01, - p19: p.iomuxc.gpio_ad_b1_00, - p20: p.iomuxc.gpio_ad_b1_10, - p21: p.iomuxc.gpio_ad_b1_11, - p22: p.iomuxc.gpio_ad_b1_08, - p23: p.iomuxc.gpio_ad_b1_09, - p24: p.iomuxc.gpio_ad_b0_12, - p25: p.iomuxc.gpio_ad_b0_13, - p28: p.iomuxc.gpio_emc_32, - p29: p.iomuxc.gpio_emc_31, - p33: p.iomuxc.gpio_emc_07, - p36: p.iomuxc.gpio_sd_b0_01, - p37: p.iomuxc.gpio_sd_b0_00, + p0: p.iomuxc.ad_b0.p03, + p1: p.iomuxc.ad_b0.p02, + p2: p.iomuxc.emc.p04, + p3: p.iomuxc.emc.p05, + p4: p.iomuxc.emc.p06, + p5: p.iomuxc.emc.p08, + p6: p.iomuxc.b0.p10, + p7: p.iomuxc.b1.p01, + p8: p.iomuxc.b1.p00, + p9: p.iomuxc.b0.p11, + p10: p.iomuxc.b0.p00, + p11: p.iomuxc.b0.p02, + p12: p.iomuxc.b0.p01, + p13: p.iomuxc.b0.p03, + p14: p.iomuxc.ad_b1.p02, + p15: p.iomuxc.ad_b1.p03, + p16: p.iomuxc.ad_b1.p07, + p17: p.iomuxc.ad_b1.p06, + p18: p.iomuxc.ad_b1.p01, + p19: p.iomuxc.ad_b1.p00, + p20: p.iomuxc.ad_b1.p10, + p21: p.iomuxc.ad_b1.p11, + p22: p.iomuxc.ad_b1.p08, + p23: p.iomuxc.ad_b1.p09, + p24: p.iomuxc.ad_b0.p12, + p25: p.iomuxc.ad_b0.p13, + p28: p.iomuxc.emc.p32, + p29: p.iomuxc.emc.p31, + p33: p.iomuxc.emc.p07, + p36: p.iomuxc.sd_b0.p01, + p37: p.iomuxc.sd_b0.p00, }, i2c: p.i2c, spi: p.spi, uart: p.uart, - gpr: p.iomuxc.gpr, gpt1: p.gpt1, gpt2: p.gpt2, dma: p.dma, @@ -343,9 +343,10 @@ impl Peripherals { /// /// Returns a GPIO that's physically tied to the LED. Use the returned handle /// to drive the LED. -pub fn configure_led(gpr: &mut hal::iomuxc::GPR, pad: hal::iomuxc::gpio::GPIO_B0_03) -> LED { - use hal::gpio::IntoGpio; - pad.alt5().into_gpio().fast(gpr).output() +pub fn configure_led(pad: iomuxc::b0::B0_03) -> LED { + let mut led = hal::gpio::GPIO::new(pad); + led.set_fast(true); + led.output() } /// TODO(mciantyre) define a better yield From 1622ad9bab3c4ee6b9917489329eb8132ec382fb Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Wed, 8 Jul 2020 15:50:11 -0400 Subject: [PATCH 02/20] Use iomuxc module exposed through HAL --- Cargo.toml | 6 ------ examples/dma_spi.rs | 4 ++-- examples/dma_uart.rs | 2 +- examples/rtic_dma_uart_log.rs | 2 +- src/lib.rs | 4 ++-- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2cacda3b..367c8ac5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,12 +20,6 @@ version = "0.3.0" path = "../imxrt/imxrt/imxrt-hal" features = ["imxrt1062", "rt"] -[dependencies.imxrt-iomuxc] -path = "../imxrt/iomuxc" - -[dependencies.imxrt106x-iomuxc] -path = "../imxrt/iomuxc/imxrt106x-iomuxc" - # Tied to "systick" feature, since # SysTick implements a blocking delay trait [dependencies.embedded-hal] diff --git a/examples/dma_spi.rs b/examples/dma_spi.rs index 4da29373..4fa2e24e 100644 --- a/examples/dma_spi.rs +++ b/examples/dma_spi.rs @@ -80,7 +80,7 @@ static TX_BUFFER: Mutex>> = Mutex::new(RefCell::new(Non static RX_BUFFER: Mutex>> = Mutex::new(RefCell::new(None)); type SpiDma = - dma::Peripheral, u16, TxBuffer, RxBuffer>; + dma::Peripheral, u16, TxBuffer, RxBuffer>; // TODO types should be Send static mut SPI_DMA: Option = None; @@ -158,7 +158,7 @@ fn rx_buffer_mut R, R>(act: F) -> Option { } // Pin 20 -type HardwareFlag = bsp::hal::gpio::GPIO; +type HardwareFlag = bsp::hal::gpio::GPIO; static mut HARDWARE_FLAG: Option = None; #[entry] diff --git a/examples/dma_uart.rs b/examples/dma_uart.rs index 2a4f693b..83ba83c4 100644 --- a/examples/dma_uart.rs +++ b/examples/dma_uart.rs @@ -40,7 +40,7 @@ static TX_BUFFER: Mutex>> = Mutex::new(RefCell::new(Non static RX_BUFFER: Mutex>> = Mutex::new(RefCell::new(None)); type DmaUart = bsp::hal::dma::Peripheral< - bsp::hal::uart::UART, + bsp::hal::uart::UART, u8, TxBuffer, RxBuffer, diff --git a/examples/rtic_dma_uart_log.rs b/examples/rtic_dma_uart_log.rs index b2027cd1..da6ccf97 100644 --- a/examples/rtic_dma_uart_log.rs +++ b/examples/rtic_dma_uart_log.rs @@ -41,7 +41,7 @@ type Producer = heapless::spsc::Producer<'static, Ty, Cap>; type Consumer = heapless::spsc::Consumer<'static, Ty, Cap>; // The UART receiver. -type UartRx = bsp::hal::uart::Rx; +type UartRx = bsp::hal::uart::Rx; #[rtic::app(device = teensy4_bsp, monotonic = rtic::cyccnt::CYCCNT, peripherals = true)] const APP: () = { diff --git a/src/lib.rs b/src/lib.rs index 2cd917df..36bac990 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,8 +129,8 @@ pub use imxrt_hal as hal; /// The LED in its final configuration pub type LED = hal::gpio::GPIO; -use imxrt106x_iomuxc as iomuxc; -use imxrt_iomuxc::consts::{U1, U2, U3, U4}; +use hal::iomuxc as iomuxc; +use iomuxc::consts::{U1, U2, U3, U4}; /// Teensy pins that do not yet have a function /// From 7a2a5eb5a59142aa0242540d9524f7ee1941eec9 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Wed, 8 Jul 2020 19:45:37 -0400 Subject: [PATCH 03/20] Target the imxrt-hal crate in the git repo --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 367c8ac5..50a1aba9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,8 @@ teensy4-fcb = { path = "teensy4-fcb" } [dependencies.imxrt-hal] version = "0.3.0" -path = "../imxrt/imxrt/imxrt-hal" +git = "https://github.com/imxrt-rs/imxrt-rs.git" +branch = "iomuxc-integration" features = ["imxrt1062", "rt"] # Tied to "systick" feature, since From e10d4726cd12db31162c8b579e761b1d51ebb6f3 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sun, 19 Jul 2020 07:27:04 -0400 Subject: [PATCH 04/20] Update DMA configuration We removed the DMA Config and ConfigBuilder types. We now configure interrupt behaviors using the channel itself. --- Cargo.toml | 8 +------- examples/dma_spi.rs | 12 +++--------- examples/dma_uart.rs | 13 +++++-------- src/lib.rs | 2 +- 4 files changed, 10 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 50a1aba9..88553730 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ teensy4-fcb = { path = "teensy4-fcb" } [dependencies.imxrt-hal] version = "0.3.0" git = "https://github.com/imxrt-rs/imxrt-rs.git" -branch = "iomuxc-integration" +rev = "1815db6" features = ["imxrt1062", "rt"] # Tied to "systick" feature, since @@ -106,9 +106,3 @@ opt-level = 0 [patch.crates-io.cortex-m-rt] path = "cortex-m-rt-patch" -# Patch `imxrt-hal` so that we may access the `hal::Peripherals::steal` -# constructor. This patch should be removed once a new version of -# `imxrt-hal` is published with the new constructor. -[patch.crates-io.imxrt-hal] -git = "https://github.com/imxrt-rs/imxrt-rs" -rev = "0305aed" \ No newline at end of file diff --git a/examples/dma_spi.rs b/examples/dma_spi.rs index 4fa2e24e..81e64c21 100644 --- a/examples/dma_spi.rs +++ b/examples/dma_spi.rs @@ -220,20 +220,14 @@ fn main() -> ! { let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle); let tx_channel = dma_channels[9].take().unwrap(); - let rx_channel = dma_channels[25].take().unwrap(); - let rx_config = dma::ConfigBuilder::new() - .interrupt_on_completion(true) - .build(); + let mut rx_channel = dma_channels[25].take().unwrap(); + rx_channel.set_interrupt_on_completion(true); // We only want to interrupt when the receive completes. When // the receive completes, we know that we're also done transferring // data. let spi = unsafe { - SPI_DMA = Some(dma::bidirectional_u16( - spi4, - (tx_channel, dma::ConfigBuilder::new().build()), - (rx_channel, rx_config), - )); + SPI_DMA = Some(dma::bidirectional_u16(spi4, tx_channel, rx_channel)); cortex_m::peripheral::NVIC::unmask(interrupt::DMA9_DMA25); SPI_DMA.as_mut().unwrap() }; diff --git a/examples/dma_uart.rs b/examples/dma_uart.rs index 83ba83c4..c6f1a3c3 100644 --- a/examples/dma_uart.rs +++ b/examples/dma_uart.rs @@ -92,18 +92,15 @@ fn main() -> ! { .unwrap(); let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle); - let tx_channel = dma_channels[7].take().unwrap(); - let rx_channel = dma_channels[23].take().unwrap(); + let mut tx_channel = dma_channels[7].take().unwrap(); + let mut rx_channel = dma_channels[23].take().unwrap(); - let config = bsp::hal::dma::ConfigBuilder::new() - .interrupt_on_completion(true) - .build(); + tx_channel.set_interrupt_on_completion(true); + rx_channel.set_interrupt_on_completion(true); let dma_uart = unsafe { DMA_PERIPHERAL = Some(bsp::hal::dma::Peripheral::new_bidirectional( - uart, - (tx_channel, config), - (rx_channel, config), + uart, tx_channel, rx_channel, )); cortex_m::peripheral::NVIC::unmask(interrupt::DMA7_DMA23); DMA_PERIPHERAL.as_mut().unwrap() diff --git a/src/lib.rs b/src/lib.rs index 36bac990..c6f7b359 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,7 +129,7 @@ pub use imxrt_hal as hal; /// The LED in its final configuration pub type LED = hal::gpio::GPIO; -use hal::iomuxc as iomuxc; +use hal::iomuxc; use iomuxc::consts::{U1, U2, U3, U4}; /// Teensy pins that do not yet have a function From eabe955e5acdf42b82edf362ac6aab506b83c6de Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sun, 19 Jul 2020 07:41:12 -0400 Subject: [PATCH 05/20] Finish updating RTIC examples Target the unreleased uart-log crate, since it's designed to the unreleased HAL, which we're also using. --- Cargo.toml | 4 +++- examples/rtic_dma_uart_log.rs | 2 +- examples/rtic_uart_log.rs | 10 +++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 88553730..dfbbc5ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,9 @@ git = "https://github.com/imxrt-rs/imxrt-rs.git" rev = "1815db6" features = ["imxrt1062", "rt"] +[dev-dependencies.imxrt-uart-log] +git = "https://github.com/imxrt-rs/imxrt-uart-log.git" + # Tied to "systick" feature, since # SysTick implements a blocking delay trait [dependencies.embedded-hal] @@ -42,7 +45,6 @@ cortex-m-rtic = "0.5.3" embedded-hal = "0.2.4" heapless = "0.5.5" log = "0.4.8" -imxrt-uart-log = "0.1.0" nb = "0.1.2" panic-halt = "0.2.0" diff --git a/examples/rtic_dma_uart_log.rs b/examples/rtic_dma_uart_log.rs index da6ccf97..6f727fb3 100644 --- a/examples/rtic_dma_uart_log.rs +++ b/examples/rtic_dma_uart_log.rs @@ -149,7 +149,7 @@ const APP: () = { #[task(binds = DMA7_DMA23, resources = [dma_interrupt_count])] fn dma7_dma23(cx: dma7_dma23::Context) { *cx.resources.dma_interrupt_count += 1; - imxrt_uart_log::dma::poll() + imxrt_uart_log::dma::poll(); } // RTIC requires that unused interrupts are declared in an extern block when diff --git a/examples/rtic_uart_log.rs b/examples/rtic_uart_log.rs index 2a4fc90e..a135c3d5 100644 --- a/examples/rtic_uart_log.rs +++ b/examples/rtic_uart_log.rs @@ -16,7 +16,7 @@ #![no_std] #![no_main] -use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; +use embedded_hal::digital::v2::OutputPin; use embedded_hal::serial::Read; use heapless::consts::U256; use panic_halt as _; @@ -35,7 +35,7 @@ type Producer = heapless::spsc::Producer<'static, Ty, Cap>; type Consumer = heapless::spsc::Consumer<'static, Ty, Cap>; // The UART receiver. -type UartRx = bsp::hal::uart::Rx; +type UartRx = bsp::hal::uart::Rx; #[rtic::app(device = teensy4_bsp, monotonic = rtic::cyccnt::CYCCNT, peripherals = true)] const APP: () = { @@ -67,7 +67,7 @@ const APP: () = { ); let mut uart = uarts .uart2 - .init(cx.device.pins.p14.alt2(), cx.device.pins.p15.alt2(), BAUD) + .init(cx.device.pins.p14, cx.device.pins.p15, BAUD) .unwrap(); uart.set_tx_fifo(core::num::NonZeroU8::new(TX_FIFO_SIZE)); uart.set_rx_fifo(true); @@ -80,7 +80,7 @@ const APP: () = { let (q_tx, q_rx) = unsafe { Q.split() }; // LED setup. - let mut led = bsp::configure_led(&mut cx.device.gpr, cx.device.pins.p13); + let mut led = bsp::configure_led(cx.device.pins.p13); led.set_high().unwrap(); // Schedule the first blink. @@ -119,7 +119,7 @@ const APP: () = { } // Toggle the LED. - cx.resources.led.toggle().unwrap(); + cx.resources.led.toggle(); // Schedule the following blink. cx.schedule.blink(cx.scheduled + PERIOD.cycles()).unwrap(); From 47c4657a6cb95c3ae7f5ac47144350cfa5b9fb67 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sun, 26 Jul 2020 15:22:53 -0400 Subject: [PATCH 06/20] Fix the usb_writer example --- examples/usb_writer.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/usb_writer.rs b/examples/usb_writer.rs index 6ffd059b..d4f156e9 100644 --- a/examples/usb_writer.rs +++ b/examples/usb_writer.rs @@ -10,8 +10,6 @@ use bsp::rt; use core::fmt::Write; use teensy4_bsp as bsp; -use embedded_hal::digital::v2::ToggleableOutputPin; - #[rt::entry] fn main() -> ! { let mut p = bsp::Peripherals::take().unwrap(); @@ -21,7 +19,7 @@ fn main() -> ! { p.ccm .pll1 .set_arm_clock(bsp::hal::ccm::PLL1::ARM_HZ, &mut p.ccm.handle, &mut p.dcdc); - let mut led: bsp::LED = bsp::configure_led(&mut p.gpr, p.pins.p13); + let mut led: bsp::LED = bsp::configure_led(p.pins.p13); let mut buffer = [0; 256]; loop { let bytes_read = reader.read(&mut buffer); @@ -39,7 +37,7 @@ fn main() -> ! { } writeln!(writer, "Hello world! 3 + 2 = {}", 3 + 2).unwrap(); - led.toggle().unwrap(); + led.toggle(); p.systick.delay(5000); } } From 16a55fb7c4c5b967b464a544e86cd2adae069ec1 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sun, 19 Jul 2020 22:01:14 -0400 Subject: [PATCH 07/20] Remove BSP peripherals, move pins into t40 module We're moving towards an API that doesn't require us to maintain the BSP peripheral struct. We'll tell users to use the imxrt-hal peripherals. We'll add functions to constrain the IOMUXC pads into Teensy 4.0, or 4.1, pin structs. Users may now construct the Teensy's Systick struct. The user provides the cortex-m- SYST peripheral, and we configure it. We rely on the fact that there's only one safe SYST instance, so we can own it. Finally, we remove the USB struct, there's a usb_init() function to configure the USB logger. We enforce SYST configuration through the interface. --- src/lib.rs | 268 ++----------------------------------------------- src/systick.rs | 31 +++++- src/t40.rs | 223 ++++++++++++++++++++++++++++++++++++++++ src/usb.rs | 98 +++++++++--------- 4 files changed, 308 insertions(+), 312 deletions(-) create mode 100644 src/t40.rs diff --git a/src/lib.rs b/src/lib.rs index c6f7b359..dd285bf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,58 +40,6 @@ //! specific to the Teensy 4. See the `teensy4-fcb` crate for details //! on FCBs. //! -//! ## Physical Pins to Pads and Alternative Functions -//! -//! The sparse table below describes the Teensy 4 pins, the pad ID, and some of the notable alternative functionalities -//! for each pin. We add entries to the table as we add capabilities to the underlying HAL crate. Contributions to complete -//! this table are welcome! If a pad's alternatives are not listed here, consult the iMXRT1060 reference manual. -//! -//! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | -//! | ---- | -------- | -------- | ------------ | ------------ | --------- | ------------ | ---------------- | ------------ | ------- | ------- | ------- | -//! | 0 |`AD_B0_03`| | | `UART6_RX` | |`FlexPWM1_1_X`| | | | | | -//! | 1 |`AD_B0_02`| | | `UART6_TX` | |`FlexPWM1_0_X`| | | | | | -//! | 2 |`EMC_04` | |`FlexPWM4_2_A`| | | | | | | | | -//! | 3 |`EMC_05` | |`FlexPWM4_2_B`| | | | | | | | | -//! | 4 |`EMC_06` | |`FlexPWM2_0_A`| | | | | | | | | -//! | 5 |`EMC_08` | |`FlexPWM2_1_A`| | | | | | | | | -//! | 6 |`B0_10` | | |`FlexPWM2_2_A`| | | | | | | | -//! | 7 |`B1_01` | | | `UART4_RX` | | | |`FlexPWM1_3_B`| | | | -//! | 8 |`B1_00` | | | `UART4_TX` | | | |`FlexPWM1_3_A`| | | | -//! | 9 |`B0_11` | | |`FlexPWM2_2_B`| | | | | | | | -//! | 10 |`B0_00` | | | |`SPI4_PCS0`| | | | | | | -//! | 11 |`B0_02` | | | |`SPI4_SDO` | | | | | | | -//! | 12 |`B0_01` | | | |`SPI4_SDI` | | | | | | | -//! | 13 |`B0_03` | | | |`SPI4_SCK` | |`GPIO2_3` (`LED`) | | | | | -//! | 14 |`AD_B1_02`| | | `UART2_TX` | | | | | | | | -//! | 15 |`AD_B1_03`| | | `UART2_RX` | | | | | | | | -//! | 16 |`AD_B1_07`| |`I2C3_SCL` | `UART3_RX` | | | | | | | | -//! | 17 |`AD_B1_06`| |`I2C3_SDA` | `UART3_TX` | | | | | | | | -//! | 18 |`AD_B1_01`| | | |`I2C1_SDA` | | | | | | | -//! | 19 |`AD_B1_00`| | | `UART2_CTS` |`I2C1_SCL` | | | | | | | -//! | 20 |`AD_B1_10`| | | `UART8_TX` | | | | | | | | -//! | 21 |`AD_B1_11`| | | `UART8_RX` | | | | | | | | -//! | 22 |`AD_B1_08`| |`FlexPWM4_0_A`| | | | | | | | | -//! | 23 |`AD_B1_09`| |`FlexPWM4_1_A`| | | | | | | | | -//! | 24 |`AD_B0_12`|`I2C4_SCL`| | `UART1_TX` | |`FlexPWM1_2_X`| | | | | | -//! | 25 |`AD_B0_13`|`I2C4_SDA`| | `UART1_RX` | |`FlexPWM1_3_X`| | | | | | -//! | 26 |`AD_B1_14`| | | | | | | | | | | -//! | 27 |`AD_B1_15`| | | | | | | | | | | -//! | 28 |`EMC_32` | |`FlexPWM3_1_B`| `UART7_RX` | | | | | | | | -//! | 29 |`EMC_31` | |`FlexPWM3_1_A`| `UART7_TX` |`SPI1_PCS1`| | | | | | | -//! | 30 |`EMC_37` | | | | | | | | | | | -//! | 31 |`EMC_36` | | | | | | | | | | | -//! | 32 |`B0_12` | | | | | | | | | | | -//! | 33 |`EMC_07` | |`FlexPWM2_0_B`| | | | | | | | | -//! | 34 |`SD_B0_03`| |`FlexPWM1_1_B`| | | `SPI1_SDI` | | | | | | -//! | 35 |`SD_B0_02`| |`FlexPWM1_1_A`| | | `SPI1_SDO` | | | | | | -//! | 36 |`SD_B0_01`| |`FlexPWM1_0_B`| `I2C3_SDA` | | `SPI1_PCS0` | | | | | | -//! | 37 |`SD_B0_00`| |`FlexPWM1_0_A`| `I2C3_SCL` | | `SPI1_SCK` | | | | | | -//! | 38 |`SD_B0_05`| |`FlexPWM1_2_B`| `UART8_RX` | | | | | | | | -//! | 39 |`SD_B0_04`| |`FlexPWM1_2_A`| `UART8_TX` | | | | | | | | -//! -//! References: -//! - [Teensy 4.0 Schematic Diagram](https://www.pjrc.com/teensy/schematic.html) -//! //! ## Examples //! //! See the `teensy4-examples` crate for build-able, run-able @@ -110,6 +58,8 @@ // Need to reference this so that it doesn't get stripped out extern crate teensy4_fcb; +pub mod t40; + #[cfg(feature = "systick")] mod systick; #[cfg(feature = "usb-logging")] @@ -117,6 +67,8 @@ pub mod usb; #[cfg(feature = "systick")] pub use systick::SysTick; +#[cfg(feature = "usb-logging")] +pub use usb::{init as usb_init, LoggingConfig}; pub use hal::ral::interrupt; // `rtic` expects these in the root. @@ -126,218 +78,10 @@ pub use hal::ral::{interrupt as Interrupt, NVIC_PRIO_BITS}; pub use cortex_m_rt as rt; pub use imxrt_hal as hal; -/// The LED in its final configuration -pub type LED = hal::gpio::GPIO; - use hal::iomuxc; -use iomuxc::consts::{U1, U2, U3, U4}; - -/// Teensy pins that do not yet have a function -/// -/// Pin 13 can be used for several things; one common usage is for the on-board LED. -pub struct Pins { - /// Pin 0 - pub p0: iomuxc::ad_b0::AD_B0_03, - /// Pin 1 - pub p1: iomuxc::ad_b0::AD_B0_02, - /// Pin 2 - pub p2: iomuxc::emc::EMC_04, - /// Pin 3 - pub p3: iomuxc::emc::EMC_05, - /// Pin 4 - pub p4: iomuxc::emc::EMC_06, - /// Pin 5 - pub p5: iomuxc::emc::EMC_08, - /// Pin 6 - pub p6: iomuxc::b0::B0_10, - /// Pin 7 - pub p7: iomuxc::b1::B1_01, - /// Pin 8 - pub p8: iomuxc::b1::B1_00, - /// Pin 9 - pub p9: iomuxc::b0::B0_11, - /// Pin 10 - pub p10: iomuxc::b0::B0_00, - /// Pin 11 - pub p11: iomuxc::b0::B0_02, - /// Pin 12 - pub p12: iomuxc::b0::B0_01, - /// Pin 13 - pub p13: iomuxc::b0::B0_03, - /// Pin 14 - pub p14: iomuxc::ad_b1::AD_B1_02, - /// Pin 15 - pub p15: iomuxc::ad_b1::AD_B1_03, - /// Pin 16 - pub p16: iomuxc::ad_b1::AD_B1_07, - /// Pin 17 - pub p17: iomuxc::ad_b1::AD_B1_06, - /// Pin 18 - pub p18: iomuxc::ad_b1::AD_B1_01, - /// Pin 19 - pub p19: iomuxc::ad_b1::AD_B1_00, - /// Pin 20 - pub p20: iomuxc::ad_b1::AD_B1_10, - /// Pin 21 - pub p21: iomuxc::ad_b1::AD_B1_11, - /// Pin 22 - pub p22: iomuxc::ad_b1::AD_B1_08, - /// Pin 23 - pub p23: iomuxc::ad_b1::AD_B1_09, - /// Pin 24 - pub p24: iomuxc::ad_b0::AD_B0_12, - /// Pin 25 - pub p25: iomuxc::ad_b0::AD_B0_13, - /// Pin 28 - pub p28: iomuxc::emc::EMC_32, - /// Pin 29 - pub p29: iomuxc::emc::EMC_31, - /// Pin 33 - pub p33: iomuxc::emc::EMC_07, - /// Pin 36 - pub p36: iomuxc::sd_b0::SD_B0_01, - /// Pin 37 - pub p37: iomuxc::sd_b0::SD_B0_00, -} -/// All peripherals available on the Teensy4 -/// -/// Nearly all of these are re-exports from the HAL. Exclusions include -/// -/// - `usb`, which is a USB logger -/// - `pins`, which are the Teensy 4's available pins -/// -/// See the [module-level documentation](index.html) for more information. -#[non_exhaustive] -pub struct Peripherals { - /// Clock control module (forwarded from the HAL) - pub ccm: hal::ccm::CCM, - /// PIT timers (forwarded from the HAL) - pub pit: hal::pit::UnclockedPIT, - /// The USB logger and serial reader - #[cfg(feature = "usb-logging")] - pub usb: usb::USB, - /// DCDC converters - pub dcdc: hal::dcdc::DCDC, - /// PWM1 controller - pub pwm1: hal::pwm::Unclocked, - /// PWM2 controller - pub pwm2: hal::pwm::Unclocked, - /// PWM3 controller - pub pwm3: hal::pwm::Unclocked, - /// PWM4 controller - pub pwm4: hal::pwm::Unclocked, - /// Teensy pins - pub pins: Pins, - /// Unclocked I2C peripherals - pub i2c: hal::i2c::Unclocked, - /// Unclocked SPI peripherals - pub spi: hal::spi::Unclocked, - /// Unclocked UART peripherals - pub uart: hal::uart::Unclocked, - /// General purpose timer 1 - pub gpt1: hal::gpt::Unclocked, - /// General purpose timer 2 - pub gpt2: hal::gpt::Unclocked, - /// DMA channels - pub dma: hal::dma::Unclocked, - /// The SysTick delay timer - #[cfg(feature = "systick")] - pub systick: SysTick, -} - -/// SYSTICK external clock frequency -/// -/// See Section 12.3.2.1 of the reference manual. The note -/// explains that the 24MHz clock is divided down to 100KHz -/// before reaching SYSTICK. -const SYSTICK_EXT_FREQ: u32 = 100_000; - -impl Peripherals { - /// Instantiate the system peripherals. This may only be called once! - pub fn take() -> Option { - let p = hal::Peripherals::take()?; - let mut cp = cortex_m::Peripherals::take()?; - Self::set_systick(&mut cp.SYST); - Some(Peripherals::new(p)) - } - - #[cfg(feature = "rtic")] - /// Steal all of the HAL's peripherals. - /// - /// # Safety - /// - /// NOTE: This constructor is only intended for use with the `rtic` crate. This is **not** an - /// alternative to the `take` constructor. The `take` constructor sets the system timer - /// interrupt while this constructor does not seeing as `rtic` will take care of this for us. - pub unsafe fn steal() -> Self { - Self::new(hal::Peripherals::steal()) - } - - fn set_systick(systick: &mut cortex_m::peripheral::SYST) { - systick.disable_counter(); - systick.set_clock_source(cortex_m::peripheral::syst::SystClkSource::External); - systick.set_reload((SYSTICK_EXT_FREQ / 1000) - 1); - systick.clear_current(); - systick.enable_counter(); - systick.enable_interrupt(); - } - - fn new(p: hal::Peripherals) -> Peripherals { - Peripherals { - ccm: p.ccm, - pit: p.pit, - #[cfg(feature = "usb-logging")] - usb: usb::USB::new(), - dcdc: p.dcdc, - pwm1: p.pwm1, - pwm2: p.pwm2, - pwm3: p.pwm3, - pwm4: p.pwm4, - pins: Pins { - p0: p.iomuxc.ad_b0.p03, - p1: p.iomuxc.ad_b0.p02, - p2: p.iomuxc.emc.p04, - p3: p.iomuxc.emc.p05, - p4: p.iomuxc.emc.p06, - p5: p.iomuxc.emc.p08, - p6: p.iomuxc.b0.p10, - p7: p.iomuxc.b1.p01, - p8: p.iomuxc.b1.p00, - p9: p.iomuxc.b0.p11, - p10: p.iomuxc.b0.p00, - p11: p.iomuxc.b0.p02, - p12: p.iomuxc.b0.p01, - p13: p.iomuxc.b0.p03, - p14: p.iomuxc.ad_b1.p02, - p15: p.iomuxc.ad_b1.p03, - p16: p.iomuxc.ad_b1.p07, - p17: p.iomuxc.ad_b1.p06, - p18: p.iomuxc.ad_b1.p01, - p19: p.iomuxc.ad_b1.p00, - p20: p.iomuxc.ad_b1.p10, - p21: p.iomuxc.ad_b1.p11, - p22: p.iomuxc.ad_b1.p08, - p23: p.iomuxc.ad_b1.p09, - p24: p.iomuxc.ad_b0.p12, - p25: p.iomuxc.ad_b0.p13, - p28: p.iomuxc.emc.p32, - p29: p.iomuxc.emc.p31, - p33: p.iomuxc.emc.p07, - p36: p.iomuxc.sd_b0.p01, - p37: p.iomuxc.sd_b0.p00, - }, - i2c: p.i2c, - spi: p.spi, - uart: p.uart, - gpt1: p.gpt1, - gpt2: p.gpt2, - dma: p.dma, - #[cfg(feature = "systick")] - systick: SysTick::new(), - } - } -} +/// The LED in its final configuration +pub type LED = hal::gpio::GPIO; /// Configure the board's LED /// diff --git a/src/systick.rs b/src/systick.rs index 7c711084..a4721407 100644 --- a/src/systick.rs +++ b/src/systick.rs @@ -20,7 +20,7 @@ fn SysTick() { /// Read the systick counter. Returns an absolute value describing /// the number of milliseconds since the SYSTICK handler was enabled. /// This may be used to implement coarse timing. -pub fn read() -> u32 { +fn read() -> u32 { unsafe { core::ptr::read_volatile(&systick_millis_count) } } @@ -44,15 +44,38 @@ pub extern "C" fn delay(millis: u32) { } } +/// SYSTICK external clock frequency +/// +/// See Section 12.3.2.1 of the reference manual. The note +/// explains that the 24MHz clock is divided down to 100KHz +/// before reaching SYSTICK. +const SYSTICK_EXT_FREQ: u32 = 100_000; + /// A type that represents the system timer, SYSTICK /// /// `SysTick` implements the `embedded_hal`'s `DelayMs` trait. It /// may be used to implement simple, blocking delays. -pub struct SysTick(()); +pub struct SysTick(cortex_m::peripheral::SYST); impl SysTick { - pub(crate) fn new() -> Self { - SysTick(()) + /// Convert the normal cortex-m SYST peripheral into a Teensy `SysTick` + /// + /// `new()` will configure the systick counter for a 1ms tick. When `new()` returns, + /// systick is counting. + /// + /// # Safety + /// + /// `new()` is safe because it assumes that it has the only `SYST` instance. + /// The only way you could acquire two `SysTick` is if you've unsafely obtained + /// a second `SYST` instance. + pub fn new(mut systick: cortex_m::peripheral::SYST) -> SysTick { + systick.disable_counter(); + systick.set_clock_source(cortex_m::peripheral::syst::SystClkSource::External); + systick.set_reload((SYSTICK_EXT_FREQ / 1000) - 1); + systick.clear_current(); + systick.enable_counter(); + systick.enable_interrupt(); + SysTick(systick) } /// Blocks for `ms` milliseconds diff --git a/src/t40.rs b/src/t40.rs new file mode 100644 index 00000000..c68cc1c1 --- /dev/null +++ b/src/t40.rs @@ -0,0 +1,223 @@ +//! Teensy 4.0 specific API +//! +//! ## Pins, Pads and Alternates +//! +//! The sparse table below describes the Teensy 4 pins, the pad ID, and some of the notable alternate functionalities +//! for each pin. We add entries to the table as we add capabilities to the underlying HAL crate. If a pad's alternates +//! are not listed here, consult the iMXRT1060 reference manual. +//! +//! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | +//! | ---- | -------- | -------- | ------------ | ------------ | --------- | ------------ | ---------------- | ------------ | ------- | ------- | ------- | +//! | 0 |`AD_B0_03`| | | `UART6_RX` | |`FlexPWM1_1_X`| | | | | | +//! | 1 |`AD_B0_02`| | | `UART6_TX` | |`FlexPWM1_0_X`| | | | | | +//! | 2 |`EMC_04` | |`FlexPWM4_2_A`| | | | | | | | | +//! | 3 |`EMC_05` | |`FlexPWM4_2_B`| | | | | | | | | +//! | 4 |`EMC_06` | |`FlexPWM2_0_A`| | | | | | | | | +//! | 5 |`EMC_08` | |`FlexPWM2_1_A`| | | | | | | | | +//! | 6 |`B0_10` | | |`FlexPWM2_2_A`| | | | | | | | +//! | 7 |`B1_01` | | | `UART4_RX` | | | |`FlexPWM1_3_B`| | | | +//! | 8 |`B1_00` | | | `UART4_TX` | | | |`FlexPWM1_3_A`| | | | +//! | 9 |`B0_11` | | |`FlexPWM2_2_B`| | | | | | | | +//! | 10 |`B0_00` | | | |`SPI4_PCS0`| | | | | | | +//! | 11 |`B0_02` | | | |`SPI4_SDO` | | | | | | | +//! | 12 |`B0_01` | | | |`SPI4_SDI` | | | | | | | +//! | 13 |`B0_03` | | | |`SPI4_SCK` | |`GPIO2_3` (`LED`) | | | | | +//! | 14 |`AD_B1_02`| | | `UART2_TX` | | | | | | | | +//! | 15 |`AD_B1_03`| | | `UART2_RX` | | | | | | | | +//! | 16 |`AD_B1_07`| |`I2C3_SCL` | `UART3_RX` | | | | | | | | +//! | 17 |`AD_B1_06`| |`I2C3_SDA` | `UART3_TX` | | | | | | | | +//! | 18 |`AD_B1_01`| | | |`I2C1_SDA` | | | | | | | +//! | 19 |`AD_B1_00`| | | `UART2_CTS` |`I2C1_SCL` | | | | | | | +//! | 20 |`AD_B1_10`| | | `UART8_TX` | | | | | | | | +//! | 21 |`AD_B1_11`| | | `UART8_RX` | | | | | | | | +//! | 22 |`AD_B1_08`| |`FlexPWM4_0_A`| | | | | | | | | +//! | 23 |`AD_B1_09`| |`FlexPWM4_1_A`| | | | | | | | | +//! | 24 |`AD_B0_12`|`I2C4_SCL`| | `UART1_TX` | |`FlexPWM1_2_X`| | | | | | +//! | 25 |`AD_B0_13`|`I2C4_SDA`| | `UART1_RX` | |`FlexPWM1_3_X`| | | | | | +//! | 26 |`AD_B1_14`| | | | | | | | | | | +//! | 27 |`AD_B1_15`| | | | | | | | | | | +//! | 28 |`EMC_32` | |`FlexPWM3_1_B`| `UART7_RX` | | | | | | | | +//! | 29 |`EMC_31` | |`FlexPWM3_1_A`| `UART7_TX` |`SPI1_PCS1`| | | | | | | +//! | 30 |`EMC_37` | | | | | | | | | | | +//! | 31 |`EMC_36` | | | | | | | | | | | +//! | 32 |`B0_12` | | | | | | | | | | | +//! | 33 |`EMC_07` | |`FlexPWM2_0_B`| | | | | | | | | +//! | 34 |`SD_B0_03`| |`FlexPWM1_1_B`| | | `SPI1_SDI` | | | | | | +//! | 35 |`SD_B0_02`| |`FlexPWM1_1_A`| | | `SPI1_SDO` | | | | | | +//! | 36 |`SD_B0_01`| |`FlexPWM1_0_B`| `I2C3_SDA` | | `SPI1_PCS0` | | | | | | +//! | 37 |`SD_B0_00`| |`FlexPWM1_0_A`| `I2C3_SCL` | | `SPI1_SCK` | | | | | | +//! | 38 |`SD_B0_05`| |`FlexPWM1_2_B`| `UART8_RX` | | | | | | | | +//! | 39 |`SD_B0_04`| |`FlexPWM1_2_A`| `UART8_TX` | | | | | | | | +//! +//! References: +//! - [Teensy 4.0 Schematic Diagram](https://www.pjrc.com/teensy/schematic.html) + +use crate::hal::iomuxc; + +/// Pin 0 +pub type P0 = iomuxc::ad_b0::AD_B0_03; +/// Pin 1 +pub type P1 = iomuxc::ad_b0::AD_B0_02; +/// Pin 2 +pub type P2 = iomuxc::emc::EMC_04; +/// Pin 3 +pub type P3 = iomuxc::emc::EMC_05; +/// Pin 4 +pub type P4 = iomuxc::emc::EMC_06; +/// Pin 5 +pub type P5 = iomuxc::emc::EMC_08; +/// Pin 6 +pub type P6 = iomuxc::b0::B0_10; +/// Pin 7 +pub type P7 = iomuxc::b1::B1_01; +/// Pin 8 +pub type P8 = iomuxc::b1::B1_00; +/// Pin 9 +pub type P9 = iomuxc::b0::B0_11; +/// Pin 10 +pub type P10 = iomuxc::b0::B0_00; +/// Pin 11 +pub type P11 = iomuxc::b0::B0_02; +/// Pin 12 +pub type P12 = iomuxc::b0::B0_01; +/// Pin 13 +pub type P13 = iomuxc::b0::B0_03; +/// Pin 14 +pub type P14 = iomuxc::ad_b1::AD_B1_02; +/// Pin 15 +pub type P15 = iomuxc::ad_b1::AD_B1_03; +/// Pin 16 +pub type P16 = iomuxc::ad_b1::AD_B1_07; +/// Pin 17 +pub type P17 = iomuxc::ad_b1::AD_B1_06; +/// Pin 18 +pub type P18 = iomuxc::ad_b1::AD_B1_01; +/// Pin 19 +pub type P19 = iomuxc::ad_b1::AD_B1_00; +/// Pin 20 +pub type P20 = iomuxc::ad_b1::AD_B1_10; +/// Pin 21 +pub type P21 = iomuxc::ad_b1::AD_B1_11; +/// Pin 22 +pub type P22 = iomuxc::ad_b1::AD_B1_08; +/// Pin 23 +pub type P23 = iomuxc::ad_b1::AD_B1_09; +/// Pin 24 +pub type P24 = iomuxc::ad_b0::AD_B0_12; +/// Pin 25 +pub type P25 = iomuxc::ad_b0::AD_B0_13; +/// Pin 28 +pub type P28 = iomuxc::emc::EMC_32; +/// Pin 29 +pub type P29 = iomuxc::emc::EMC_31; +/// Pin 33 +pub type P33 = iomuxc::emc::EMC_07; +/// Pin 36 +pub type P36 = iomuxc::sd_b0::SD_B0_01; +/// Pin 37 +pub type P37 = iomuxc::sd_b0::SD_B0_00; + +/// Teensy 4.0 pins +/// +/// Pin 13 can be used for several things; one common usage is for the on-board LED. +pub struct Pins { + /// Pin 0 + pub p0: P0, + /// Pin 1 + pub p1: P1, + /// Pin 2 + pub p2: P2, + /// Pin 3 + pub p3: P3, + /// Pin 4 + pub p4: P4, + /// Pin 5 + pub p5: P5, + /// Pin 6 + pub p6: P6, + /// Pin 7 + pub p7: P7, + /// Pin 8 + pub p8: P8, + /// Pin 9 + pub p9: P9, + /// Pin 10 + pub p10: P10, + /// Pin 11 + pub p11: P11, + /// Pin 12 + pub p12: P12, + /// Pin 13 + pub p13: P13, + /// Pin 14 + pub p14: P14, + /// Pin 15 + pub p15: P15, + /// Pin 16 + pub p16: P16, + /// Pin 17 + pub p17: P17, + /// Pin 18 + pub p18: P18, + /// Pin 19 + pub p19: P19, + /// Pin 20 + pub p20: P20, + /// Pin 21 + pub p21: P21, + /// Pin 22 + pub p22: P22, + /// Pin 23 + pub p23: P23, + /// Pin 24 + pub p24: P24, + /// Pin 25 + pub p25: P25, + /// Pin 28 + pub p28: P28, + /// Pin 29 + pub p29: P29, + /// Pin 33 + pub p33: P33, + /// Pin 36 + pub p36: P36, + /// Pin 37 + pub p37: P37, +} + +/// Constrain the processor pads to the Teensy 4.0 pins +pub fn pins(iomuxc: crate::hal::iomuxc::Pads) -> Pins { + Pins { + p0: iomuxc.ad_b0.p03, + p1: iomuxc.ad_b0.p02, + p2: iomuxc.emc.p04, + p3: iomuxc.emc.p05, + p4: iomuxc.emc.p06, + p5: iomuxc.emc.p08, + p6: iomuxc.b0.p10, + p7: iomuxc.b1.p01, + p8: iomuxc.b1.p00, + p9: iomuxc.b0.p11, + p10: iomuxc.b0.p00, + p11: iomuxc.b0.p02, + p12: iomuxc.b0.p01, + p13: iomuxc.b0.p03, + p14: iomuxc.ad_b1.p02, + p15: iomuxc.ad_b1.p03, + p16: iomuxc.ad_b1.p07, + p17: iomuxc.ad_b1.p06, + p18: iomuxc.ad_b1.p01, + p19: iomuxc.ad_b1.p00, + p20: iomuxc.ad_b1.p10, + p21: iomuxc.ad_b1.p11, + p22: iomuxc.ad_b1.p08, + p23: iomuxc.ad_b1.p09, + p24: iomuxc.ad_b0.p12, + p25: iomuxc.ad_b0.p13, + p28: iomuxc.emc.p32, + p29: iomuxc.emc.p31, + p33: iomuxc.emc.p07, + p36: iomuxc.sd_b0.p01, + p37: iomuxc.sd_b0.p00, + } +} diff --git a/src/usb.rs b/src/usb.rs index 743fff6a..846bab3f 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -9,7 +9,10 @@ //! [`log`]: https://crates.io/crates/log use crate::interrupt; // bring in interrupt variants for #[interrupt] macro -use core::fmt; +use core::{ + fmt, + sync::atomic::{AtomicBool, Ordering}, +}; use teensy4_usb_sys as usbsys; /// Logging configuration @@ -46,58 +49,61 @@ impl Default for LoggingConfig { } } -/// A handle that enables USB I/O -/// -/// Calling `init` will initialize the USB stack and enable the USB interrupt. -/// Once initialized, messages will be written over USB. Alternatively, use `split` -/// to turn the USB into `Reader` and `Writer` halves. -pub struct USB(&'static mut Logger); - -impl USB { - /// Initializes the USB stack. This prepares the logging back-end. Returns a `Reader` - /// that can read USB serial messages. - /// - /// To select the default logger behavior, specify `Default::default()` as the - /// argument for `config`. - /// - /// This may only be called once. If this is not called, we do not initialize the logger, - /// and log messages will not be written to the USB host. - pub fn init(self, config: LoggingConfig) -> Reader { - self.0.enabled = true; - self.0.filters = config.filters; - ::log::set_logger(self.0) - .map(|_| ::log::set_max_level(config.max_level)) - .unwrap(); - Self::start(); - Reader(core::marker::PhantomData) +/// Indicate an error when preparing the USB stack +#[derive(Debug)] +pub enum Error { + /// The error indicates that you've already set the logger, either from this + /// interface or through another logging interface. + SetLogger, + /// The USB stack is already in use + AlreadySet, +} + +impl From<::log::SetLoggerError> for Error { + fn from(_: ::log::SetLoggerError) -> Self { + Error::SetLogger } +} - /// # Safety - /// - /// This is only called once, when we're setting up peripherals. - /// If `init()` is called, we will set the members of the struct - /// into their state. There can only be one Logging struct, so - /// there's only one reference to the logger singleton. - pub(super) fn new() -> Self { - unsafe { USB(&mut LOGGER) } +static TAKEN: AtomicBool = AtomicBool::new(false); + +/// Initializes the USB stack. This prepares the logging back-end. Returns a `Reader` +/// that can read USB serial messages. +/// +/// To select the default logger behavior, specify `Default::default()` as the +/// argument for `config`. +/// +/// Before configuring the USB logger, you'll need to configure [`SysTick`](struct.SysTick.html). +/// Once you've configured `SysTick`, supply its reference here. +/// +/// This may only be called once. If this is not called, we do not initialize the logger, +/// and log messages will not be written to the USB host. Returns a +/// [`SetLoggerError`](struct.SetLoggerError.html) if the logging subsystem already has a +/// logger. +pub fn init(_: &crate::SysTick, config: LoggingConfig) -> Result { + let taken = TAKEN.swap(true, Ordering::SeqCst); + if taken { + return Err(Error::AlreadySet); } + unsafe { + LOGGER.enabled = true; + LOGGER.filters = config.filters; - #[inline(always)] - fn start() { - unsafe { - usbsys::usb_pll_start(); - usbsys::usb_init(); - cortex_m::peripheral::NVIC::unmask(crate::interrupt::USB_OTG1); - } + ::log::set_logger(&LOGGER).map(|_| ::log::set_max_level(config.max_level))?; + + usbsys::usb_pll_start(); + usbsys::usb_init(); + cortex_m::peripheral::NVIC::unmask(crate::interrupt::USB_OTG1); } + Ok(Reader(core::marker::PhantomData)) +} - /// Split the USB handle into reader and writer halves - pub fn split(self) -> (Reader, Writer) { - Self::start(); - ((Reader(core::marker::PhantomData)), unsafe { - Writer::new() - }) +pub fn split() -> Result<(Reader, Writer), Error> { + let taken = TAKEN.swap(true, Ordering::SeqCst); + if taken { + return Err(Error::AlreadySet); } + Ok((Reader(core::marker::PhantomData), unsafe { Writer::new() })) } #[crate::rt::interrupt] From 9f04d006db18b2ae00866e90d89df4a1f68ec8e9 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sun, 19 Jul 2020 22:33:20 -0400 Subject: [PATCH 08/20] Update all examples --- Cargo.toml | 2 +- examples/dma_memcpy.rs | 7 ++++--- examples/dma_spi.rs | 20 +++++++++----------- examples/dma_uart.rs | 14 +++++++------- examples/gpt.rs | 3 ++- examples/i2c.rs | 10 ++++++---- examples/led.rs | 3 ++- examples/pit.rs | 6 ++++-- examples/pwm.rs | 18 ++++++++++-------- examples/rtic_blink.rs | 4 ++-- examples/rtic_dma_uart_log.rs | 9 ++++----- examples/rtic_led.rs | 4 ++-- examples/rtic_uart_log.rs | 9 ++++----- examples/spi.rs | 20 +++++++++----------- examples/systick.rs | 9 ++++++--- examples/timer.rs | 8 ++++---- examples/uart.rs | 17 ++++++++--------- examples/usb.rs | 20 +++++++++++++------- src/lib.rs | 4 ++-- 19 files changed, 99 insertions(+), 88 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index dfbbc5ac..6b527d9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,7 +96,7 @@ systick = ["embedded-hal"] # NOTE: When using this feature along with the `rtic` crate the # default features must first be disabled in order to avoid a # duplicate definition of `SysTick`. -rtic = [] +rtic = ["imxrt-hal/rtic"] # Don't optimize build dependencies, like proc macros. # Helps with build times. diff --git a/examples/dma_memcpy.rs b/examples/dma_memcpy.rs index 13da9cd7..ca8668c1 100644 --- a/examples/dma_memcpy.rs +++ b/examples/dma_memcpy.rs @@ -34,8 +34,9 @@ const NUMBER_OF_ELEMENTS: Element = (BUFFER_SIZE - 7) as Element; #[entry] fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); - peripherals.usb.init(Default::default()); - peripherals.systick.delay(5_000); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + bsp::usb_init(&systick, Default::default()).unwrap(); + systick.delay(5_000); let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle); let channel = dma_channels[13].take().unwrap(); @@ -141,6 +142,6 @@ fn main() -> ! { tx_buffer.clear(); start += 1; - peripherals.systick.delay(5_000); + systick.delay(5_000); } } diff --git a/examples/dma_spi.rs b/examples/dma_spi.rs index 81e64c21..18b65177 100644 --- a/examples/dma_spi.rs +++ b/examples/dma_spi.rs @@ -164,7 +164,9 @@ static mut HARDWARE_FLAG: Option = None; #[entry] fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); - peripherals.usb.init(Default::default()); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + bsp::usb_init(&systick, Default::default()).unwrap(); + let pins = bsp::t40::pins(peripherals.iomuxc); peripherals.ccm.pll1.set_arm_clock( bsp::hal::ccm::PLL1::ARM_HZ, @@ -173,7 +175,7 @@ fn main() -> ! { ); unsafe { - let p20 = peripherals.pins.p20; + let p20 = pins.p20; HARDWARE_FLAG = Some(bsp::hal::gpio::GPIO::new(p20).output()); } @@ -181,7 +183,7 @@ fn main() -> ! { // SPI setup // - peripherals.systick.delay(5000); + systick.delay(5000); log::info!("Initializing SPI4 clocks..."); let (_, _, _, spi4_builder) = peripherals.spi.clock( @@ -191,12 +193,8 @@ fn main() -> ! { ); log::info!("Constructing SPI4 peripheral..."); - let mut spi4 = spi4_builder.build( - peripherals.pins.p11, - peripherals.pins.p12, - peripherals.pins.p13, - ); - spi4.enable_chip_select_0(peripherals.pins.p10); + let mut spi4 = spi4_builder.build(pins.p11, pins.p12, pins.p13); + spi4.enable_chip_select_0(pins.p10); match spi4.set_clock_speed(bsp::hal::spi::ClockSpeed(SPI_BAUD_RATE_HZ)) { Ok(()) => { @@ -263,7 +261,7 @@ fn main() -> ! { core::sync::atomic::spin_loop_hint(); } } - peripherals.systick.delay(500); + systick.delay(500); log::info!("Started DMA transfers for WHO_AM_I"); FLAG.store(false, Ordering::Release); @@ -315,7 +313,7 @@ fn main() -> ! { } } - peripherals.systick.delay(500); + systick.delay(500); FLAG.store(false, Ordering::Release); prepare_transfer(spi); loop { diff --git a/examples/dma_uart.rs b/examples/dma_uart.rs index c6f1a3c3..e59ce990 100644 --- a/examples/dma_uart.rs +++ b/examples/dma_uart.rs @@ -79,17 +79,17 @@ unsafe fn DMA7_DMA23() { #[entry] fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); - peripherals.usb.init(Default::default()); - peripherals.systick.delay(5_000); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + bsp::usb_init(&systick, Default::default()).unwrap(); + let pins = bsp::t40::pins(peripherals.iomuxc); + + systick.delay(5_000); let uarts = peripherals.uart.clock( &mut peripherals.ccm.handle, bsp::hal::ccm::uart::ClockSelect::OSC, bsp::hal::ccm::uart::PrescalarSelect::DIVIDE_1, ); - let uart = uarts - .uart2 - .init(peripherals.pins.p14, peripherals.pins.p15, BAUD) - .unwrap(); + let uart = uarts.uart2.init(pins.p14, pins.p15, BAUD).unwrap(); let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle); let mut tx_channel = dma_channels[7].take().unwrap(); @@ -105,7 +105,7 @@ fn main() -> ! { cortex_m::peripheral::NVIC::unmask(interrupt::DMA7_DMA23); DMA_PERIPHERAL.as_mut().unwrap() }; - let mut led = bsp::configure_led(peripherals.pins.p13); + let mut led = bsp::configure_led(pins.p13); let rx_buffer = match bsp::hal::dma::Circular::new(&RX_MEM.0) { Ok(circular) => circular, diff --git a/examples/gpt.rs b/examples/gpt.rs index ed7b0ab0..bf5f166c 100644 --- a/examples/gpt.rs +++ b/examples/gpt.rs @@ -28,6 +28,7 @@ unsafe fn GPT1() { #[entry] fn main() -> ! { let mut periphs = bsp::Peripherals::take().unwrap(); + let pins = bsp::t40::pins(periphs.iomuxc); let (_, ipg_hz) = periphs.ccm.pll1.set_arm_clock( bsp::hal::ccm::PLL1::ARM_HZ, @@ -52,7 +53,7 @@ fn main() -> ! { cortex_m::peripheral::NVIC::unmask(interrupt::GPT1); } - let mut led = bsp::configure_led(periphs.pins.p13); + let mut led = bsp::configure_led(pins.p13); loop { let gpt1 = unsafe { TIMER.as_mut().unwrap() }; gpt1.set_enable(false); diff --git a/examples/i2c.rs b/examples/i2c.rs index 3da4ba45..ed2c458e 100644 --- a/examples/i2c.rs +++ b/examples/i2c.rs @@ -43,8 +43,10 @@ where #[bsp::rt::entry] fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); - peripherals.usb.init(Default::default()); - peripherals.systick.delay(5000); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + let pins = bsp::t40::pins(peripherals.iomuxc); + bsp::usb_init(&systick, Default::default()).unwrap(); + systick.delay(5000); log::info!("Enabling I2C clocks..."); let (_, _, i2c3_builder, _) = peripherals.i2c.clock( @@ -54,7 +56,7 @@ fn main() -> ! { ); log::info!("Constructing I2C3 instance on pins 16 and 17..."); - let mut i2c3 = i2c3_builder.build(peripherals.pins.p16, peripherals.pins.p17); + let mut i2c3 = i2c3_builder.build(pins.p16, pins.p17); if let Err(err) = i2c3.set_bus_idle_timeout(core::time::Duration::from_micros(200)) { log::warn!("Error when setting bus idle timeout: {:?}", err); @@ -73,7 +75,7 @@ fn main() -> ! { log::info!("Starting I/O loop..."); let mut counter = 0; loop { - peripherals.systick.delay(1000); + systick.delay(1000); log::info!("Querying WHO_AM_I..."); counter += 1; match who_am_i(&mut i2c3) { diff --git a/examples/led.rs b/examples/led.rs index c20e32d5..a90b71f0 100644 --- a/examples/led.rs +++ b/examples/led.rs @@ -16,7 +16,8 @@ use embedded_hal::digital::v2::OutputPin; #[entry] fn main() -> ! { let peripherals = bsp::Peripherals::take().unwrap(); - let mut led = bsp::configure_led(peripherals.pins.p13); + let pins = bsp::t40::pins(peripherals.iomuxc); + let mut led = bsp::configure_led(pins.p13); loop { led.set_high().unwrap(); diff --git a/examples/pit.rs b/examples/pit.rs index 4bb6c94e..85456630 100644 --- a/examples/pit.rs +++ b/examples/pit.rs @@ -30,13 +30,15 @@ unsafe fn PIT() { #[entry] fn main() -> ! { let mut periphs = bsp::Peripherals::take().unwrap(); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + let pins = bsp::t40::pins(periphs.iomuxc); // When flashing a debug build, I'm finding that // the chip is likely to crash if we don't put this // delay here. I've narrowed it down to something // with the WFI in the loop, maybe...? If I instead // busy-loop on an atomic U32, I don't crash in debug // builds. - periphs.systick.delay(25); + systick.delay(25); let (_, ipg_hz) = periphs.ccm.pll1.set_arm_clock( bsp::hal::ccm::PLL1::ARM_HZ, &mut periphs.ccm.handle, @@ -77,7 +79,7 @@ fn main() -> ! { .start(core::time::Duration::from_millis(250)); cortex_m::peripheral::NVIC::unmask(interrupt::PIT); } - let mut led = bsp::configure_led(periphs.pins.p13); + let mut led = bsp::configure_led(pins.p13); loop { led.toggle(); cortex_m::asm::wfi(); diff --git a/examples/pwm.rs b/examples/pwm.rs index 15ff1cfb..48da8e65 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -29,16 +29,18 @@ fn percent(duty: u16) -> f32 { fn main() -> ! { // Prepare all the BSP peripherals let mut p = bsp::Peripherals::take().unwrap(); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + let pins = bsp::t40::pins(p.iomuxc); // Initialize the logging, so we can use it in the PWM loop below - p.usb.init(Default::default()); + bsp::usb_init(&systick, Default::default()).unwrap(); // Delay is only to let a user set-up their USB serial connection... - p.systick.delay(5000); + systick.delay(5000); // Set the core and IPG clock. The IPG clock frequency drives the PWM (sub)modules let (_, ipg_hz) = p.ccm .pll1 .set_arm_clock(bsp::hal::ccm::PLL1::ARM_HZ, &mut p.ccm.handle, &mut p.dcdc); - p.systick.delay(100); + systick.delay(100); // Enable the clocks for the PWM2 module let mut pwm2 = p.pwm2.clock(&mut p.ccm.handle); // Get the outputs from the PWM2 module, submodule 2. @@ -47,8 +49,8 @@ fn main() -> ! { .sm2 .outputs( &mut pwm2.handle, - p.pins.p6, - p.pins.p9, + pins.p6, + pins.p9, bsp::hal::pwm::Timing { clock_select: bsp::hal::ccm::pwm::ClockSelect::IPG(ipg_hz), prescalar: bsp::hal::ccm::pwm::Prescalar::PRSC_5, @@ -71,15 +73,15 @@ fn main() -> ! { ctrl.enable(Channel::B); ctrl.set_duty(Channel::A, duty1); ctrl.set_duty(Channel::B, duty2); - p.systick.delay(200); + systick.delay(200); log::info!("Disabling 'B' PWM..."); ctrl.disable(Channel::B); - p.systick.delay(200); + systick.delay(200); log::info!("Disabling 'A' PWM..."); ctrl.disable(Channel::A); - p.systick.delay(400); + systick.delay(400); core::mem::swap(&mut duty1, &mut duty2); } diff --git a/examples/rtic_blink.rs b/examples/rtic_blink.rs index 61281740..b897854a 100644 --- a/examples/rtic_blink.rs +++ b/examples/rtic_blink.rs @@ -53,8 +53,8 @@ const APP: () = { // Schedule the first blink. cx.schedule.blink(cx.start + PERIOD.cycles()).unwrap(); - - let mut led = bsp::configure_led(cx.device.pins.p13); + let pins = bsp::t40::pins(cx.device.iomuxc); + let mut led = bsp::configure_led(pins.p13); led.set_high().unwrap(); init::LateResources { led } diff --git a/examples/rtic_dma_uart_log.rs b/examples/rtic_dma_uart_log.rs index 6f727fb3..137d658d 100644 --- a/examples/rtic_dma_uart_log.rs +++ b/examples/rtic_dma_uart_log.rs @@ -66,6 +66,8 @@ const APP: () = { &mut cx.device.dcdc, ); + let pins = bsp::t40::pins(cx.device.iomuxc); + // DMA setup. let mut dma_channels = cx.device.dma.clock(&mut cx.device.ccm.handle); let channel = dma_channels[7].take().unwrap(); @@ -76,10 +78,7 @@ const APP: () = { bsp::hal::ccm::uart::ClockSelect::OSC, bsp::hal::ccm::uart::PrescalarSelect::DIVIDE_1, ); - let mut uart = uarts - .uart2 - .init(cx.device.pins.p14, cx.device.pins.p15, BAUD) - .unwrap(); + let mut uart = uarts.uart2.init(pins.p14, pins.p15, BAUD).unwrap(); uart.set_tx_fifo(core::num::NonZeroU8::new(TX_FIFO_SIZE)); uart.set_rx_fifo(true); uart.set_receiver_interrupt(Some(0)); @@ -93,7 +92,7 @@ const APP: () = { let (q_tx, q_rx) = unsafe { Q.split() }; // LED setup. - let mut led = bsp::configure_led(cx.device.pins.p13); + let mut led = bsp::configure_led(pins.p13); led.set_high().unwrap(); // Schedule the first blink. diff --git a/examples/rtic_led.rs b/examples/rtic_led.rs index d598f681..c9dd1d76 100644 --- a/examples/rtic_led.rs +++ b/examples/rtic_led.rs @@ -25,8 +25,8 @@ const APP: () = { // Device-specific peripherals let device: bsp::Peripherals = cx.device; - - let mut led = bsp::configure_led(device.pins.p13); + let pins = bsp::t40::pins(device.iomuxc); + let mut led = bsp::configure_led(pins.p13); led.set_high().unwrap(); } #[idle] diff --git a/examples/rtic_uart_log.rs b/examples/rtic_uart_log.rs index a135c3d5..4dce7c83 100644 --- a/examples/rtic_uart_log.rs +++ b/examples/rtic_uart_log.rs @@ -59,16 +59,15 @@ const APP: () = { &mut cx.device.dcdc, ); + let pins = bsp::t40::pins(cx.device.iomuxc); + // UART setup. let uarts = cx.device.uart.clock( &mut cx.device.ccm.handle, bsp::hal::ccm::uart::ClockSelect::OSC, bsp::hal::ccm::uart::PrescalarSelect::DIVIDE_1, ); - let mut uart = uarts - .uart2 - .init(cx.device.pins.p14, cx.device.pins.p15, BAUD) - .unwrap(); + let mut uart = uarts.uart2.init(pins.p14, pins.p15, BAUD).unwrap(); uart.set_tx_fifo(core::num::NonZeroU8::new(TX_FIFO_SIZE)); uart.set_rx_fifo(true); uart.set_receiver_interrupt(Some(0)); @@ -80,7 +79,7 @@ const APP: () = { let (q_tx, q_rx) = unsafe { Q.split() }; // LED setup. - let mut led = bsp::configure_led(cx.device.pins.p13); + let mut led = bsp::configure_led(pins.p13); led.set_high().unwrap(); // Schedule the first blink. diff --git a/examples/spi.rs b/examples/spi.rs index 95f45c97..1931821f 100644 --- a/examples/spi.rs +++ b/examples/spi.rs @@ -33,7 +33,9 @@ const SPI_BAUD_RATE_HZ: u32 = 1_000_000; #[entry] fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); - peripherals.usb.init(Default::default()); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + bsp::usb_init(&systick, Default::default()).unwrap(); + let pins = bsp::t40::pins(peripherals.iomuxc); peripherals.ccm.pll1.set_arm_clock( bsp::hal::ccm::PLL1::ARM_HZ, @@ -41,7 +43,7 @@ fn main() -> ! { &mut peripherals.dcdc, ); - peripherals.systick.delay(5000); + systick.delay(5000); log::info!("Initializing SPI4 clocks..."); let (_, _, _, spi4_builder) = peripherals.spi.clock( @@ -51,11 +53,7 @@ fn main() -> ! { ); log::info!("Constructing SPI4 peripheral..."); - let mut spi4 = spi4_builder.build( - peripherals.pins.p11, - peripherals.pins.p12, - peripherals.pins.p13, - ); + let mut spi4 = spi4_builder.build(pins.p11, pins.p12, pins.p13); match spi4.set_clock_speed(bsp::hal::spi::ClockSpeed(SPI_BAUD_RATE_HZ)) { Ok(()) => { @@ -76,7 +74,7 @@ fn main() -> ! { // We're using the SPI's default chip select pin. This uses a // dummy `OutputPin` that does nothing! If you'd rather use any // GPIO, replace this line to construct a GPIO from another pin. - spi4.enable_chip_select_0(peripherals.pins.p10); + spi4.enable_chip_select_0(pins.p10); struct DummyCS; impl embedded_hal::digital::v2::OutputPin for DummyCS { type Error = core::convert::Infallible; @@ -89,9 +87,9 @@ fn main() -> ! { } let mut cs4 = DummyCS; log::info!("Waiting 5 seconds before querying MPU9250..."); - peripherals.systick.delay(4000); + systick.delay(4000); - match ak8963_init(&mut peripherals.systick, &mut spi4, &mut cs4) { + match ak8963_init(&mut systick, &mut spi4, &mut cs4) { Ok(()) => (), Err(err) => { log::warn!("Unable to initialize AK8963: {:?}", err); @@ -101,7 +99,7 @@ fn main() -> ! { } }; loop { - peripherals.systick.delay(1000); + systick.delay(1000); match who_am_i(&mut spi4, &mut cs4) { Ok(who) => log::info!("Received {:#X} for WHO_AM_I", who), Err(err) => log::warn!("Error when querying WHO_AM_I: {:?}", err), diff --git a/examples/systick.rs b/examples/systick.rs index bbebb8e9..59f7ae4b 100644 --- a/examples/systick.rs +++ b/examples/systick.rs @@ -6,6 +6,7 @@ #![no_std] #![no_main] + extern crate panic_halt; use bsp::rt; @@ -15,11 +16,13 @@ const LED_PERIOD_MS: u32 = 1_000; #[rt::entry] fn main() -> ! { - let mut p = bsp::Peripherals::take().unwrap(); - let mut led: bsp::LED = bsp::configure_led(p.pins.p13); + let p = bsp::Peripherals::take().unwrap(); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + let pins = bsp::t40::pins(p.iomuxc); + let mut led: bsp::LED = bsp::configure_led(pins.p13); loop { - p.systick.delay(LED_PERIOD_MS); + systick.delay(LED_PERIOD_MS); led.toggle(); } } diff --git a/examples/timer.rs b/examples/timer.rs index 5b8b602a..583424d1 100644 --- a/examples/timer.rs +++ b/examples/timer.rs @@ -22,8 +22,9 @@ use teensy4_bsp as bsp; #[entry] fn main() -> ! { let mut periphs = bsp::Peripherals::take().unwrap(); - periphs.systick.delay(25); - periphs.usb.init(Default::default()); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + let pins = bsp::t40::pins(periphs.iomuxc); + bsp::usb_init(&systick, Default::default()).unwrap(); let (_, ipg_hz) = periphs.ccm.pll1.set_arm_clock( bsp::hal::ccm::PLL1::ARM_HZ, @@ -43,8 +44,7 @@ fn main() -> ! { let (timer0, timer1, _, mut timer3) = periphs.pit.clock(&mut cfg); let mut timer = pit::chain(timer0, timer1); - let mut led: bsp::LED = bsp::configure_led(periphs.pins.p13); - let mut systick = periphs.systick; + let mut led: bsp::LED = bsp::configure_led(pins.p13); loop { let (_, period) = timer.time(|| { led.set_high().unwrap(); diff --git a/examples/uart.rs b/examples/uart.rs index 3330b5fe..9336b5ea 100644 --- a/examples/uart.rs +++ b/examples/uart.rs @@ -79,17 +79,16 @@ fn read>(uart: &mut R, bytes: &mut [u8]) -> Result<(), R::Error> { #[entry] fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); - peripherals.usb.init(Default::default()); - peripherals.systick.delay(5_000); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); + let pins = bsp::t40::pins(peripherals.iomuxc); + bsp::usb_init(&systick, Default::default()).unwrap(); + systick.delay(5_000); let uarts = peripherals.uart.clock( &mut peripherals.ccm.handle, bsp::hal::ccm::uart::ClockSelect::OSC, bsp::hal::ccm::uart::PrescalarSelect::DIVIDE_1, ); - let mut uart = uarts - .uart2 - .init(peripherals.pins.p14, peripherals.pins.p15, BAUD) - .unwrap(); + let mut uart = uarts.uart2.init(pins.p14, pins.p15, BAUD).unwrap(); let fifo_size = uart.set_tx_fifo(core::num::NonZeroU8::new(TX_FIFO_SIZE)); log::info!("Setting TX FIFO to {}", fifo_size); // If this is disabled, we won't receive the four bytes from the transfer! @@ -97,14 +96,14 @@ fn main() -> ! { uart.set_parity(PARITY); uart.set_rx_inversion(INVERTED); uart.set_tx_inversion(INVERTED); - let mut led = bsp::configure_led(peripherals.pins.p13); + let mut led = bsp::configure_led(pins.p13); let (mut tx, mut rx) = uart.split(); loop { - peripherals.systick.delay(1_000); + systick.delay(1_000); led.toggle(); let mut buffer = DATA; write(&mut tx, &buffer).unwrap(); - peripherals.systick.delay(1); + systick.delay(1); match read(&mut rx, &mut buffer) { Ok(_) => continue, Err(err) => log::warn!("Receiver error: {:?}", err.flags), diff --git a/examples/usb.rs b/examples/usb.rs index 361ac223..0a129b5d 100644 --- a/examples/usb.rs +++ b/examples/usb.rs @@ -16,16 +16,22 @@ use teensy4_bsp as bsp; #[rt::entry] fn main() -> ! { let mut p = bsp::Peripherals::take().unwrap(); + let pins = bsp::t40::pins(p.iomuxc); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); // Initialize the USB stack with the default logging settings - let mut usb_reader = p.usb.init(bsp::usb::LoggingConfig { - filters: &[("usb", None)], - ..Default::default() - }); - p.systick.delay(2000); + let mut usb_reader = bsp::usb_init( + &systick, + bsp::usb::LoggingConfig { + filters: &[("usb", None)], + ..Default::default() + }, + ) + .unwrap(); + systick.delay(2000); p.ccm .pll1 .set_arm_clock(bsp::hal::ccm::PLL1::ARM_HZ, &mut p.ccm.handle, &mut p.dcdc); - let mut led: bsp::LED = bsp::configure_led(p.pins.p13); + let mut led: bsp::LED = bsp::configure_led(pins.p13); let mut buffer = [0; 256]; loop { let bytes_read = usb_reader.read(&mut buffer); @@ -48,6 +54,6 @@ fn main() -> ! { log::debug!("Sleeping for 1 second..."); log::trace!("{} + {} = {}", 3, 2, 3 + 2); led.toggle(); - p.systick.delay(5000); + systick.delay(5000); } } diff --git a/src/lib.rs b/src/lib.rs index dd285bf7..48538c92 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,9 +76,9 @@ pub use hal::ral::interrupt; pub use hal::ral::{interrupt as Interrupt, NVIC_PRIO_BITS}; pub use cortex_m_rt as rt; -pub use imxrt_hal as hal; - use hal::iomuxc; +pub use hal::Peripherals; +pub use imxrt_hal as hal; /// The LED in its final configuration pub type LED = hal::gpio::GPIO; From 6447b6f894a19a78881b4cff8f3068ad4d2228fd Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Mon, 20 Jul 2020 20:35:21 -0400 Subject: [PATCH 09/20] Remove re-export of USB types; fix docs --- examples/dma_memcpy.rs | 2 +- examples/dma_spi.rs | 2 +- examples/dma_uart.rs | 2 +- examples/i2c.rs | 2 +- examples/pwm.rs | 2 +- examples/spi.rs | 2 +- examples/timer.rs | 2 +- examples/uart.rs | 2 +- examples/usb.rs | 2 +- src/lib.rs | 6 +++--- src/systick.rs | 8 ++++---- src/usb.rs | 5 ++--- 12 files changed, 18 insertions(+), 19 deletions(-) diff --git a/examples/dma_memcpy.rs b/examples/dma_memcpy.rs index ca8668c1..fa3f3bb7 100644 --- a/examples/dma_memcpy.rs +++ b/examples/dma_memcpy.rs @@ -35,7 +35,7 @@ const NUMBER_OF_ELEMENTS: Element = (BUFFER_SIZE - 7) as Element; fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); systick.delay(5_000); let mut dma_channels = peripherals.dma.clock(&mut peripherals.ccm.handle); diff --git a/examples/dma_spi.rs b/examples/dma_spi.rs index 18b65177..c976bef5 100644 --- a/examples/dma_spi.rs +++ b/examples/dma_spi.rs @@ -165,7 +165,7 @@ static mut HARDWARE_FLAG: Option = None; fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); let pins = bsp::t40::pins(peripherals.iomuxc); peripherals.ccm.pll1.set_arm_clock( diff --git a/examples/dma_uart.rs b/examples/dma_uart.rs index e59ce990..833b4d66 100644 --- a/examples/dma_uart.rs +++ b/examples/dma_uart.rs @@ -80,7 +80,7 @@ unsafe fn DMA7_DMA23() { fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); let pins = bsp::t40::pins(peripherals.iomuxc); systick.delay(5_000); diff --git a/examples/i2c.rs b/examples/i2c.rs index ed2c458e..7de5d32f 100644 --- a/examples/i2c.rs +++ b/examples/i2c.rs @@ -45,7 +45,7 @@ fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); let pins = bsp::t40::pins(peripherals.iomuxc); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); systick.delay(5000); log::info!("Enabling I2C clocks..."); diff --git a/examples/pwm.rs b/examples/pwm.rs index 48da8e65..86b68a5a 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -32,7 +32,7 @@ fn main() -> ! { let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); let pins = bsp::t40::pins(p.iomuxc); // Initialize the logging, so we can use it in the PWM loop below - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); // Delay is only to let a user set-up their USB serial connection... systick.delay(5000); // Set the core and IPG clock. The IPG clock frequency drives the PWM (sub)modules diff --git a/examples/spi.rs b/examples/spi.rs index 1931821f..40896ea4 100644 --- a/examples/spi.rs +++ b/examples/spi.rs @@ -34,7 +34,7 @@ const SPI_BAUD_RATE_HZ: u32 = 1_000_000; fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); let pins = bsp::t40::pins(peripherals.iomuxc); peripherals.ccm.pll1.set_arm_clock( diff --git a/examples/timer.rs b/examples/timer.rs index 583424d1..dbbd8119 100644 --- a/examples/timer.rs +++ b/examples/timer.rs @@ -24,7 +24,7 @@ fn main() -> ! { let mut periphs = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); let pins = bsp::t40::pins(periphs.iomuxc); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); let (_, ipg_hz) = periphs.ccm.pll1.set_arm_clock( bsp::hal::ccm::PLL1::ARM_HZ, diff --git a/examples/uart.rs b/examples/uart.rs index 9336b5ea..98980545 100644 --- a/examples/uart.rs +++ b/examples/uart.rs @@ -81,7 +81,7 @@ fn main() -> ! { let mut peripherals = bsp::Peripherals::take().unwrap(); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); let pins = bsp::t40::pins(peripherals.iomuxc); - bsp::usb_init(&systick, Default::default()).unwrap(); + bsp::usb::init(&systick, Default::default()).unwrap(); systick.delay(5_000); let uarts = peripherals.uart.clock( &mut peripherals.ccm.handle, diff --git a/examples/usb.rs b/examples/usb.rs index 0a129b5d..b3108c40 100644 --- a/examples/usb.rs +++ b/examples/usb.rs @@ -19,7 +19,7 @@ fn main() -> ! { let pins = bsp::t40::pins(p.iomuxc); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); // Initialize the USB stack with the default logging settings - let mut usb_reader = bsp::usb_init( + let mut usb_reader = bsp::usb::init( &systick, bsp::usb::LoggingConfig { filters: &[("usb", None)], diff --git a/src/lib.rs b/src/lib.rs index 48538c92..4e1ad46c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,8 +67,6 @@ pub mod usb; #[cfg(feature = "systick")] pub use systick::SysTick; -#[cfg(feature = "usb-logging")] -pub use usb::{init as usb_init, LoggingConfig}; pub use hal::ral::interrupt; // `rtic` expects these in the root. @@ -80,7 +78,9 @@ use hal::iomuxc; pub use hal::Peripherals; pub use imxrt_hal as hal; -/// The LED in its final configuration +/// The LED +/// +/// See [`configure_led`](fn.configure_led.html) to prepare the LED. pub type LED = hal::gpio::GPIO; /// Configure the board's LED diff --git a/src/systick.rs b/src/systick.rs index a4721407..5e052a47 100644 --- a/src/systick.rs +++ b/src/systick.rs @@ -26,11 +26,11 @@ fn read() -> u32 { /// Blocks for at least `millis` milliseconds /// -/// `delay()` will spin-loop on updates from SYSTICK, until +/// `delay` will spin-loop on updates from SYSTICK, until /// `millis` milliseconds have elapsed. SYSTICK has a 1ms /// interrupt interval, so the minimal delay is around 1ms. #[no_mangle] -pub extern "C" fn delay(millis: u32) { +extern "C" fn delay(millis: u32) { if 0 == millis { return; } @@ -60,12 +60,12 @@ pub struct SysTick(cortex_m::peripheral::SYST); impl SysTick { /// Convert the normal cortex-m SYST peripheral into a Teensy `SysTick` /// - /// `new()` will configure the systick counter for a 1ms tick. When `new()` returns, + /// `new` will configure the systick counter for a 1ms tick. When `new()` returns, /// systick is counting. /// /// # Safety /// - /// `new()` is safe because it assumes that it has the only `SYST` instance. + /// `new` is safe because it assumes that it has the only `SYST` instance. /// The only way you could acquire two `SysTick` is if you've unsafely obtained /// a second `SYST` instance. pub fn new(mut systick: cortex_m::peripheral::SYST) -> SysTick { diff --git a/src/usb.rs b/src/usb.rs index 846bab3f..64c3b390 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -3,8 +3,7 @@ //! The USB stack provides a [`log`] implementation for logging over USB //! //! This is `Serial.println()` in Rust. Use the macros of the -//! [`log`] crate to write data over USB. Messages can be read -//! back using `screen` or `PuTTY`. +//! [`log`] crate to write data over USB. //! //! [`log`]: https://crates.io/crates/log @@ -24,7 +23,7 @@ use teensy4_usb_sys as usbsys; /// Set the `filters` collection to specify log targets of interest. /// /// If the default configuration is good for you, use `Default::default()` -/// as the argument to `init()`. +/// as the argument to [`init`](fn.init.html). pub struct LoggingConfig { /// The max log level /// From b046b46b93f094c12321842855ab2026a6d8805e Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Tue, 21 Jul 2020 17:28:30 -0400 Subject: [PATCH 10/20] Add feature hints in BSP documentation Hits are available when generating docs with a nightly compiler: cargo +nightly rustdoc --open --all-features -- --cfg docsrs --- Cargo.toml | 3 +++ src/lib.rs | 3 +++ src/systick.rs | 1 + 3 files changed, 7 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 6b527d9b..e4200c24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,3 +108,6 @@ opt-level = 0 [patch.crates-io.cortex-m-rt] path = "cortex-m-rt-patch" +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 4e1ad46c..62cb90cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,7 @@ //! continuous days, or risk a millisecond counter wrap-around. #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] // Need to reference this so that it doesn't get stripped out extern crate teensy4_fcb; @@ -63,6 +64,7 @@ pub mod t40; #[cfg(feature = "systick")] mod systick; #[cfg(feature = "usb-logging")] +#[cfg_attr(docsrs, doc(cfg(feature = "usb-logging")))] pub mod usb; #[cfg(feature = "systick")] @@ -70,6 +72,7 @@ pub use systick::SysTick; pub use hal::ral::interrupt; // `rtic` expects these in the root. +#[doc(hidden)] #[cfg(feature = "rtic")] pub use hal::ral::{interrupt as Interrupt, NVIC_PRIO_BITS}; diff --git a/src/systick.rs b/src/systick.rs index 5e052a47..4ab64892 100644 --- a/src/systick.rs +++ b/src/systick.rs @@ -55,6 +55,7 @@ const SYSTICK_EXT_FREQ: u32 = 100_000; /// /// `SysTick` implements the `embedded_hal`'s `DelayMs` trait. It /// may be used to implement simple, blocking delays. +#[cfg_attr(docsrs, doc(cfg(feature = "systick")))] pub struct SysTick(cortex_m::peripheral::SYST); impl SysTick { From 8bb5fe9edc2771b1954546a076786ba6888501d2 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Tue, 21 Jul 2020 21:42:57 -0400 Subject: [PATCH 11/20] Define common, t40, and t41 pins Many pads map to the same pins across the Teensy 4.0 and 4.1 This commit moves the common pins into a `common` module. We then import the common pins in the t40 and t41 modules, while also defining the pins that are unique. Each t40 and t41 module provides its own `Pins` type, and users will make their own selections on t40 and t41 pins. --- src/common.rs | 133 +++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 ++- src/t40.rs | 153 ++++++++++++++----------------------------- src/t41.rs | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+), 108 deletions(-) create mode 100644 src/common.rs create mode 100644 src/t41.rs diff --git a/src/common.rs b/src/common.rs new file mode 100644 index 00000000..3f8fb543 --- /dev/null +++ b/src/common.rs @@ -0,0 +1,133 @@ +//! Common APIs across both the Teensy 4.0 and 4.1 boards +//! +//! # Common Pinout +//! +//! The Teensy 4.0 and 4.1 have many similar pad to pin mappings. This table documents +//! the pins that are common across both boards. For pins that are unique to +//! each board, and to acquire all of a board's pins, see the [`t40`](../t40/index.html) +//! and [`t41`](../t41/index.html) modules. +//! +//! ## This table is incomplete +//! +//! We believe this table's contents are accurate. But, there may be alternate functions that are not +//! documented, and we're maintaining this table on a best-effort basis. Besides this table, +//! there are two other ways to identify which pads support which peripheral: +//! +//! - study the i.MX RT 1060 Reference Manual. This is the authority on pad configuration. +//! - study the trait implementations for the pad. Select a pin type alias, like [`P0`](type.P0.html), +//! and click-through to its pad documentation (`AD_B0_03`). Notice the listing of `imxrt-iomuxc` +//! trait implementations. This describes what kinds of functions the pin supports. The constraints +//! may be enforced by the HAL's APIs. +//! +//! We welcome documentation contributions! +//! +//! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | +//! | ---- | -------- | -------- | ------------ | ------------ | --------- | ------------ | ---------------- | ------------ | ------- | ------- | ------- | +//! | 0 |`AD_B0_03`| | | `UART6_RX` | |`FlexPWM1_1_X`| | | | | | +//! | 1 |`AD_B0_02`| | | `UART6_TX` | |`FlexPWM1_0_X`| | | | | | +//! | 2 |`EMC_04` | |`FlexPWM4_2_A`| | | | | | | | | +//! | 3 |`EMC_05` | |`FlexPWM4_2_B`| | | | | | | | | +//! | 4 |`EMC_06` | |`FlexPWM2_0_A`| | | | | | | | | +//! | 5 |`EMC_08` | |`FlexPWM2_1_A`| | | | | | | | | +//! | 6 |`B0_10` | | |`FlexPWM2_2_A`| | | | | | | | +//! | 7 |`B1_01` | | | `UART4_RX` | | | |`FlexPWM1_3_B`| | | | +//! | 8 |`B1_00` | | | `UART4_TX` | | | |`FlexPWM1_3_A`| | | | +//! | 9 |`B0_11` | | |`FlexPWM2_2_B`| | | | | | | | +//! | 10 |`B0_00` | | | |`SPI4_PCS0`| | | | | | | +//! | 11 |`B0_02` | | | |`SPI4_SDO` | | | | | | | +//! | 12 |`B0_01` | | | |`SPI4_SDI` | | | | | | | +//! | 13 |`B0_03` | | | |`SPI4_SCK` | |`GPIO2_3` (`LED`) | | | | | +//! | 14 |`AD_B1_02`| | | `UART2_TX` | | | | | | | | +//! | 15 |`AD_B1_03`| | | `UART2_RX` | | | | | | | | +//! | 16 |`AD_B1_07`| |`I2C3_SCL` | `UART3_RX` | | | | | | | | +//! | 17 |`AD_B1_06`| |`I2C3_SDA` | `UART3_TX` | | | | | | | | +//! | 18 |`AD_B1_01`| | | |`I2C1_SDA` | | | | | | | +//! | 19 |`AD_B1_00`| | | `UART2_CTS` |`I2C1_SCL` | | | | | | | +//! | 20 |`AD_B1_10`| | | `UART8_TX` | | | | | | | | +//! | 21 |`AD_B1_11`| | | `UART8_RX` | | | | | | | | +//! | 22 |`AD_B1_08`| |`FlexPWM4_0_A`| | | | | | | | | +//! | 23 |`AD_B1_09`| |`FlexPWM4_1_A`| | | | | | | | | +//! | 24 |`AD_B0_12`|`I2C4_SCL`| | `UART1_TX` | |`FlexPWM1_2_X`| | | | | | +//! | 25 |`AD_B0_13`|`I2C4_SDA`| | `UART1_RX` | |`FlexPWM1_3_X`| | | | | | +//! | 26 |`AD_B1_14`| | | | | | | | | | | +//! | 27 |`AD_B1_15`| | | | | | | | | | | +//! | 28 |`EMC_32` | |`FlexPWM3_1_B`| `UART7_RX` | | | | | | | | +//! | 29 |`EMC_31` | |`FlexPWM3_1_A`| `UART7_TX` |`SPI1_PCS1`| | | | | | | +//! | 30 |`EMC_37` | | | | | | | | | | | +//! | 31 |`EMC_36` | | | | | | | | | | | +//! | 32 |`B0_12` | | | | | | | | | | | +//! | 33 |`EMC_07` | |`FlexPWM2_0_B`| | | | | | | | | +//! +//! References: +//! - [Teensy Schematics](https://www.pjrc.com/teensy/schematic.html) + +use crate::hal::iomuxc::{ad_b0::*, ad_b1::*, b0::*, b1::*, emc::*}; + +/// Pin 0 (common) +pub type P0 = AD_B0_03; +/// Pin 1 (common) +pub type P1 = AD_B0_02; +/// Pin 2 (common) +pub type P2 = EMC_04; +/// Pin 3 (common) +pub type P3 = EMC_05; +/// Pin 4 (common) +pub type P4 = EMC_06; +/// Pin 5 (common) +pub type P5 = EMC_08; +/// Pin 6 (common) +pub type P6 = B0_10; +/// Pin 7 (common) +pub type P7 = B1_01; +/// Pin 8 (common) +pub type P8 = B1_00; +/// Pin 9 (common) +pub type P9 = B0_11; +/// Pin 10 (common) +pub type P10 = B0_00; +/// Pin 11 (common) +pub type P11 = B0_02; +/// Pin 12 (common) +pub type P12 = B0_01; +/// Pin 13 (common) +pub type P13 = B0_03; +/// Pin 14 (common) +pub type P14 = AD_B1_02; +/// Pin 15 (common) +pub type P15 = AD_B1_03; +/// Pin 16 (common) +pub type P16 = AD_B1_07; +/// Pin 17 (common) +pub type P17 = AD_B1_06; +/// Pin 18 (common) +pub type P18 = AD_B1_01; +/// Pin 19 (common) +pub type P19 = AD_B1_00; +/// Pin 20 (common) +pub type P20 = AD_B1_10; +/// Pin 21 (common) +pub type P21 = AD_B1_11; +/// Pin 22 (common) +pub type P22 = AD_B1_08; +/// Pin 23 (common) +pub type P23 = AD_B1_09; +/// Pin 24 (common) +pub type P24 = AD_B0_12; +/// Pin 25 (common) +pub type P25 = AD_B0_13; +/// Pin 26 (common) +pub type P26 = AD_B1_14; +/// Pin 27 (common) +pub type P27 = AD_B1_15; +/// Pin 28 (common) +pub type P28 = EMC_32; +/// Pin 29 (common) +pub type P29 = EMC_31; +/// Pin 30 (common) +pub type P30 = EMC_37; +/// Pin 31 (common) +pub type P31 = EMC_36; +/// Pin 32 (common) +pub type P32 = B0_12; +/// Pin 33 (common) +pub type P33 = EMC_07; diff --git a/src/lib.rs b/src/lib.rs index 62cb90cb..ce294fcf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ //! If a user also registers a `SysTick` or `USB_OTG1` handler, it may //! result in a duplicate definition error. //! -//! ## Re-exports +//! # Re-exports //! //! The BSP re-exports the following: //! @@ -40,7 +40,7 @@ //! specific to the Teensy 4. See the `teensy4-fcb` crate for details //! on FCBs. //! -//! ## Examples +//! # Examples //! //! See the `teensy4-examples` crate for build-able, run-able //! examples. The examples utilize this BSP crate to blink LEDs, @@ -59,7 +59,9 @@ // Need to reference this so that it doesn't get stripped out extern crate teensy4_fcb; +pub mod common; pub mod t40; +pub mod t41; #[cfg(feature = "systick")] mod systick; @@ -84,7 +86,7 @@ pub use imxrt_hal as hal; /// The LED /// /// See [`configure_led`](fn.configure_led.html) to prepare the LED. -pub type LED = hal::gpio::GPIO; +pub type LED = hal::gpio::GPIO; /// Configure the board's LED /// diff --git a/src/t40.rs b/src/t40.rs index c68cc1c1..029a582f 100644 --- a/src/t40.rs +++ b/src/t40.rs @@ -1,125 +1,39 @@ //! Teensy 4.0 specific API //! -//! ## Pins, Pads and Alternates +//! # Pins unique to the Teensy 4.0 //! -//! The sparse table below describes the Teensy 4 pins, the pad ID, and some of the notable alternate functionalities -//! for each pin. We add entries to the table as we add capabilities to the underlying HAL crate. If a pad's alternates -//! are not listed here, consult the iMXRT1060 reference manual. +//! See the [`common` documentation](../common/index.html) for pins that are consistent +//! across both boards. //! //! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | //! | ---- | -------- | -------- | ------------ | ------------ | --------- | ------------ | ---------------- | ------------ | ------- | ------- | ------- | -//! | 0 |`AD_B0_03`| | | `UART6_RX` | |`FlexPWM1_1_X`| | | | | | -//! | 1 |`AD_B0_02`| | | `UART6_TX` | |`FlexPWM1_0_X`| | | | | | -//! | 2 |`EMC_04` | |`FlexPWM4_2_A`| | | | | | | | | -//! | 3 |`EMC_05` | |`FlexPWM4_2_B`| | | | | | | | | -//! | 4 |`EMC_06` | |`FlexPWM2_0_A`| | | | | | | | | -//! | 5 |`EMC_08` | |`FlexPWM2_1_A`| | | | | | | | | -//! | 6 |`B0_10` | | |`FlexPWM2_2_A`| | | | | | | | -//! | 7 |`B1_01` | | | `UART4_RX` | | | |`FlexPWM1_3_B`| | | | -//! | 8 |`B1_00` | | | `UART4_TX` | | | |`FlexPWM1_3_A`| | | | -//! | 9 |`B0_11` | | |`FlexPWM2_2_B`| | | | | | | | -//! | 10 |`B0_00` | | | |`SPI4_PCS0`| | | | | | | -//! | 11 |`B0_02` | | | |`SPI4_SDO` | | | | | | | -//! | 12 |`B0_01` | | | |`SPI4_SDI` | | | | | | | -//! | 13 |`B0_03` | | | |`SPI4_SCK` | |`GPIO2_3` (`LED`) | | | | | -//! | 14 |`AD_B1_02`| | | `UART2_TX` | | | | | | | | -//! | 15 |`AD_B1_03`| | | `UART2_RX` | | | | | | | | -//! | 16 |`AD_B1_07`| |`I2C3_SCL` | `UART3_RX` | | | | | | | | -//! | 17 |`AD_B1_06`| |`I2C3_SDA` | `UART3_TX` | | | | | | | | -//! | 18 |`AD_B1_01`| | | |`I2C1_SDA` | | | | | | | -//! | 19 |`AD_B1_00`| | | `UART2_CTS` |`I2C1_SCL` | | | | | | | -//! | 20 |`AD_B1_10`| | | `UART8_TX` | | | | | | | | -//! | 21 |`AD_B1_11`| | | `UART8_RX` | | | | | | | | -//! | 22 |`AD_B1_08`| |`FlexPWM4_0_A`| | | | | | | | | -//! | 23 |`AD_B1_09`| |`FlexPWM4_1_A`| | | | | | | | | -//! | 24 |`AD_B0_12`|`I2C4_SCL`| | `UART1_TX` | |`FlexPWM1_2_X`| | | | | | -//! | 25 |`AD_B0_13`|`I2C4_SDA`| | `UART1_RX` | |`FlexPWM1_3_X`| | | | | | -//! | 26 |`AD_B1_14`| | | | | | | | | | | -//! | 27 |`AD_B1_15`| | | | | | | | | | | -//! | 28 |`EMC_32` | |`FlexPWM3_1_B`| `UART7_RX` | | | | | | | | -//! | 29 |`EMC_31` | |`FlexPWM3_1_A`| `UART7_TX` |`SPI1_PCS1`| | | | | | | -//! | 30 |`EMC_37` | | | | | | | | | | | -//! | 31 |`EMC_36` | | | | | | | | | | | -//! | 32 |`B0_12` | | | | | | | | | | | -//! | 33 |`EMC_07` | |`FlexPWM2_0_B`| | | | | | | | | //! | 34 |`SD_B0_03`| |`FlexPWM1_1_B`| | | `SPI1_SDI` | | | | | | //! | 35 |`SD_B0_02`| |`FlexPWM1_1_A`| | | `SPI1_SDO` | | | | | | //! | 36 |`SD_B0_01`| |`FlexPWM1_0_B`| `I2C3_SDA` | | `SPI1_PCS0` | | | | | | //! | 37 |`SD_B0_00`| |`FlexPWM1_0_A`| `I2C3_SCL` | | `SPI1_SCK` | | | | | | //! | 38 |`SD_B0_05`| |`FlexPWM1_2_B`| `UART8_RX` | | | | | | | | //! | 39 |`SD_B0_04`| |`FlexPWM1_2_A`| `UART8_TX` | | | | | | | | -//! -//! References: -//! - [Teensy 4.0 Schematic Diagram](https://www.pjrc.com/teensy/schematic.html) -use crate::hal::iomuxc; +pub use crate::common::*; +use crate::hal::iomuxc::sd_b0::*; -/// Pin 0 -pub type P0 = iomuxc::ad_b0::AD_B0_03; -/// Pin 1 -pub type P1 = iomuxc::ad_b0::AD_B0_02; -/// Pin 2 -pub type P2 = iomuxc::emc::EMC_04; -/// Pin 3 -pub type P3 = iomuxc::emc::EMC_05; -/// Pin 4 -pub type P4 = iomuxc::emc::EMC_06; -/// Pin 5 -pub type P5 = iomuxc::emc::EMC_08; -/// Pin 6 -pub type P6 = iomuxc::b0::B0_10; -/// Pin 7 -pub type P7 = iomuxc::b1::B1_01; -/// Pin 8 -pub type P8 = iomuxc::b1::B1_00; -/// Pin 9 -pub type P9 = iomuxc::b0::B0_11; -/// Pin 10 -pub type P10 = iomuxc::b0::B0_00; -/// Pin 11 -pub type P11 = iomuxc::b0::B0_02; -/// Pin 12 -pub type P12 = iomuxc::b0::B0_01; -/// Pin 13 -pub type P13 = iomuxc::b0::B0_03; -/// Pin 14 -pub type P14 = iomuxc::ad_b1::AD_B1_02; -/// Pin 15 -pub type P15 = iomuxc::ad_b1::AD_B1_03; -/// Pin 16 -pub type P16 = iomuxc::ad_b1::AD_B1_07; -/// Pin 17 -pub type P17 = iomuxc::ad_b1::AD_B1_06; -/// Pin 18 -pub type P18 = iomuxc::ad_b1::AD_B1_01; -/// Pin 19 -pub type P19 = iomuxc::ad_b1::AD_B1_00; -/// Pin 20 -pub type P20 = iomuxc::ad_b1::AD_B1_10; -/// Pin 21 -pub type P21 = iomuxc::ad_b1::AD_B1_11; -/// Pin 22 -pub type P22 = iomuxc::ad_b1::AD_B1_08; -/// Pin 23 -pub type P23 = iomuxc::ad_b1::AD_B1_09; -/// Pin 24 -pub type P24 = iomuxc::ad_b0::AD_B0_12; -/// Pin 25 -pub type P25 = iomuxc::ad_b0::AD_B0_13; -/// Pin 28 -pub type P28 = iomuxc::emc::EMC_32; -/// Pin 29 -pub type P29 = iomuxc::emc::EMC_31; -/// Pin 33 -pub type P33 = iomuxc::emc::EMC_07; -/// Pin 36 -pub type P36 = iomuxc::sd_b0::SD_B0_01; -/// Pin 37 -pub type P37 = iomuxc::sd_b0::SD_B0_00; +/// Pin 34 (4.0) +pub type P34 = SD_B0_03; +/// Pin 35 (4.0) +pub type P35 = SD_B0_02; +/// Pin 36 (4.0) +pub type P36 = SD_B0_01; +/// Pin 37 (4.0) +pub type P37 = SD_B0_00; +/// Pin 38 (4.0) +pub type P38 = SD_B0_05; +/// Pin 39 (4.0) +pub type P39 = SD_B0_04; /// Teensy 4.0 pins /// -/// Pin 13 can be used for several things; one common usage is for the on-board LED. +/// See [`pins`](fn.pins.html) to constrain the processor's pads, and acquire +/// Teensy 4.0 pins. pub struct Pins { /// Pin 0 pub p0: P0, @@ -173,16 +87,35 @@ pub struct Pins { pub p24: P24, /// Pin 25 pub p25: P25, + /// Pin 26 + pub p26: P26, + /// Pin 27 + pub p27: P27, /// Pin 28 pub p28: P28, /// Pin 29 pub p29: P29, + /// Pin 30 + pub p30: P30, + /// Pin 31 + pub p31: P31, + /// Pin 32 + pub p32: P32, /// Pin 33 pub p33: P33, + // END OF COMMON PINS + /// Pin 34 + pub p34: P34, + /// Pin 35 + pub p35: P35, /// Pin 36 pub p36: P36, /// Pin 37 pub p37: P37, + /// Pin 38 + pub p38: P38, + /// Pin 39 + pub p39: P39, } /// Constrain the processor pads to the Teensy 4.0 pins @@ -214,10 +147,20 @@ pub fn pins(iomuxc: crate::hal::iomuxc::Pads) -> Pins { p23: iomuxc.ad_b1.p09, p24: iomuxc.ad_b0.p12, p25: iomuxc.ad_b0.p13, + p26: iomuxc.ad_b1.p14, + p27: iomuxc.ad_b1.p15, p28: iomuxc.emc.p32, p29: iomuxc.emc.p31, + p30: iomuxc.emc.p37, + p31: iomuxc.emc.p36, + p32: iomuxc.b0.p12, p33: iomuxc.emc.p07, + // END OF COMMON PINS + p34: iomuxc.sd_b0.p03, + p35: iomuxc.sd_b0.p02, p36: iomuxc.sd_b0.p01, p37: iomuxc.sd_b0.p00, + p38: iomuxc.sd_b0.p05, + p39: iomuxc.sd_b0.p04, } } diff --git a/src/t41.rs b/src/t41.rs new file mode 100644 index 00000000..2ab07d47 --- /dev/null +++ b/src/t41.rs @@ -0,0 +1,178 @@ +//! Teensy 4.1 specific API +//! +//! # Pins unique to the Teensy 4.1 +//! +//! See the [`common` documentation](../common/index.html) for pins that are consistent +//! across both boards. +//! +//! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | +//! | ---- | -------- | -------- | ------------ | ------------ | --------- | ------------ | ---------------- | ------------ | ------- | ------- | ------- | +//! | 34 |`B1_13` | | | | | | | | | | | +//! | 35 |`B1_12` | | | | | | | | | | | +//! | 36 |`B1_02` | | | | | | | | | | | +//! | 37 |`B1_03` | | | | | | | | | | | +//! | 38 |`AD_B1_12`| | | | | | | | | | | +//! | 39 |`AD_B1_13`| | | | | | | | | | | +//! | 40 |`AD_B1_04`| | | | | | | | | | | +//! | 41 |`AD_B1_05`| | | | | | | | | | | + +pub use crate::common::*; +use crate::hal::iomuxc::{ad_b1::*, b1::*}; + +/// Pin 34 (4.1) +pub type P34 = B1_13; +/// Pin 35 (4.1) +pub type P35 = B1_12; +/// Pin 36 (4.1) +pub type P36 = B1_02; +/// Pin 37 (4.1) +pub type P37 = B1_03; +/// Pin 38 (4.1) +pub type P38 = AD_B1_12; +/// Pin 39 (4.1) +pub type P39 = AD_B1_13; +/// Pin 40 (4.1) +pub type P40 = AD_B1_04; +/// Pin 41 (4.1) +pub type P41 = AD_B1_05; + +/// Teensy 4.1 pins +/// +/// See [`pins`](fn.pins.html) to constrain the processor's pads, and acquire +/// Teensy 4.1 pins. +pub struct Pins { + /// Pin 0 + pub p0: P0, + /// Pin 1 + pub p1: P1, + /// Pin 2 + pub p2: P2, + /// Pin 3 + pub p3: P3, + /// Pin 4 + pub p4: P4, + /// Pin 5 + pub p5: P5, + /// Pin 6 + pub p6: P6, + /// Pin 7 + pub p7: P7, + /// Pin 8 + pub p8: P8, + /// Pin 9 + pub p9: P9, + /// Pin 10 + pub p10: P10, + /// Pin 11 + pub p11: P11, + /// Pin 12 + pub p12: P12, + /// Pin 13 + pub p13: P13, + /// Pin 14 + pub p14: P14, + /// Pin 15 + pub p15: P15, + /// Pin 16 + pub p16: P16, + /// Pin 17 + pub p17: P17, + /// Pin 18 + pub p18: P18, + /// Pin 19 + pub p19: P19, + /// Pin 20 + pub p20: P20, + /// Pin 21 + pub p21: P21, + /// Pin 22 + pub p22: P22, + /// Pin 23 + pub p23: P23, + /// Pin 24 + pub p24: P24, + /// Pin 25 + pub p25: P25, + /// Pin 26 + pub p26: P26, + /// Pin 27 + pub p27: P27, + /// Pin 28 + pub p28: P28, + /// Pin 29 + pub p29: P29, + /// Pin 30 + pub p30: P30, + /// Pin 31 + pub p31: P31, + /// Pin 32 + pub p32: P32, + /// Pin 33 + pub p33: P33, + // END OF COMMON PINS + /// Pin 34 + pub p34: P34, + /// Pin 35 + pub p35: P35, + /// Pin 36 + pub p36: P36, + /// Pin 37 + pub p37: P37, + /// Pin 38 + pub p38: P38, + /// Pin 39 + pub p39: P39, + /// Pin 40 + pub p40: P40, + /// Pin 41 + pub p41: P41, +} + +/// Constrain the processor pads to the Teensy 4.1 pins +pub fn pins(iomuxc: crate::hal::iomuxc::Pads) -> Pins { + Pins { + p0: iomuxc.ad_b0.p03, + p1: iomuxc.ad_b0.p02, + p2: iomuxc.emc.p04, + p3: iomuxc.emc.p05, + p4: iomuxc.emc.p06, + p5: iomuxc.emc.p08, + p6: iomuxc.b0.p10, + p7: iomuxc.b1.p01, + p8: iomuxc.b1.p00, + p9: iomuxc.b0.p11, + p10: iomuxc.b0.p00, + p11: iomuxc.b0.p02, + p12: iomuxc.b0.p01, + p13: iomuxc.b0.p03, + p14: iomuxc.ad_b1.p02, + p15: iomuxc.ad_b1.p03, + p16: iomuxc.ad_b1.p07, + p17: iomuxc.ad_b1.p06, + p18: iomuxc.ad_b1.p01, + p19: iomuxc.ad_b1.p00, + p20: iomuxc.ad_b1.p10, + p21: iomuxc.ad_b1.p11, + p22: iomuxc.ad_b1.p08, + p23: iomuxc.ad_b1.p09, + p24: iomuxc.ad_b0.p12, + p25: iomuxc.ad_b0.p13, + p26: iomuxc.ad_b1.p14, + p27: iomuxc.ad_b1.p15, + p28: iomuxc.emc.p32, + p29: iomuxc.emc.p31, + p30: iomuxc.emc.p37, + p31: iomuxc.emc.p36, + p32: iomuxc.b0.p12, + p33: iomuxc.emc.p07, + // END OF COMMON PINS + p34: iomuxc.b1.p13, + p35: iomuxc.b1.p12, + p36: iomuxc.b1.p02, + p37: iomuxc.b1.p03, + p38: iomuxc.ad_b1.p12, + p39: iomuxc.ad_b1.p13, + p40: iomuxc.ad_b1.p04, + p41: iomuxc.ad_b1.p05, + } +} From 249453da60363d180177b442c5df96c9c3f5a081 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Tue, 21 Jul 2020 21:51:36 -0400 Subject: [PATCH 12/20] Add type erased Teensy 4.0 & 4.1 pins --- src/t40.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/t41.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/t40.rs b/src/t40.rs index 029a582f..1ec38ba9 100644 --- a/src/t40.rs +++ b/src/t40.rs @@ -1,4 +1,4 @@ -//! Teensy 4.0 specific API +//! Teensy 4.0 specific APIs //! //! # Pins unique to the Teensy 4.0 //! @@ -15,7 +15,7 @@ //! | 39 |`SD_B0_04`| |`FlexPWM1_2_A`| `UART8_TX` | | | | | | | | pub use crate::common::*; -use crate::hal::iomuxc::sd_b0::*; +use crate::hal::iomuxc::{sd_b0::*, ErasedPad}; /// Pin 34 (4.0) pub type P34 = SD_B0_03; @@ -30,6 +30,14 @@ pub type P38 = SD_B0_05; /// Pin 39 (4.0) pub type P39 = SD_B0_04; +/// Type-erased Teensy 4.0 pins +/// +/// To get pin 13, the LED, index into the 13th element of this array: +/// `erased_pins[13]`. +/// +/// Use [`Pins::erase`] to erase pin types. +pub type ErasedPins = [ErasedPad; 40]; + /// Teensy 4.0 pins /// /// See [`pins`](fn.pins.html) to constrain the processor's pads, and acquire @@ -164,3 +172,52 @@ pub fn pins(iomuxc: crate::hal::iomuxc::Pads) -> Pins { p39: iomuxc.sd_b0.p04, } } + +impl Pins { + /// Erase the types of all pins + pub fn erase(self) -> ErasedPins { + [ + self.p0.erase(), + self.p1.erase(), + self.p2.erase(), + self.p3.erase(), + self.p4.erase(), + self.p5.erase(), + self.p6.erase(), + self.p7.erase(), + self.p8.erase(), + self.p9.erase(), + self.p10.erase(), + self.p11.erase(), + self.p12.erase(), + self.p13.erase(), + self.p14.erase(), + self.p15.erase(), + self.p16.erase(), + self.p17.erase(), + self.p18.erase(), + self.p19.erase(), + self.p20.erase(), + self.p21.erase(), + self.p22.erase(), + self.p23.erase(), + self.p24.erase(), + self.p25.erase(), + self.p26.erase(), + self.p27.erase(), + self.p28.erase(), + self.p29.erase(), + self.p30.erase(), + self.p31.erase(), + self.p32.erase(), + self.p33.erase(), + // END OF COMMON PINS + self.p34.erase(), + self.p35.erase(), + self.p36.erase(), + self.p37.erase(), + self.p38.erase(), + self.p39.erase(), + ] + } +} diff --git a/src/t41.rs b/src/t41.rs index 2ab07d47..201faec8 100644 --- a/src/t41.rs +++ b/src/t41.rs @@ -1,4 +1,4 @@ -//! Teensy 4.1 specific API +//! Teensy 4.1 specific APIs //! //! # Pins unique to the Teensy 4.1 //! @@ -17,7 +17,7 @@ //! | 41 |`AD_B1_05`| | | | | | | | | | | pub use crate::common::*; -use crate::hal::iomuxc::{ad_b1::*, b1::*}; +use crate::hal::iomuxc::{ad_b1::*, b1::*, ErasedPad}; /// Pin 34 (4.1) pub type P34 = B1_13; @@ -36,6 +36,14 @@ pub type P40 = AD_B1_04; /// Pin 41 (4.1) pub type P41 = AD_B1_05; +/// Type-erased Teensy 4.1 pins +/// +/// To get pin 13, the LED, index into the 13th element of this array: +/// `erased_pins[13]`. +/// +/// Use [`Pins::erase`] to erase pin types. +pub type ErasedPins = [ErasedPad; 42]; + /// Teensy 4.1 pins /// /// See [`pins`](fn.pins.html) to constrain the processor's pads, and acquire @@ -176,3 +184,54 @@ pub fn pins(iomuxc: crate::hal::iomuxc::Pads) -> Pins { p41: iomuxc.ad_b1.p05, } } + +impl Pins { + /// Erase the types of all pins + pub fn erase(self) -> ErasedPins { + [ + self.p0.erase(), + self.p1.erase(), + self.p2.erase(), + self.p3.erase(), + self.p4.erase(), + self.p5.erase(), + self.p6.erase(), + self.p7.erase(), + self.p8.erase(), + self.p9.erase(), + self.p10.erase(), + self.p11.erase(), + self.p12.erase(), + self.p13.erase(), + self.p14.erase(), + self.p15.erase(), + self.p16.erase(), + self.p17.erase(), + self.p18.erase(), + self.p19.erase(), + self.p20.erase(), + self.p21.erase(), + self.p22.erase(), + self.p23.erase(), + self.p24.erase(), + self.p25.erase(), + self.p26.erase(), + self.p27.erase(), + self.p28.erase(), + self.p29.erase(), + self.p30.erase(), + self.p31.erase(), + self.p32.erase(), + self.p33.erase(), + // END OF COMMON PINS + self.p34.erase(), + self.p35.erase(), + self.p36.erase(), + self.p37.erase(), + self.p38.erase(), + self.p39.erase(), + self.p40.erase(), + self.p41.erase(), + ] + } +} From b1f1ee1ce769ad72ffd4e5a52f42f6a7e4a6b8bd Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Wed, 22 Jul 2020 17:29:13 -0400 Subject: [PATCH 13/20] Fix docs --- src/common.rs | 2 +- src/lib.rs | 3 +-- src/t40.rs | 4 ++-- src/t41.rs | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/common.rs b/src/common.rs index 3f8fb543..809d9d38 100644 --- a/src/common.rs +++ b/src/common.rs @@ -2,7 +2,7 @@ //! //! # Common Pinout //! -//! The Teensy 4.0 and 4.1 have many similar pad to pin mappings. This table documents +//! The Teensy 4.0 and 4.1 have many similar pad to pin mappings. This module provides //! the pins that are common across both boards. For pins that are unique to //! each board, and to acquire all of a board's pins, see the [`t40`](../t40/index.html) //! and [`t41`](../t41/index.html) modules. diff --git a/src/lib.rs b/src/lib.rs index ce294fcf..af0eabef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -79,7 +79,6 @@ pub use hal::ral::interrupt; pub use hal::ral::{interrupt as Interrupt, NVIC_PRIO_BITS}; pub use cortex_m_rt as rt; -use hal::iomuxc; pub use hal::Peripherals; pub use imxrt_hal as hal; @@ -92,7 +91,7 @@ pub type LED = hal::gpio::GPIO; /// /// Returns a GPIO that's physically tied to the LED. Use the returned handle /// to drive the LED. -pub fn configure_led(pad: iomuxc::b0::B0_03) -> LED { +pub fn configure_led(pad: common::P13) -> LED { let mut led = hal::gpio::GPIO::new(pad); led.set_fast(true); led.output() diff --git a/src/t40.rs b/src/t40.rs index 1ec38ba9..b62b5105 100644 --- a/src/t40.rs +++ b/src/t40.rs @@ -2,7 +2,7 @@ //! //! # Pins unique to the Teensy 4.0 //! -//! See the [`common` documentation](../common/index.html) for pins that are consistent +//! See the [`common` module](../common/index.html) for pins that are consistent //! across both boards. //! //! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | @@ -35,7 +35,7 @@ pub type P39 = SD_B0_04; /// To get pin 13, the LED, index into the 13th element of this array: /// `erased_pins[13]`. /// -/// Use [`Pins::erase`] to erase pin types. +/// Use [`Pins::erase`](struct.Pins.html#method.erase) to erase pin types. pub type ErasedPins = [ErasedPad; 40]; /// Teensy 4.0 pins diff --git a/src/t41.rs b/src/t41.rs index 201faec8..708855d0 100644 --- a/src/t41.rs +++ b/src/t41.rs @@ -2,7 +2,7 @@ //! //! # Pins unique to the Teensy 4.1 //! -//! See the [`common` documentation](../common/index.html) for pins that are consistent +//! See the [`common` module](../common/index.html) for pins that are consistent //! across both boards. //! //! | Pin | Pad ID | Alt0 | Alt1 | Alt2 | Alt3 | Alt4 | Alt5 | Alt6 | Alt7 | Alt8 | Alt9 | @@ -41,7 +41,7 @@ pub type P41 = AD_B1_05; /// To get pin 13, the LED, index into the 13th element of this array: /// `erased_pins[13]`. /// -/// Use [`Pins::erase`] to erase pin types. +/// Use [`Pins::erase`](struct.Pins.html#method.erase) to erase pin types. pub type ErasedPins = [ErasedPad; 42]; /// Teensy 4.1 pins From 016920778f099d31f075d93a9080ad63c12108f4 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Wed, 22 Jul 2020 19:19:33 -0400 Subject: [PATCH 14/20] Add support for unit & documentation tests Use `make test` to run the tests. We're requiring a nightly compiler, since we need to use a lang_item in a documentation test. --- Cargo.toml | 8 ++++++-- Makefile | 8 +++++++- src/common.rs | 27 ++++++++++++++++++++++++--- src/lib.rs | 30 ++++++++++++++++++++++++++++++ src/t40.rs | 10 ++++++++++ src/t41.rs | 10 ++++++++++ 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e4200c24..98c3d3ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ Part of the teensy4-rs project. [dependencies] cortex-m = "0.6.2" cortex-m-rt = "0.6.12" # Note: not the 'real' cortex-m-rt + +[target.thumbv7em-none-eabihf.dependencies] teensy4-fcb = { path = "teensy4-fcb" } [dependencies.imxrt-hal] @@ -40,12 +42,14 @@ optional = true path = "teensy4-usb-sys" optional = true -[dev-dependencies] +[target.thumbv7em-none-eabihf.dev-dependencies] cortex-m-rtic = "0.5.3" embedded-hal = "0.2.4" heapless = "0.5.5" log = "0.4.8" nb = "0.1.2" + +[dev-dependencies] panic-halt = "0.2.0" [[example]] @@ -110,4 +114,4 @@ path = "cortex-m-rt-patch" [package.metadata.docs.rs] all-features = true -rustdoc-args = ["--cfg", "docsrs"] \ No newline at end of file +rustdoc-args = ["--cfg", "docsrs"] diff --git a/Makefile b/Makefile index 37b1263d..873bef28 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ CARGO ?= cargo TEENSY_LOADER ?= teensy_loader_cli MODE ?= --release INSTALL_DEPS ?= 1 +HOST ?= $(shell rustc --version --verbose | grep host | cut -d ' ' -f 2) ifneq ($(INSTALL_DEPS),0) # Ensure the thumbv7em-none-eabihf component is installed @@ -77,4 +78,9 @@ libt4usb: .PHONY: clean clean: - @cargo clean \ No newline at end of file + @cargo clean + +.PHONY: test +test: + @cargo +nightly test --lib --tests --target $(HOST) + @cargo +nightly test --doc --target $(HOST) \ No newline at end of file diff --git a/src/common.rs b/src/common.rs index 809d9d38..af363a46 100644 --- a/src/common.rs +++ b/src/common.rs @@ -2,14 +2,35 @@ //! //! # Common Pinout //! -//! The Teensy 4.0 and 4.1 have many similar pad to pin mappings. This module provides +//! The Teensy 4.0 and 4.1 share many pins. This module provides //! the pins that are common across both boards. For pins that are unique to //! each board, and to acquire all of a board's pins, see the [`t40`](../t40/index.html) //! and [`t41`](../t41/index.html) modules. //! -//! ## This table is incomplete +//! Note that this pin API is optional, provided only for convenience. You are free to +//! configure the pins using the pad identifiers, instead of the physical pin identifiers. //! -//! We believe this table's contents are accurate. But, there may be alternate functions that are not +//! The following examples are equivalent ways to configure the LED. The first uses the +//! pins API. The second uses the processor pad that drivers the LED. +//! +//! ```no_run +//! use teensy4_bsp as bsp; +//! let peripherals = bsp::Peripherals::take().unwrap(); +//! let pins = bsp::t40::pins(peripherals.iomuxc); +//! let led = bsp::configure_led(pins.p13); +//! ``` +//! +//! ```no_run +//! use teensy4_bsp as bsp; +//! let peripherals = bsp::Peripherals::take().unwrap(); +//! let led = bsp::configure_led(peripherals.iomuxc.b0.p03); +//! ``` +//! +//! ## Common pin table +//! +//! **This table is incomplete** +//! +//! We believe this table is accurate. But, there may be alternate functions that are not //! documented, and we're maintaining this table on a best-effort basis. Besides this table, //! there are two other ways to identify which pads support which peripheral: //! diff --git a/src/lib.rs b/src/lib.rs index af0eabef..19e68731 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,35 @@ //! //! # Examples //! +//! Turn on a Teensy 4.0's LED: +//! +//! ```no_run +//! # #![feature(lang_items)] +//! #![no_std] +//! #![no_main] +//! +//! extern crate panic_halt; +//! +//! use bsp::rt::entry; +//! use cortex_m::asm::wfi; +//! use teensy4_bsp as bsp; +//! +//! use embedded_hal::digital::v2::OutputPin; +//! +//! #[entry] +//! fn main() -> ! { +//! let peripherals = bsp::Peripherals::take().unwrap(); +//! let pins = bsp::t40::pins(peripherals.iomuxc); +//! let mut led = bsp::configure_led(pins.p13); +//! +//! loop { +//! led.set_high().unwrap(); +//! wfi(); +//! } +//! } +//! # #[lang = "eh_personality"] extern fn eh_personality() {} +//! ``` +//! //! See the `teensy4-examples` crate for build-able, run-able //! examples. The examples utilize this BSP crate to blink LEDs, //! establish timers, and log data over USB. @@ -57,6 +86,7 @@ #![cfg_attr(docsrs, feature(doc_cfg))] // Need to reference this so that it doesn't get stripped out +#[cfg(target_arch = "arm")] extern crate teensy4_fcb; pub mod common; diff --git a/src/t40.rs b/src/t40.rs index b62b5105..68342ffe 100644 --- a/src/t40.rs +++ b/src/t40.rs @@ -13,6 +13,16 @@ //! | 37 |`SD_B0_00`| |`FlexPWM1_0_A`| `I2C3_SCL` | | `SPI1_SCK` | | | | | | //! | 38 |`SD_B0_05`| |`FlexPWM1_2_B`| `UART8_RX` | | | | | | | | //! | 39 |`SD_B0_04`| |`FlexPWM1_2_A`| `UART8_TX` | | | | | | | | +//! +//! # Example: get Teensy 4.0 pins +//! +//! ```no_run +//! use teensy4_bsp as bsp; +//! +//! let peripherals = bsp::Peripherals::take().unwrap(); +//! let pins = bsp::t40::pins(peripherals.iomuxc); +//! let led = bsp::configure_led(pins.p13); +//! ``` pub use crate::common::*; use crate::hal::iomuxc::{sd_b0::*, ErasedPad}; diff --git a/src/t41.rs b/src/t41.rs index 708855d0..a72aa528 100644 --- a/src/t41.rs +++ b/src/t41.rs @@ -15,6 +15,16 @@ //! | 39 |`AD_B1_13`| | | | | | | | | | | //! | 40 |`AD_B1_04`| | | | | | | | | | | //! | 41 |`AD_B1_05`| | | | | | | | | | | +//! +//! # Example +//! +//! ```no_run +//! use teensy4_bsp as bsp; +//! +//! let peripherals = bsp::Peripherals::take().unwrap(); +//! let pins = bsp::t41::pins(peripherals.iomuxc); +//! let led = bsp::configure_led(pins.p13); +//! ``` pub use crate::common::*; use crate::hal::iomuxc::{ad_b1::*, b1::*, ErasedPad}; From afe923743c9a9c3c157977aed76ac8ce9059dce6 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Wed, 22 Jul 2020 19:27:02 -0400 Subject: [PATCH 15/20] Build RTIC examples in make all; remove download Don't want to abuse make with download actions. --- Makefile | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 873bef28..778eb358 100644 --- a/Makefile +++ b/Makefile @@ -35,16 +35,20 @@ endif endif # INSTALL_DEPS != 0 TARGET_EXAMPLES := target/thumbv7em-none-eabihf/release/examples -EXAMPLES := $(shell ls examples | xargs basename | cut -f 1 -d .) +EXAMPLES := $(shell ls examples | grep -v rtic | xargs basename | cut -f 1 -d .) RTIC_EXAMPLES := $(shell ls examples | grep rtic | xargs basename | cut -f 1 -d .) .PHONY: all all: - @cargo build $(MODE) --examples @for example in $(EXAMPLES);\ do cargo objcopy $(MODE) --example $$example \ -- -O ihex $(TARGET_EXAMPLES)/$$example.hex;\ done + @for example in $(RTIC_EXAMPLES);\ + do cargo objcopy $(MODE) --example $$example \ + --no-default-features --features=rtic \ + -- -O ihex $(TARGET_EXAMPLES)/$$example.hex;\ + done # Build all RTIC-related examples .PHONY: rtic @@ -54,22 +58,6 @@ rtic: --no-default-features --features=rtic;\ done -.PHONY: example_% -example_%: - @cargo build \ - $(MODE) --example $(subst example_,,$@) - -.PHONY: objcopy_% -objcopy_%: example_% - @cargo objcopy \ - $(MODE) --example $(subst objcopy_,,$@) \ - -- -O ihex \ - $(TARGET_EXAMPLES)/$(subst objcopy_,,$@).hex - -.PHONY: download_% -download_%: objcopy_% - @$(LOADER) $(TARGET_EXAMPLES)/$(subst download_,,$@).hex - libt4boot: @make -C teensy4-rt/bin From 353720f50ede7e6a6e089889dd651dcc05ed20fb Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Wed, 22 Jul 2020 19:32:20 -0400 Subject: [PATCH 16/20] Add test job to CI The job will run any unit and documentation tests --- .github/bors.toml | 3 ++- .github/workflows/build.yml | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/bors.toml b/.github/bors.toml index 8141e2ba..9762620a 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -3,6 +3,7 @@ status = [ "doc", "format", "precompiled", - "template" + "template", + "test" ] delete_merged_branches = true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8ecf908d..c0d4c86a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,8 +17,6 @@ jobs: command: fmt args: --verbose --all -- --check - # Since we don't have any automated tests right now, we can use a clippy - # run to check the build and surface linting errors. clippy: runs-on: ubuntu-latest steps: @@ -45,3 +43,14 @@ jobs: run: INSTALL_DEPS=0 make libt4boot - name: Build USB stack run: INSTALL_DEPS=0 make libt4usb + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: nightly + override: true + - name: Run unit and documentation tests + run: INSTALL_DEPS=0 make test \ No newline at end of file From 8b478670ea0f7d8e31c2fbfd8aecc6002852afe8 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sun, 26 Jul 2020 14:49:01 -0400 Subject: [PATCH 17/20] Fix usb_writer example --- examples/usb_writer.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/usb_writer.rs b/examples/usb_writer.rs index d4f156e9..c6c70b66 100644 --- a/examples/usb_writer.rs +++ b/examples/usb_writer.rs @@ -13,13 +13,15 @@ use teensy4_bsp as bsp; #[rt::entry] fn main() -> ! { let mut p = bsp::Peripherals::take().unwrap(); + let pins = bsp::t40::pins(p.iomuxc); + let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); // Split the USB stack into read / write halves - let (mut reader, mut writer) = p.usb.split(); - p.systick.delay(2000); + let (mut reader, mut writer) = bsp::usb::split().unwrap(); + systick.delay(2000); p.ccm .pll1 .set_arm_clock(bsp::hal::ccm::PLL1::ARM_HZ, &mut p.ccm.handle, &mut p.dcdc); - let mut led: bsp::LED = bsp::configure_led(p.pins.p13); + let mut led: bsp::LED = bsp::configure_led(pins.p13); let mut buffer = [0; 256]; loop { let bytes_read = reader.read(&mut buffer); @@ -38,6 +40,6 @@ fn main() -> ! { writeln!(writer, "Hello world! 3 + 2 = {}", 3 + 2).unwrap(); led.toggle(); - p.systick.delay(5000); + systick.delay(5000); } } From dadf0f958b437547d3b121c7aa4491adc6b19a57 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sat, 1 Aug 2020 16:28:34 -0400 Subject: [PATCH 18/20] Add more documentation --- src/common.rs | 2 ++ src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++-------- src/systick.rs | 11 +++++++++++ src/usb.rs | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/common.rs b/src/common.rs index af363a46..8bff37f0 100644 --- a/src/common.rs +++ b/src/common.rs @@ -14,6 +14,7 @@ //! pins API. The second uses the processor pad that drivers the LED. //! //! ```no_run +//! // Using the BSP's pin API //! use teensy4_bsp as bsp; //! let peripherals = bsp::Peripherals::take().unwrap(); //! let pins = bsp::t40::pins(peripherals.iomuxc); @@ -21,6 +22,7 @@ //! ``` //! //! ```no_run +//! // Using i.MX RT pads instead of Teensy pins //! use teensy4_bsp as bsp; //! let peripherals = bsp::Peripherals::take().unwrap(); //! let led = bsp::configure_led(peripherals.iomuxc.b0.p03); diff --git a/src/lib.rs b/src/lib.rs index 19e68731..aa9d2640 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,17 @@ -//! A Rust board support package (BSP) for the Teensy 4. +//! A Rust board support package (BSP) for the Teensy 4. Supports the Teensy 4.0 and +//! 4.1 boards. +//! +//! Peripherals are re-exported from the [`imxrt-rs`](https://docs.rs/imxrt-hal/latest/imxrt_hal/) +//! hardware abstraction layer. See the HAL's documentation for more information on creating +//! and using peripherals. //! -//! The BSP is mainly a pass-through of the `imxrt-hal` hardware abstraction layer. //! The BSP restricts the processor pads that are available, since the physical Teensy //! only has a few user-accessible pins. From these pins, you may construct peripherals -//! and perform I/O. -//! -//! The BSP also exposes a USB logging interface. See the [`usb`](usb/index.html) module -//! for more details. +//! and perform I/O. The two Teensy 4 boards support many of the same pins; see the +//! [`common`](common/index.html) module for those similar pins. To construct Teensy 4.0 +//! or 4.1 pins, see the corresponding `pins` function in each of the corresponding modules. //! -//! The BSP does assume some facilities of the processor, both which are required for the +//! The BSP assumes some facilities of the processor, both which are required for the //! USB stack. Each are controllable through feature-flags. Each feature is on by default. //! //! - it registers the `SysTick` exception handler, and configures @@ -18,7 +21,6 @@ //! peripheral for logging. Enabled with the `"usb-logging"` feature, //! which is on by default. Depends on the `"systick"` feature. //! -//! These peripherals and capabilities are not exported from the BSP. //! If a user also registers a `SysTick` or `USB_OTG1` handler, it may //! result in a duplicate definition error. //! @@ -75,6 +77,37 @@ //! examples. The examples utilize this BSP crate to blink LEDs, //! establish timers, and log data over USB. //! +//! # Using RTIC +//! +//! To develop Teensy 4 applications with the RTIC framework, +//! +//! 1. disables the `teensy4-bsp`'s default features +//! 2. enable the BSP's `"rtic"` feature +//! 3. patch the `cortex-m-rt` crate with the Teensy 4's special runtime, available in +//! the `teensy4-bsp`'s repository. +//! +//! All three steps can be summarized by this `Cargo.toml` snippet: +//! +//! ```toml +//! [dependencies.teensy4-bsp] +//! git = "https://github.com/mciantyre/teensy4-rs" +//! branch = "master" +//! default-features = false +//! features = ["rtic"] +//! +//! [patch.crates-io.cortex-m-rt] +//! git = "https://github.com/mciantyre/teensy4-rs" +//! branch = "master" +//! ``` +//! +//! You need to disable the BSP's default features, which disables the `"systick"` feature, +//! to enable RTIC's SYSTICK handler. This means that you cannot use the USB logger when +//! developing RTIC applications. Consider using the [`imxrt-uart-log`](https://crates.io/crates/imxrt-uart-log) +//! crate for an alternate logging implementation. +//! +//! You need to replace the typical `cortex-m-rt` runtime with our custom runtime. The patch +//! above lets us replace RTIC's runtime crate with an API-compatible runtime. +//! //! ## Notice of alpha status //! //! We've made some assumptions in this MVP BSP. diff --git a/src/systick.rs b/src/systick.rs index 4ab64892..5c835921 100644 --- a/src/systick.rs +++ b/src/systick.rs @@ -55,6 +55,17 @@ const SYSTICK_EXT_FREQ: u32 = 100_000; /// /// `SysTick` implements the `embedded_hal`'s `DelayMs` trait. It /// may be used to implement simple, blocking delays. +/// +/// # Example +/// +/// ```no_run +/// use teensy4_bsp as bsp; +/// +/// let core_peripherals = cortex_m::Peripherals::take().unwrap(); +/// let mut systick = bsp::SysTick::new(core_peripherals.SYST); +/// +/// systick.delay(50 /* ms */); +/// ``` #[cfg_attr(docsrs, doc(cfg(feature = "systick")))] pub struct SysTick(cortex_m::peripheral::SYST); diff --git a/src/usb.rs b/src/usb.rs index 64c3b390..ef280115 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -6,6 +6,38 @@ //! [`log`] crate to write data over USB. //! //! [`log`]: https://crates.io/crates/log +//! +//! # Logging Example +//! +//! ```no_run +//! use teensy4_bsp as bsp; +//! +//! let core_peripherals = cortex_m::Peripherals::take().unwrap(); +//! let mut systick = bsp::SysTick::new(core_peripherals.SYST); +//! bsp::usb::init( +//! &systick, +//! bsp::usb::LoggingConfig { +//! filters: &[("motor", None)], +//! ..Default::default() +//! }, +//! ) +//! .unwrap(); +//! +//! log::info!("Hello world! 3 + 2 = {}", 5); +//! ``` +//! +//! # Reader / Writer Example +//! +//! ```no_run +//! use teensy4_bsp as bsp; +//! use core::fmt::Write; +//! +//! let core_peripherals = cortex_m::Peripherals::take().unwrap(); +//! let mut systick = bsp::SysTick::new(core_peripherals.SYST); +//! let (mut reader, mut writer) = bsp::usb::split().unwrap(); +//! +//! write!(writer, "Hello world! 3 + 2 = {}", 5); +//! ``` use crate::interrupt; // bring in interrupt variants for #[interrupt] macro use core::{ From 8cb7aafbba9f068a7f83fd8caefbbc4ff9236a41 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sat, 1 Aug 2020 16:31:47 -0400 Subject: [PATCH 19/20] Require systick reference in usb::split() --- examples/usb_writer.rs | 2 +- src/usb.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/usb_writer.rs b/examples/usb_writer.rs index c6c70b66..bb95eb33 100644 --- a/examples/usb_writer.rs +++ b/examples/usb_writer.rs @@ -16,7 +16,7 @@ fn main() -> ! { let pins = bsp::t40::pins(p.iomuxc); let mut systick = bsp::SysTick::new(cortex_m::Peripherals::take().unwrap().SYST); // Split the USB stack into read / write halves - let (mut reader, mut writer) = bsp::usb::split().unwrap(); + let (mut reader, mut writer) = bsp::usb::split(&systick).unwrap(); systick.delay(2000); p.ccm .pll1 diff --git a/src/usb.rs b/src/usb.rs index ef280115..4e97a408 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -34,7 +34,7 @@ //! //! let core_peripherals = cortex_m::Peripherals::take().unwrap(); //! let mut systick = bsp::SysTick::new(core_peripherals.SYST); -//! let (mut reader, mut writer) = bsp::usb::split().unwrap(); +//! let (mut reader, mut writer) = bsp::usb::split(&systick).unwrap(); //! //! write!(writer, "Hello world! 3 + 2 = {}", 5); //! ``` @@ -129,7 +129,7 @@ pub fn init(_: &crate::SysTick, config: LoggingConfig) -> Result Ok(Reader(core::marker::PhantomData)) } -pub fn split() -> Result<(Reader, Writer), Error> { +pub fn split(_: &crate::SysTick) -> Result<(Reader, Writer), Error> { let taken = TAKEN.swap(true, Ordering::SeqCst); if taken { return Err(Error::AlreadySet); From d7427eda138a15e91050f5ab36280dd7052a1d56 Mon Sep 17 00:00:00 2001 From: Ian McIntyre Date: Sat, 29 Aug 2020 07:50:23 -0400 Subject: [PATCH 20/20] Update HAL and imxrt-uart-log dependencies --- Cargo.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 98c3d3ed..27df2195 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,14 +18,9 @@ cortex-m-rt = "0.6.12" # Note: not the 'real' cortex-m-rt teensy4-fcb = { path = "teensy4-fcb" } [dependencies.imxrt-hal] -version = "0.3.0" -git = "https://github.com/imxrt-rs/imxrt-rs.git" -rev = "1815db6" +version = "0.4.0" features = ["imxrt1062", "rt"] -[dev-dependencies.imxrt-uart-log] -git = "https://github.com/imxrt-rs/imxrt-uart-log.git" - # Tied to "systick" feature, since # SysTick implements a blocking delay trait [dependencies.embedded-hal] @@ -46,6 +41,7 @@ optional = true cortex-m-rtic = "0.5.3" embedded-hal = "0.2.4" heapless = "0.5.5" +imxrt-uart-log = "0.2.0" log = "0.4.8" nb = "0.1.2"