diff --git a/boards/feather_m0/src/lib.rs b/boards/feather_m0/src/lib.rs index 5599fc0220da..9bf9ca17eb61 100644 --- a/boards/feather_m0/src/lib.rs +++ b/boards/feather_m0/src/lib.rs @@ -266,6 +266,7 @@ pub fn i2c_master( I2CMaster3::new(clock, baud, sercom3, pm, sda, scl) } +/// UART pads for the labelled RX & TX pins pub type UartPads = uart::Pads; /// UART device for the labelled RX & TX pins @@ -291,6 +292,7 @@ pub fn uart( } #[cfg(feature = "usb")] +/// Convenience function for setting up USB pub fn usb_allocator( usb: pac::USB, clocks: &mut GenericClockController, diff --git a/boards/feather_m4/Cargo.toml b/boards/feather_m4/Cargo.toml index 639f75417051..e33f6a1c47b8 100644 --- a/boards/feather_m4/Cargo.toml +++ b/boards/feather_m4/Cargo.toml @@ -11,16 +11,16 @@ readme = "README.md" documentation = "https://atsamd-rs.github.io/atsamd/atsamd51j/feather_m4/" [dependencies] -cortex-m = "~0.6" +cortex-m = "0.7" embedded-hal = "0.2.3" nb = "0.1" [dependencies.cortex-m-rt] -version = "0.6.12" +version = "0.7" optional = true [dependencies.atsamd-hal] -version = "0.13" +path = "../../hal" default-features = false [dependencies.usb-device] diff --git a/boards/feather_m4/examples/blinky_basic.rs b/boards/feather_m4/examples/blinky_basic.rs index e90c2ecd3eed..a632a069ad0f 100644 --- a/boards/feather_m4/examples/blinky_basic.rs +++ b/boards/feather_m4/examples/blinky_basic.rs @@ -1,7 +1,6 @@ #![no_std] #![no_main] -use bsp::hal; use feather_m4 as bsp; #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; @@ -9,6 +8,7 @@ use panic_halt as _; use panic_semihosting as _; use bsp::entry; +use bsp::hal; use hal::clock::GenericClockController; use hal::delay::Delay; use hal::pac::{CorePeripherals, Peripherals}; @@ -25,8 +25,8 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = bsp::Pins::new(peripherals.PORT); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + let pins = bsp::Pins::new(peripherals.PORT); + let mut red_led = pins.d13.into_push_pull_output(); let mut delay = Delay::new(core.SYST, &mut clocks); loop { delay.delay_ms(2000u16); diff --git a/boards/feather_m4/examples/dmac.rs b/boards/feather_m4/examples/dmac.rs index b22dc41c883e..b58919df1436 100644 --- a/boards/feather_m4/examples/dmac.rs +++ b/boards/feather_m4/examples/dmac.rs @@ -9,15 +9,15 @@ use cortex_m::asm; use feather_m4 as bsp; use panic_halt as _; +use bsp::hal; use hal::{ clock::GenericClockController, - entry, pac::{CorePeripherals, Peripherals}, }; use hal::dmac::{DmaController, PriorityLevel, Transfer, TriggerAction, TriggerSource}; -#[entry] +#[bsp::entry] fn main() -> ! { let mut peripherals = Peripherals::take().unwrap(); let core = CorePeripherals::take().unwrap(); diff --git a/boards/feather_m4/examples/neopixel_rainbow.rs b/boards/feather_m4/examples/neopixel_rainbow.rs index b8f838e7f1e0..b33781c0a0ca 100644 --- a/boards/feather_m4/examples/neopixel_rainbow.rs +++ b/boards/feather_m4/examples/neopixel_rainbow.rs @@ -10,6 +10,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -39,11 +40,11 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = bsp::Pins::new(peripherals.PORT); + let pins = bsp::Pins::new(peripherals.PORT); let mut delay = Delay::new(core.SYST, &mut clocks); // (Re-)configure PB3 as output - let ws_data_pin = pins.neopixel.into_push_pull_output(&mut pins.port); + let ws_data_pin = pins.neopixel.into_push_pull_output(); // Create a spin timer whoes period will be 9 x 120MHz clock cycles (75ns) let timer = SpinTimer::new(9); let mut neopixel = ws2812::Ws2812::new(timer, ws_data_pin); diff --git a/boards/feather_m4/examples/pwm.rs b/boards/feather_m4/examples/pwm.rs index 6b229ff4461e..9b0de85e8d5e 100644 --- a/boards/feather_m4/examples/pwm.rs +++ b/boards/feather_m4/examples/pwm.rs @@ -7,6 +7,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -33,8 +34,8 @@ fn main() -> ! { ); let mut delay = Delay::new(core.SYST, &mut clocks); - let mut pins = bsp::Pins::new(peripherals.PORT); - let red_led = pins.d13.into_function_e(&mut pins.port); + let pins = bsp::Pins::new(peripherals.PORT); + let red_led: bsp::RedLedPwm = pins.d13.into(); let gclk0 = clocks.gclk0(); let mut pwm4 = Pwm4::new( diff --git a/boards/feather_m4/examples/serial.rs b/boards/feather_m4/examples/serial.rs index 2d21b98ed50e..d3ec1ab24f82 100644 --- a/boards/feather_m4/examples/serial.rs +++ b/boards/feather_m4/examples/serial.rs @@ -3,6 +3,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -15,7 +16,6 @@ use hal::pac::gclk::genctrl::SRC_A; use hal::pac::gclk::pchctrl::GEN_A; use hal::pac::{CorePeripherals, Peripherals}; use hal::prelude::*; -use hal::sercom::{PadPin, Sercom5Pad0, Sercom5Pad1, UART5}; use hal::time::Hertz; #[entry] @@ -30,31 +30,18 @@ fn main() -> ! { &mut peripherals.NVMCTRL, ); clocks.configure_gclk_divider_and_source(GEN_A::GCLK2, 1, SRC_A::DFLL, false); - let gclk2 = clocks - .get_gclk(GEN_A::GCLK2) - .expect("Could not get clock 2"); - let mut pins = bsp::Pins::new(peripherals.PORT); + let pins = bsp::Pins::new(peripherals.PORT); let mut delay = Delay::new(core.SYST, &mut clocks); - let tx: Sercom5Pad0<_> = pins - .d1 - .into_pull_down_input(&mut pins.port) - .into_pad(&mut pins.port); - let rx: Sercom5Pad1<_> = pins - .d0 - .into_pull_down_input(&mut pins.port) - .into_pad(&mut pins.port); - let uart_clk = clocks - .sercom5_core(&gclk2) - .expect("Could not configure sercom5 clock"); - - let mut uart = UART5::new( - &uart_clk, + let (tx, rx) = (pins.d1, pins.d0); + let mut uart = bsp::uart( + &mut clocks, Hertz(19200), peripherals.SERCOM5, &mut peripherals.MCLK, - (rx, tx), + rx, + tx, ); loop { diff --git a/boards/feather_m4/examples/sleeping_timer_rtc.rs b/boards/feather_m4/examples/sleeping_timer_rtc.rs index da21b151e192..acebc794fe47 100644 --- a/boards/feather_m4/examples/sleeping_timer_rtc.rs +++ b/boards/feather_m4/examples/sleeping_timer_rtc.rs @@ -4,6 +4,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -65,8 +66,8 @@ fn main() -> ! { }); // Configure our red LED and blink forever, sleeping between! - let mut pins = bsp::Pins::new(peripherals.PORT); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + let pins = bsp::Pins::new(peripherals.PORT); + let mut red_led = pins.d13.into_push_pull_output(); loop { red_led.set_low().unwrap(); sleeping_delay.delay_ms(1_000u32); diff --git a/boards/feather_m4/examples/timers.rs b/boards/feather_m4/examples/timers.rs index e6213188b09e..65c65d3367d5 100644 --- a/boards/feather_m4/examples/timers.rs +++ b/boards/feather_m4/examples/timers.rs @@ -29,8 +29,8 @@ fn main() -> ! { &mut peripherals.NVMCTRL, ); // Using the red LED as the feedback for this simple timer example. - let mut pins = bsp::Pins::new(peripherals.PORT); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + let pins = bsp::Pins::new(peripherals.PORT); + let mut red_led = pins.d13.into_push_pull_output(); // gclk0 represents a configured clock using the 120MHz oscillator. let gclk0 = clocks.gclk0(); diff --git a/boards/feather_m4/examples/trng.rs b/boards/feather_m4/examples/trng.rs index d9ffb415f221..dd93a4750e53 100644 --- a/boards/feather_m4/examples/trng.rs +++ b/boards/feather_m4/examples/trng.rs @@ -5,6 +5,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -30,8 +31,8 @@ fn main() -> ! { ); // We will use the red led and a delay in this simplest possible // demonstration of the random number generator. - let mut pins = bsp::Pins::new(peripherals.PORT); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + let pins = bsp::Pins::new(peripherals.PORT); + let mut red_led = pins.d13.into_push_pull_output(); let mut delay = hal::delay::Delay::new(core.SYST, &mut clocks); // Create a struct as a representation of the random number generator peripheral diff --git a/boards/feather_m4/examples/uart_poll_echo.rs b/boards/feather_m4/examples/uart_poll_echo.rs index e669516bd7de..39af8f9f71b5 100644 --- a/boards/feather_m4/examples/uart_poll_echo.rs +++ b/boards/feather_m4/examples/uart_poll_echo.rs @@ -10,6 +10,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -22,7 +23,6 @@ use hal::pac::gclk::genctrl::SRC_A; use hal::pac::gclk::pchctrl::GEN_A; use hal::pac::{CorePeripherals, Peripherals}; use hal::prelude::*; -use hal::sercom::{PadPin, Sercom5Pad0, Sercom5Pad1, UART5}; use hal::time::Hertz; #[entry] @@ -37,32 +37,19 @@ fn main() -> ! { &mut peripherals.NVMCTRL, ); clocks.configure_gclk_divider_and_source(GEN_A::GCLK2, 1, SRC_A::DFLL, false); - let gclk2 = clocks - .get_gclk(GEN_A::GCLK2) - .expect("Could not get clock 2"); - let mut pins = bsp::Pins::new(peripherals.PORT); + let pins = bsp::Pins::new(peripherals.PORT); let mut delay = Delay::new(core.SYST, &mut clocks); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); - - let tx: Sercom5Pad0<_> = pins - .d1 - .into_pull_down_input(&mut pins.port) - .into_pad(&mut pins.port); - let rx: Sercom5Pad1<_> = pins - .d0 - .into_pull_down_input(&mut pins.port) - .into_pad(&mut pins.port); - let uart_clk = clocks - .sercom5_core(&gclk2) - .expect("Could not configure sercom5 clock"); + let mut red_led = pins.d13.into_push_pull_output(); - let mut uart = UART5::new( - &uart_clk, + let (tx, rx) = (pins.d1, pins.d0); + let mut uart = bsp::uart( + &mut clocks, Hertz(19200), peripherals.SERCOM5, &mut peripherals.MCLK, - (rx, tx), + rx, + tx, ); // Write out a message on start up diff --git a/boards/feather_m4/examples/usb_echo.rs b/boards/feather_m4/examples/usb_echo.rs index 5608e43e48f9..3bd14af35d83 100644 --- a/boards/feather_m4/examples/usb_echo.rs +++ b/boards/feather_m4/examples/usb_echo.rs @@ -3,6 +3,7 @@ use bsp::hal; use feather_m4 as bsp; + #[cfg(not(feature = "use_semihosting"))] use panic_halt as _; #[cfg(feature = "use_semihosting")] @@ -11,6 +12,7 @@ use panic_semihosting as _; use bsp::entry; use hal::clock::GenericClockController; use hal::pac::{interrupt, CorePeripherals, Peripherals}; +use hal::prelude::*; use hal::usb::UsbBus; use usb_device::bus::UsbBusAllocator; @@ -31,8 +33,8 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = bsp::Pins::new(peripherals.PORT); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + let pins = bsp::Pins::new(peripherals.PORT); + let mut red_led: bsp::RedLed = pins.d13.into(); let bus_allocator = unsafe { USB_ALLOCATOR = Some(bsp::usb_allocator( @@ -68,7 +70,7 @@ fn main() -> ! { loop { cycle_delay(5 * 1024 * 1024); - red_led.toggle(); + red_led.toggle().unwrap(); } } diff --git a/boards/feather_m4/src/lib.rs b/boards/feather_m4/src/lib.rs index 18707ffd364c..2dcc855316c7 100644 --- a/boards/feather_m4/src/lib.rs +++ b/boards/feather_m4/src/lib.rs @@ -1,136 +1,204 @@ #![no_std] #![recursion_limit = "1024"] -pub use atsamd_hal as hal; - #[cfg(feature = "rt")] use cortex_m_rt; #[cfg(feature = "rt")] pub use cortex_m_rt::entry; -use hal::prelude::*; -use hal::*; - -pub use hal::common::*; +pub use atsamd_hal as hal; +pub use embedded_hal as ehal; pub use hal::pac; -pub use hal::samd51::*; -use gpio::{Floating, Input, Port}; use hal::clock::GenericClockController; use hal::sercom::{ v2::{ + spi, uart::{self, BaudMode, Oversampling}, - IoSet1, Sercom5, + IoSet1, Sercom1, Sercom5, UndocIoSet1, }, - I2CMaster2, PadPin, SPIMaster1, + I2CMaster2, }; use hal::time::Hertz; -use gpio::v2::{AlternateC, AnyPin, Pin, C, PB16, PB17}; - -#[cfg(feature = "usb")] -use gpio::v2::{PA24, PA25}; #[cfg(feature = "usb")] use hal::usb::usb_device::bus::UsbBusAllocator; #[cfg(feature = "usb")] pub use hal::usb::UsbBus; -define_pins!( - /// Maps the pins to their arduino names and - /// the numbers printed on the board. - struct Pins, - pac: pac, - - /// Analog pin 0. Can act as a true analog output - /// as it has a DAC (which is not currently supported - /// by this hal) as well as input. - pin a0 = a2, - - /// Analog Pin 1 - pin a1 = a5, - /// Analog Pin 2 - pin a2 = b8, - /// Analog Pin 3 - pin a3 = b9, - /// Analog Pin 4 - pin a4 = a4, - /// Analog Pin 5 - pin a5 = a6, - - /// Pin 0, rx - pin d0 = b17, - /// Pin 1, tx - pin d1 = b16, - /// Pin 4, PWM capable - pin d4 = a14, - - /// Pin 5, PWM capable - pin d5 = a16, - /// Pin 6, PWM capable - pin d6 = a18, - /// Neopixel Pin - pin neopixel = b3, - /// Pin 9, PWM capable. Also analog input (A7) - pin d9 = a19, - /// Pin 10, PWM capable - pin d10 = a20, - /// Pin 11, PWM capable - pin d11 = a21, - /// Pin 12, PWM capable - pin d12 = a22, - /// Pin 13, which is also attached to - /// the red LED. PWM capable. - pin d13 = a23, - - /// The I2C data line - pin sda = a12, - /// The I2C clock line - pin scl = a13, - - /// The SPI SCK - pin sck = a17, - /// The SPI MOSI - pin mosi = b23, - /// The SPI MISO - pin miso = b22, - - /// The USB D- pad - pin usb_dm = a24, - /// The USB D+ pad - pin usb_dp = a25, +hal::bsp_pins!( + PA02 { + /// Analog pin 0. Can act as a true analog output + /// as it has a DAC (which is not currently supported + /// by this hal) as well as input. + name: a0, + } + PA05 { + /// Analog Pin 1 + name: a1, + } + PB08 { + /// Analog Pin 2 + name: a2, + } + PB09 { + /// Analog Pin 3 + name: a3, + } + PA04 { + /// Analog Pin 4 + name: a4, + } + PA06 { + /// Analog Pin 5 + name: a5, + } + PB01 { + /// Analog Vdiv (1/2 resistor divider for monitoring the battery) + name: battery, + } + + PB17 { + /// Pin 0, UART rx + name: d0, + aliases: { + AlternateC: UartRx + } + } + PB16 { + /// Pin 1, UART tx + name: d1, + aliases: { + AlternateC: UartTx + } + } + PA14 { + /// Pin 4, PWM capable + name: d4, + } + PA16 { + /// Pin 5, PWM capable + name: d5, + } + PA18 { + /// Pin 6, PWM capable + name: d6, + } + PB03 { + /// Neopixel Pin + name: neopixel, + } + PA19 { + /// Pin 9, PWM capable. Also analog input (A7) + name: d9, + } + PA20 { + /// Pin 10, PWM capable + name: d10, + } + PA21 { + /// Pin 11, PWM capable + name: d11, + } + PA22 { + /// Pin 12, PWM capable + name: d12, + } + PA23 { + /// Pin 13, which is also attached to the red LED. PWM capable. + name: d13, + aliases: { + PushPullOutput: RedLed, + AlternateE: RedLedPwm + } + } + PA12 { + /// The I2C data line + name: sda, + aliases: { + AlternateC: Sda + } + } + PA13 { + /// The I2C clock line + name: scl, + aliases: { + AlternateC: Scl + } + } + PA17 { + /// The SPI SCK + name: sck, + aliases: { + AlternateC: Sclk + } + } + PB23 { + /// The SPI MOSI + name: mosi, + aliases: { + AlternateC: Mosi + } + } + PB22 { + /// The SPI MISO + name: miso, + aliases: { + AlternateC: Miso + } + } + PA24 { + /// The USB D- pad + name: usb_dm, + aliases: { + AlternateG: UsbDm + } + } + PA25 { + /// The USB D+ pad + name: usb_dp, + aliases: { + AlternateG: UsbDp + } + } ); +/// SPI pads for the labelled SPI peripheral +/// +/// You can use these pads with other, user-defined [`spi::Config`]urations. +pub type SpiPads = spi::Pads; + +/// SPI master for the labelled SPI peripheral +/// +/// This type implements [`FullDuplex`](ehal::spi::FullDuplex). +pub type Spi = spi::Spi>; + /// Convenience for setting up the labelled SPI peripheral. /// This powers up SERCOM1 and configures it for use as an /// SPI Master in SPI Mode 0. -pub fn spi_master>( +pub fn spi_master( clocks: &mut GenericClockController, - bus_speed: F, + baud: impl Into, sercom1: pac::SERCOM1, mclk: &mut pac::MCLK, - sck: gpio::Pa17>, - mosi: gpio::Pb23>, - miso: gpio::Pb22>, - port: &mut Port, -) -> SPIMaster1< - hal::sercom::Sercom1Pad2>, - hal::sercom::Sercom1Pad3>, - hal::sercom::Sercom1Pad1>, -> { + sclk: impl Into, + mosi: impl Into, + miso: impl Into, +) -> Spi { let gclk0 = clocks.gclk0(); - SPIMaster1::new( - &clocks.sercom1_core(&gclk0).unwrap(), - bus_speed.into(), - hal::hal::spi::Mode { - phase: hal::hal::spi::Phase::CaptureOnFirstTransition, - polarity: hal::hal::spi::Polarity::IdleLow, - }, - sercom1, - mclk, - (miso.into_pad(port), mosi.into_pad(port), sck.into_pad(port)), - ) + let clock = clocks.sercom1_core(&gclk0).unwrap(); + let freq = clock.freq(); + let (miso, mosi, sclk) = (miso.into(), mosi.into(), sclk.into()); + let pads = spi::Pads::default().data_in(miso).data_out(mosi).sclk(sclk); + spi::Config::new(mclk, sercom1, pads, freq) + .baud(baud) + .spi_mode(spi::MODE_0) + .enable() } +/// I2C master for the labelled SDA & SCL pins +pub type I2C = I2CMaster2; + /// Convenience for setting up the labelled SDA, SCL pins to /// operate as an I2C master running at the specified frequency. pub fn i2c_master>( @@ -138,26 +206,21 @@ pub fn i2c_master>( bus_speed: F, sercom2: pac::SERCOM2, mclk: &mut pac::MCLK, - sda: gpio::Pa12>, - scl: gpio::Pa13>, - port: &mut Port, -) -> I2CMaster2< - hal::sercom::Sercom2Pad0>, - hal::sercom::Sercom2Pad1>, -> { + sda: impl Into, + scl: impl Into, +) -> I2C { let gclk0 = clocks.gclk0(); I2CMaster2::new( &clocks.sercom2_core(&gclk0).unwrap(), bus_speed.into(), sercom2, mclk, - sda.into_pad(port), - scl.into_pad(port), + sda.into(), + scl.into(), ) } -pub type UartRx = Pin; -pub type UartTx = Pin; +/// UART pads for the labelled RX & TX pins pub type UartPads = uart::Pads; /// UART device for the labelled RX & TX pins @@ -170,25 +233,24 @@ pub fn uart( baud: impl Into, sercom5: Sercom5, mclk: &mut pac::MCLK, - rx: impl AnyPin, - tx: impl AnyPin, + rx: impl Into, + tx: impl Into, ) -> Uart { let gclk0 = clocks.gclk0(); let clock = &clocks.sercom5_core(&gclk0).unwrap(); let baud = baud.into(); - let pads = uart::Pads::default() - .rx(rx.into().into_alternate::()) - .tx(tx.into().into_alternate::()); + let pads = uart::Pads::default().rx(rx.into()).tx(tx.into()); uart::Config::new(mclk, sercom5, pads, clock.freq()) .baud(baud, BaudMode::Fractional(Oversampling::Bits16)) .enable() } #[cfg(feature = "usb")] +/// Convenience function for setting up USB pub fn usb_allocator( - dm: impl AnyPin, - dp: impl AnyPin, + dm: impl Into, + dp: impl Into, usb: pac::USB, clocks: &mut GenericClockController, mclk: &mut pac::MCLK, @@ -198,6 +260,6 @@ pub fn usb_allocator( clocks.configure_gclk_divider_and_source(GEN_A::GCLK2, 1, SRC_A::DFLL, false); let usb_gclk = clocks.get_gclk(GEN_A::GCLK2).unwrap(); let usb_clock = &clocks.usb(&usb_gclk).unwrap(); - + let (dm, dp) = (dm.into(), dp.into()); UsbBusAllocator::new(UsbBus::new(usb_clock, mclk, dm, dp, usb)) } diff --git a/crates.json b/crates.json index 9efef8326ce4..ec22191c56dd 100644 --- a/crates.json +++ b/crates.json @@ -33,7 +33,7 @@ "build": "cargo build --examples --features=unproven,dma,usb,rtic,sdmmc,adalogger" }, "feather_m4": { - "tier": 2, + "tier": 1, "build": "cargo build --examples --features=unproven,usb" }, "gemma_m0": {