diff --git a/boards/feather_m0/CHANGELOG.md b/boards/feather_m0/CHANGELOG.md index 210ca889c537..b30d8bf59bff 100644 --- a/boards/feather_m0/CHANGELOG.md +++ b/boards/feather_m0/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs - Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API - Add an `i2c` example - Make use of `bsp_peripherals`, `periph_alias` and `pin_alias` macros diff --git a/boards/feather_m0/examples/eic.rs b/boards/feather_m0/examples/eic.rs index 7eb7fd78c86a..9f2e18e81fe4 100644 --- a/boards/feather_m0/examples/eic.rs +++ b/boards/feather_m0/examples/eic.rs @@ -19,7 +19,7 @@ use hal::clock::GenericClockController; use hal::delay::Delay; use hal::eic::pin::{ExtInt2, Sense}; use hal::eic::EIC; -use hal::gpio::v2::{Pin, PullUpInterrupt}; +use hal::gpio::{Pin, PullUpInterrupt}; use hal::prelude::*; use pac::{interrupt, CorePeripherals, Peripherals}; diff --git a/boards/feather_m0/examples/i2c.rs b/boards/feather_m0/examples/i2c.rs index 26375962370f..33abce390bdd 100644 --- a/boards/feather_m0/examples/i2c.rs +++ b/boards/feather_m0/examples/i2c.rs @@ -1,4 +1,4 @@ -//! This example showcases the i2c::v2 module. +//! This example showcases the i2c module. #![no_std] #![no_main] @@ -21,7 +21,7 @@ use hal::clock::GenericClockController; use hal::dmac::{DmaController, PriorityLevel}; use hal::ehal::blocking::i2c::WriteRead; use hal::prelude::*; -use hal::sercom::v2::i2c; +use hal::sercom::i2c; const LENGTH: usize = 1; const ADDRESS: u8 = 0x77; diff --git a/boards/feather_m0/examples/uart.rs b/boards/feather_m0/examples/uart.rs index 1170e0e3fc5f..a51495e0fcf3 100644 --- a/boards/feather_m0/examples/uart.rs +++ b/boards/feather_m0/examples/uart.rs @@ -1,4 +1,4 @@ -//! This example showcases the uart::v2 module. +//! This example showcases the uart module. #![no_std] #![no_main] diff --git a/boards/feather_m0/src/lib.rs b/boards/feather_m0/src/lib.rs index ac0ac8b202bd..76b8f6235567 100644 --- a/boards/feather_m0/src/lib.rs +++ b/boards/feather_m0/src/lib.rs @@ -8,7 +8,7 @@ pub use hal::ehal; pub use hal::pac; use hal::clock::GenericClockController; -use hal::sercom::v2::{ +use hal::sercom::{ i2c, spi, uart::{self, BaudMode, Oversampling}, }; diff --git a/boards/feather_m4/CHANGELOG.md b/boards/feather_m4/CHANGELOG.md index b0a5a1025892..afeaae8da439 100644 --- a/boards/feather_m4/CHANGELOG.md +++ b/boards/feather_m4/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs - Add an `i2c` example - Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API - Updated to 2021 edition, updated dependencies, removed unused dependencies (#562) diff --git a/boards/feather_m4/examples/i2c.rs b/boards/feather_m4/examples/i2c.rs index 350def9915c0..5b1b4b2c9c97 100644 --- a/boards/feather_m4/examples/i2c.rs +++ b/boards/feather_m4/examples/i2c.rs @@ -1,4 +1,4 @@ -//! This example showcases the i2c::v2 module. +//! This example showcases the i2c module. #![no_std] #![no_main] @@ -21,7 +21,7 @@ use hal::clock::GenericClockController; use hal::dmac::{DmaController, PriorityLevel}; use hal::ehal::blocking::i2c::WriteRead; use hal::prelude::*; -use hal::sercom::v2::i2c; +use hal::sercom::i2c; const LENGTH: usize = 1; const ADDRESS: u8 = 0x77; diff --git a/boards/feather_m4/src/lib.rs b/boards/feather_m4/src/lib.rs index 86128b1534c3..442a45fc11d0 100644 --- a/boards/feather_m4/src/lib.rs +++ b/boards/feather_m4/src/lib.rs @@ -8,7 +8,7 @@ pub use hal::ehal; pub use hal::pac; use hal::clock::GenericClockController; -use hal::sercom::v2::{ +use hal::sercom::{ i2c, spi, uart::{self, BaudMode, Oversampling}, IoSet1, Sercom1, Sercom2, Sercom5, UndocIoSet1, diff --git a/boards/metro_m0/CHANGELOG.md b/boards/metro_m0/CHANGELOG.md index d71c9b300db7..00bdf0eec514 100644 --- a/boards/metro_m0/CHANGELOG.md +++ b/boards/metro_m0/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs - Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API - Add an `i2c` example - Updated to 2021 edition, updated dependencies, removed unused dependencies (#562) diff --git a/boards/metro_m0/examples/i2c.rs b/boards/metro_m0/examples/i2c.rs index 37efbb6e62b4..c6add5dfe4cb 100644 --- a/boards/metro_m0/examples/i2c.rs +++ b/boards/metro_m0/examples/i2c.rs @@ -1,4 +1,4 @@ -//! This example showcases the i2c::v2 module. +//! This example showcases the i2c module. #![no_std] #![no_main] @@ -21,7 +21,7 @@ use hal::clock::GenericClockController; use hal::dmac::{DmaController, PriorityLevel}; use hal::ehal::blocking::i2c::WriteRead; use hal::prelude::*; -use hal::sercom::v2::i2c; +use hal::sercom::i2c; const LENGTH: usize = 1; const ADDRESS: u8 = 0x77; diff --git a/boards/metro_m0/src/lib.rs b/boards/metro_m0/src/lib.rs index 040906a0bbeb..8d0549576028 100644 --- a/boards/metro_m0/src/lib.rs +++ b/boards/metro_m0/src/lib.rs @@ -9,7 +9,7 @@ pub use hal::pac; use hal::clock::GenericClockController; use hal::prelude::*; -use hal::sercom::v2::{i2c, spi, uart, Sercom0, Sercom3, Sercom4, Sercom5}; +use hal::sercom::{i2c, spi, uart, Sercom0, Sercom3, Sercom4, Sercom5}; use hal::time::{Hertz, MegaHertz}; #[cfg(feature = "usb")] diff --git a/boards/metro_m4/CHANGELOG.md b/boards/metro_m4/CHANGELOG.md index 59cb3260cdfc..9ccb56c829cd 100644 --- a/boards/metro_m4/CHANGELOG.md +++ b/boards/metro_m4/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs - Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API - Add an `i2c` example - Fix incorrect clocking in `uart` helper function diff --git a/boards/metro_m4/examples/adc.rs b/boards/metro_m4/examples/adc.rs index be593b50e89b..808d615adf36 100644 --- a/boards/metro_m4/examples/adc.rs +++ b/boards/metro_m4/examples/adc.rs @@ -16,7 +16,7 @@ use cortex_m_semihosting::hprintln; use bsp::entry; use hal::adc::Adc; use hal::clock::GenericClockController; -use hal::gpio::v2::B; +use hal::gpio::B; use hal::prelude::*; use pac::gclk::pchctrl::GEN_A::GCLK11; use pac::{CorePeripherals, Peripherals}; diff --git a/boards/metro_m4/examples/clock_out.rs b/boards/metro_m4/examples/clock_out.rs index fa884ab93727..420672d66886 100644 --- a/boards/metro_m4/examples/clock_out.rs +++ b/boards/metro_m4/examples/clock_out.rs @@ -13,7 +13,7 @@ use panic_semihosting as _; use bsp::entry; use hal::clock::GenericClockController; -use hal::gpio::v2::M; +use hal::gpio::M; use pac::gclk::genctrl::SRC_A::DPLL0; use pac::gclk::pchctrl::GEN_A::GCLK2; diff --git a/boards/metro_m4/examples/i2c.rs b/boards/metro_m4/examples/i2c.rs index 949dd14077e8..c7d59ccbe4c6 100644 --- a/boards/metro_m4/examples/i2c.rs +++ b/boards/metro_m4/examples/i2c.rs @@ -1,4 +1,4 @@ -//! This example showcases the i2c::v2 module. +//! This example showcases the i2c module. #![no_std] #![no_main] @@ -21,7 +21,7 @@ use hal::clock::GenericClockController; use hal::dmac::{DmaController, PriorityLevel}; use hal::ehal::blocking::i2c::WriteRead; use hal::prelude::*; -use hal::sercom::v2::i2c; +use hal::sercom::i2c; const LENGTH: usize = 1; const ADDRESS: u8 = 0x77; diff --git a/boards/metro_m4/examples/pwm.rs b/boards/metro_m4/examples/pwm.rs index 693a5c0d2086..62a7c68ceec2 100644 --- a/boards/metro_m4/examples/pwm.rs +++ b/boards/metro_m4/examples/pwm.rs @@ -10,7 +10,7 @@ use metro_m4 as bsp; use hal::clock::GenericClockController; use hal::delay::Delay; -use hal::gpio::v2::E; +use hal::gpio::E; use hal::prelude::*; use hal::pwm::{Pwm2, TC2Pinout}; use pac::{CorePeripherals, Peripherals}; diff --git a/boards/metro_m4/src/lib.rs b/boards/metro_m4/src/lib.rs index 191d7837d7d9..4f55043e2ae7 100644 --- a/boards/metro_m4/src/lib.rs +++ b/boards/metro_m4/src/lib.rs @@ -12,7 +12,7 @@ pub use cortex_m_rt::entry; use hal::{ clock::GenericClockController, qspi::{OneShot, Qspi}, - sercom::v2::{ + sercom::{ i2c, spi, uart::{self, BaudMode, Oversampling}, IoSet1, IoSet6, Sercom2, Sercom3, Sercom5, diff --git a/boards/samd11_bare/CHANGELOG.md b/boards/samd11_bare/CHANGELOG.md index 15d3aee4098a..6df782926fc3 100644 --- a/boards/samd11_bare/CHANGELOG.md +++ b/boards/samd11_bare/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased +- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs - Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API - Add an `i2c` example diff --git a/boards/samd11_bare/Cargo.toml b/boards/samd11_bare/Cargo.toml index 2ab097c4ac0f..0f9bbddb82eb 100644 --- a/boards/samd11_bare/Cargo.toml +++ b/boards/samd11_bare/Cargo.toml @@ -35,6 +35,9 @@ use_semihosting = [] [profile.release] debug = true +[profile.dev] +opt-level = "s" + # for cargo flash [package.metadata] chip = "ATSAMD11C14A" diff --git a/boards/samd11_bare/examples/adc.rs b/boards/samd11_bare/examples/adc.rs index ae2dafe956cf..f887525e313c 100644 --- a/boards/samd11_bare/examples/adc.rs +++ b/boards/samd11_bare/examples/adc.rs @@ -22,7 +22,7 @@ use samd11_bare as bsp; use bsp::entry; use hal::adc::Adc; use hal::clock::GenericClockController; -use hal::gpio::v2::*; +use hal::gpio::*; use hal::pac::{CorePeripherals, Peripherals}; use hal::prelude::*; use rtt_target::{rprintln, rtt_init_print}; diff --git a/boards/samd11_bare/examples/i2c.rs b/boards/samd11_bare/examples/i2c.rs index 85e1c5d17fbb..ce6e7a35e742 100644 --- a/boards/samd11_bare/examples/i2c.rs +++ b/boards/samd11_bare/examples/i2c.rs @@ -21,7 +21,7 @@ use hal::clock::GenericClockController; use hal::dmac::{DmaController, PriorityLevel}; use hal::ehal::blocking::i2c::WriteRead; use hal::prelude::*; -use hal::sercom::v2::i2c; +use hal::sercom::i2c; const LENGTH: usize = 1; const ADDRESS: u8 = 0x77; diff --git a/boards/samd11_bare/examples/pwm.rs b/boards/samd11_bare/examples/pwm.rs index 27b3eb5604c6..13178e7c1d16 100644 --- a/boards/samd11_bare/examples/pwm.rs +++ b/boards/samd11_bare/examples/pwm.rs @@ -13,7 +13,7 @@ use bsp::{hal, pac}; use bsp::entry; use hal::clock::GenericClockController; use hal::delay::Delay; -use hal::gpio::v2::*; +use hal::gpio::*; use hal::prelude::*; use hal::pwm::{Channel, Pwm0}; use pac::{CorePeripherals, Peripherals}; diff --git a/boards/samd11_bare/examples/serial.rs b/boards/samd11_bare/examples/serial.rs index d3f6658c01f0..e17508b06157 100644 --- a/boards/samd11_bare/examples/serial.rs +++ b/boards/samd11_bare/examples/serial.rs @@ -17,7 +17,7 @@ use hal::delay::Delay; use hal::pac::{CorePeripherals, Peripherals}; use hal::pac::gclk::{clkctrl::GEN_A, genctrl::SRC_A}; -use hal::sercom::v2::{ +use hal::sercom::{ uart::{self, BaudMode, Oversampling}, Sercom0, }; diff --git a/boards/samd11_bare/src/lib.rs b/boards/samd11_bare/src/lib.rs index 52faaecfb6d3..87a1b540f769 100644 --- a/boards/samd11_bare/src/lib.rs +++ b/boards/samd11_bare/src/lib.rs @@ -10,7 +10,7 @@ pub use hal::ehal; pub use hal::pac; use hal::clock::GenericClockController; -use hal::sercom::v2::{ +use hal::sercom::{ i2c, uart::{self, BaudMode, Oversampling}, Sercom0, diff --git a/boards/wio_terminal/CHANGELOG.md b/boards/wio_terminal/CHANGELOG.md index 5d857d191655..f129dcc463d8 100644 --- a/boards/wio_terminal/CHANGELOG.md +++ b/boards/wio_terminal/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +- Fix removed deprecated modules from HAL +- Update `lib.rs` and examples to reflect removal of `v1` APIs and promotion of `v2` APIs - Update `i2c_master` convenience function to use the new `sercom::v2::i2c` API - Add an `i2c` example diff --git a/boards/wio_terminal/src/buttons.rs b/boards/wio_terminal/src/buttons.rs index 222398f5d0e9..9e74755e7591 100644 --- a/boards/wio_terminal/src/buttons.rs +++ b/boards/wio_terminal/src/buttons.rs @@ -1,6 +1,6 @@ use atsamd_hal::clock::GenericClockController; -use atsamd_hal::common::eic; -use atsamd_hal::common::eic::pin::{ +use atsamd_hal::eic; +use atsamd_hal::eic::pin::{ ExtInt10, ExtInt11, ExtInt12, ExtInt3, ExtInt4, ExtInt5, ExtInt7, Sense, }; use atsamd_hal::pac::{interrupt, EIC, MCLK}; diff --git a/boards/wio_terminal/src/display.rs b/boards/wio_terminal/src/display.rs index aa51015949d1..0a8f879284ba 100644 --- a/boards/wio_terminal/src/display.rs +++ b/boards/wio_terminal/src/display.rs @@ -1,10 +1,10 @@ use atsamd_hal::clock::GenericClockController; +use atsamd_hal::ehal::blocking::delay::DelayMs; use atsamd_hal::ehal::digital::v2::OutputPin; -use atsamd_hal::hal::blocking::delay::DelayMs; -use atsamd_hal::hal::spi::{Phase, Polarity}; +use atsamd_hal::ehal::spi::{Phase, Polarity}; use atsamd_hal::pac::{MCLK, SERCOM7}; -use atsamd_hal::sercom::v2::spi; -use atsamd_hal::sercom::v2::{IoSet4, Sercom7}; +use atsamd_hal::sercom::spi; +use atsamd_hal::sercom::{IoSet4, Sercom7}; use atsamd_hal::time::Hertz; use atsamd_hal::typelevel::NoneT; use display_interface_spi::SPIInterface; diff --git a/boards/wio_terminal/src/pins.rs b/boards/wio_terminal/src/pins.rs index c062ca35df93..e76d95cceec7 100644 --- a/boards/wio_terminal/src/pins.rs +++ b/boards/wio_terminal/src/pins.rs @@ -6,7 +6,7 @@ use super::sound::{Buzzer, Microphone}; use super::storage::{QSPIFlash, SDCard}; use super::wifi::WifiPins; -/// [`Pin`](atsamd_hal::gpio::v2::Pin) aliases defined by the +/// [`Pin`](atsamd_hal::gpio::Pin) aliases defined by the /// [`bsp_pins!`](atsamd_hal::bsp_pins) macro pub mod aliases { atsamd_hal::bsp_pins!( diff --git a/boards/wio_terminal/src/sensors.rs b/boards/wio_terminal/src/sensors.rs index e3824e0ed8bd..c69c9fd167ec 100644 --- a/boards/wio_terminal/src/sensors.rs +++ b/boards/wio_terminal/src/sensors.rs @@ -2,10 +2,7 @@ use atsamd_hal::adc::Adc; use atsamd_hal::clock::GenericClockController; use atsamd_hal::pac::gclk::pchctrl::GEN_A::GCLK11; use atsamd_hal::pac::{ADC1, MCLK, SERCOM4}; -use atsamd_hal::sercom::{ - v2::{i2c, IoSet3, Sercom4}, - PadPin, -}; +use atsamd_hal::sercom::{i2c, IoSet3, Sercom4}; use atsamd_hal::time::U32Ext; use lis3dh::{Lis3dh, SlaveAddr}; diff --git a/boards/wio_terminal/src/serial.rs b/boards/wio_terminal/src/serial.rs index fd0000df123c..7bf377a594d5 100644 --- a/boards/wio_terminal/src/serial.rs +++ b/boards/wio_terminal/src/serial.rs @@ -1,6 +1,6 @@ use atsamd_hal::clock::GenericClockController; use atsamd_hal::pac::{self, MCLK, SERCOM2}; -use atsamd_hal::sercom::v2::{uart, IoSet2, Sercom2}; +use atsamd_hal::sercom::{uart, IoSet2, Sercom2}; use atsamd_hal::time::Hertz; #[cfg(feature = "usb")] diff --git a/boards/wio_terminal/src/storage.rs b/boards/wio_terminal/src/storage.rs index 99352c5cbad6..f5cc9270723b 100644 --- a/boards/wio_terminal/src/storage.rs +++ b/boards/wio_terminal/src/storage.rs @@ -2,7 +2,7 @@ use atsamd_hal::{ clock::{GenericClockController, Sercom6CoreClock}, pac::{MCLK, QSPI, SERCOM6}, qspi, - sercom::v2::{spi, IoSet1, Sercom6}, + sercom::{spi, IoSet1, Sercom6}, time::{Hertz, U32Ext}, typelevel::NoneT, }; diff --git a/boards/wio_terminal/src/wifi.rs b/boards/wio_terminal/src/wifi.rs index 9a0285420888..cd5f89652e8c 100644 --- a/boards/wio_terminal/src/wifi.rs +++ b/boards/wio_terminal/src/wifi.rs @@ -6,7 +6,7 @@ use atsamd_hal::{ ehal::serial::{Read, Write}, pac::{interrupt, MCLK, SERCOM0}, prelude::nb, - sercom::v2::{uart, IoSet2, Sercom0}, + sercom::{uart, IoSet2, Sercom0}, time::{Hertz, U32Ext}, }; use bbqueue::{self, BBBuffer, Consumer, Producer}; @@ -288,10 +288,8 @@ impl Wifi { /// Imports necessary for using `wifi_singleton`. pub mod wifi_prelude { pub use crate::wifi::*; - pub use atsamd_hal::gpio::Port; pub use atsamd_hal::pac::SERCOM0; pub use atsamd_hal::pac::{interrupt, MCLK}; - pub use atsamd_hal::sercom::{Sercom0Pad0, Sercom0Pad2, UART0}; pub use bbqueue::{BBBuffer, Producer}; pub use cortex_m::interrupt::CriticalSection; diff --git a/hal/CHANGELOG.md b/hal/CHANGELOG.md index 7fdcedb4d0bf..922cfb459ef9 100644 --- a/hal/CHANGELOG.md +++ b/hal/CHANGELOG.md @@ -1,5 +1,14 @@ -# Unreleased Changes +# v0.15.0 +- Remove deprecated modules: + - Remove `gpio::v1`, `sercom::v1` module, promote `gpio::v2` to `gpio` and `sercom::v2` to `sercom`. + - Remove deprecated `hal` in favour of `ehal` + - Remove deprecated `target_device` in favour of `pac` + - Remove deprecated `spi_common` module + - Remove deprecated `common` module + - Remove deprecated `samd51`, `same51`, `same53`, `same54` modules + - Remove deprecated `SpinTimer` + - Provide the necessary fixes to support those changes. - Cleanup most `clippy` lints - Update `seq_macro` and remove `replace_with` dependencies (#568) - Add a `bsp_peripherals!` macro and fix a bug in `bsp_pins!` (#515) diff --git a/hal/README.md b/hal/README.md index ea559ac8dd45..46618b46fa91 100644 --- a/hal/README.md +++ b/hal/README.md @@ -32,9 +32,9 @@ This crate can support other variants in a similar fashion; pull requests for th ## Examples? -Check out the metro_m0 board support crate examples: +Check out the `feather_m0` board support crate examples: -https://github.com/atsamd-rs/atsamd/tree/master/boards/metro_m0/examples +https://github.com/atsamd-rs/atsamd/tree/master/boards/feather_m0/examples ## License diff --git a/hal/src/gpio/v2/dynpin.rs b/hal/src/gpio/dynpin.rs similarity index 100% rename from hal/src/gpio/v2/dynpin.rs rename to hal/src/gpio/dynpin.rs diff --git a/hal/src/gpio/mod.rs b/hal/src/gpio/mod.rs index d56d58e64b08..4a344abf3ef8 100644 --- a/hal/src/gpio/mod.rs +++ b/hal/src/gpio/mod.rs @@ -5,51 +5,19 @@ //! //! ## Versions //! -//! There are currently two versions of the GPIO module. The inital GPIO API -//! used a macro-heavy implementation, and it contained a few mistakes. The -//! discussion in issue [#214](https://github.com/atsamd-rs/atsamd/issues/214) +//! The inital GPIO API used a macro-heavy implementation, and it contained a +//! few mistakes. The discussion in issue [#214](https://github.com/atsamd-rs/atsamd/issues/214) //! spurred the creation of a new module with fewer macros and a corrected, //! refactored API. //! -//! The new module is provided in [`v2`]. The old module was removed, but a -//! compatibility shim is provided in [`v1`] to support existing code. Users -//! should expect to eventually migrate to [`v2`]. +//! The GPIO module has been completely rewritten (the `v2` module in +//! pre-`0.15.0` HAL versions). The old module (`v1`) was removed in HAL version +//! `0.15.0`. //! -//! ## Errors in [`v1`] +//! ## Features //! -//! [`v2`] fixes a number of errors in [`v1`]: +//! - Converting between pin modes no longer requires access to the `Port` type. //! -//! - [`v1`] implements an open-drain output mode, but SAMD chips do not have -//! open-drain outputs. There is (almost) no mention of "open-drain" anywhere -//! in the datasheets. In fact, the SAMD21 datasheet notes a removal of the -//! term in Rev. E. Open-drain outputs have been has been removed in [`v2`]. -//! - [`v1`] allows users to enable a pull-up resistor while in an output mode, -//! but this is not possible for SAMD chips. There is no corresponding entry -//! in the "Pin Configurations Summary" table in any of the three datasheets. -//! Moreover, when a pull resistor is enabled for inputs, its direction is set -//! using the `OUT` bit, which would not be possible in an output mode. -//! - [`v1`] does not implement any of the disabled pin modes, i.e. when both -//! `DIR` and `INEN` are `0`. As a consequence, the state of [`v1`] pins at -//! reset is incorrect. [`v1`] assumes they are in floating input mode, but -//! they are actually in floating disabled mode. -//! -//! ## New features -//! -//! The [`v2`] module has several new features: -//! -//! - Converting between pin modes no longer requires access to the [`Port`] -//! type. -//! -//! For example, the follow code in [`v1`], -//! ``` -//! let pins = peripherals.PORT.split(); -//! let pa8 = pins.pa8.into_push_pull_output(&mut pins.port); -//! ``` -//! would look like this in [`v2`]. -//! ``` -//! let pins = v2::Pins::new(peripherals.PORT); -//! let pa08 = pins.pa08.into_push_pull_output(); -//! ``` //! As a consequence, pin mode conversions can now be implemented using //! [`From`]/[`Into`]. //! ``` @@ -57,48 +25,37 @@ //! let pa08: Pin = pins.pa08.into(); //! ``` //! -//! - [`v2`] defines a new [`AnyPin`] trait that can be used to simplify -//! function arguments and reduce the number of type parameters required when -//! dealing with GPIO pins. -//! - [`v2`] offers a type-erased, [`DynPin`] type, for run-time tracking of -//! pins. -//! - [`v2`] provides a new [`bsp_pins`] macro to help BSP authors provide -//! meaningful names and type aliases for their GPIO pins. -//! -//! ## Compatibility +//! - Defines a new [`AnyPin`] trait that can be used to simplify function +//! arguments and reduce the number of type parameters required when dealing +//! with GPIO pins. See the [`AnyPin`] documentation for more details. //! -//! The original [`v1`] module has been removed. It has been replaced with a -//! compatibility shim to support existing code. The shim implements all [`v1`] -//! pin types in terms of [`v2::Pin`]. In fact, it declares its own [`v1::Pin`] -//! type as a newtype wrapper around a [`v2::Pin`], and it defines the -//! individual `Pa0`, `Pa1`, etc. pin types as type aliases of the new -//! [`v1::Pin`] type. +//! - Offers a type-erased, [`DynPin`] type, for run-time tracking of pins. +//! - Provides a new [`bsp_pins`] macro to help BSP authors provide meaningful +//! names and type aliases for their GPIO pins. //! -//! As a consequence, it is easy to define the conversion between a [`v1::Pin`] -//! and its corresponding [`v2::Pin`] using [`From`]/[`Into`]. -//! ``` -//! let pins = peripherals.PORT.split(); -//! let pa8: v1::Pa8<_> = pins.pa8; -//! let pa08 = v2::Pin<_, _> = pa8.into(); -//! ``` -//! Moreover, all [`v1::Pin`] and [`v2::Pin`] types implement the [`AnyPin`] -//! trait, which is particularly useful for supporting both module versions -//! simultaneously. See the [`AnyPin`] documentation for more details. -//! ``` -//! /// Take the v1 or v2 representation of pin PA08, in any mode, then convert -//! /// it to a push-pull output and set it high -//! fn example(pin: impl AnyPin) { -//! let mut pin = pin.into().into_push_pull_output(); -//! pin.set_high().ok(); -//! } -//! ``` -//! [`AnyPin`]: v2::AnyPin -//! [`DynPin`]: v2::DynPin //! [`bsp_pins`]: crate::bsp_pins +//! +//! # Pin modules +//! +//! The API provides two different submodules, [`pin`] and [`dynpin`], +//! representing two different ways to handle GPIO pins. The default, [`pin`], +//! is a type-level API that tracks the state of each pin at compile-time. The +//! alternative, [`dynpin`] is a type-erased, value-level API that tracks the +//! state of each pin at run-time. +//! +//! The type-level API is strongly preferred. By representing the state of each +//! pin within the type system, the compiler can detect logic errors at +//! compile-time. Furthermore, the type-level API has absolutely zero run-time +//! cost. +//! +//! If needed, [`dynpin`] can be used to erase the type-level differences +//! between pins. However, by doing so, pins must now be tracked at run-time, +//! and each pin has a non-zero memory footprint. -pub mod v1; +pub mod pin; +pub use pin::*; -#[allow(deprecated)] -pub use v1::*; +pub mod dynpin; +pub use dynpin::*; -pub mod v2; +mod reg; diff --git a/hal/src/gpio/v2/pin.rs b/hal/src/gpio/pin.rs similarity index 97% rename from hal/src/gpio/v2/pin.rs rename to hal/src/gpio/pin.rs index 2d549f007492..f0991274406a 100644 --- a/hal/src/gpio/v2/pin.rs +++ b/hal/src/gpio/pin.rs @@ -70,7 +70,7 @@ //! //! ``` //! use atsamd_hal::pac::Peripherals; -//! use atsamd_hal::gpio::v2::Pins; +//! use atsamd_hal::gpio::Pins; //! use embedded_hal::digital::v2::OutputPin; //! //! let mut peripherals = Peripherals::take().unwrap(); @@ -1508,7 +1508,7 @@ macro_rules! __declare_pins_type { )+ ) => { /// BSP replacement for the HAL - /// [`Pins`](atsamd_hal::gpio::v2::Pins) type + /// [`Pins`](atsamd_hal::gpio::Pins) type /// /// This type is intended to provide more meaningful names for the /// given pins. @@ -1517,9 +1517,9 @@ macro_rules! __declare_pins_type { $( $( #[$id_cfg] )* $( #[$name_doc] )* - pub $name: $crate::gpio::v2::Pin< - $crate::gpio::v2::$Id, - $crate::gpio::v2::Reset + pub $name: $crate::gpio::Pin< + $crate::gpio::$Id, + $crate::gpio::Reset >, )+ } @@ -1535,11 +1535,11 @@ macro_rules! __declare_pins_type { /// dropped. /// /// [`PORT`](atsamd_hal::pac::PORT) - /// [`Pin`](atsamd_hal::gpio::v2::Pin) - /// [`Pins`](atsamd_hal::gpio::v2::Pins) + /// [`Pin`](atsamd_hal::gpio::Pin) + /// [`Pins`](atsamd_hal::gpio::Pins) #[inline] pub fn new(port: $crate::pac::PORT) -> Self { - let mut pins = $crate::gpio::v2::Pins::new(port); + let mut pins = $crate::gpio::Pins::new(port); Self { port: Some(unsafe{ pins.port() }), $( @@ -1582,33 +1582,33 @@ macro_rules! __create_pin_aliases { $crate::paste::paste! { $( $( #[$attr] )* - /// Alias for a configured [`Pin`](atsamd_hal::gpio::v2::Pin) - pub type $Alias = $crate::gpio::v2::Pin< - $crate::gpio::v2::$Id, - $crate::gpio::v2::$Mode + /// Alias for a configured [`Pin`](atsamd_hal::gpio::Pin) + pub type $Alias = $crate::gpio::Pin< + $crate::gpio::$Id, + $crate::gpio::$Mode >; $( #[$attr] )* - #[doc = "[`PinId`](atsamd_hal::gpio::v2::PinId) for the [`"] + #[doc = "[`PinId`](atsamd_hal::gpio::PinId) for the [`"] #[doc = $Alias "`] alias"] - pub type [<$Alias Id>] = $crate::gpio::v2::$Id; + pub type [<$Alias Id>] = $crate::gpio::$Id; $( #[$attr] )* - #[doc = "[`PinMode`](atsamd_hal::gpio::v2::PinMode) for the [`"] + #[doc = "[`PinMode`](atsamd_hal::gpio::PinMode) for the [`"] #[doc = $Alias "`] alias"] - pub type [<$Alias Mode>] = $crate::gpio::v2::$Mode; + pub type [<$Alias Mode>] = $crate::gpio::$Mode; $( #[$attr] )* - #[doc = "[DynPinId](atsamd_hal::gpio::v2::DynPinId) "] + #[doc = "[DynPinId](atsamd_hal::gpio::DynPinId) "] #[doc = "for the `" $Alias "` alias."] - pub const [<$Alias:snake:upper _ID>]: $crate::gpio::v2::DynPinId = - <$crate::gpio::v2::$Id as $crate::gpio::v2::PinId>::DYN; + pub const [<$Alias:snake:upper _ID>]: $crate::gpio::DynPinId = + <$crate::gpio::$Id as $crate::gpio::PinId>::DYN; $( #[$attr] )* - #[doc = "[DynPinMode](atsamd_hal::gpio::v2::DynPinMode) "] + #[doc = "[DynPinMode](atsamd_hal::gpio::DynPinMode) "] #[doc = "for the `" $Alias "` alias."] - pub const [<$Alias:snake:upper _MODE>]: $crate::gpio::v2::DynPinMode = - <$crate::gpio::v2::$Mode as $crate::gpio::v2::PinMode>::DYN; + pub const [<$Alias:snake:upper _MODE>]: $crate::gpio::DynPinMode = + <$crate::gpio::$Mode as $crate::gpio::PinMode>::DYN; )* } }; diff --git a/hal/src/gpio/v2/reg.rs b/hal/src/gpio/reg.rs similarity index 100% rename from hal/src/gpio/v2/reg.rs rename to hal/src/gpio/reg.rs diff --git a/hal/src/gpio/v1.rs b/hal/src/gpio/v1.rs deleted file mode 100644 index 10fdd1095bac..000000000000 --- a/hal/src/gpio/v1.rs +++ /dev/null @@ -1,833 +0,0 @@ -//! # Version 1 of the GPIO module -//! -//! This module is a compatibility shim that allows existing code to use the new -//! [v2](super::v2) module. This API will eventually be deprecated and removed. -//! -//! Working with GPIO pins. -//! The pins are associated with the PORT hardware. This module defines a -//! [split](GpioExt::split) method on the [PORT](crate::pac::PORT) -//! type that is used to safely reference the individual pin configuration. -//! The IO pins can be switched into alternate function modes, which -//! routes the pins to different peripherals depending on the mode -//! for the pin. The pin configuration is reflected through the -//! use of type states to make the interface (ideally, or at least practically) -//! impossible to misuse. - -#![deprecated( - since = "0.13.0", - note = "The gpio::v1 module is deprecated, and will be removed in a subsequent release. - Please use the gpio::v2 module instead." -)] - -use crate::ehal::digital::v2::OutputPin; -#[cfg(feature = "unproven")] -use crate::ehal::digital::v2::{InputPin, StatefulOutputPin, ToggleableOutputPin}; -use crate::pac::PORT; - -use crate::gpio::v2::{self, Alternate, AlternateConfig, AnyPin, OutputConfig}; -pub use crate::gpio::v2::{PinId, PinMode}; -use crate::typelevel::Sealed; - -//============================================================================== -// Type definitions -//============================================================================== - -/// Represents a pin configured for input. -/// The MODE type is typically one of `Floating`, `PullDown` or -/// `PullUp`. -pub type Input = v2::Input; - -/// Represents a pin configured for interrupt. -/// The MODE type is one of `Floating`, `PullDown` or `PullUp`. -pub type Interrupt = v2::Interrupt; - -/// Represents a pin configured for output. -/// The MODE type is typically one of `PushPull`, or -/// `OpenDrain`. -pub type Output = v2::Output; - -// The following collection of types is used to encode the -// state of the pin at compile time and helps to avoid misuse. - -/// Floating Input -pub type Floating = v2::Floating; -/// Pulled down Input -pub type PullDown = v2::PullDown; -/// Pulled up Input -pub type PullUp = v2::PullUp; - -/// Totem Pole aka Push-Pull -pub type PushPull = v2::PushPull; -/// Open drain output. -/// The SAMD5x/E5x chips don't actually have open drain outputs. -/// This option was added by mistake. It is currently an alias of `PushPull` -pub type OpenDrain = v2::PushPull; -/// Open drain output, which can be read when not driven -/// The SAMD5x/E5x chips don't actually have open drain outputs. -/// This option actually represents a readable `PushPull` output -pub type ReadableOpenDrain = v2::Readable; - -/// Peripheral Function B -pub type PfB = v2::AlternateB; -/// Peripheral Function C -pub type PfC = v2::AlternateC; -/// Peripheral Function D -pub type PfD = v2::AlternateD; -/// Peripheral Function E -pub type PfE = v2::AlternateE; -/// Peripheral Function F -pub type PfF = v2::AlternateF; -/// Peripheral Function G -pub type PfG = v2::AlternateG; -/// Peripheral Function H -#[cfg(any(feature = "samd21", feature = "min-samd51g"))] -pub type PfH = v2::AlternateH; -/// Peripheral Function I -#[cfg(feature = "min-samd51g")] -pub type PfI = v2::AlternateI; -/// Peripheral Function J -#[cfg(feature = "min-samd51g")] -pub type PfJ = v2::AlternateJ; -/// Peripheral Function K -#[cfg(feature = "min-samd51g")] -pub type PfK = v2::AlternateK; -/// Peripheral Function L -#[cfg(feature = "min-samd51g")] -pub type PfL = v2::AlternateL; -/// Peripheral Function M -#[cfg(feature = "min-samd51g")] -pub type PfM = v2::AlternateM; -/// Peripheral Function N -#[cfg(feature = "min-samd51g")] -pub type PfN = v2::AlternateN; - -//============================================================================== -// Pin -//============================================================================== - -/// Represents a GPIO pin with a corresponding [`PinId`] and [`PinMode`] -/// -/// The [`v2::Pin`] type provides many of the same inherent functions, but it -/// does so without requiring the `PORT` as an argument, breaking backwards -/// compatibility. -/// -/// `v1` [`Pin`] type is a newtype wrapper for [`v2::Pin`]s. To aid in -/// compatibility, the `v1` [`Pin`] types also implement [`AnyPin`]. [`From`] & -/// [`Into`] conversions are provided between the two pin types. -pub struct Pin -where - I: PinId, - M: PinMode, -{ - pub(crate) pin: v2::Pin, -} - -impl Pin -where - I: PinId, - M: PinMode, -{ - #[inline] - unsafe fn new() -> Pin { - Pin { - pin: v2::Pin::new(), - } - } - - #[inline] - pub fn into_mode(mut self) -> Pin { - // Change pin mode unconditionally, to match the original `v1` behavior - self.pin.regs.change_mode::(); - // Safe because we drop the existing Pin - unsafe { Pin::new() } - } - - /// Configures the pin to operate as a floating input - #[allow(unused_variables)] - #[inline] - pub fn into_floating_input(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as a pulled down input pin - #[allow(unused_variables)] - #[inline] - pub fn into_pull_down_input(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as a pulled up input pin - #[allow(unused_variables)] - #[inline] - pub fn into_pull_up_input(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as a floating interrupt - #[allow(unused_variables)] - #[inline] - pub fn into_floating_interrupt(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as a pulled down interrupt pin - #[allow(unused_variables)] - #[inline] - pub fn into_pull_down_interrupt(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as a pulled up interrupt pin - #[allow(unused_variables)] - #[inline] - pub fn into_pull_up_interrupt(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as an open drain output - #[allow(unused_variables)] - #[inline] - pub fn into_open_drain_output(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as an open drain output which can be read - #[allow(unused_variables)] - #[inline] - pub fn into_readable_open_drain_output( - self, - port: &mut Port, - ) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate as a push-pull output - #[allow(unused_variables)] - #[inline] - pub fn into_push_pull_output(self, port: &mut Port) -> Pin> { - self.into_mode() - } - - #[inline] - fn into_alternate(self) -> Pin> { - self.into_mode() - } - - /// Configures the pin to operate with a peripheral - #[allow(unused_variables)] - #[inline] - pub fn into_function_b(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[allow(unused_variables)] - #[inline] - pub fn into_function_c(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[allow(unused_variables)] - #[inline] - pub fn into_function_d(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[allow(unused_variables)] - #[inline] - pub fn into_function_e(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[allow(unused_variables)] - #[inline] - pub fn into_function_f(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[allow(unused_variables)] - #[inline] - pub fn into_function_g(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(any(feature = "samd21", feature = "min-samd51g"))] - #[allow(unused_variables)] - #[inline] - pub fn into_function_h(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(feature = "min-samd51g")] - #[allow(unused_variables)] - #[inline] - pub fn into_function_i(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(feature = "min-samd51g")] - #[allow(unused_variables)] - #[inline] - pub fn into_function_j(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(feature = "min-samd51g")] - #[allow(unused_variables)] - #[inline] - pub fn into_function_k(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(feature = "min-samd51g")] - #[allow(unused_variables)] - #[inline] - pub fn into_function_l(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(feature = "min-samd51g")] - #[allow(unused_variables)] - #[inline] - pub fn into_function_m(self, port: &mut Port) -> Pin { - self.into_alternate() - } - - /// Configures the pin to operate with a peripheral - #[cfg(feature = "min-samd51g")] - #[allow(unused_variables)] - #[inline] - pub fn into_function_n(self, port: &mut Port) -> Pin { - self.into_alternate() - } -} - -//============================================================================== -// AnyPin -//============================================================================== - -impl Sealed for Pin -where - I: PinId, - M: PinMode, -{ -} - -/// Implement [`AnyPin`] for `v1` [`Pin`] types to enhance compatibility with -/// [`v2::Pin`]s -impl AnyPin for Pin -where - I: PinId, - M: PinMode, -{ - type Id = I; - type Mode = M; -} - -/// Type alias to recover the specific `v1` [`Pin`] type from an implementation -/// of [`AnyPin`] -/// -/// By definition, `P == SpecificPin

` for all `P: AnyPin`. -pub type SpecificPin

= Pin<

::Id,

::Mode>; - -impl AsRef

for SpecificPin

{ - #[inline] - fn as_ref(&self) -> &P { - // SAFETY: This is guaranteed to be safe, because P == SpecificPin

- // Transmuting between `v1` and `v2` `Pin` types is also safe, because - // single-field, newtype structs are guaranteed to have the same layout - // as the field, even for repr(Rust). - unsafe { core::mem::transmute(self) } - } -} - -impl AsMut

for SpecificPin

{ - #[inline] - fn as_mut(&mut self) -> &mut P { - // SAFETY: This is guaranteed to be safe, because P == SpecificPin

- // Transmuting between `v1` and `v2` `Pin` types is also safe, because - // single-field, newtype structs are guaranteed to have the same layout - // as the field, even for repr(Rust). - unsafe { core::mem::transmute(self) } - } -} - -//============================================================================== -// IntoFunction -//============================================================================== - -/// A trait that makes it easier to generically manage -/// converting a pin from its current state into some -/// other functional mode. The configuration change -/// requires exclusive access to the Port hardware, -/// which is why this isn't simply the standard `Into` -/// trait. -pub trait IntoFunction { - /// Consume the pin and configure it to operate in - /// the mode T. - fn into_function(self, port: &mut Port) -> T; -} - -impl IntoFunction>> for Pin -where - I: PinId, - M: PinMode, - C: AlternateConfig, -{ - #[allow(unused_variables)] - #[inline] - fn into_function(self, port: &mut Port) -> Pin> { - self.into_alternate() - } -} - -//============================================================================== -// Conversions -//============================================================================== - -/// Convert from a `v2::Pin` to a `v1::Pin` -impl From> for Pin -where - I: PinId, - M: PinMode, -{ - fn from(pin: v2::Pin) -> Pin { - Pin { pin } - } -} - -/// Convert from a `v1::Pin` to a `v2::Pin` -impl From> for v2::Pin -where - I: PinId, - M: PinMode, -{ - fn from(pin: Pin) -> v2::Pin { - pin.pin - } -} - -//============================================================================== -// Embedded HAL traits -//============================================================================== - -impl Pin> { - /// Control state of the internal pull up - /// - /// This function shouldn't exist. It is not possible to enable a pull-up - /// resistor in an output mode. - #[allow(unused_variables)] - #[inline] - pub fn internal_pull_up(&mut self, port: &mut Port, on: bool) { - unimplemented!(); - } -} - -impl Pin> -where - I: PinId, - M: OutputConfig, -{ - /// Toggle the logic level of the pin; if it is currently - /// high, set it low and vice versa. - #[inline] - pub fn toggle(&mut self) { - self.pin._toggle(); - } -} - -#[cfg(feature = "unproven")] -impl ToggleableOutputPin for Pin> -where - I: PinId, - M: OutputConfig, -{ - // TODO: switch to ! when it’s stable - type Error = (); - - #[inline] - fn toggle(&mut self) -> Result<(), Self::Error> { - self.pin._toggle(); - Ok(()) - } -} - -#[cfg(feature = "unproven")] -impl InputPin for Pin> { - // TODO: switch to ! when it’s stable - type Error = (); - - #[inline] - fn is_high(&self) -> Result { - Ok(self.pin._is_high()) - } - - #[inline] - fn is_low(&self) -> Result { - Ok(self.pin._is_low()) - } -} - -#[cfg(feature = "unproven")] -impl InputPin for Pin> -where - I: PinId, - M: crate::gpio::v2::pin::InputConfig, -{ - // TODO: switch to ! when it’s stable - type Error = (); - - #[inline] - fn is_high(&self) -> Result { - Ok(self.pin._is_high()) - } - - #[inline] - fn is_low(&self) -> Result { - Ok(self.pin._is_low()) - } -} - -#[cfg(feature = "unproven")] -impl StatefulOutputPin for Pin> -where - I: PinId, - M: OutputConfig, -{ - #[inline] - fn is_set_high(&self) -> Result { - Ok(self.pin._is_set_high()) - } - - #[inline] - fn is_set_low(&self) -> Result { - Ok(self.pin._is_set_low()) - } -} - -impl OutputPin for Pin> -where - I: PinId, - M: OutputConfig, -{ - // TODO: switch to ! when it’s stable - type Error = (); - - #[inline] - fn set_high(&mut self) -> Result<(), Self::Error> { - self.pin._set_high(); - Ok(()) - } - - #[inline] - fn set_low(&mut self) -> Result<(), Self::Error> { - self.pin._set_low(); - Ok(()) - } -} - -//============================================================================== -// Port & Parts -//============================================================================== - -/// The GpioExt trait allows splitting the PORT hardware into -/// its constituent pin parts. -pub trait GpioExt { - type Parts; - - /// Consume and split the device into its constitent parts - fn split(self) -> Self::Parts; -} - -/// Opaque port reference -pub struct Port { - _0: (), -} - -macro_rules! port { - ([ - $( - $( #[$cfg:meta] )? - ($PinId:ident, $PinType:ident), - )+ - ]) => { - $crate::paste::item! { - $( - $( #[$cfg] )? - /// Represents the IO pin with the matching name - pub type $PinType = Pin; - )+ - - /// Holds the GPIO Port peripheral and broken out pin instances - pub struct Parts { - /// Opaque port reference - pub port: Port, - $( - $( #[$cfg] )? - pub [<$PinType:lower>]: $PinType>, - )+ - } - - impl GpioExt for PORT { - type Parts = Parts; - - /// Split the PORT peripheral into discrete pins - fn split(self) -> Parts { - Parts { - port: Port {_0: ()}, - // Safe because we only create one `Pin` per `PinId` - $( - $( #[$cfg] )? - [<$PinType:lower>]: unsafe { Pin::::new() }, - )+ - } - } - } - } - }; -} - -port!([ - #[cfg(not(feature = "samd11"))] - (PA00, Pa0), - #[cfg(not(feature = "samd11"))] - (PA01, Pa1), - (PA02, Pa2), - #[cfg(not(feature = "samd11c"))] - (PA03, Pa3), - (PA04, Pa4), - (PA05, Pa5), - #[cfg(not(feature = "samd11c"))] - (PA06, Pa6), - #[cfg(not(feature = "samd11c"))] - (PA07, Pa7), - (PA08, Pa8), - (PA09, Pa9), - #[cfg(not(feature = "samd11"))] - (PA10, Pa10), - #[cfg(not(feature = "samd11"))] - (PA11, Pa11), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PA12, Pa12), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PA13, Pa13), - (PA14, Pa14), - (PA15, Pa15), - #[cfg(not(feature = "samd11c"))] - (PA16, Pa16), - #[cfg(not(feature = "samd11"))] - (PA17, Pa17), - #[cfg(not(feature = "samd11"))] - (PA18, Pa18), - #[cfg(not(feature = "samd11"))] - (PA19, Pa19), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PA20, Pa20), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PA21, Pa21), - #[cfg(not(feature = "samd11c"))] - (PA22, Pa22), - #[cfg(not(feature = "samd11c"))] - (PA23, Pa23), - (PA24, Pa24), - (PA25, Pa25), - #[cfg(not(feature = "samd11"))] - (PA27, Pa27), - #[cfg(any(feature = "samd11", feature = "samd21"))] - (PA28, Pa28), - (PA30, Pa30), - (PA31, Pa31), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB00, Pb0), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB01, Pb1), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB02, Pb2), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB03, Pb3), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB04, Pb4), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB05, Pb5), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB06, Pb6), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB07, Pb7), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB08, Pb8), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB09, Pb9), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB10, Pb10), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB11, Pb11), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB12, Pb12), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB13, Pb13), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB14, Pb14), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB15, Pb15), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB16, Pb16), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB17, Pb17), - #[cfg(any(feature = "min-samd51n"))] - (PB18, Pb18), - #[cfg(any(feature = "min-samd51n"))] - (PB19, Pb19), - #[cfg(any(feature = "min-samd51n"))] - (PB20, Pb20), - #[cfg(any(feature = "min-samd51n"))] - (PB21, Pb21), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB22, Pb22), - #[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] - (PB23, Pb23), - #[cfg(any(feature = "min-samd51n"))] - (PB24, Pb24), - #[cfg(any(feature = "min-samd51n"))] - (PB25, Pb25), - #[cfg(any(feature = "min-samd51p"))] - (PB26, Pb26), - #[cfg(any(feature = "min-samd51p"))] - (PB27, Pb27), - #[cfg(any(feature = "min-samd51p"))] - (PB28, Pb28), - #[cfg(any(feature = "min-samd51p"))] - (PB29, Pb29), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB30, Pb30), - #[cfg(any(feature = "min-samd21j", feature = "min-samd51j"))] - (PB31, Pb31), - #[cfg(any(feature = "min-samd51n"))] - (PC00, Pc0), - #[cfg(any(feature = "min-samd51n"))] - (PC01, Pc1), - #[cfg(any(feature = "min-samd51n"))] - (PC02, Pc2), - #[cfg(any(feature = "min-samd51n"))] - (PC03, Pc3), - #[cfg(any(feature = "min-samd51p"))] - (PC04, Pc4), - #[cfg(any(feature = "min-samd51n"))] - (PC05, Pc5), - #[cfg(any(feature = "min-samd51n"))] - (PC06, Pc6), - #[cfg(any(feature = "min-samd51n"))] - (PC07, Pc7), - #[cfg(any(feature = "min-samd51n"))] - (PC10, Pc10), - #[cfg(any(feature = "min-samd51n"))] - (PC11, Pc11), - #[cfg(any(feature = "min-samd51n"))] - (PC12, Pc12), - #[cfg(any(feature = "min-samd51n"))] - (PC13, Pc13), - #[cfg(any(feature = "min-samd51n"))] - (PC14, Pc14), - #[cfg(any(feature = "min-samd51n"))] - (PC15, Pc15), - #[cfg(any(feature = "min-samd51n"))] - (PC16, Pc16), - #[cfg(any(feature = "min-samd51n"))] - (PC17, Pc17), - #[cfg(any(feature = "min-samd51n"))] - (PC18, Pc18), - #[cfg(any(feature = "min-samd51n"))] - (PC19, Pc19), - #[cfg(any(feature = "min-samd51n"))] - (PC20, Pc20), - #[cfg(any(feature = "min-samd51n"))] - (PC21, Pc21), - #[cfg(any(feature = "min-samd51p"))] - (PC22, Pc22), - #[cfg(any(feature = "min-samd51p"))] - (PC23, Pc23), - #[cfg(any(feature = "min-samd51n"))] - (PC24, Pc24), - #[cfg(any(feature = "min-samd51n"))] - (PC25, Pc25), - #[cfg(any(feature = "min-samd51n"))] - (PC26, Pc26), - #[cfg(any(feature = "min-samd51n"))] - (PC27, Pc27), - #[cfg(any(feature = "min-samd51n"))] - (PC28, Pc28), - #[cfg(any(feature = "min-samd51p"))] - (PC30, Pc30), - #[cfg(any(feature = "min-samd51p"))] - (PC31, Pc31), - #[cfg(any(feature = "min-samd51p"))] - (PD00, Pd0), - #[cfg(any(feature = "min-samd51p"))] - (PD01, Pd1), - #[cfg(any(feature = "min-samd51p"))] - (PD08, Pd8), - #[cfg(any(feature = "min-samd51p"))] - (PD09, Pd9), - #[cfg(any(feature = "min-samd51p"))] - (PD10, Pd10), - #[cfg(any(feature = "min-samd51p"))] - (PD11, Pd11), - #[cfg(any(feature = "min-samd51p"))] - (PD12, Pd12), - #[cfg(any(feature = "min-samd51p"))] - (PD20, Pd20), - #[cfg(any(feature = "min-samd51p"))] - (PD21, Pd21), -]); - -//============================================================================== -// Define pins macro -//============================================================================== - -/// This macro is a helper for defining a `Pins` type in a board support -/// crate. This type is used to provide more meaningful aliases for the -/// various GPIO pins for a given board. -#[macro_export] -macro_rules! define_pins { - ($(#[$topattr:meta])* struct $Type:ident, - pac: $pac:ident, - $( $(#[$attr:meta])* pin $name:ident = $pin_ident:ident),+ , ) => { - -$crate::paste::item! { - $(#[$topattr])* - pub struct $Type { - /// Opaque port reference - pub port: Port, - - $( - $(#[$attr])* - pub $name: gpio::[

]> - ),+ - } -} - -impl $Type { - /// Returns the pins for the device - $crate::paste::item! { - pub fn new(port: $pac::PORT) -> Self { - let pins = port.split(); - $Type { - port: pins.port, - $( - $(#[$attr])* - $name: pins.[

] - ),+ - } - } - } -} -}} diff --git a/hal/src/gpio/v2.rs b/hal/src/gpio/v2.rs deleted file mode 100644 index 700f05b9e917..000000000000 --- a/hal/src/gpio/v2.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! # Version 2 of the GPIO module -//! -//! The new API provides two different submodules, [`pin`] and [`dynpin`], -//! representing two different ways to handle GPIO pins. The default, [`pin`], -//! is a type-level API that tracks the state of each pin at compile-time. The -//! alternative, [`dynpin`] is a type-erased, value-level API that tracks the -//! state of each pin at run-time. -//! -//! The type-level API is strongly preferred. By representing the state of each -//! pin within the type system, the compiler can detect logic errors at -//! compile-time. Furthermore, the type-level API has absolutely zero run-time -//! cost. -//! -//! If needed, [`dynpin`] can be used to erase the type-level differences -//! between pins. However, by doing so, pins must now be tracked at run-time, -//! and each pin has a non-zero memory footprint. - -#![allow(clippy::bool_comparison)] - -pub mod pin; -pub use pin::*; - -pub mod dynpin; -pub use dynpin::*; - -mod reg; diff --git a/hal/src/lib.rs b/hal/src/lib.rs index 6a7b0f85ae0e..7bc015994b3a 100644 --- a/hal/src/lib.rs +++ b/hal/src/lib.rs @@ -1,11 +1,5 @@ #![no_std] -#[deprecated( - since = "0.13.0", - note = "`atsamd_hal::hal` is deprecated and will be removed in a future release. \ - Use `atsamd_hal::ehal` instead" -)] -pub use embedded_hal as hal; pub use embedded_hal as ehal; pub use paste; @@ -67,14 +61,6 @@ pub use atsame54n as pac; #[cfg(feature = "same54p")] pub use atsame54p as pac; -#[deprecated( - since = "0.13.0", - note = "`atsamd_hal::target_device` is deprecated and will be removed in a future release. \ - Use `atsamd_hal::pac` instead" -)] -#[cfg(not(feature = "library"))] -pub use pac as target_device; - #[cfg(feature = "use_rtt")] pub use jlink_rtt; @@ -107,8 +93,6 @@ pub mod rtc; #[cfg(feature = "device")] pub mod sercom; pub mod sleeping_delay; -#[cfg(feature = "device")] -pub mod spi_common; pub mod time; pub mod timer_params; pub mod timer_traits; @@ -135,103 +119,6 @@ pub mod thumbv7em; #[cfg(feature = "min-samd51g")] pub use crate::thumbv7em::*; -// This module maintains backwards compatibility for the v1 SERCOM pads API -#[cfg(feature = "device")] -pub mod pad { - pub use crate::sercom::v1::pads::PadPin; -} - -// This module maintains backwards compatibility within this major release -#[deprecated( - since = "0.13.0", - note = "The `common` module is deprecated and will be removed in a future - release. Directly use modules from atsamd_hal instead." -)] -#[macro_use] -pub mod common { - #[cfg(feature = "device")] - pub use crate::delay; - #[cfg(feature = "device")] - pub use crate::gpio; - #[cfg(feature = "device")] - pub use crate::prelude; - #[cfg(feature = "device")] - pub use crate::rtc; - #[cfg(feature = "device")] - pub use crate::sercom; - pub use crate::sleeping_delay; - #[cfg(feature = "device")] - #[allow(deprecated)] - pub use crate::spi_common; - pub use crate::time; - pub use crate::timer_params; - pub use crate::timer_traits; - - #[cfg(all(feature = "unproven", feature = "dma"))] - pub use crate::dmac; - - #[cfg(any(feature = "samd11", feature = "samd21"))] - pub use crate::thumbv6m; - #[cfg(any(feature = "samd11", feature = "samd21"))] - pub use crate::thumbv6m::*; - - #[cfg(feature = "min-samd51g")] - pub use crate::thumbv7em; - #[cfg(feature = "min-samd51g")] - pub use crate::thumbv7em::*; - - #[cfg(feature = "device")] - pub use crate::pad; -} - -// The following modules are included purely for backward compatibility reasons. -// Whenever major breaking changes are made to the HAL next, these modules -// should be removed. - -#[cfg(feature = "samd51")] -#[deprecated( - since = "0.13.0", - note = "The `samd51` module is deprecated and will be removed in a future - release." -)] -pub mod samd51 { - #[cfg(feature = "unproven")] - pub use crate::pwm; -} - -#[deprecated( - since = "0.13.0", - note = "The `same51` module is deprecated and will be removed in a future - release." -)] -#[cfg(feature = "same51")] -pub mod same51 { - #[cfg(feature = "unproven")] - pub use crate::pwm; -} - -#[deprecated( - since = "0.13.0", - note = "The `same53` module is deprecated and will be removed in a future - release." -)] -#[cfg(feature = "same53")] -pub mod same53 { - #[cfg(feature = "unproven")] - pub use crate::pwm; -} - -#[deprecated( - since = "0.13.0", - note = "The `same54` module is deprecated and will be removed in a future - release." -)] -#[cfg(feature = "same54")] -pub mod same54 { - #[cfg(feature = "unproven")] - pub use crate::pwm; -} - #[macro_use] mod bsp_peripherals_macro; pub use bsp_peripherals_macro::*; diff --git a/hal/src/prelude.rs b/hal/src/prelude.rs index 0be95d3878b4..cd8c9d6fdb23 100644 --- a/hal/src/prelude.rs +++ b/hal/src/prelude.rs @@ -1,9 +1,5 @@ //! Import the prelude to gain convenient access to helper traits pub use crate::eic::pin::EicPin; -#[allow(deprecated)] -pub use crate::gpio::v1::GpioExt as _atsamd21_hal_gpio_GpioExt; -#[allow(deprecated)] -pub use crate::spi_common::CommonSpi as _atsamd_hal_spi_common_CommonSpi; pub use crate::time::U32Ext as _atsamd21_hal_time_U32Ext; pub use crate::timer_traits::InterruptDrivenTimer as _atsamd_hal_timer_traits_InterruptDrivenTimer; diff --git a/hal/src/sercom/v2/dma.rs b/hal/src/sercom/dma.rs similarity index 99% rename from hal/src/sercom/v2/dma.rs rename to hal/src/sercom/dma.rs index 6e8dff3e5e5d..f742fdf7fd7e 100644 --- a/hal/src/sercom/v2/dma.rs +++ b/hal/src/sercom/dma.rs @@ -10,7 +10,7 @@ use crate::{ transfer::BufferPair, Beat, Buffer, Transfer, TriggerAction, }, - sercom::v2::{ + sercom::{ i2c::{self, I2c}, spi::{self, Spi}, uart::{self, Uart}, diff --git a/hal/src/sercom/v2/i2c.rs b/hal/src/sercom/i2c.rs similarity index 91% rename from hal/src/sercom/v2/i2c.rs rename to hal/src/sercom/i2c.rs index 226f34cba29b..19d27cd0c023 100644 --- a/hal/src/sercom/v2/i2c.rs +++ b/hal/src/sercom/i2c.rs @@ -26,12 +26,12 @@ //! aliases for [`Pad`] types. //! //! ```no_run -//! use atsamd_hal::gpio::v2::{PA08, PA09, AlternateC}; -//! use atsamd_hal::sercom::v2::{Sercom0, i2c}; +//! use atsamd_hal::gpio::{PA08, PA09, AlternateC}; +//! use atsamd_hal::sercom::{Sercom0, i2c}; //! use atsamd_hal::typelevel::NoneT; //! //! // SAMx5x-specific imports -//! use atsamd_hal::sercom::v2::pad::IoSet1; +//! use atsamd_hal::sercom::pad::IoSet1; //! //! type Sda = Pin; //! type Scl = Pin; @@ -47,14 +47,13 @@ //! don't have [`Pin`] aliases pre-defined. //! //! ```no_run -//! use atsamd_hal::gpio::v2::{PA08, PA09}; -//! use atsamd_hal::sercom::v2::{Sercom0, i2c}; +//! use atsamd_hal::gpio::{PA08, PA09}; +//! use atsamd_hal::sercom::{Sercom0, i2c}; //! //! type Pads = i2c::PadsFromIds; //! ``` //! -//! Instances of [`Pads`] are created using the [`new`](Pads::new) method. Both -//! [`v1::Pin`] and [`v2::Pin`] types are accepted here. +//! Instances of [`Pads`] are created using the [`new`](Pads::new) method. //! //! On SAMD21 and SAMx5x chips, [`new`](Pads::new) method automatically convert //! each pin to the correct [`PinMode`]. But for SAMD11 chips, users must @@ -65,8 +64,8 @@ //! //! ```no_run //! use atsamd_hal::pac::Peripherals; -//! use atsamd_hal::gpio::v2::Pins; -//! use atsamd_hal::sercom::v2::{Sercom0, i2c}; +//! use atsamd_hal::gpio::Pins; +//! use atsamd_hal::sercom::{Sercom0, i2c}; //! //! let mut peripherals = Peripherals::take().unwrap(); //! let pins = Pins::new(peripherals.PORT); @@ -85,8 +84,8 @@ //! configuration. Users are responsible for correctly configuring the GCLK. //! //! ```no_run -//! use atsamd_hal::gpio::v2::{PA08, PA09}; -//! use atsamd_hal::sercom::v2::{Sercom0, i2c}; +//! use atsamd_hal::gpio::{PA08, PA09}; +//! use atsamd_hal::sercom::{Sercom0, i2c}; //! //! type Pads = i2c::PadsFromIds; //! type Config = i2c::Config; @@ -163,7 +162,7 @@ //! then use the `set_*` methods. //! //! ```no_run -//! use atsamd_hal::sercom::v2::i2c::I2c; +//! use atsamd_hal::sercom::i2c::I2c; //! use atsamd_hal::time::*; //! //! // Assume config is a valid Duplex I2C Config struct @@ -191,17 +190,15 @@ //! [`disable`]: I2c::disable //! [`reconfigure`]: I2c::reconfigure //! [`bsp_pins`]: crate::bsp_pins -//! [`Sercom`]: crate::sercom::v2::Sercom -//! [`Pad0`]: crate::sercom::v2::pad::Pad0 -//! [`Pad1`]: crate::sercom::v2::pad::Pad1 -//! [`Pad`]: crate::sercom::v2::pad::Pad -//! [`IsPad`]: crate::sercom::v2::pad::IsPad -//! [`PadNum`]: crate::sercom::v2::pad::PadNum -//! [`v1::Pin`]: crate::gpio::v1::Pin -//! [`v2::Pin`]: crate::gpio::v2::pin::Pin -//! [`Pin`]: crate::gpio::v2::pin::Pin -//! [`PinId`]: crate::gpio::v2::pin::PinId -//! [`PinMode`]: crate::gpio::v2::pin::PinMode +//! [`Sercom`]: crate::sercom::Sercom +//! [`Pad0`]: crate::sercom::pad::Pad0 +//! [`Pad1`]: crate::sercom::pad::Pad1 +//! [`Pad`]: crate::sercom::pad::Pad +//! [`IsPad`]: crate::sercom::pad::IsPad +//! [`PadNum`]: crate::sercom::pad::PadNum +//! [`Pin`]: crate::gpio::pin::Pin +//! [`PinId`]: crate::gpio::pin::PinId +//! [`PinMode`]: crate::gpio::pin::PinMode //! [`i2c::Write`]: embedded_hal::blocking::i2c::Write //! [`i2c::Read`]: embedded_hal::blocking::i2c::Read //! [`i2c::WriteRead`]: embedded_hal::blocking::i2c::WriteRead @@ -229,7 +226,7 @@ documentation for more information. ```no_run use atsamd_hal::dmac::channel::{AnyChannel, Ready}; -use atsand_hal::sercom::v2::i2c::{I2c, AnyConfig, Error}; +use atsand_hal::sercom::i2c::{I2c, AnyConfig, Error}; fn i2c_send_with_dma>(i2c: I2c, channel: C) -> Result<(), Error>{ // Create data to send. Note that it must be `'static`. let buffer: [u8; 50] = [0xff; 50]; @@ -397,7 +394,7 @@ impl I2c { /// transactions. /// /// ``` - /// use atsamd_hal::sercom::v2::i2c::I2c; + /// use atsamd_hal::sercom::i2c::I2c; /// i2c.reconfigure(|c| c.set_run_in_standby(false)); /// ``` #[inline] diff --git a/hal/src/sercom/v2/i2c/config.rs b/hal/src/sercom/i2c/config.rs similarity index 99% rename from hal/src/sercom/v2/i2c/config.rs rename to hal/src/sercom/i2c/config.rs index 89461ac88c6a..c1ec53080797 100644 --- a/hal/src/sercom/v2/i2c/config.rs +++ b/hal/src/sercom/i2c/config.rs @@ -3,7 +3,7 @@ use super::{I2c, InactiveTimeout, PadSet, Registers}; use crate::{ pac::sercom0::i2cm::ctrla::MODE_A, - sercom::v2::*, + sercom::*, time::Hertz, typelevel::{Is, Sealed}, }; diff --git a/hal/src/sercom/v2/i2c/flags.rs b/hal/src/sercom/i2c/flags.rs similarity index 100% rename from hal/src/sercom/v2/i2c/flags.rs rename to hal/src/sercom/i2c/flags.rs diff --git a/hal/src/sercom/v2/i2c/impl_ehal.rs b/hal/src/sercom/i2c/impl_ehal.rs similarity index 100% rename from hal/src/sercom/v2/i2c/impl_ehal.rs rename to hal/src/sercom/i2c/impl_ehal.rs diff --git a/hal/src/sercom/v2/i2c/pads_thumbv6m.rs b/hal/src/sercom/i2c/pads_thumbv6m.rs similarity index 91% rename from hal/src/sercom/v2/i2c/pads_thumbv6m.rs rename to hal/src/sercom/i2c/pads_thumbv6m.rs index 4d5977f0c361..7bd11070c3ab 100644 --- a/hal/src/sercom/v2/i2c/pads_thumbv6m.rs +++ b/hal/src/sercom/i2c/pads_thumbv6m.rs @@ -3,12 +3,12 @@ //! See the [i2c module](super) documentation for more details on declaring and //! instantiating a [`Pads`] type. -use crate::{gpio::v2::AnyPin, sercom::v2::*, typelevel::Sealed}; +use crate::{gpio::AnyPin, sercom::*, typelevel::Sealed}; use core::marker::PhantomData; /// Container for a set of SERCOM [`Pad`]s /// -/// See the [module-level](crate::sercom::v2::i2c) documentation for more +/// See the [module-level](crate::sercom::i2c) documentation for more /// details on specifying a `Pads` type and creating instances. pub struct Pads where @@ -70,7 +70,7 @@ where SCL: IsI2cPad, { /// Consume the [`Pads`] and return each individual - /// [`Pin`](crate::gpio::v2::Pin) + /// [`Pin`](crate::gpio::Pin) #[inline] pub fn free(self) -> (SDA, SCL) { (self.sda, self.scl) @@ -92,8 +92,8 @@ where /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, i2c}; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, i2c}; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = i2c::PadsFromIds; @@ -105,8 +105,8 @@ where /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId #[cfg(feature = "samd11")] pub type PadsFromIds = Pads, Pad>; @@ -121,8 +121,8 @@ pub type PadsFromIds = Pads, Pad /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, i2c}; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, i2c}; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = i2c::PadsFromIds; @@ -134,8 +134,8 @@ pub type PadsFromIds = Pads, Pad /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId #[cfg(feature = "samd21")] pub type PadsFromIds = Pads, Pad>; @@ -158,7 +158,7 @@ pub type PadsFromIds = Pads, Pad>; /// /// This trait is a simplified version of the [`AnyKind`] trait pattern. /// -/// [`Pin`]: crate::gpio::v2::Pin +/// [`Pin`]: crate::gpio::Pin /// [`Config`]: super::Config /// [type-level function]: crate::typelevel#type-level-functions /// [`AnyKind`]: crate::typelevel#anykind-trait-pattern diff --git a/hal/src/sercom/v2/i2c/pads_thumbv7em.rs b/hal/src/sercom/i2c/pads_thumbv7em.rs similarity index 91% rename from hal/src/sercom/v2/i2c/pads_thumbv7em.rs rename to hal/src/sercom/i2c/pads_thumbv7em.rs index 681be7cf04f9..8bb15bc5135d 100644 --- a/hal/src/sercom/v2/i2c/pads_thumbv7em.rs +++ b/hal/src/sercom/i2c/pads_thumbv7em.rs @@ -3,12 +3,12 @@ //! See the [i2c module](super) documentation for more details on declaring and //! instantiating a [`Pads`] type. -use crate::{gpio::v2::AnyPin, sercom::v2::*, typelevel::Sealed}; +use crate::{gpio::AnyPin, sercom::*, typelevel::Sealed}; use core::marker::PhantomData; /// Container for a set of SERCOM [`Pad`]s /// -/// See the [module-level](crate::sercom::v2::i2c) documentation for more +/// See the [module-level](crate::sercom::i2c) documentation for more /// details on specifying a `Pads` type and creating instances. pub struct Pads where @@ -50,7 +50,7 @@ where SCL: IsI2cPad + InIoSet, { /// Consume the [`Pads`] and return each individual - /// [`Pin`](crate::gpio::v2::Pin) + /// [`Pin`](crate::gpio::Pin) #[inline] pub fn free(self) -> (SDA, SCL) { (self.sda, self.scl) @@ -72,8 +72,8 @@ where /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, IoSet1, i2c}; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, IoSet1, i2c}; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = i2c::PadsFromIds; @@ -85,8 +85,8 @@ where /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId pub type PadsFromIds = Pads, Pad>; //============================================================================= @@ -108,7 +108,7 @@ pub type PadsFromIds = Pads, Pad>; /// /// This trait is a simplified version of the [`AnyKind`] trait pattern. /// -/// [`Pin`]: crate::gpio::v2::Pin +/// [`Pin`]: crate::gpio::Pin /// [`Config`]: super::Config /// [type-level function]: crate::typelevel#type-level-functions /// [`AnyKind`]: crate::typelevel#anykind-trait-pattern diff --git a/hal/src/sercom/v2/i2c/reg.rs b/hal/src/sercom/i2c/reg.rs similarity index 99% rename from hal/src/sercom/v2/i2c/reg.rs rename to hal/src/sercom/i2c/reg.rs index a6de9b9a2fad..a226782b8ed2 100644 --- a/hal/src/sercom/v2/i2c/reg.rs +++ b/hal/src/sercom/i2c/reg.rs @@ -4,7 +4,7 @@ use super::flags::{BusState, Error}; use super::InactiveTimeout; use super::{Flags, Status}; use crate::pac; -use crate::sercom::v2::*; +use crate::sercom::*; use crate::time::Hertz; const MASTER_ACT_READ: u8 = 2; diff --git a/hal/src/sercom/mod.rs b/hal/src/sercom/mod.rs index cf66cbb4472b..eb16b8080620 100644 --- a/hal/src/sercom/mod.rs +++ b/hal/src/sercom/mod.rs @@ -2,32 +2,124 @@ //! //! The SERCOM module is used to configure the SERCOM peripherals as USART, SPI //! or I2C interfaces. -//! -//! ## Versions -//! -//! There are currently two versions of the SERCOM module. The inital SERCOM API -//! was based on a macro-heavy implementation. The discussion in issue -//! [#214](https://github.com/atsamd-rs/atsamd/issues/214) spurred the creation -//! of a new module with less macro-use and a refactored API. -//! -//! The new module is provided in [v2]. The old module was removed, but a -//! compatibility shim is provided in [v1] to support existing code. -//! -//! ## Migration -//! -//! The [v2] module will eventually replace [v1]. New users are encouraged to -//! use [v2] instead of [v1]. -//! -//! The new [`v2::spi`] and [`v2::uart`] modules are substantially more -//! configurable and safe than the existing, [`v1::spi`] and [`v1::uart`] -//! modules. To assist in migration, the [`v2::spi::Pads`] and -//! [`v2::uart::Pads`] structs accept both [`v1::Pin`]s and [`v2::Pin`]s. -//! -//! [`Pad`]: v2::pads::Pad -//! [`v1::Pin`]: crate::gpio::v1::Pin -//! [`v2::Pin`]: crate::gpio::v2::pin::Pin +#![cfg_attr( + feature = "min-samd51g", + doc = " +# Undocumented features + +The ATSAMx5x chips contain certain features that aren't documented in the datasheet. +These features are implemented in the HAL based on experimentation with certain boards +which have verifiably demonstrated that those features work as intended. + +* [`UndocIoSet1`](pad::UndocIoSet1): Implement an undocumented `IoSet` for PA16, PA17, +PB22 & PB23 configured for [`Sercom1`]. The pygamer & feather_m4 use this combination, +but it is not listed as valid in the datasheet. + +* [`UndocIoSet2`](pad::UndocIoSet2): Implement an undocumented `IoSet` for PA00, PA01, +PB22 & PB23 configured for [`Sercom1`]. The itsybitsy_m4 uses this combination, but it is +not listed as valid in the datasheet. + +* [`PB02`] is I2C-capable according to metro_m4. As such, [`PB02`] +implements [`IsI2cPad`]. + +* [`PB03`] is I2C-capable according to metro_m4. As such, [`PB03`] +implements [`IsI2cPad`](pad::IsI2cPad). + +[`PB02`]: crate::gpio::pin::PB02 +[`PB03`]: crate::gpio::pin::PB03 +[`IsI2cPad`]: pad::IsI2cPad +" +)] + +use core::ops::Deref; + +use paste::paste; +use seq_macro::seq; + +use crate::pac; + +#[cfg(feature = "min-samd51g")] +use pac::MCLK as APB_CLK_CTRL; +#[cfg(any(feature = "samd11", feature = "samd21"))] +use pac::PM as APB_CLK_CTRL; + +use pac::{sercom0, SERCOM0, SERCOM1}; +#[cfg(any(feature = "samd21", feature = "min-samd51g"))] +use pac::{SERCOM2, SERCOM3}; +#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] +use pac::{SERCOM4, SERCOM5}; +#[cfg(feature = "min-samd51n")] +use pac::{SERCOM6, SERCOM7}; + +#[cfg(feature = "dma")] +use crate::dmac::TriggerSource; + +use crate::typelevel::Sealed; + +pub mod pad; +pub use pad::*; + +pub mod i2c; +pub mod spi; +pub mod spi_future; +pub mod uart; + +#[cfg(feature = "dma")] +pub mod dma; + +//============================================================================== +// Sercom +//============================================================================== + +/// Type-level `enum` representing a Serial Communication Interface (SERCOM) +pub trait Sercom: Sealed + Deref { + /// SERCOM number + const NUM: usize; + /// RX Trigger source for DMA transactions + #[cfg(feature = "dma")] + const DMA_RX_TRIGGER: TriggerSource; + /// TX trigger source for DMA transactions + #[cfg(feature = "dma")] + const DMA_TX_TRIGGER: TriggerSource; + /// Enable the corresponding APB clock + fn enable_apb_clock(&mut self, ctrl: &APB_CLK_CTRL); +} + +macro_rules! sercom { + ( $apbmask:ident: ($start:literal, $end:literal) ) => { + seq!(N in $start..=$end { + paste! { + /// Type alias for the corresponding SERCOM instance + pub type Sercom~N = SERCOM~N; + impl Sealed for Sercom~N {} + impl Sercom for Sercom~N { + const NUM: usize = N; + #[cfg(feature = "dma")] + const DMA_RX_TRIGGER: TriggerSource = TriggerSource::[]; + #[cfg(feature = "dma")] + const DMA_TX_TRIGGER: TriggerSource = TriggerSource::[]; + #[inline] + fn enable_apb_clock(&mut self, ctrl: &APB_CLK_CTRL) { + ctrl.$apbmask.modify(|_, w| w.[]().set_bit()); + } + } + } + }); + }; +} -pub mod v1; -pub use v1::*; +#[cfg(any(feature = "samd11", feature = "samd21"))] +sercom!(apbcmask: (0, 1)); +#[cfg(feature = "samd21")] +sercom!(apbcmask: (2, 3)); +#[cfg(feature = "min-samd21g")] +sercom!(apbcmask: (4, 5)); -pub mod v2; +#[cfg(feature = "min-samd51g")] +sercom!(apbamask: (0, 1)); +#[cfg(feature = "min-samd51g")] +sercom!(apbbmask: (2, 3)); +#[cfg(feature = "min-samd51g")] +sercom!(apbdmask: (4, 5)); +#[cfg(feature = "min-samd51n")] +sercom!(apbdmask: (6, 7)); diff --git a/hal/src/sercom/v2/pad.rs b/hal/src/sercom/pad.rs similarity index 98% rename from hal/src/sercom/v2/pad.rs rename to hal/src/sercom/pad.rs index c1d2a0187bcc..6909a11467e5 100644 --- a/hal/src/sercom/v2/pad.rs +++ b/hal/src/sercom/pad.rs @@ -21,8 +21,8 @@ //! `PinMode` for a given SERCOM pad, while the [`Pad`] alias recovers the //! configured [`Pin`] type. //! -//! [`AlternateC`]: crate::gpio::v2::AlternateC -//! [`AlternateD`]: crate::gpio::v2::AlternateD +//! [`AlternateC`]: crate::gpio::AlternateC +//! [`AlternateD`]: crate::gpio::AlternateD //! [type class]: crate::typelevel#type-classes //! [type-level function]: crate::typelevel#type-level-functions #![cfg_attr( @@ -44,8 +44,8 @@ use seq_macro::seq; use super::Sercom; #[cfg(not(feature = "samd11"))] -use crate::gpio::v2::OptionalPinId; -use crate::gpio::v2::{AnyPin, OptionalPin, Pin, PinId, PinMode}; +use crate::gpio::OptionalPinId; +use crate::gpio::{AnyPin, OptionalPin, Pin, PinId, PinMode}; use crate::typelevel::{NoneT, Sealed}; #[cfg(any(feature = "samd11", feature = "samd21"))] diff --git a/hal/src/sercom/v2/pad/impl_pad_thumbv6m.rs b/hal/src/sercom/pad/impl_pad_thumbv6m.rs similarity index 99% rename from hal/src/sercom/v2/pad/impl_pad_thumbv6m.rs rename to hal/src/sercom/pad/impl_pad_thumbv6m.rs index 347c258d9243..bfd11ec6eb20 100644 --- a/hal/src/sercom/v2/pad/impl_pad_thumbv6m.rs +++ b/hal/src/sercom/pad/impl_pad_thumbv6m.rs @@ -1,7 +1,7 @@ //! Implementations of the [`IsPad`], [`IsI2cPad`], [`GetPad`] traits -use crate::gpio::v2::*; -use crate::sercom::v2::*; +use crate::gpio::*; +use crate::sercom::*; //============================================================================== // Pad definitions diff --git a/hal/src/sercom/v2/pad/impl_pad_thumbv7em.rs b/hal/src/sercom/pad/impl_pad_thumbv7em.rs similarity index 99% rename from hal/src/sercom/v2/pad/impl_pad_thumbv7em.rs rename to hal/src/sercom/pad/impl_pad_thumbv7em.rs index 989370131166..db1ed32da5b2 100644 --- a/hal/src/sercom/v2/pad/impl_pad_thumbv7em.rs +++ b/hal/src/sercom/pad/impl_pad_thumbv7em.rs @@ -1,7 +1,7 @@ //! Implementations of the [`IsPad`], [`GetPad`] and [`InIoSet`] traits -use crate::gpio::v2::*; -use crate::sercom::v2::*; +use crate::gpio::*; +use crate::sercom::*; //============================================================================== // Pad definitions diff --git a/hal/src/sercom/v2/spi.rs b/hal/src/sercom/spi.rs similarity index 96% rename from hal/src/sercom/v2/spi.rs rename to hal/src/sercom/spi.rs index 77758a9d88b2..c54c4571c367 100644 --- a/hal/src/sercom/v2/spi.rs +++ b/hal/src/sercom/spi.rs @@ -29,12 +29,12 @@ //! used to define convenient type aliases for `Pad` types. //! //! ``` -//! use atsamd_hal::gpio::v2::{PA08, PA09, AlternateC}; -//! use atsamd_hal::sercom::v2::{Sercom0, spi}; +//! use atsamd_hal::gpio::{PA08, PA09, AlternateC}; +//! use atsamd_hal::sercom::{Sercom0, spi}; //! use atsamd_hal::typelevel::NoneT; //! //! // SAMx5x-specific imports -//! use atsamd_hal::sercom::v2::pad::IoSet1; +//! use atsamd_hal::sercom::pad::IoSet1; //! //! type Miso = Pin; //! type Sclk = Pin; @@ -46,10 +46,10 @@ //! ``` //! //! [`enable`]: Config::enable -//! [`gpio`]: crate::gpio::v2 -//! [`Pin`]: crate::gpio::v2::pin::Pin -//! [`PinId`]: crate::gpio::v2::pin::PinId -//! [`PinMode`]: crate::gpio::v2::pin::PinMode +//! [`gpio`]: crate::gpio +//! [`Pin`]: crate::gpio::pin::Pin +//! [`PinId`]: crate::gpio::pin::PinId +//! [`PinMode`]: crate::gpio::pin::PinMode #![cfg_attr( not(feature = "samd11"), doc = " @@ -58,12 +58,12 @@ Alternatively, you can use the `PadsFromIds` alias to define a set of don't have [`Pin`] aliases pre-defined. ``` -use atsamd_hal::gpio::v2::{PA08, PA09}; -use atsamd_hal::sercom::v2::{Sercom0, spi}; +use atsamd_hal::gpio::{PA08, PA09}; +use atsamd_hal::sercom::{Sercom0, spi}; use atsamd_hal::typelevel::NoneT; // SAMx5x-specific imports -use atsamd_hal::sercom::v2::pad::IoSet1; +use atsamd_hal::sercom::pad::IoSet1; // SAMD21 version type Pads = spi::PadsFromIds; @@ -82,11 +82,11 @@ type Pads = spi::PadsFromIds; //! //! ``` //! use atsamd_hal::target_device::Peripherals; -//! use atsamd_hal::gpio::v2::Pins; -//! use atsamd_hal::sercom::v2::{Sercom0, spi}; +//! use atsamd_hal::gpio::Pins; +//! use atsamd_hal::sercom::{Sercom0, spi}; //! //! // SAMx5x-specific imports -//! use atsamd_hal::sercom::v2::pad::IoSet1; +//! use atsamd_hal::sercom::pad::IoSet1; //! //! let mut peripherals = Peripherals::take().unwrap(); //! let pins = Pins::new(peripherals.PORT); @@ -133,17 +133,17 @@ type Pads = spi::PadsFromIds; //! sub-module. //! //! ``` -//! use atsamd_hal::gpio::v2::{PA08, PA09}; -//! use atsamd_hal::sercom::v2::{Sercom0, spi}; -//! use atsamd_hal::sercom::v2::spi::Master; +//! use atsamd_hal::gpio::{PA08, PA09}; +//! use atsamd_hal::sercom::{Sercom0, spi}; +//! use atsamd_hal::sercom::spi::Master; //! use atsamd_hal::typelevel::NoneT; //! //! // SAMD11/SAMD21-specific imports -//! use atsamd_hal::sercom::v2::spi::NineBit; +//! use atsamd_hal::sercom::spi::NineBit; //! //! // SAMx5x-specific imports -//! use atsamd_hal::sercom::v2::spi::lengths::U2; -//! use atsamd_hal::sercom::v2::pad::IoSet1; +//! use atsamd_hal::sercom::spi::lengths::U2; +//! use atsamd_hal::sercom::pad::IoSet1; //! //! // SAMD11/SAMD21 version //! type Pads = spi::PadsFromIds; @@ -230,17 +230,17 @@ type Pads = spi::PadsFromIds; //! automaically from the set of [`ValidPads`]. //! //! ``` -//! use atsamd_hal::gpio::v2::{PA08, PA09}; -//! use atsamd_hal::sercom::v2::{Sercom0, spi}; -//! use atsamd_hal::sercom::v2::spi::{Master, Rx}; +//! use atsamd_hal::gpio::{PA08, PA09}; +//! use atsamd_hal::sercom::{Sercom0, spi}; +//! use atsamd_hal::sercom::spi::{Master, Rx}; //! use atsamd_hal::typelevel::NoneT; //! //! // SAMD11/SAMD21-specific imports -//! use atsamd_hal::sercom::v2::spi::NineBit; +//! use atsamd_hal::sercom::spi::NineBit; //! //! // SAMx5x-specific imports -//! use atsamd_hal::sercom::v2::spi::lengths::U2; -//! use atsamd_hal::sercom::v2::pad::IoSet1; +//! use atsamd_hal::sercom::spi::lengths::U2; +//! use atsamd_hal::sercom::pad::IoSet1; //! //! // SAMD11/SAMD21 version //! type Pads = spi::PadsFromIds; @@ -271,10 +271,10 @@ type Pads = spi::PadsFromIds; //! ``` //! //! [`enable`]: Config::enable -//! [`gpio`]: crate::gpio::v2 -//! [`Pin`]: crate::gpio::v2::pin::Pin -//! [`PinId`]: crate::gpio::v2::pin::PinId -//! [`PinMode`]: crate::gpio::v2::pin::PinMode +//! [`gpio`]: crate::gpio +//! [`Pin`]: crate::gpio::pin::Pin +//! [`PinId`]: crate::gpio::pin::PinId +//! [`PinMode`]: crate::gpio::pin::PinMode #![cfg_attr( feature = "dma", doc = " @@ -319,7 +319,7 @@ use bitflags::bitflags; use embedded_hal::spi; pub use embedded_hal::spi::{Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; -use crate::sercom::v2::*; +use crate::sercom::*; use crate::time::Hertz; use crate::typelevel::{Is, NoneT, Sealed}; diff --git a/hal/src/sercom/v2/spi/char_size.rs b/hal/src/sercom/spi/char_size.rs similarity index 100% rename from hal/src/sercom/v2/spi/char_size.rs rename to hal/src/sercom/spi/char_size.rs diff --git a/hal/src/sercom/v2/spi/impl_ehal_thumbv6m.rs b/hal/src/sercom/spi/impl_ehal_thumbv6m.rs similarity index 100% rename from hal/src/sercom/v2/spi/impl_ehal_thumbv6m.rs rename to hal/src/sercom/spi/impl_ehal_thumbv6m.rs diff --git a/hal/src/sercom/v2/spi/impl_ehal_thumbv7em.rs b/hal/src/sercom/spi/impl_ehal_thumbv7em.rs similarity index 100% rename from hal/src/sercom/v2/spi/impl_ehal_thumbv7em.rs rename to hal/src/sercom/spi/impl_ehal_thumbv7em.rs diff --git a/hal/src/sercom/v2/spi/length.rs b/hal/src/sercom/spi/length.rs similarity index 100% rename from hal/src/sercom/v2/spi/length.rs rename to hal/src/sercom/spi/length.rs diff --git a/hal/src/sercom/v2/spi/pads_thumbv6m.rs b/hal/src/sercom/spi/pads_thumbv6m.rs similarity index 98% rename from hal/src/sercom/v2/spi/pads_thumbv6m.rs rename to hal/src/sercom/spi/pads_thumbv6m.rs index 8f32d0c5e2e0..3db30a727701 100644 --- a/hal/src/sercom/v2/spi/pads_thumbv6m.rs +++ b/hal/src/sercom/spi/pads_thumbv6m.rs @@ -6,8 +6,8 @@ use core::marker::PhantomData; #[cfg(feature = "samd21")] -use crate::gpio::v2::AnyPin; -use crate::sercom::v2::*; +use crate::gpio::AnyPin; +use crate::sercom::*; use crate::typelevel::{NoneT, Sealed}; use super::{Capability, Duplex, Rx, Tx}; @@ -205,7 +205,7 @@ where SS: OptionalPad, { /// Consume the [`Pads`] and return each individual - /// [`Pin`](crate::gpio::v2::Pin) + /// [`Pin`](crate::gpio::Pin) #[inline] pub fn free(self) -> (DI, DO, CK, SS) { (self.data_in, self.data_out, self.sclk, self.ss) @@ -388,8 +388,8 @@ where /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, spi}; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, spi}; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = spi::PadsFromIds; @@ -401,9 +401,9 @@ where /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId -/// [`OptionalPinId`]: crate::gpio::v2::OptionalPinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId +/// [`OptionalPinId`]: crate::gpio::OptionalPinId #[cfg(feature = "samd21")] pub type PadsFromIds = Pads< S, @@ -432,7 +432,7 @@ pub type PadsFromIds = Pads< /// /// This trait is a simplified version of the [`AnyKind`] trait pattern. /// -/// [`Pin`]: crate::gpio::v2::Pin +/// [`Pin`]: crate::gpio::Pin /// [`Config`]: super::Config /// [type-level function]: crate::typelevel#type-level-functions /// [`AnyKind`]: crate::typelevel#anykind-trait-pattern diff --git a/hal/src/sercom/v2/spi/pads_thumbv7em.rs b/hal/src/sercom/spi/pads_thumbv7em.rs similarity index 96% rename from hal/src/sercom/v2/spi/pads_thumbv7em.rs rename to hal/src/sercom/spi/pads_thumbv7em.rs index d60c0b724a76..56c93af70722 100644 --- a/hal/src/sercom/v2/spi/pads_thumbv7em.rs +++ b/hal/src/sercom/spi/pads_thumbv7em.rs @@ -5,8 +5,8 @@ use core::marker::PhantomData; -use crate::gpio::v2::AnyPin; -use crate::sercom::v2::*; +use crate::gpio::AnyPin; +use crate::sercom::*; use crate::typelevel::{NoneT, Sealed}; use super::{Capability, Duplex, Rx, Tx}; @@ -230,7 +230,7 @@ where } /// Consume the [`Pads`] and return each individual - /// [`Pin`](crate::gpio::v2::Pin) + /// [`Pin`](crate::gpio::Pin) #[inline] pub fn free(self) -> (DI, DO, CK, SS) { (self.data_in, self.data_out, self.sclk, self.ss) @@ -253,9 +253,9 @@ where /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, spi}; -/// use atsamd_hal::sercom::v2::pad::IoSet1; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, spi}; +/// use atsamd_hal::sercom::pad::IoSet1; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = spi::PadsFromIds; @@ -267,9 +267,9 @@ where /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId -/// [`OptionalPinId`]: crate::gpio::v2::OptionalPinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId +/// [`OptionalPinId`]: crate::gpio::OptionalPinId pub type PadsFromIds = Pads< S, I, @@ -298,7 +298,7 @@ pub type PadsFromIds = Pad /// /// This trait is a simplified version of the [`AnyKind`] trait pattern. /// -/// [`Pin`]: crate::gpio::v2::Pin +/// [`Pin`]: crate::gpio::Pin /// [type-level function]: crate::typelevel#type-level-functions /// [`AnyKind`]: crate::typelevel#anykind-trait-pattern pub trait PadSet: Sealed { diff --git a/hal/src/sercom/v2/spi/reg.rs b/hal/src/sercom/spi/reg.rs similarity index 99% rename from hal/src/sercom/v2/spi/reg.rs rename to hal/src/sercom/spi/reg.rs index 8a7931928660..5a21ee8b2dbf 100644 --- a/hal/src/sercom/v2/spi/reg.rs +++ b/hal/src/sercom/spi/reg.rs @@ -12,7 +12,7 @@ use crate::pac::sercom0::spi::ctrla::MODE_A; #[cfg(feature = "min-samd51g")] use crate::pac::sercom0::spim::ctrla::MODE_A; -use crate::sercom::v2::Sercom; +use crate::sercom::Sercom; use crate::time::Hertz; use super::{BitOrder, DataWidth, Error, Flags, Phase, Polarity, Status}; diff --git a/hal/src/sercom/v2/spi_future.rs b/hal/src/sercom/spi_future.rs similarity index 96% rename from hal/src/sercom/v2/spi_future.rs rename to hal/src/sercom/spi_future.rs index 67304acb9783..213e17d0cb37 100644 --- a/hal/src/sercom/v2/spi_future.rs +++ b/hal/src/sercom/spi_future.rs @@ -21,9 +21,9 @@ //! transaction. //! //! ``` -//! use atsamd_hal::gpio::v2::{Pin, PA10, PushPullOutput}; -//! use atsamd_hal::sercom::v2::spi::AnySpi; -//! use atsamd_hal::sercom::v2::spi_future::SpiFuture; +//! use atsamd_hal::gpio::{Pin, PA10, PushPullOutput}; +//! use atsamd_hal::sercom::spi::AnySpi; +//! use atsamd_hal::sercom::spi_future::SpiFuture; //! //! fn wake_up() { //! //... @@ -93,11 +93,11 @@ //! //! ``` //! use core::task::Poll; -//! use atsamd_hal::gpio::v2::{PA08, PA09, PA10, PA11, Pin, PushPullOutput}; -//! use atsamd_hal::sercom::v2::Sercom0; -//! use atsamd_hal::sercom::v2::pad::{IoSet1, Pad0, Pad1, Pad3}; -//! use atsamd_hal::sercom::v2::spi::{self, Master, lengths::U12}; -//! use atsamd_hal::sercom::v2::spi_future::SpiFuture; +//! use atsamd_hal::gpio::{PA08, PA09, PA10, PA11, Pin, PushPullOutput}; +//! use atsamd_hal::sercom::Sercom0; +//! use atsamd_hal::sercom::pad::{IoSet1, Pad0, Pad1, Pad3}; +//! use atsamd_hal::sercom::spi::{self, Master, lengths::U12}; +//! use atsamd_hal::sercom::spi_future::SpiFuture; //! //! type Pads = spi::Pads; //! type SS = Pin; @@ -166,7 +166,7 @@ //! [`EightBit`]: super::spi::EightBit //! [`NineBit`]: super::spi::NineBit //! [`Length`]: super::spi::Length -//! [`Pin`]: crate::gpio::v2::pin::Pin +//! [`Pin`]: crate::gpio::pin::Pin //! [`Future`]: core::future::Future //! [`Waker`]: core::task::Waker //! [`Poll`]: core::task::Poll @@ -177,7 +177,7 @@ use core::task::Poll; use embedded_hal::digital::v2::OutputPin; -use crate::gpio::v2::pin::{OptionalPin, SomePin}; +use crate::gpio::pin::{OptionalPin, SomePin}; use crate::typelevel::NoneT; use super::spi::{AnySpi, Error, Flags}; diff --git a/hal/src/sercom/v2/uart.rs b/hal/src/sercom/uart.rs similarity index 95% rename from hal/src/sercom/v2/uart.rs rename to hal/src/sercom/uart.rs index 2d2667ff77d6..4147fd08c9b1 100644 --- a/hal/src/sercom/v2/uart.rs +++ b/hal/src/sercom/uart.rs @@ -26,8 +26,8 @@ //! used to define convenient type aliases for [`Pad`] types. //! //! ``` -//! use atsamd_hal::gpio::v2::{PA08, PA09, AlternateC}; -//! use atsamd_hal::sercom::v2::{Sercom0, uart}; +//! use atsamd_hal::gpio::{PA08, PA09, AlternateC}; +//! use atsamd_hal::sercom::{Sercom0, uart}; //! use atsamd_hal::typelevel::NoneT; //! //! type Rx = Pin; @@ -42,8 +42,8 @@ Alternatively, you can use the [`PadsFromIds`] alias to define a set of don't have [`Pin`] aliases pre-defined. ``` -use atsamd_hal::gpio::v2::{PA08, PA09}; -use atsamd_hal::sercom::v2::{Sercom0, uart}; +use atsamd_hal::gpio::{PA08, PA09}; +use atsamd_hal::sercom::{Sercom0, uart}; type Pads = uart::PadsFromIds; ``` @@ -53,8 +53,7 @@ type Pads = uart::PadsFromIds; //! //! Instances of [`Pads`] are created using the builder pattern. Start by //! creating an empty set of [`Pads`] using [`Default`]. Then pass each -//! respective [`Pin`] using the corresponding methods. Both [`v1::Pin`] and -//! [`v2::Pin`] types are accepted here. +//! respective [`Pin`] using the corresponding methods. //! //! On SAMD21 and SAMx5x chips, the builder methods automatically convert each //! pin to the correct [`PinMode`]. But for SAMD11 chips, users must manually @@ -65,8 +64,8 @@ type Pads = uart::PadsFromIds; //! //! ``` //! use atsamd_hal::pac::Peripherals; -//! use atsamd_hal::gpio::v2::Pins; -//! use atsamd_hal::sercom::v2::{Sercom0, uart}; +//! use atsamd_hal::gpio::Pins; +//! use atsamd_hal::sercom::{Sercom0, uart}; //! //! let mut peripherals = Peripherals::take().unwrap(); //! let pins = Pins::new(peripherals.PORT); @@ -87,9 +86,9 @@ type Pads = uart::PadsFromIds; //! [`Pads`] type; and a [`CharSize`], which defaults to [`EightBit`]. //! //! ``` -//! use atsamd_hal::gpio::v2::{PA08, PA09}; -//! use atsamd_hal::sercom::v2::{Sercom0, uart}; -//! use atsamd_hal::sercom::v2::uart::{NineBit}; +//! use atsamd_hal::gpio::{PA08, PA09}; +//! use atsamd_hal::sercom::{Sercom0, uart}; +//! use atsamd_hal::sercom::uart::{NineBit}; //! use atsamd_hal::typelevel::NoneT; //! //! type Pads = uart::PadsFromIds; @@ -124,7 +123,7 @@ type Pads = uart::PadsFromIds; //! consumes the [`Config`] and returns an enabled [`Uart`] peripheral. //! //! ``` -//! use atsamd_hal::sercom::v2::uart::{StopBits, NineBit, BitOrder, BaudMode, Oversampling}; +//! use atsamd_hal::sercom::uart::{StopBits, NineBit, BitOrder, BaudMode, Oversampling}; //! //! let uart = uart::Config::new(&mclk, sercom, pads, freq) //! .baud(1.mhz(), BaudMode::Arithmetic(Oversampling::Bits16)) @@ -137,7 +136,7 @@ type Pads = uart::PadsFromIds; //! Alternatively, //! //! ``` -//! use atsamd_hal::sercom::v2::uart::{StopBits, NineBit, BitOrder, BaudMode, Oversampling}; +//! use atsamd_hal::sercom::uart::{StopBits, NineBit, BitOrder, BaudMode, Oversampling}; //! //! let uart = uart::Config::new(&mclk, sercom, pads, freq); //! uart.set_baud(1.mhz(), BaudMode::Arithmetic(Oversampling::Bits16)); @@ -192,9 +191,9 @@ type Pads = uart::PadsFromIds; //! RxDuplex>` and a `Uart`. //! //! ``` -//! use atsamd_hal::gpio::v2::{PA08, PA09}; -//! use atsamd_hal::sercom::v2::{Sercom0, uart}; -//! use atsamd_hal::sercom::v2::uart::NineBit; +//! use atsamd_hal::gpio::{PA08, PA09}; +//! use atsamd_hal::sercom::{Sercom0, uart}; +//! use atsamd_hal::sercom::uart::NineBit; //! use atsamd_hal::typelevel::NoneT; //! //! // Assuming SAMD21 or SAMx5x @@ -241,7 +240,7 @@ type Pads = uart::PadsFromIds; //! constituents: //! //! ``` -//! use atsamd_hal::sercom::v2::uart::Uart; +//! use atsamd_hal::sercom::uart::Uart; //! // Assume uart is a Uart //! let (rx, tx) = uart.split(); //! ``` @@ -255,7 +254,7 @@ type Pads = uart::PadsFromIds; //! [`Uart`]. //! //! ``` -//! use atsamd_hal::sercom::v2::uart::Uart; +//! use atsamd_hal::sercom::uart::Uart; //! //! // Assume rx is a Uart and tx is a Uart //! let uart = Uart::join(rx, tx); @@ -270,7 +269,7 @@ type Pads = uart::PadsFromIds; //! and [`TxDuplex`] halves. //! //! ``` -//! use atsamd_hal::sercom::v2::uart::Uart; +//! use atsamd_hal::sercom::uart::Uart; //! use atsamd_hal::time::*; //! //! // Assume rx is a Uart and tx is a Uart @@ -303,7 +302,7 @@ type Pads = uart::PadsFromIds; //! then use the `set_*` methods. //! //! ``` -//! use atsamd_hal::sercom::v2::uart::Uart; +//! use atsamd_hal::sercom::uart::Uart; //! use atsamd_hal::time::*; //! //! // Assume config is a valid Duplex UART Config struct @@ -335,11 +334,10 @@ type Pads = uart::PadsFromIds; //! [`disable`]: Uart::disable //! [`reconfigure`]: Uart::reconfigure //! [`bsp_pins`]: crate::bsp_pins -//! [`Pin`]: crate::gpio::v2::pin::Pin -//! [`v1::Pin`]: crate::gpio::v1::Pin -//! [`v2::Pin`]: crate::gpio::v2::pin::Pin -//! [`PinId`]: crate::gpio::v2::pin::PinId -//! [`PinMode`]: crate::gpio::v2::pin::PinMode +//! [`Pin`]: crate::gpio::pin::Pin +//! [`Pin`]: crate::gpio::pin::Pin +//! [`PinId`]: crate::gpio::pin::PinId +//! [`PinMode`]: crate::gpio::pin::PinMode //! [`split`]: Uart::split //! [`join`]: Uart::join //! [`NoneT`]: crate::typelevel::NoneT @@ -413,7 +411,7 @@ pub use config::*; pub mod impl_ehal; -use crate::{sercom::v2::*, typelevel::Sealed}; +use crate::{sercom::*, typelevel::Sealed}; use core::{convert::TryInto, marker::PhantomData}; use num_traits::AsPrimitive; @@ -802,7 +800,7 @@ where /// transactions. /// /// ``` - /// use atsamd_hal::sercom::v2::uart::{BaudMode, Oversampling, Uart}; + /// use atsamd_hal::sercom::uart::{BaudMode, Oversampling, Uart}; /// uart.reconfigure(|c| c.set_run_in_standby(false)); /// ``` #[inline] @@ -849,7 +847,7 @@ where /// transactions. /// /// ``` - /// use atsamd_hal::sercom::v2::uart::{BaudMode, Oversampling, Uart}; + /// use atsamd_hal::sercom::uart::{BaudMode, Oversampling, Uart}; /// uart.reconfigure(|c| c.set_run_in_standby(false)); /// ``` #[inline] diff --git a/hal/src/sercom/v2/uart/charsize.rs b/hal/src/sercom/uart/charsize.rs similarity index 100% rename from hal/src/sercom/v2/uart/charsize.rs rename to hal/src/sercom/uart/charsize.rs diff --git a/hal/src/sercom/v2/uart/config.rs b/hal/src/sercom/uart/config.rs similarity index 99% rename from hal/src/sercom/v2/uart/config.rs rename to hal/src/sercom/uart/config.rs index e9c0c4696187..1aaaa69e2447 100644 --- a/hal/src/sercom/v2/uart/config.rs +++ b/hal/src/sercom/uart/config.rs @@ -6,7 +6,7 @@ use super::{ }; use crate::{ pac, - sercom::v2::*, + sercom::*, time::Hertz, typelevel::{Is, Sealed}, }; diff --git a/hal/src/sercom/v2/uart/flags.rs b/hal/src/sercom/uart/flags.rs similarity index 100% rename from hal/src/sercom/v2/uart/flags.rs rename to hal/src/sercom/uart/flags.rs diff --git a/hal/src/sercom/v2/uart/impl_ehal.rs b/hal/src/sercom/uart/impl_ehal.rs similarity index 100% rename from hal/src/sercom/v2/uart/impl_ehal.rs rename to hal/src/sercom/uart/impl_ehal.rs diff --git a/hal/src/sercom/v2/uart/pads_thumbv6m.rs b/hal/src/sercom/uart/pads_thumbv6m.rs similarity index 97% rename from hal/src/sercom/v2/uart/pads_thumbv6m.rs rename to hal/src/sercom/uart/pads_thumbv6m.rs index aa7445de8e17..4fd2ca42d5d5 100644 --- a/hal/src/sercom/v2/uart/pads_thumbv6m.rs +++ b/hal/src/sercom/uart/pads_thumbv6m.rs @@ -3,11 +3,11 @@ use core::marker::PhantomData; use super::{AnyConfig, Capability, CharSize, Config, Duplex, Rx, Tx}; -use crate::sercom::v2::*; +use crate::sercom::*; use crate::typelevel::{NoneT, Sealed}; #[cfg(not(feature = "samd11"))] -use crate::gpio::v2::AnyPin; +use crate::gpio::AnyPin; //============================================================================= // RxpoTxpo @@ -157,7 +157,7 @@ padnum_permutations!( () [NoneT Pad0 Pad1 Pad2 Pad3] ); /// Container for a set of SERCOM [`Pad`]s /// -/// See the [module-level](crate::sercom::v2::uart) documentation for more +/// See the [module-level](crate::sercom::uart) documentation for more /// details on specifying a `Pads` type and creating instances. pub struct Pads where @@ -350,8 +350,8 @@ where /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, uart}; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, uart}; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = uart::PadsFromIds; @@ -363,9 +363,9 @@ where /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId -/// [`OptionalPinId`]: crate::gpio::v2::OptionalPinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId +/// [`OptionalPinId`]: crate::gpio::OptionalPinId #[cfg(feature = "samd21")] pub type PadsFromIds = Pads< @@ -393,9 +393,9 @@ pub type PadsFromIds = Pads /// [`Pads`] without itself being generic over all six type parameters of the /// [`Pads`] type. /// -/// [`Pin`]: crate::gpio::v2::Pin +/// [`Pin`]: crate::gpio::Pin /// [type-level function]: crate::typelevel#type-level-functions -/// [`Config`]: crate::sercom::v2::uart::Config +/// [`Config`]: crate::sercom::uart::Config pub trait PadSet: Sealed { type Sercom: Sercom; type Rx: OptionalPad; @@ -439,7 +439,7 @@ where /// guarantees to the [`Config`] struct that this set of `Pads` can be /// configured through that trait. /// -/// [`Config`]: crate::sercom::v2::uart::Config +/// [`Config`]: crate::sercom::uart::Config pub trait ValidPads: PadSet + RxpoTxpo { type Capability: Capability; } diff --git a/hal/src/sercom/v2/uart/pads_thumbv7em.rs b/hal/src/sercom/uart/pads_thumbv7em.rs similarity index 94% rename from hal/src/sercom/v2/uart/pads_thumbv7em.rs rename to hal/src/sercom/uart/pads_thumbv7em.rs index 65ff6e35f9a6..8c6c5c65245d 100644 --- a/hal/src/sercom/v2/uart/pads_thumbv7em.rs +++ b/hal/src/sercom/uart/pads_thumbv7em.rs @@ -5,10 +5,10 @@ use core::marker::PhantomData; use crate::pac::sercom0::usart_int::ctrla::{RXPO_A, TXPO_A}; use super::{AnyConfig, Capability, CharSize, Config, Duplex, Rx, Tx}; -use crate::sercom::v2::*; +use crate::sercom::*; use crate::typelevel::{NoneT, Sealed}; -use crate::gpio::v2::AnyPin; +use crate::gpio::AnyPin; //============================================================================= // Rxpo @@ -93,7 +93,7 @@ where /// Container for a set of SERCOM [`Pad`]s /// -/// See the [module-level](crate::sercom::v2::uart) documentation for more +/// See the [module-level](crate::sercom::uart) documentation for more /// details on specifying a `Pads` type and creating instances. pub struct Pads where @@ -228,9 +228,9 @@ where /// /// ``` /// use atsamd_hal::pac::Peripherals; -/// use atsamd_hal::gpio::v2::{PA08, PA09, Pins}; -/// use atsamd_hal::sercom::v2::{Sercom0, uart}; -/// use atsamd_hal::sercom::v2::pad::IoSet1; +/// use atsamd_hal::gpio::{PA08, PA09, Pins}; +/// use atsamd_hal::sercom::{Sercom0, uart}; +/// use atsamd_hal::sercom::pad::IoSet1; /// use atsamd_hal::typelevel::NoneT; /// /// pub type Pads = uart::PadsFromIds; @@ -242,9 +242,9 @@ where /// } /// ``` /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`PinId`]: crate::gpio::v2::PinId -/// [`OptionalPinId`]: crate::gpio::v2::OptionalPinId +/// [`Pin`]: crate::gpio::Pin +/// [`PinId`]: crate::gpio::PinId +/// [`OptionalPinId`]: crate::gpio::OptionalPinId pub type PadsFromIds = Pads< S, I, @@ -271,8 +271,8 @@ pub type PadsFromIds = P /// instance of [`Pads`] without itself being generic over all six type /// parameters of the [`Pads`] type. /// -/// [`Pin`]: crate::gpio::v2::Pin -/// [`Config`]: crate::sercom::v2::uart::Config +/// [`Pin`]: crate::gpio::Pin +/// [`Config`]: crate::sercom::uart::Config /// [type-level function]: crate::typelevel#type-level-functions pub trait PadSet: Sealed { type Sercom: Sercom; @@ -321,7 +321,7 @@ where /// traits. It guarantees to the [`Config`] struct that this set of `Pads` can /// be configured through those traits. /// -/// [`Config`]: crate::sercom::v2::uart::Config +/// [`Config`]: crate::sercom::uart::Config pub trait ValidPads: PadSet + Rxpo + Txpo { type Capability: Capability; } diff --git a/hal/src/sercom/v2/uart/reg.rs b/hal/src/sercom/uart/reg.rs similarity index 99% rename from hal/src/sercom/v2/uart/reg.rs rename to hal/src/sercom/uart/reg.rs index 397ae410d397..bc6dd8c1162e 100644 --- a/hal/src/sercom/v2/uart/reg.rs +++ b/hal/src/sercom/uart/reg.rs @@ -3,7 +3,7 @@ use super::{BaudMode, BitOrder, CharSizeEnum, Flags, Oversampling, Parity, Status, StopBits}; use crate::pac; -use crate::sercom::v2::*; +use crate::sercom::*; #[cfg(any(feature = "samd11", feature = "samd21"))] use pac::sercom0::usart::ctrla::MODE_A; diff --git a/hal/src/sercom/v1.rs b/hal/src/sercom/v1.rs deleted file mode 100644 index 84d5a4dba36d..000000000000 --- a/hal/src/sercom/v1.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! # Version 1 of the SERCOM module -//! -//! This module retains the previous SERCOM API. The [`pads`] module provides a -//! compatibility shim that uses the new [`v2::pad`] module to implement the -//! old API. This API will eventually be deprecated and removed. -//! -//! [`v2::pad`]: super::v2::pad - -pub mod pads; -pub use pads::*; - -#[cfg(any(feature = "samd11", feature = "samd21"))] -pub use crate::common::thumbv6m::sercom::v1::*; - -#[cfg(feature = "min-samd51g")] -pub use crate::common::thumbv7em::sercom::v1::*; diff --git a/hal/src/sercom/v1/pads.rs b/hal/src/sercom/v1/pads.rs deleted file mode 100644 index 38cbd416ee69..000000000000 --- a/hal/src/sercom/v1/pads.rs +++ /dev/null @@ -1,224 +0,0 @@ -//! Version 1 of the SERCOM pads module -//! -//! This module is a compatibility shim that allows existing code to use the new -//! [`sercom::v2`](crate::sercom::v2) module. This API will eventually be -//! deprecated and removed. -//! -//! To recreate the `v1` API with `v2` types, this module defines its own -//! [`Pad`] type, which is just a wrapper around a [`Pin`] configured as a -//! SERCOM pad. The `SercomXPadY` types of the original, `v1` API are recreated -//! as type aliases of the form -//! -//! ``` -//! type SercomXPadY = Pad -//! ``` -//! -//! Use the [`PadPin`] trait to construct `Pad`s. The corresponding `Pin` can be -//! recovered using the [`free`] method. -//! -//! ``` -//! use atsamd_hal::pac::Peripherals; -//! use atsamd_hal::gpio::v1::GpioExt; -//! use atsamd_hal::sercom::v1::{PadPin, Sercom0Pad0}; -//! -//! let peripherals = Peripherals::take().unwrap(); -//! let mut parts = peripherals.PORT.split(); -//! let pad: Sercom0Pad0<_> = parts.pa8.into_pad(&mut parts.port); -//! let pin = pad.free(); -//! ``` -//! -//! [`free`]: Pad::free - -#![allow(deprecated)] - -use core::marker::PhantomData; - -use paste::paste; - -use crate::gpio::v1::{self, IntoFunction, Pin, Port}; -use crate::gpio::v2::{self, AnyPin, PinId, PinMode}; -use crate::sercom::v2::*; -use crate::typelevel::Sealed; - -//============================================================================== -// IsPad -//============================================================================== - -/// Extend implementations of [`IsPad`] from [`v2::Pin`]s to [`v1::Pin`]s -impl IsPad for v1::Pin -where - I: PinId, - M: PinMode, - v1::Pin: AnyPin, - v2::Pin: IsPad, -{ - type Sercom = as IsPad>::Sercom; - type PadNum = as IsPad>::PadNum; -} - -//============================================================================== -// Pad -//============================================================================== - -/// A GPIO [`Pin`] configured to act as a SERCOM [`Pad`] -/// -/// This type is just a wrapper around a correctly-configured [`Pin`]. The -/// `SercomXPadY` types of the original, `v1` API are recreated as type aliases -/// of the form -/// -/// ``` -/// type SercomXPadY = Pad -/// ``` -pub struct Pad -where - S: Sercom, - N: PadNum, - P: IsPad, -{ - sercom: PhantomData, - padnum: PhantomData, - pin: P, -} - -impl Pad -where - S: Sercom, - N: PadNum, - P: IsPad, -{ - /// Consume the [`Pad`] and recover the corresponding [`Pin`] - #[inline] - pub fn free(self) -> P { - self.pin - } -} - -impl Sealed for Pad -where - S: Sercom, - N: PadNum, - P: IsPad, -{ -} - -//============================================================================== -// Pad aliases -//============================================================================== - -macro_rules! pad_alias { - ( $($Sercom:ty),+ ) => { - $( - pad_alias!($Sercom: Pad0); - pad_alias!($Sercom: Pad1); - pad_alias!($Sercom: Pad2); - pad_alias!($Sercom: Pad3); - )+ - }; - ($Sercom:ty: $Pad:ty) => { - paste! { - /// Represents a numbered pad for the associated sercom instance. The pad is - /// generic over any pin, only the PadPin implementations in this the sercom - /// module make sense. - pub type [<$Sercom $Pad>]

= Pad<$Sercom, $Pad, P>; - } - } -} - -pad_alias!(Sercom0, Sercom1); -#[cfg(any(feature = "samd21", feature = "min-samd51g"))] -pad_alias!(Sercom2, Sercom3); -#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] -pad_alias!(Sercom4, Sercom5); -#[cfg(feature = "min-samd51n")] -pad_alias!(Sercom6, Sercom7); - -//============================================================================== -// CompatiblePad -//============================================================================== - -/// Type class to improve compatibility between `v1` and `v2` SERCOM pad types -/// -/// The `sercom::v1::pads` module uses a wrapper [`Pad`] type to represent -/// SERCOM pads. The `v2::pad` module, on the other hand, does not use a -/// wrapper. Instead, it labels each correctly-configured [`v2::Pin`] with the -/// [`IsPad`] trait. -/// -/// This trait forms a [type class] over both. It allows the [`v1::uart`], -/// [`v1::spi`] and [`v1::i2c`] modules to accept both `v1` and `v2` pad types. -/// -/// [`v1::uart`]: super::uart -/// [`v1::spi`]: super::spi -/// [`v1::i2c`]: super::i2c -/// [type class]: crate::typelevel#type-classes -pub trait CompatiblePad: Sealed { - type Sercom: Sercom; - type PadNum: PadNum; -} - -impl CompatiblePad for Pad -where - S: Sercom, - N: PadNum, - P: IsPad, -{ - type Sercom = S; - type PadNum = N; -} - -impl CompatiblePad for P { - type Sercom = P::Sercom; - type PadNum = P::PadNum; -} - -//============================================================================== -// PadPin -//============================================================================== - -/// The PadPin trait makes it more ergonomic to convert a pin into a Sercom pad. -/// You should not implement this trait for yourself; only the implementations -/// in the sercom module make sense. -pub trait PadPin

: Sealed { - fn into_pad(self, port: &mut Port) -> P; -} - -#[cfg(feature = "samd11")] -impl PadPin>> for Pin -where - S: Sercom, - N: PadNum, - I: GetPad, - M: PinMode, - Pin: IntoFunction>, - Pin: IsPad, -{ - #[inline] - fn into_pad(self, port: &mut Port) -> Pad> { - let pin = self.into_function(port); - Pad { - sercom: PhantomData, - padnum: PhantomData, - pin, - } - } -} - -#[cfg(not(feature = "samd11"))] -impl PadPin>> for Pin -where - S: Sercom, - N: PadNum, - I: GetPad, - M: PinMode, - Pin: IntoFunction>, - Pin: IsPad, -{ - #[inline] - fn into_pad(self, port: &mut Port) -> Pad> { - let pin = self.into_function(port); - Pad { - sercom: PhantomData, - padnum: PhantomData, - pin, - } - } -} diff --git a/hal/src/sercom/v2.rs b/hal/src/sercom/v2.rs deleted file mode 100644 index c876f0e4e3af..000000000000 --- a/hal/src/sercom/v2.rs +++ /dev/null @@ -1,126 +0,0 @@ -//! # Version 2 of the SERCOM module -//! -//! This module provides a new API for the SERCOM peripherals. So far, only the -//! [`pad`] and [`spi`] modules have been updated, but it is expected that the -//! `uart`, and `i2c` modules will eventually receive updates as well. -#![cfg_attr( - feature = "min-samd51g", - doc = " -# Undocumented features - -The ATSAMx5x chips contain certain features that aren't documented in the datasheet. -These features are implemented in the HAL based on experimentation with certain boards -which have verifiably demonstrated that those features work as intended. - -* [`UndocIoSet1`](pad::UndocIoSet1): Implement an undocumented `IoSet` for PA16, PA17, -PB22 & PB23 configured for [`Sercom1`]. The pygamer & feather_m4 use this combination, -but it is not listed as valid in the datasheet. - -* [`UndocIoSet2`](pad::UndocIoSet2): Implement an undocumented `IoSet` for PA00, PA01, -PB22 & PB23 configured for [`Sercom1`]. The itsybitsy_m4 uses this combination, but it is -not listed as valid in the datasheet. - -* [`PB02`] is I2C-capable according to metro_m4. As such, [`PB02`] -implements [`IsI2cPad`]. - -* [`PB03`] is I2C-capable according to metro_m4. As such, [`PB03`] -implements [`IsI2cPad`](pad::IsI2cPad). - -[`PB02`]: crate::gpio::v2::pin::PB02 -[`PB03`]: crate::gpio::v2::pin::PB03 -[`IsI2cPad`]: pad::IsI2cPad -" -)] - -use core::ops::Deref; - -use paste::paste; -use seq_macro::seq; - -use crate::pac; - -#[cfg(feature = "min-samd51g")] -use pac::MCLK as APB_CLK_CTRL; -#[cfg(any(feature = "samd11", feature = "samd21"))] -use pac::PM as APB_CLK_CTRL; - -use pac::{sercom0, SERCOM0, SERCOM1}; -#[cfg(any(feature = "samd21", feature = "min-samd51g"))] -use pac::{SERCOM2, SERCOM3}; -#[cfg(any(feature = "min-samd21g", feature = "min-samd51g"))] -use pac::{SERCOM4, SERCOM5}; -#[cfg(feature = "min-samd51n")] -use pac::{SERCOM6, SERCOM7}; - -#[cfg(feature = "dma")] -use crate::common::dmac::TriggerSource; - -use crate::typelevel::Sealed; - -pub mod pad; -pub use pad::*; - -pub mod i2c; -pub mod spi; -pub mod spi_future; -pub mod uart; - -#[cfg(feature = "dma")] -pub mod dma; - -//============================================================================== -// Sercom -//============================================================================== - -/// Type-level `enum` representing a Serial Communication Interface (SERCOM) -pub trait Sercom: Sealed + Deref { - /// SERCOM number - const NUM: usize; - /// RX Trigger source for DMA transactions - #[cfg(feature = "dma")] - const DMA_RX_TRIGGER: TriggerSource; - /// TX trigger source for DMA transactions - #[cfg(feature = "dma")] - const DMA_TX_TRIGGER: TriggerSource; - /// Enable the corresponding APB clock - fn enable_apb_clock(&mut self, ctrl: &APB_CLK_CTRL); -} - -macro_rules! sercom { - ( $apbmask:ident: ($start:literal, $end:literal) ) => { - seq!(N in $start..=$end { - paste! { - /// Type alias for the corresponding SERCOM instance - pub type Sercom~N = SERCOM~N; - impl Sealed for Sercom~N {} - impl Sercom for Sercom~N { - const NUM: usize = N; - #[cfg(feature = "dma")] - const DMA_RX_TRIGGER: TriggerSource = TriggerSource::[]; - #[cfg(feature = "dma")] - const DMA_TX_TRIGGER: TriggerSource = TriggerSource::[]; - #[inline] - fn enable_apb_clock(&mut self, ctrl: &APB_CLK_CTRL) { - ctrl.$apbmask.modify(|_, w| w.[]().set_bit()); - } - } - } - }); - }; -} - -#[cfg(any(feature = "samd11", feature = "samd21"))] -sercom!(apbcmask: (0, 1)); -#[cfg(feature = "samd21")] -sercom!(apbcmask: (2, 3)); -#[cfg(feature = "min-samd21g")] -sercom!(apbcmask: (4, 5)); - -#[cfg(feature = "min-samd51g")] -sercom!(apbamask: (0, 1)); -#[cfg(feature = "min-samd51g")] -sercom!(apbbmask: (2, 3)); -#[cfg(feature = "min-samd51g")] -sercom!(apbdmask: (4, 5)); -#[cfg(feature = "min-samd51n")] -sercom!(apbdmask: (6, 7)); diff --git a/hal/src/spi_common.rs b/hal/src/spi_common.rs deleted file mode 100644 index 360430ebe759..000000000000 --- a/hal/src/spi_common.rs +++ /dev/null @@ -1,77 +0,0 @@ -#![deprecated( - since = "0.13.0", - note = "The `spi_common` module is deprecated, and will be removed in a subsequent release. - Please use the `sercom::v2::spi::AnySpi` trait instead." -)] - -use crate::hal::spi::{Mode, Phase, Polarity}; -use crate::time::{Hertz, U32Ext}; - -#[cfg(any(feature = "samd11", feature = "samd21"))] -use crate::pac::sercom0::SPI; - -#[cfg(any( - feature = "samd51", - feature = "same51", - feature = "same53", - feature = "same54" -))] -use crate::pac::sercom0::SPIM as SPI; - -/// Consolidated common logic for dealing with ATSAMD SPI peripherals. -pub trait CommonSpi { - /// Helper for accessing the spi member of the sercom instance - fn spi(&self) -> &SPI; - - /// Helper for accessing the spi member of the sercom instance - fn spi_mut(&mut self) -> &SPI; - - /// Disable the SPI - fn disable(&mut self) { - self.spi_mut().ctrla.modify(|_, w| w.enable().clear_bit()); - // wait for configuration to take effect - while self.spi().syncbusy.read().enable().bit_is_set() {} - } - - /// Enable the SPI - fn enable(&mut self) { - self.spi_mut().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for configuration to take effect - while self.spi().syncbusy.read().enable().bit_is_set() {} - } - - /// Set the polarity (CPOL) and phase (CPHA) of the SPI - fn set_mode(&mut self, mode: Mode) { - self.disable(); - self.spi_mut().ctrla.modify(|_, w| { - match mode.polarity { - Polarity::IdleLow => w.cpol().clear_bit(), - Polarity::IdleHigh => w.cpol().set_bit(), - }; - - match mode.phase { - Phase::CaptureOnFirstTransition => w.cpha().clear_bit(), - Phase::CaptureOnSecondTransition => w.cpha().set_bit(), - } - }); - self.enable(); - } - - /// Method for calculating the output frequency given our baud settings. - /// - /// for synchronous SERCOM peripherals, the calculation for the final - /// frequency is `f_baud = f_ref / (2 * (BAUD + 1))`. - fn freq>(&self, src_clock_freq: Hertz) -> Hertz { - let baud: u8 = self.spi().baud.read().bits(); - (src_clock_freq.0 / (2_u32 * (baud as u32 + 1_u32))).hz() - } - - /// Helper for calculating our baudrate register - /// - /// for synchronous SERCOM peripherals, the calculation for this - /// register is `BAUD = f_ref / (2 * f_baud) - 1`. - #[inline] - fn calculate_baud>(freq: F, src_clock_freq: Hertz) -> u8 { - (src_clock_freq.0 / (2 * freq.into().0) - 1) as u8 - } -} diff --git a/hal/src/thumbv6m/adc.rs b/hal/src/thumbv6m/adc.rs index c2cbcbdd9f71..a4d818639a15 100644 --- a/hal/src/thumbv6m/adc.rs +++ b/hal/src/thumbv6m/adc.rs @@ -1,9 +1,7 @@ //! Analogue-to-Digital Conversion use crate::clock::GenericClockController; -#[allow(deprecated)] -use crate::gpio::v1; -use crate::gpio::v2::*; -use crate::hal::adc::{Channel, OneShot}; +use crate::ehal::adc::{Channel, OneShot}; +use crate::gpio::*; use crate::pac::{adc, ADC, PM}; /// Samples per reading @@ -179,20 +177,6 @@ macro_rules! adc_pins { } } -/// Implement [`Channel`] for [`v1::Pin`]s based on the implementations for -/// `v2` [`Pin`]s -#[allow(deprecated)] -impl Channel for v1::Pin -where - I: PinId, - Pin: Channel, -{ - type ID = u8; - fn channel() -> u8 { - Pin::::channel() - } -} - #[cfg(feature = "samd11")] adc_pins! { PA02: 0, diff --git a/hal/src/thumbv6m/eic/pin.rs b/hal/src/thumbv6m/eic/pin.rs index d202a3285ed6..e71869a53901 100644 --- a/hal/src/thumbv6m/eic/pin.rs +++ b/hal/src/thumbv6m/eic/pin.rs @@ -1,8 +1,5 @@ -#![allow(deprecated)] - use crate::gpio::{ - self, v2::AnyPin, v2::FloatingInterrupt, v2::Pin, v2::PinId, v2::PinMode, - v2::PullDownInterrupt, v2::PullUpInterrupt, Port, + self, pin::*, AnyPin, FloatingInterrupt, PinId, PinMode, PullDownInterrupt, PullUpInterrupt, }; use crate::pac; @@ -17,13 +14,13 @@ pub trait EicPin { type PullDown; /// Configure a pin as a floating external interrupt - fn into_floating_ei(self, port: &mut Port) -> Self::Floating; + fn into_floating_ei(self) -> Self::Floating; /// Configure a pin as pulled-up external interrupt - fn into_pull_up_ei(self, port: &mut Port) -> Self::PullUp; + fn into_pull_up_ei(self) -> Self::PullUp; /// Configure a pin as pulled-down external interrupt - fn into_pull_down_ei(self, port: &mut Port) -> Self::PullDown; + fn into_pull_down_ei(self) -> Self::PullDown; } pub type Sense = pac::eic::config::SENSE0_A; @@ -151,26 +148,26 @@ crate::paste::item! { $( $(#[$attr])* - impl EicPin for gpio::$PinType { - type Floating = [<$PadType $num>]>; - type PullUp = [<$PadType $num>]>; - type PullDown = [<$PadType $num>]>; + impl EicPin for Pin { + type Floating = [<$PadType $num>]>; + type PullUp = [<$PadType $num>]>; + type PullDown = [<$PadType $num>]>; - fn into_floating_ei(self, port: &mut Port) -> Self::Floating { - [<$PadType $num>]::new(self.into_floating_interrupt(port)) + fn into_floating_ei(self) -> Self::Floating { + [<$PadType $num>]::new(self.into_floating_interrupt()) } - fn into_pull_up_ei(self, port: &mut Port) -> Self::PullUp { - [<$PadType $num>]::new(self.into_pull_up_interrupt(port)) + fn into_pull_up_ei(self) -> Self::PullUp { + [<$PadType $num>]::new(self.into_pull_up_interrupt()) } - fn into_pull_down_ei(self, port: &mut Port) -> Self::PullDown { - [<$PadType $num>]::new(self.into_pull_down_interrupt(port)) + fn into_pull_down_ei(self) -> Self::PullDown { + [<$PadType $num>]::new(self.into_pull_down_interrupt()) } } $(#[$attr])* - impl ExternalInterrupt for gpio::$PinType { + impl ExternalInterrupt for gpio::$PinType { fn id(&self) -> ExternalInterruptID { $num } @@ -200,180 +197,180 @@ where #[cfg(feature = "samd11")] ei!(ExtInt[1] { - Pa15, + PA15, }); #[cfg(feature = "samd11")] ei!(ExtInt[2] { - Pa2, + PA02, }); #[cfg(feature = "samd11")] ei!(ExtInt[3] { - Pa31, + PA31, }); #[cfg(feature = "samd11")] ei!(ExtInt[4] { - Pa4, - Pa24, + PA04, + PA24, }); #[cfg(feature = "samd11")] ei!(ExtInt[5] { - Pa5, - Pa25, + PA05, + PA25, }); #[cfg(feature = "samd11")] ei!(ExtInt[6] { - Pa8, + PA08, }); #[cfg(feature = "samd11")] ei!(ExtInt[7] { - Pa9, + PA09, }); // SAMD21 #[cfg(feature = "samd21")] ei!(ExtInt[0] { - Pa0, - Pa16, + PA00, + PA16, #[cfg(feature = "min-samd21j")] - Pb0, + PB00, #[cfg(feature = "min-samd21j")] - Pb16, + PB16, }); #[cfg(feature = "samd21")] ei!(ExtInt[1] { - Pa1, - Pa17, + PA01, + PA17, #[cfg(feature = "min-samd21j")] - Pb1, + PB01, #[cfg(feature = "min-samd21j")] - Pb17, + PB17, }); #[cfg(feature = "samd21")] ei!(ExtInt[2] { - Pa2, - Pa18, + PA02, + PA18, #[cfg(feature = "min-samd21g")] - Pb2, + PB02, }); #[cfg(feature = "samd21")] ei!(ExtInt[3] { - Pa3, - Pa19, + PA03, + PA19, #[cfg(feature = "min-samd21g")] - Pb3, + PB03, }); #[cfg(feature = "samd21")] ei!(ExtInt[4] { - Pa4, + PA04, #[cfg(feature = "min-samd21g")] - Pa20, + PA20, #[cfg(feature = "min-samd21j")] - Pb4, + PB04, }); #[cfg(feature = "samd21")] ei!(ExtInt[5] { - Pa5, + PA05, #[cfg(feature = "min-samd21g")] - Pa21, + PA21, #[cfg(feature = "min-samd21j")] - Pb5, + PB05, }); #[cfg(feature = "samd21")] ei!(ExtInt[6] { - Pa6, - Pa22, + PA06, + PA22, #[cfg(feature = "min-samd21j")] - Pb6, + PB06, #[cfg(feature = "min-samd21g")] - Pb22, + PB22, }); #[cfg(feature = "samd21")] ei!(ExtInt[7] { - Pa7, - Pa23, + PA07, + PA23, #[cfg(feature = "min-samd21j")] - Pb7, + PB07, #[cfg(feature = "min-samd21g")] - Pb23, + PB23, }); #[cfg(feature = "samd21")] ei!(ExtInt[8] { - Pa28, + PA28, #[cfg(feature = "min-samd21g")] - Pb8, + PB08, }); #[cfg(feature = "samd21")] ei!(ExtInt[9] { - Pa9, + PA09, #[cfg(feature = "min-samd21g")] - Pb9, + PB09, }); #[cfg(feature = "samd21")] ei!(ExtInt[10] { - Pa10, - Pa30, + PA10, + PA30, #[cfg(feature = "min-samd21g")] - Pb10, + PB10, }); #[cfg(feature = "samd21")] ei!(ExtInt[11] { - Pa11, - Pa31, + PA11, + PA31, #[cfg(feature = "min-samd21g")] - Pb11, + PB11, }); #[cfg(feature = "samd21")] ei!(ExtInt[12] { #[cfg(feature = "min-samd21g")] - Pa12, - Pa24, + PA12, + PA24, #[cfg(feature = "min-samd21j")] - Pb12, + PB12, }); #[cfg(feature = "samd21")] ei!(ExtInt[13] { #[cfg(feature = "min-samd21g")] - Pa13, - Pa25, + PA13, + PA25, #[cfg(feature = "min-samd21j")] - Pb13, + PB13, }); #[cfg(feature = "samd21")] ei!(ExtInt[14] { - Pa14, + PA14, #[cfg(feature = "min-samd21j")] - Pb14, + PB14, #[cfg(feature = "min-samd21j")] - Pb30, + PB30, }); #[cfg(feature = "samd21")] ei!(ExtInt[15] { - Pa15, - Pa27, + PA15, + PA27, #[cfg(feature = "min-samd21j")] - Pb15, + PB15, #[cfg(feature = "min-samd21j")] - Pb31, + PB31, }); diff --git a/hal/src/thumbv6m/mod.rs b/hal/src/thumbv6m/mod.rs index 42f1820bd1a4..b704c09ff40e 100644 --- a/hal/src/thumbv6m/mod.rs +++ b/hal/src/thumbv6m/mod.rs @@ -22,5 +22,3 @@ pub mod watchdog; #[cfg(feature = "usb")] #[cfg(feature = "samd21")] pub mod usb; - -pub(crate) mod sercom; diff --git a/hal/src/thumbv6m/pwm.rs b/hal/src/thumbv6m/pwm.rs index fdf66dbc5908..a1455846bc9b 100644 --- a/hal/src/thumbv6m/pwm.rs +++ b/hal/src/thumbv6m/pwm.rs @@ -1,5 +1,5 @@ use crate::clock; -use crate::hal::{Pwm, PwmPin}; +use crate::ehal::{Pwm, PwmPin}; use crate::time::Hertz; use crate::timer_params::TimerParams; diff --git a/hal/src/thumbv6m/sercom/mod.rs b/hal/src/thumbv6m/sercom/mod.rs deleted file mode 100644 index a3a6d96c3f59..000000000000 --- a/hal/src/thumbv6m/sercom/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v1; diff --git a/hal/src/thumbv6m/sercom/v1.rs b/hal/src/thumbv6m/sercom/v1.rs deleted file mode 100644 index 34e105e71a0a..000000000000 --- a/hal/src/thumbv6m/sercom/v1.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Working with the SERCOM peripherals. -//! -//! The atsamd21 hardware has several SERCOM instances that can -//! be configured to perform a variety of serial communication -//! tasks. This configuration is expressed through the use of -//! type states to make it difficult to misuse. -//! Each sercom instance is associated with a group of IO pins -//! referred to as a Pad. When the pins are set to the appropriate -//! peripheral function mode they are routed to the sercom pad. - -pub mod i2c; -pub mod spi; -pub mod uart; - -pub use self::i2c::*; - -#[allow(deprecated)] -pub use self::spi::*; - -#[allow(deprecated)] -pub use self::uart::*; diff --git a/hal/src/thumbv6m/sercom/v1/i2c.rs b/hal/src/thumbv6m/sercom/v1/i2c.rs deleted file mode 100644 index 5e9da44b9194..000000000000 --- a/hal/src/thumbv6m/sercom/v1/i2c.rs +++ /dev/null @@ -1,409 +0,0 @@ -// Note: section 7.2.3 shows which pins support I2C Hs mode - -use crate::clock; -use crate::hal::blocking::i2c::{Read, Write, WriteRead}; -use crate::pac::sercom0::I2CM; -use crate::pac::{PM, SERCOM0, SERCOM1}; -#[cfg(feature = "samd21")] -use crate::pac::{SERCOM2, SERCOM3}; -#[cfg(feature = "min-samd21g")] -use crate::pac::{SERCOM4, SERCOM5}; -use crate::sercom::v1::pads::CompatiblePad; -use crate::sercom::v2::pad::{Pad0, Pad1}; -use crate::time::Hertz; - -const BUS_STATE_UNKNOWN: u8 = 0; -const BUS_STATE_IDLE: u8 = 1; -const BUS_STATE_BUSY: u8 = 3; - -const MASTER_ACT_READ: u8 = 2; -const MASTER_ACT_STOP: u8 = 3; - -/// Define an I2C master type for the given SERCOM and pad pair. -macro_rules! i2c { - ([ - $($Type:ident: - ( - $pad0:ident, // No longer used - $pad1:ident, // No longer used - $SERCOM:ident, - $powermask:ident, - $clock:ident - ), - )+ - ]) => { - - $( - -/// Represents the Sercom instance configured to act as an I2C Master. -/// The embedded_hal blocking I2C traits are implemented by this instance. -pub struct $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - sda: P0, - scl: P1, - sercom: $SERCOM, -} - -impl $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - /// Configures the sercom instance to work as an I2C Master. - /// The clock is obtained via the `GenericClockGenerator` type. - /// `freq` specifies the bus frequency to use for I2C communication. - /// There are typically a handful of values that tend to be supported; - /// standard mode is 100.khz(), full speed mode is 400.khz(). - /// The hardware in the atsamd device supports fast mode at 1.mhz() - /// and fast mode, but there may be additional hardware configuration - /// missing from the current software implementation that prevents that - /// from working as-written today. - /// - /// ```no_run - /// let mut i2c = I2CMaster3::new( - /// &clocks.sercom3_core(&gclk0).unwrap(), - /// 400.khz(), - /// p.device.SERCOM3, - /// &mut p.device.PM, - /// // Metro M0 express has I2C on pins PA22, PA23 - /// pins.pa22.into_pad(&mut pins.port), - /// pins.pa23.into_pad(&mut pins.port), - /// ); - /// ``` - pub fn new>( - clock: &clock::$clock, - freq: F, - sercom: $SERCOM, - pm: &mut PM, - sda: P0, - scl: P1, - ) -> Self { - // Power up the peripheral bus clock. - // safe because we're exclusively owning SERCOM - pm.apbcmask.modify(|_, w| w.$powermask().set_bit()); - - unsafe { - // reset the sercom instance - sercom.i2cm().ctrla.modify(|_, w| w.swrst().set_bit()); - // wait for reset to complete - while sercom.i2cm().syncbusy.read().swrst().bit_is_set() - || sercom.i2cm().ctrla.read().swrst().bit_is_set() - {} - - // Put the hardware into i2c master mode - sercom.i2cm().ctrla.modify(|_, w| w.mode().i2c_master()); - // wait for configuration to take effect - while sercom.i2cm().syncbusy.read().enable().bit_is_set() {} - - // set the baud rate - let gclk = clock.freq(); - let baud = (gclk.0 / (2 * freq.into().0) - 1) as u8; - sercom.i2cm().baud.modify(|_, w| w.baud().bits(baud)); - - sercom.i2cm().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for configuration to take effect - while sercom.i2cm().syncbusy.read().enable().bit_is_set() {} - - // set the bus idle - sercom - .i2cm() - .status - .modify(|_, w| w.busstate().bits(BUS_STATE_IDLE)); - // wait for it to take effect - while sercom.i2cm().syncbusy.read().sysop().bit_is_set() {} - } - - Self { sda, scl, sercom } - } - - /// Breaks the sercom device up into its constituent pins and the SERCOM - /// instance. Does not make any changes to power management. - pub fn free(self) -> (P0, P1, $SERCOM) { - (self.sda, self.scl, self.sercom) - } - - fn start_tx_write(&mut self, addr: u8) -> Result<(), I2CError> { - let status = self.i2cm().status.read(); - if status.busstate().bits() == BUS_STATE_BUSY - || (status.arblost().bit_is_set() && status.busstate().bits() != BUS_STATE_IDLE) - || status.busstate().bits() == BUS_STATE_UNKNOWN - { - return Err(I2CError::BusError); - } - - // Signal start and transmit encoded address. - unsafe { - self.i2cm() - .addr - .write(|w| w.addr().bits((addr as u16) << 1)); - } - - // wait for transmission to complete - while !self.i2cm().intflag.read().mb().bit_is_set() {} - - self.status_to_err() - } - - fn status_to_err(&mut self) -> Result<(), I2CError> { - let status = self.i2cm().status.read(); - if status.arblost().bit_is_set() { - return Err(I2CError::ArbitrationLost); - } - if status.buserr().bit_is_set() { - return Err(I2CError::BusError); - } - if status.rxnack().bit_is_set() { - return Err(I2CError::Nack); - } - if status.lowtout().bit_is_set() || status.sexttout().bit_is_set() - || status.mexttout().bit_is_set() - { - return Err(I2CError::Timeout); - } - - Ok(()) - } - - fn start_tx_read(&mut self, addr: u8) -> Result<(), I2CError> { - let status = self.i2cm().status.read(); - if status.busstate().bits() == BUS_STATE_BUSY - || (status.arblost().bit_is_set() && status.busstate().bits() != BUS_STATE_IDLE) - || status.busstate().bits() == BUS_STATE_UNKNOWN - { - return Err(I2CError::BusError); - } - - self.i2cm().intflag.modify(|_, w| w.error().clear_bit()); - - // Signal start (or rep start if appropriate) - // and transmit encoded address. - unsafe { - self.i2cm() - .addr - .write(|w| w.addr().bits(((addr as u16) << 1) | 1)); - } - - // wait for transmission to complete - loop { - let intflag = self.i2cm().intflag.read(); - // If arbitration was lost, it will be signalled via the mb bit - if intflag.mb().bit_is_set() { - return Err(I2CError::ArbitrationLost); - } - if intflag.sb().bit_is_set() || intflag.error().bit_is_set() { - break; - } - } - - self.status_to_err() - } - - fn wait_sync(&mut self) { - while self.i2cm().syncbusy.read().sysop().bit_is_set() {} - } - - fn cmd(&mut self, cmd: u8) { - unsafe { - self.i2cm().ctrlb.modify(|_, w| w.cmd().bits(cmd)); - } - self.wait_sync(); - } - - fn cmd_stop(&mut self) { - self.cmd(MASTER_ACT_STOP) - } - - fn cmd_read(&mut self) { - unsafe { - self.i2cm().ctrlb.modify(|_, w| { - // clear bit means send ack - w.ackact().clear_bit(); - w.cmd().bits(MASTER_ACT_READ) - }); - } - self.wait_sync(); - } - - fn i2cm(&mut self) -> &I2CM { - &self.sercom.i2cm() - } - - fn send_bytes(&mut self, bytes: &[u8]) -> Result<(), I2CError> { - for b in bytes { - unsafe { - self.i2cm().data.write(|w| w.bits(*b)); - } - - loop { - let intflag = self.i2cm().intflag.read(); - if intflag.mb().bit_is_set() || intflag.error().bit_is_set() { - break; - } - } - self.status_to_err()?; - } - Ok(()) - } - - fn read_one(&mut self) -> u8 { - while !self.i2cm().intflag.read().sb().bit_is_set() {} - self.i2cm().data.read().bits() - } - - fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<(), I2CError> { - // Some manual iterator gumph because we need to ack bytes after the first. - let mut iter = buffer.iter_mut(); - *iter.next().expect("buffer len is at least 1") = self.read_one(); - - loop { - match iter.next() { - None => break, - Some(dest) => { - // Ack the last byte so that we can receive another one - self.cmd_read(); - *dest = self.read_one(); - } - } - } - - // arrange to send nack on next command to - // stop slave from transmitting more data - self.i2cm().ctrlb.modify(|_, w| w.ackact().set_bit()); - - Ok(()) - } - - fn do_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), I2CError> { - self.start_tx_write(addr)?; - self.send_bytes(bytes) - } - - fn do_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), I2CError> { - self.start_tx_read(addr)?; - self.fill_buffer(buffer) - } - - fn do_write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), I2CError> { - self.start_tx_write(addr)?; - self.send_bytes(bytes)?; - self.start_tx_read(addr)?; - self.fill_buffer(buffer) - } -} - -impl Write for $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - type Error = I2CError; - - /// Sends bytes to slave with address `addr` - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { - let res = self.do_write(addr, bytes); - self.cmd_stop(); - res - } -} - -impl Read for $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - type Error = I2CError; - - fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - let res = self.do_read(addr, buffer); - self.cmd_stop(); - res - } -} - -impl WriteRead for $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - type Error = I2CError; - - fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { - let res = self.do_write_read(addr, bytes, buffer); - self.cmd_stop(); - res - } -} - )+ - }; -} - -i2c!([ - I2CMaster0: - ( - Sercom0Pad0, - Sercom0Pad1, - SERCOM0, - sercom0_, - Sercom0CoreClock - ), - I2CMaster1: - ( - Sercom1Pad0, - Sercom1Pad1, - SERCOM1, - sercom1_, - Sercom1CoreClock - ), -]); - -#[cfg(feature = "samd21")] -i2c!([ - I2CMaster2: - ( - Sercom2Pad0, - Sercom2Pad1, - SERCOM2, - sercom2_, - Sercom2CoreClock - ), - I2CMaster3: - ( - Sercom3Pad0, - Sercom3Pad1, - SERCOM3, - sercom3_, - Sercom3CoreClock - ), -]); - -#[cfg(feature = "min-samd21g")] -i2c!([ - I2CMaster4: - ( - Sercom4Pad0, - Sercom4Pad1, - SERCOM4, - sercom4_, - Sercom4CoreClock - ), - I2CMaster5: - ( - Sercom5Pad0, - Sercom5Pad1, - SERCOM5, - sercom5_, - Sercom5CoreClock - ), -]); - -#[derive(Debug)] -pub enum I2CError { - ArbitrationLost, - AddressError, - BusError, - Timeout, - Nack, -} diff --git a/hal/src/thumbv6m/sercom/v1/spi.rs b/hal/src/thumbv6m/sercom/v1/spi.rs deleted file mode 100644 index 83d35a3c66af..000000000000 --- a/hal/src/thumbv6m/sercom/v1/spi.rs +++ /dev/null @@ -1,296 +0,0 @@ -#![deprecated( - since = "0.13.0", - note = "The `sercom::v1::spi` module is deprecated, and will be removed in a subsequent release. - Please use the `sercom::v2::spi` module instead." -)] - -use core::marker::PhantomData; - -use crate::clock; -use crate::hal::spi::{FullDuplex, Mode, Phase, Polarity}; -use crate::pac::sercom0::SPI; -use crate::pac::{PM, SERCOM0, SERCOM1}; -#[cfg(feature = "samd21")] -use crate::pac::{SERCOM2, SERCOM3}; -#[cfg(feature = "min-samd21g")] -use crate::pac::{SERCOM4, SERCOM5}; -use crate::sercom::v1::pads::CompatiblePad; -use crate::sercom::v2::*; -#[allow(deprecated)] -use crate::spi_common::CommonSpi; -use crate::time::Hertz; - -#[derive(Debug)] -pub enum Error { - Overrun, -} - -/// The DipoDopo trait defines a way to get the data in and data out pin out -/// values for a given SPIMasterXPadout configuration. You should not implement -/// this trait for yourself; only the implementations in the sercom module make -/// sense. -pub trait DipoDopo { - const DIPO: u8; - const DOPO: u8; - fn dipo_dopo(&self) -> (u8, u8) { - (Self::DIPO, Self::DOPO) - } -} - -macro_rules! padout { - ( ($dipo:literal, $dopo:literal) => $pad0:ident, $pad1:ident, $pad2:ident) => { - impl DipoDopo for ($pad0, $pad1, $pad2) { - const DIPO: u8 = $dipo; - const DOPO: u8 = $dopo; - } - }; -} - -padout!((0, 1) => Pad0, Pad2, Pad3); -padout!((0, 2) => Pad0, Pad3, Pad1); - -padout!((1, 1) => Pad1, Pad2, Pad3); -padout!((1, 3) => Pad1, Pad0, Pad3); - -padout!((2, 0) => Pad2, Pad0, Pad1); -padout!((2, 2) => Pad2, Pad3, Pad1); -padout!((2, 3) => Pad2, Pad0, Pad3); - -padout!((3, 0) => Pad3, Pad0, Pad1); - -/// A pad mapping configuration for the SERCOM in SPI master mode. -/// -/// This type can only be constructed using the From implementations -/// in this module, which are restricted to valid configurations. -/// -/// Defines which sercom pad is mapped to which SPI function. -pub struct Padout -where - S: Sercom, -{ - sercom: PhantomData, - _miso: MISO, - _mosi: MOSI, - _sclk: SCLK, -} - -/// Convert from a tuple of (MISO, MOSI, SCK) to SPIMasterXPadout -impl From<(PAD0, PAD1, PAD2)> for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum): DipoDopo, -{ - fn from(pads: (PAD0, PAD1, PAD2)) -> Padout { - Padout { - sercom: PhantomData, - _miso: pads.0, - _mosi: pads.1, - _sclk: pads.2, - } - } -} - -impl DipoDopo for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum): DipoDopo, -{ - const DIPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum)>::DIPO; - const DOPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum)>::DOPO; -} - -/// Define an SPIMasterX type for the given Sercom number. -/// -/// Also defines the valid "pad to spi function" mappings for this instance so -/// that construction is restricted to correct configurations. -macro_rules! spi_master { - ($Type:ident: ($Sercom:ident, $SERCOM:ident, $powermask:ident, $clock:ident)) => { - $crate::paste::item! { - pub type [<$Type Padout>] = Padout<$Sercom, MISO, MOSI, SCLK>; - } - - /// SPIMasterX represents the corresponding SERCOMX instance - /// configured to act in the role of an SPI Master. - /// Objects of this type implement the HAL `FullDuplex` and blocking - /// SPI traits. - /// - /// This type is generic over any valid pad mapping where there is - /// a defined "data in pin out data out pin out" implementation. - pub struct $Type { - padout: Padout<$Sercom, MISO, MOSI, SCK>, - sercom: $SERCOM, - } - - #[allow(deprecated)] - impl CommonSpi for $Type { - /// Helper for accessing the spi member of the sercom instance - fn spi(&self) -> &SPI { - &self.sercom.spi() - } - - /// Helper for accessing the spi member of the sercom instance - fn spi_mut(&mut self) -> &SPI { - &self.sercom.spi() - } - } - - #[allow(deprecated)] - impl $Type { - /// Power on and configure SERCOMX to work as an SPI Master operating - /// with the specified frequency and SPI Mode. The padout specifies - /// which pins are bound to the MISO, MOSI, SCK functions. - /// - /// You can use a tuple of three SercomXPadY instances for which - /// there exists a From implementation for SPIMasterXPadout. - pub fn new, T: Into>>( - clock: &clock::$clock, - freq: F, - mode: Mode, - sercom: $SERCOM, - pm: &mut PM, - padout: T, - ) -> Self - where - Padout<$Sercom, MISO, MOSI, SCK>: DipoDopo, - { - let padout = padout.into(); - - // Power up the peripheral bus clock. - // safe because we're exclusively owning SERCOM - pm.apbcmask.modify(|_, w| w.$powermask().set_bit()); - - // reset the sercom instance - sercom.spi().ctrla.modify(|_, w| w.swrst().set_bit()); - // wait for reset to complete - while sercom.spi().syncbusy.read().swrst().bit_is_set() - || sercom.spi().ctrla.read().swrst().bit_is_set() - {} - - // Put the hardware into spi master mode - sercom.spi().ctrla.modify(|_, w| w.mode().spi_master()); - // wait for configuration to take effect - while sercom.spi().syncbusy.read().enable().bit_is_set() {} - - // 8 bit data size and enable the receiver - unsafe { - sercom.spi().ctrlb.modify(|_, w| { - w.chsize().bits(0); - w.rxen().set_bit() - }); - } - - // set the baud rate - let baud = Self::calculate_baud(freq, clock.freq()); - - unsafe { - sercom.spi().baud.modify(|_, w| w.baud().bits(baud)); - - sercom.spi().ctrla.modify(|_, w| { - match mode.polarity { - Polarity::IdleLow => w.cpol().clear_bit(), - Polarity::IdleHigh => w.cpol().set_bit(), - }; - - match mode.phase { - Phase::CaptureOnFirstTransition => w.cpha().clear_bit(), - Phase::CaptureOnSecondTransition => w.cpha().set_bit(), - }; - - let (dipo, dopo) = padout.dipo_dopo(); - w.dipo().bits(dipo); - w.dopo().bits(dopo); - - // MSB first - w.dord().clear_bit() - }); - } - - sercom.spi().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for configuration to take effect - while sercom.spi().syncbusy.read().enable().bit_is_set() {} - - Self { padout, sercom } - } - - /// Set the baud rate - pub fn set_baud>(&mut self, freq: F, clock: &clock::$clock) { - self.disable(); - let baud = Self::calculate_baud(freq, clock.freq()); - unsafe { - self.spi_mut().baud.modify(|_, w| w.baud().bits(baud)); - } - self.enable(); - } - - /// Tear down the SPI instance and yield the constituent pins and - /// SERCOM instance. No explicit de-initialization is performed. - pub fn free(self) -> (Padout<$Sercom, MISO, MOSI, SCK>, $SERCOM) { - (self.padout, self.sercom) - } - } - - #[allow(deprecated)] - impl FullDuplex for $Type { - type Error = Error; - - fn read(&mut self) -> nb::Result { - let status = self.spi().status.read(); - if status.bufovf().bit_is_set() { - return Err(nb::Error::Other(Error::Overrun)); - } - - let intflag = self.spi().intflag.read(); - // rxc is receive complete - if intflag.rxc().bit_is_set() { - Ok(self.spi().data.read().data().bits() as u8) - } else { - Err(nb::Error::WouldBlock) - } - } - - fn send(&mut self, byte: u8) -> nb::Result<(), Error> { - let intflag = self.spi().intflag.read(); - // dre is data register empty - if intflag.dre().bit_is_set() { - self.spi_mut() - .data - .write(|w| unsafe { w.data().bits(byte as u16) }); - Ok(()) - } else { - Err(nb::Error::WouldBlock) - } - } - } - - impl ::embedded_hal::blocking::spi::transfer::Default - for $Type - { - } - impl ::embedded_hal::blocking::spi::write::Default - for $Type - { - } - #[cfg(feature = "unproven")] - impl ::embedded_hal::blocking::spi::write_iter::Default - for $Type - { - } - }; -} - -spi_master!(SPIMaster0: (Sercom0, SERCOM0, sercom0_, Sercom0CoreClock)); -spi_master!(SPIMaster1: (Sercom1, SERCOM1, sercom1_, Sercom1CoreClock)); -#[cfg(feature = "samd21")] -spi_master!(SPIMaster2: (Sercom2, SERCOM2, sercom2_, Sercom2CoreClock)); -#[cfg(feature = "samd21")] -spi_master!(SPIMaster3: (Sercom3, SERCOM3, sercom3_, Sercom3CoreClock)); -#[cfg(feature = "min-samd21g")] -spi_master!(SPIMaster4: (Sercom4, SERCOM4, sercom4_, Sercom4CoreClock)); -#[cfg(feature = "min-samd21g")] -spi_master!(SPIMaster5: (Sercom5, SERCOM5, sercom5_, Sercom5CoreClock)); diff --git a/hal/src/thumbv6m/sercom/v1/uart.rs b/hal/src/thumbv6m/sercom/v1/uart.rs deleted file mode 100644 index 4ff944cae503..000000000000 --- a/hal/src/thumbv6m/sercom/v1/uart.rs +++ /dev/null @@ -1,517 +0,0 @@ -#![deprecated( - since = "0.13.0", - note = "The `sercom::v1::uart` module is deprecated, and will be removed in a subsequent release. - Please use the `sercom::v2::uart` module instead." -)] - -use crate::clock; -use crate::hal::blocking::serial::{write::Default, Write}; -use crate::hal::serial; -use crate::pac::sercom0::USART; -use crate::pac::{PM, SERCOM0, SERCOM1}; -#[cfg(feature = "samd21")] -use crate::pac::{SERCOM2, SERCOM3}; -#[cfg(feature = "min-samd21g")] -use crate::pac::{SERCOM4, SERCOM5}; -use crate::sercom::v1::pads::CompatiblePad; -use crate::sercom::v2::*; -use crate::time::Hertz; -use core::fmt; -use core::marker::PhantomData; - -/// The RxpoTxpo trait defines a way to get the data in and data out pin out -/// values for a given UARTXPadout configuration. You should not implement -/// this trait for yourself; only the implementations in the sercom module make -/// sense. -pub trait RxpoTxpo { - const RXPO: u8; - const TXPO: u8; - fn rxpo_txpo(&self) -> (u8, u8) { - (Self::RXPO, Self::TXPO) - } -} - -macro_rules! padout { - ( ($rxpo:literal, $txpo:literal) => $pad0:ident, $pad1:ident) => { - impl RxpoTxpo for ($pad0, $pad1) { - const RXPO: u8 = $rxpo; - const TXPO: u8 = $txpo; - } - }; - ( ($rxpo:literal, $txpo:literal) => $pad0:ident, $pad1:ident, $pad2:ident, $pad3:ident) => { - impl RxpoTxpo for ($pad0, $pad1, $pad2, $pad3) { - const RXPO: u8 = $rxpo; - const TXPO: u8 = $txpo; - } - }; -} - -padout!((0, 1) => Pad0, Pad2); - -padout!((1, 0) => Pad1, Pad0); -padout!((1, 2) => Pad1, Pad0, Pad2, Pad3); -padout!((1, 1) => Pad1, Pad2); - -padout!((2, 0) => Pad2, Pad0); - -padout!((3, 0) => Pad3, Pad0); -padout!((3, 1) => Pad3, Pad2); - -/// A pad mapping configuration for the SERCOM in UART mode. -/// -/// This type can only be constructed using the From implementations -/// in this module, which are restricted to valid configurations. -/// -/// Defines which sercom pad is mapped to which UART function. -pub struct Padout -where - S: Sercom, -{ - sercom: PhantomData, - rx: RX, - tx: TX, - rts: RTS, - cts: CTS, -} - -/// A pad mapping configuration for the receiving half of the SERCOM in UART -/// mode. -pub struct RxPadout -where - S: Sercom, -{ - sercom: PhantomData, - rx: RX, - cts: CTS, -} - -/// A pad mapping configuration for the transmitting half of the SERCOM in UART -/// mode. -pub struct TxPadout -where - S: Sercom, -{ - sercom: PhantomData, - tx: TX, - rts: RTS, -} - -impl Padout -where - S: Sercom, -{ - /// Splits the padout into transmit and receive halves - pub fn split(self) -> (TxPadout, RxPadout) { - ( - TxPadout { - sercom: PhantomData, - tx: self.tx, - rts: self.rts, - }, - RxPadout { - sercom: PhantomData, - rx: self.rx, - cts: self.cts, - }, - ) - } - - /// Combines transmit and receive halves back into a duplex padout - pub fn join(tx: TxPadout, rx: RxPadout) -> Self { - Self { - sercom: PhantomData, - rx: rx.rx, - tx: tx.tx, - rts: tx.rts, - cts: rx.cts, - } - } -} - -/// Convert from a tuple of (RX, TX) to UARTXPadout -impl From<(PAD0, PAD1)> for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum): RxpoTxpo, -{ - fn from(pads: (PAD0, PAD1)) -> Padout { - Padout { - sercom: PhantomData, - rx: pads.0, - tx: pads.1, - rts: (), - cts: (), - } - } -} - -impl RxpoTxpo for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum): RxpoTxpo, -{ - const RXPO: u8 = <(PAD0::PadNum, PAD1::PadNum)>::RXPO; - const TXPO: u8 = <(PAD0::PadNum, PAD1::PadNum)>::TXPO; -} - -/// Convert from a tuple of (RX, TX, RTS, CTS) to UARTXPadout -impl From<(PAD0, PAD1, PAD2, PAD3)> for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - PAD3: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum): RxpoTxpo, -{ - fn from(pads: (PAD0, PAD1, PAD2, PAD3)) -> Padout { - Padout { - sercom: PhantomData, - rx: pads.0, - tx: pads.1, - rts: pads.2, - cts: pads.3, - } - } -} - -impl RxpoTxpo for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - PAD3: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum): RxpoTxpo, -{ - const RXPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum)>::RXPO; - const TXPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum)>::TXPO; -} - -/// Define a UARTX type for the given Sercom. -/// -/// Also defines the valid "pad to uart function" mappings for this instance so -/// that construction is restricted to valid configurations. -macro_rules! uart { - ($Type:ident: ($Sercom:ident, $SERCOM:ident, $powermask:ident, $clock:ident)) => { - $crate::paste::item! { - pub type [<$Type Padout>] = Padout<$Sercom, RX, TX, RTS, CTS>; - pub type [<$Type TxPadout>] = TxPadout<$Sercom, TX, RTS>; - pub type [<$Type RxPadout>] = RxPadout<$Sercom, RX, CTS>; - } - - $crate::paste::item! { - /// UARTX represents the corresponding SERCOMX instance - /// configured to act in the role of a UART Master. - /// Objects of this type implement the HAL `serial::Read`, - /// `serial::Write` traits. - /// - /// This type is generic over any valid pad mapping where there is - /// a defined "receive pin out transmit pin out" implementation. - pub struct $Type { - padout: Padout<$Sercom, RX, TX, RTS, CTS>, - sercom: $SERCOM, - } - - impl $Type { - /// Power on and configure SERCOMX to work as a UART Master operating - /// with the specified frequency. The padout specifies - /// which pins are bound to the RX, TX and optionally RTS and CTS - /// functions. - /// - /// You can use any tuple of two or four SercomXPadY instances - /// for which there exists a From implementation for - /// UARTXPadout. - pub fn new, T: Into>>( - clock: &clock::$clock, - freq: F, - sercom: $SERCOM, - pm: &mut PM, - padout: T - ) -> $Type where - Padout<$Sercom, RX, TX, RTS, CTS>: RxpoTxpo { - let padout = padout.into(); - - pm.apbcmask.modify(|_, w| w.$powermask().set_bit()); - - // Lots of union fields which require unsafe access - unsafe { - // Reset - sercom.usart().ctrla.modify(|_, w| w.swrst().set_bit()); - while sercom.usart().syncbusy.read().swrst().bit_is_set() - || sercom.usart().ctrla.read().swrst().bit_is_set() { - // wait for sync of CTRLA.SWRST - } - - // Unsafe b/c of direct call to bits on rxpo/txpo - sercom.usart().ctrla.modify(|_, w| { - w.dord().set_bit(); - - let (rxpo, txpo) = padout.rxpo_txpo(); - w.rxpo().bits(rxpo); - w.txpo().bits(txpo); - - w.form().bits(0x00); - w.sampr().bits(0x00); // 16x oversample fractional - w.runstdby().set_bit(); // Run in standby - w.form().bits(0); // 0 is no parity bits - - w.mode().usart_int_clk() // Internal clock mode - }); - - // Calculate value for BAUD register - let sample_rate: u8 = 16; - let fref = clock.freq().0; - - // TODO: Support fractional BAUD mode - // let mul_ratio = (fref.0 * 1000) / (freq.into().0 * 16); - // - // let baud = mul_ratio / 1000; - // let fp = ((mul_ratio - (baud*1000))*8)/1000; - // - // sercom.usart().baud()_frac_mode.modify(|_, w| { - // w.baud().bits(baud as u16); - // w.fp().bits(fp as u8) - // }); - - // Asynchronous arithmetic mode (Table 24-2 in datasheet) - let baud = calculate_baud_value(freq.into().0, fref, sample_rate); - - sercom.usart().baud().modify(|_, w| { - w.baud().bits(baud) - }); - - sercom.usart().ctrlb.modify(|_, w| { - w.sbmode().clear_bit(); // 0 is one stop bit see sec 25.8.2 - w.chsize().bits(0x0); - w.txen().set_bit(); - w.rxen().set_bit() - }); - - while sercom.usart().syncbusy.read().ctrlb().bit_is_set() {} - - sercom.usart().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for sync of ENABLE - while sercom.usart().syncbusy.read().enable().bit_is_set() {} - } - - Self { - padout, - sercom, - } - } - - pub fn free(self) -> (Padout<$Sercom, RX, TX, RTS, CTS>, $SERCOM) { - (self.padout, self.sercom) - } - - /// Splits the UART into transmit and receive halves - pub fn split(self) -> ([<$Type Tx>], [<$Type Rx>]) { - let (tx_pads, rx_pads) = self.padout.split(); - ( - [<$Type Tx>] { - padout: tx_pads, - sercom: self.sercom, - }, - [<$Type Rx>] { - padout: rx_pads, - sercom: PhantomData, - }, - ) - } - - /// Combines transmit and receive halves back into a duplex UART - pub fn join(tx: [<$Type Tx>], rx: [<$Type Rx>]) -> Self { - Self { - padout: [<$Type Padout>]::join(tx.padout, rx.padout), - sercom: tx.sercom, - } - } - - /// # Safety - /// - /// Only this struct instance should be able to access TX-related fields on this SERCOM. - unsafe fn usart(&self) -> &USART { - return &self.sercom.usart(); - } - - pub fn intenset(&mut self, f: F) - where F: FnOnce(&mut crate::pac::sercom0::usart::intenset::W) - { - unsafe { - self.usart().intenset.write(|w| { - f(w); - w - }); - } - } - - pub fn intenclr(&mut self, f: F) - where F: FnOnce(&mut crate::pac::sercom0::usart::intenclr::W) - { - unsafe { - self.usart().intenclr.write(|w| { - f(w); - w - }); - } - } - - pub fn flags(&self) -> crate::pac::sercom0::usart::status::R { - unsafe { - self.usart().status.read() - } - } - } - - /// The transmitting half of the corresponding UARTX instance (as returned by `UARTX::split`) - pub struct [<$Type Tx>] { - padout: TxPadout<$Sercom, TX, RTS>, - /// We store the SERCOM object here so we can retrieve it later, - /// but conceptually, ownership is shared between the Rx and Tx halves. - sercom: $SERCOM, - } - - impl [<$Type Tx>] { - /// # Safety - /// - /// Only this struct instance should be able to access TX-related fields on this SERCOM. - unsafe fn usart(&self) -> &USART { - return &self.sercom.usart(); - } - - fn do_write(usart: &USART, word: u8) -> nb::Result<(), ()> { - unsafe { - if !usart.intflag.read().dre().bit_is_set() { - return Err(nb::Error::WouldBlock); - } - - usart.data.write(|w| { - w.bits(word as u16) - }); - } - - Ok(()) - } - - fn do_flush(usart: &USART) -> nb::Result<(), ()> { - // simply await DRE empty - if !usart.intflag.read().dre().bit_is_set() { - return Err(nb::Error::WouldBlock); - } - - Ok(()) - } - } - - impl serial::Write for [<$Type Tx>] { - type Error = (); - - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { - Self::do_write(unsafe { self.usart() }, word) - } - - fn flush(&mut self) -> nb::Result<(), Self::Error> { - Self::do_flush(unsafe { self.usart() }) - } - } - - impl serial::Write for $Type { - type Error = (); - - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { - [<$Type Tx>]::::do_write(unsafe { self.usart() }, word) - } - - fn flush(&mut self) -> nb::Result<(), Self::Error> { - [<$Type Tx>]::::do_flush(unsafe { self.usart() }) - } - } - - /// The receiving half of the corresponding UARTX instance (as returned by `UARTX::split`) - pub struct [<$Type Rx>] { - padout: RxPadout<$Sercom, RX, CTS>, - sercom: PhantomData<$SERCOM>, - } - - impl [<$Type Rx>] { - /// # Safety - /// - /// Only this struct instance should be able to access RX-related fields on this SERCOM. - unsafe fn usart(&self) -> &USART { - (*$SERCOM::ptr()).usart() - } - - fn do_read(usart: &USART) -> nb::Result { - let has_data = usart.intflag.read().rxc().bit_is_set(); - - if !has_data { - return Err(nb::Error::WouldBlock); - } - - let data = usart.data.read().bits(); - - Ok(data as u8) - } - } - - impl serial::Read for [<$Type Rx>] { - type Error = (); - - fn read(&mut self) -> nb::Result { - Self::do_read(unsafe { self.usart() }) - } - } - - impl serial::Read for $Type { - type Error = (); - - fn read(&mut self) -> nb::Result { - [<$Type Rx>]::::do_read(self.sercom.usart()) - } - } - - impl Default for [<$Type Tx>] {} - - impl Default for $Type {} - - impl fmt::Write for [<$Type Tx>] { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.bwrite_all(s.as_bytes()).map_err(|_| fmt::Error) - } - } - - impl fmt::Write for $Type { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.bwrite_all(s.as_bytes()).map_err(|_| fmt::Error) - } - } - } - }; -} - -uart!(UART0: (Sercom0, SERCOM0, sercom0_, Sercom0CoreClock)); -uart!(UART1: (Sercom1, SERCOM1, sercom1_, Sercom1CoreClock)); -#[cfg(feature = "samd21")] -uart!(UART2: (Sercom2, SERCOM2, sercom2_, Sercom2CoreClock)); -#[cfg(feature = "samd21")] -uart!(UART3: (Sercom3, SERCOM3, sercom3_, Sercom3CoreClock)); -#[cfg(feature = "min-samd21g")] -uart!(UART4: (Sercom4, SERCOM4, sercom4_, Sercom4CoreClock)); -#[cfg(feature = "min-samd21g")] -uart!(UART5: (Sercom5, SERCOM5, sercom5_, Sercom5CoreClock)); - -const SHIFT: u8 = 32; - -fn calculate_baud_value(baudrate: u32, clk_freq: u32, n_samples: u8) -> u16 { - let sample_rate = (n_samples as u64 * baudrate as u64) << 32; - let ratio = sample_rate / clk_freq as u64; - let scale = (1u64 << SHIFT) - ratio; - let baud_calculated = (65536u64 * scale) >> SHIFT; - - baud_calculated as u16 -} diff --git a/hal/src/thumbv6m/timer.rs b/hal/src/thumbv6m/timer.rs index e835fb21da6a..eeb324490e86 100644 --- a/hal/src/thumbv6m/timer.rs +++ b/hal/src/thumbv6m/timer.rs @@ -17,8 +17,6 @@ use crate::time::{Hertz, Nanoseconds}; use crate::timer_traits::InterruptDrivenTimer; use void::Void; -use cortex_m::asm::delay as cycle_delay; - // Note: // TC3 + TC4 can be paired to make a 32-bit counter // TC5 + TC6 can be paired to make a 32-bit counter @@ -187,39 +185,3 @@ tc! { TimerCounter4: (TC4, tc4_, Tc4Tc5Clock), TimerCounter5: (TC5, tc5_, Tc4Tc5Clock), } - -#[deprecated( - since = "0.13.0", - note = "`SpinTimer` is deprecated, and will be removed in a subsequent release." -)] -#[derive(Clone, Copy)] -pub struct SpinTimer { - cycles: u32, -} - -#[allow(deprecated)] -impl SpinTimer { - pub fn new(cycles: u32) -> SpinTimer { - SpinTimer { cycles } - } -} - -#[allow(deprecated)] -impl Periodic for SpinTimer {} - -#[allow(deprecated)] -impl CountDown for SpinTimer { - type Time = u32; - - fn start(&mut self, cycles: T) - where - T: Into, - { - self.cycles = cycles.into(); - } - - fn wait(&mut self) -> nb::Result<(), void::Void> { - cycle_delay(self.cycles); - Ok(()) - } -} diff --git a/hal/src/thumbv6m/usb/bus.rs b/hal/src/thumbv6m/usb/bus.rs index cd2cbc99eb67..584870193161 100644 --- a/hal/src/thumbv6m/usb/bus.rs +++ b/hal/src/thumbv6m/usb/bus.rs @@ -8,7 +8,7 @@ use super::Descriptors; use crate::calibration::{usb_transn_cal, usb_transp_cal, usb_trim_cal}; use crate::clock; -use crate::gpio::v2::{AlternateG, AnyPin, Pin, PA24, PA25}; +use crate::gpio::{AlternateG, AnyPin, Pin, PA24, PA25}; use crate::pac; use crate::pac::usb::DEVICE; use crate::pac::{PM, USB}; diff --git a/hal/src/thumbv6m/usb/mod.rs b/hal/src/thumbv6m/usb/mod.rs index fb051aae34c7..73fd05566fe4 100644 --- a/hal/src/thumbv6m/usb/mod.rs +++ b/hal/src/thumbv6m/usb/mod.rs @@ -1,6 +1,9 @@ //! USB Device support -use crate::gpio; +use crate::gpio::{ + pin::{Pin, PA23, PA24, PA25}, + AlternateG, +}; pub use usb_device; @@ -11,10 +14,10 @@ mod devicedesc; use self::devicedesc::Descriptors; /// Emit SOF at 1Khz on this pin when configured as function G -pub type SofPad = gpio::Pa23; +pub type SofPad = Pin; /// USB D- is connected here -pub type DmPad = gpio::Pa24; +pub type DmPad = Pin; /// USB D+ is connected here -pub type DpPad = gpio::Pa25; +pub type DpPad = Pin; diff --git a/hal/src/thumbv7em/adc.rs b/hal/src/thumbv7em/adc.rs index 511cfac6e55d..e8b8a3d6de7d 100644 --- a/hal/src/thumbv7em/adc.rs +++ b/hal/src/thumbv7em/adc.rs @@ -1,10 +1,8 @@ //! Analogue-to-Digital Conversion use crate::clock::GenericClockController; #[rustfmt::skip] -#[allow(deprecated)] -use crate::gpio::v1; -use crate::gpio::v2::*; -use crate::hal::adc::{Channel, OneShot}; +use crate::gpio::*; +use crate::ehal::adc::{Channel, OneShot}; use crate::pac::gclk::genctrl::SRC_A::DFLL; use crate::pac::gclk::pchctrl::GEN_A; use crate::pac::{adc0, ADC0, ADC1, MCLK}; @@ -287,20 +285,6 @@ macro_rules! adc_pins { } } -/// Implement [`Channel`] for [`v1::Pin`]s based on the implementations for -/// `v2` [`Pin`]s -#[allow(deprecated)] -impl Channel for v1::Pin -where - I: PinId, - Pin: Channel, -{ - type ID = u8; - fn channel() -> u8 { - Pin::::channel() - } -} - adc_pins! { PA02: (ADC0, 0), PA03: (ADC0, 1), diff --git a/hal/src/thumbv7em/dsu.rs b/hal/src/thumbv7em/dsu.rs index 43f4ee5b1f75..c0f685360c84 100644 --- a/hal/src/thumbv7em/dsu.rs +++ b/hal/src/thumbv7em/dsu.rs @@ -5,7 +5,7 @@ //! - Run a CRC32 checksum over memory #![warn(missing_docs)] -use crate::target_device::{DSU, PAC}; +use crate::pac::{DSU, PAC}; /// Device Service Unit pub struct Dsu { diff --git a/hal/src/thumbv7em/eic/pin.rs b/hal/src/thumbv7em/eic/pin.rs index 2a8965310c16..5a433d21996e 100644 --- a/hal/src/thumbv7em/eic/pin.rs +++ b/hal/src/thumbv7em/eic/pin.rs @@ -1,8 +1,5 @@ -#![allow(deprecated)] - use crate::gpio::{ - self, v2::AnyPin, v2::FloatingInterrupt, v2::Pin, v2::PinId, v2::PinMode, - v2::PullDownInterrupt, v2::PullUpInterrupt, Port, + self, pin::*, AnyPin, FloatingInterrupt, PinId, PinMode, PullDownInterrupt, PullUpInterrupt, }; use crate::pac; @@ -17,13 +14,13 @@ pub trait EicPin { type PullDown; /// Configure a pin as a floating external interrupt - fn into_floating_ei(self, port: &mut Port) -> Self::Floating; + fn into_floating_ei(self) -> Self::Floating; /// Configure a pin as pulled-up external interrupt - fn into_pull_up_ei(self, port: &mut Port) -> Self::PullUp; + fn into_pull_up_ei(self) -> Self::PullUp; /// Configure a pin as pulled-down external interrupt - fn into_pull_down_ei(self, port: &mut Port) -> Self::PullDown; + fn into_pull_down_ei(self) -> Self::PullDown; } pub type Sense = pac::eic::config::SENSE0_A; @@ -151,26 +148,26 @@ crate::paste::item! { $( $(#[$attr])* - impl EicPin for gpio::$PinType { - type Floating = [<$PadType $num>]>; - type PullUp = [<$PadType $num>]>; - type PullDown = [<$PadType $num>]>; + impl EicPin for Pin { + type Floating = [<$PadType $num>]>; + type PullUp = [<$PadType $num>]>; + type PullDown = [<$PadType $num>]>; - fn into_floating_ei(self, port: &mut Port) -> Self::Floating { - [<$PadType $num>]::new(self.into_floating_interrupt(port)) + fn into_floating_ei(self) -> Self::Floating { + [<$PadType $num>]::new(self.into_floating_interrupt()) } - fn into_pull_up_ei(self, port: &mut Port) -> Self::PullUp { - [<$PadType $num>]::new(self.into_pull_up_interrupt(port)) + fn into_pull_up_ei(self) -> Self::PullUp { + [<$PadType $num>]::new(self.into_pull_up_interrupt()) } - fn into_pull_down_ei(self, port: &mut Port) -> Self::PullDown { - [<$PadType $num>]::new(self.into_pull_down_interrupt(port)) + fn into_pull_down_ei(self) -> Self::PullDown { + [<$PadType $num>]::new(self.into_pull_down_interrupt()) } } $(#[$attr])* - impl ExternalInterrupt for gpio::$PinType { + impl ExternalInterrupt for gpio::$PinType { fn id(&self) -> ExternalInterruptID { $num } @@ -193,209 +190,209 @@ where } ei!(ExtInt[0] { - Pa0, - Pa16, + PA00, + PA16, #[cfg(feature = "min-samd51j")] - Pb0, + PB00, #[cfg(feature = "min-samd51j")] - Pb16, + PB16, #[cfg(feature = "min-samd51n")] - Pc0, + PC00, #[cfg(feature = "min-samd51n")] - Pc16, + PC16, #[cfg(feature = "min-samd51p")] - Pd0, + PD00, }); ei!(ExtInt[1] { - Pa1, - Pa17, + PA01, + PA17, #[cfg(feature = "min-samd51j")] - Pb1, + PB01, #[cfg(feature = "min-samd51j")] - Pb17, + PB17, #[cfg(feature = "min-samd51n")] - Pc1, + PC01, #[cfg(feature = "min-samd51n")] - Pc17, + PC17, #[cfg(feature = "min-samd51p")] - Pd1, + PD01, }); ei!(ExtInt[2] { - Pa2, - Pa18, - Pb2, + PA02, + PA18, + PB02, #[cfg(feature = "min-samd51n")] - Pb18, + PB18, #[cfg(feature = "min-samd51n")] - Pc2, + PC02, #[cfg(feature = "min-samd51n")] - Pc18, + PC18, }); ei!(ExtInt[3] { - Pa3, - Pa19, - Pb3, + PA03, + PA19, + PB03, #[cfg(feature = "min-samd51n")] - Pb19, + PB19, #[cfg(feature = "min-samd51n")] - Pc3, + PC03, #[cfg(feature = "min-samd51n")] - Pc19, + PC19, #[cfg(feature = "min-samd51p")] - Pd8, + PD08, }); ei!(ExtInt[4] { - Pa4, - Pa20, + PA04, + PA20, #[cfg(feature = "min-samd51j")] - Pb4, + PB04, #[cfg(feature = "min-samd51n")] - Pb20, + PB20, #[cfg(feature = "min-samd51p")] - Pc4, + PC04, #[cfg(feature = "min-samd51n")] - Pc20, + PC20, #[cfg(feature = "min-samd51p")] - Pd9, + PD09, }); ei!(ExtInt[5] { - Pa5, - Pa21, + PA05, + PA21, #[cfg(feature = "min-samd51j")] - Pb5, + PB05, #[cfg(feature = "min-samd51n")] - Pb21, + PB21, #[cfg(feature = "min-samd51n")] - Pc5, + PC05, #[cfg(feature = "min-samd51n")] - Pc21, + PC21, #[cfg(feature = "min-samd51p")] - Pd10, + PD10, }); ei!(ExtInt[6] { - Pa6, - Pa22, + PA06, + PA22, #[cfg(feature = "min-samd51j")] - Pb6, - Pb22, + PB06, + PB22, #[cfg(feature = "min-samd51n")] - Pc6, + PC06, #[cfg(feature = "min-samd51p")] - Pc22, + PC22, #[cfg(feature = "min-samd51p")] - Pd11, + PD11, }); ei!(ExtInt[7] { - Pa7, - Pa23, + PA07, + PA23, #[cfg(feature = "min-samd51j")] - Pb7, - Pb23, + PB07, + PB23, #[cfg(feature = "min-samd51p")] - Pc23, + PC23, #[cfg(feature = "min-samd51p")] - Pd12, + PD12, }); ei!(ExtInt[8] { - Pa24, - Pb8, + PA24, + PB08, #[cfg(feature = "min-samd51n")] - Pb24, + PB24, #[cfg(feature = "min-samd51n")] - Pc24, + PC24, }); ei!(ExtInt[9] { - Pa9, - Pa25, - Pb9, + PA09, + PA25, + PB09, #[cfg(feature = "min-samd51n")] - Pb25, + PB25, #[cfg(feature = "min-samd51n")] - Pc7, + PC07, #[cfg(feature = "min-samd51n")] - Pc25, + PC25, }); ei!(ExtInt[10] { - Pa10, - Pb10, + PA10, + PB10, #[cfg(feature = "min-samd51n")] - Pc10, + PC10, #[cfg(feature = "min-samd51n")] - Pc26, + PC26, #[cfg(feature = "min-samd51p")] - Pd20, + PD20, }); ei!(ExtInt[11] { - Pa11, - Pa27, - Pb11, + PA11, + PA27, + PB11, #[cfg(feature = "min-samd51n")] - Pc11, + PC11, #[cfg(feature = "min-samd51n")] - Pc27, + PC27, #[cfg(feature = "min-samd51p")] - Pd21, + PD21, }); ei!(ExtInt[12] { - Pa12, + PA12, #[cfg(feature = "min-samd51j")] - Pb12, + PB12, #[cfg(feature = "min-samd51p")] - Pb26, + PB26, #[cfg(feature = "min-samd51n")] - Pc12, + PC12, #[cfg(feature = "min-samd51n")] - Pc28, + PC28, }); ei!(ExtInt[13] { - Pa13, + PA13, #[cfg(feature = "min-samd51j")] - Pb13, + PB13, #[cfg(feature = "min-samd51p")] - Pb27, + PB27, #[cfg(feature = "min-samd51n")] - Pc13, + PC13, }); ei!(ExtInt[14] { - Pa14, - Pa30, + PA14, + PA30, #[cfg(feature = "min-samd51j")] - Pb14, + PB14, #[cfg(feature = "min-samd51p")] - Pb28, + PB28, #[cfg(feature = "min-samd51j")] - Pb30, + PB30, #[cfg(feature = "min-samd51n")] - Pc14, + PC14, #[cfg(feature = "min-samd51p")] - Pc30, + PC30, }); ei!(ExtInt[15] { - Pa15, - Pa31, + PA15, + PA31, #[cfg(feature = "min-samd51j")] - Pb15, + PB15, #[cfg(feature = "min-samd51p")] - Pb29, + PB29, #[cfg(feature = "min-samd51j")] - Pb31, + PB31, #[cfg(feature = "min-samd51n")] - Pc15, + PC15, #[cfg(feature = "min-samd51p")] - Pc31, + PC31, }); diff --git a/hal/src/thumbv7em/mod.rs b/hal/src/thumbv7em/mod.rs index 82da4a008590..1156e3a95415 100644 --- a/hal/src/thumbv7em/mod.rs +++ b/hal/src/thumbv7em/mod.rs @@ -3,7 +3,6 @@ pub mod clock; pub mod eic; pub mod pukcc; pub mod qspi; -pub(crate) mod sercom; pub mod timer; pub mod trng; diff --git a/hal/src/thumbv7em/nvm.rs b/hal/src/thumbv7em/nvm.rs index 31ce05394979..83b5a783e9b0 100644 --- a/hal/src/thumbv7em/nvm.rs +++ b/hal/src/thumbv7em/nvm.rs @@ -22,9 +22,9 @@ pub mod smart_eeprom; -pub use crate::target_device::nvmctrl::ctrla::PRM_A; -use crate::target_device::nvmctrl::ctrlb::CMD_AW; -use crate::target_device::NVMCTRL; +pub use crate::pac::nvmctrl::ctrla::PRM_A; +use crate::pac::nvmctrl::ctrlb::CMD_AW; +use crate::pac::NVMCTRL; use core::num::NonZeroU32; use core::ops::Range; diff --git a/hal/src/thumbv7em/pwm.rs b/hal/src/thumbv7em/pwm.rs index 4faeb0b26df5..b3e71076cd0b 100644 --- a/hal/src/thumbv7em/pwm.rs +++ b/hal/src/thumbv7em/pwm.rs @@ -1,9 +1,9 @@ #![allow(non_snake_case)] use crate::clock; -use crate::gpio::v2::{AlternateE, AnyPin, Pin}; +use crate::ehal::{Pwm, PwmPin}; use crate::gpio::*; -use crate::hal::{Pwm, PwmPin}; +use crate::gpio::{AlternateE, AnyPin, Pin}; use crate::time::Hertz; use crate::timer_params::TimerParams; @@ -19,13 +19,13 @@ use crate::pac::{TC6, TC7}; /// /// The previous Pinout types were enums that took specific v1::Pin types. As a /// result, there was no way to make that implementation simultaneously -/// compatible with both v1::Pin and v2::Pin. +/// compatible with both v1::Pin and Pin. /// /// BUT, the enum variant syntax is the same as the namespaced function syntax. /// I converted the enums to structs, and I created constructor methods with the /// same names as the previous enum variants. By constructing Pinout types with /// functions rather than enum variants, you can make it generic over v1::Pin -/// and v2::Pin types. +/// and Pin types. /// /// This is (mostly) backwards compatible with the current syntax, and all the /// existing calls compile. The only incompatible change is the requirement of @@ -46,9 +46,9 @@ macro_rules! impl_tc_pinout { $( $( #[$attr] )? - impl $Type { + impl $Type<$Id> { #[inline] - pub fn $func(pin: impl AnyPin) -> Self { + pub fn $func(pin: impl AnyPin) -> Self { let _pin = pin.into().into_alternate(); Self { _pin } } @@ -237,13 +237,13 @@ pub enum Channel { /// /// The previous Pinout types were enums that took specific v1::Pin types. As a /// result, there was no way to make that implementation simultaneously -/// compatible with both v1::Pin and v2::Pin. +/// compatible with both v1::Pin and Pin. /// /// BUT, the enum variant syntax is the same as the namespaced function syntax. /// I converted the enums to structs, and I created constructor methods with the /// same names as the previous enum variants. By constructing Pinout types with /// functions rather than enum variants, you can make it generic over v1::Pin -/// and v2::Pin types. +/// and Pin types. /// /// This is (mostly) backwards compatible with the current syntax, and all the /// existing calls compile. The only incompatible change is the requirement of @@ -264,9 +264,9 @@ macro_rules! impl_tcc_pinout { $( $( #[$attr] )? - impl $Type { + impl $Type<$Id, $Mode> { #[inline] - pub fn $func(pin: impl AnyPin) -> Self { + pub fn $func(pin: impl AnyPin) -> Self { let _pin = pin.into().into_alternate(); Self { _pin } } diff --git a/hal/src/thumbv7em/qspi.rs b/hal/src/thumbv7em/qspi.rs index 6c831bc4ecd7..c65c428f90d9 100644 --- a/hal/src/thumbv7em/qspi.rs +++ b/hal/src/thumbv7em/qspi.rs @@ -1,5 +1,5 @@ use crate::{ - gpio::v2::{AlternateH, AnyPin, Pin, PA08, PA09, PA10, PA11, PB10, PB11}, + gpio::{AlternateH, AnyPin, Pin, PA08, PA09, PA10, PA11, PB10, PB11}, pac::qspi::instrframe, pac::{MCLK, QSPI}, }; diff --git a/hal/src/thumbv7em/sercom/mod.rs b/hal/src/thumbv7em/sercom/mod.rs deleted file mode 100644 index a3a6d96c3f59..000000000000 --- a/hal/src/thumbv7em/sercom/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod v1; diff --git a/hal/src/thumbv7em/sercom/v1.rs b/hal/src/thumbv7em/sercom/v1.rs deleted file mode 100644 index b6306ec7fda0..000000000000 --- a/hal/src/thumbv7em/sercom/v1.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Working with the SERCOM peripherals. -//! -//! The atsamd51/atsame5x hardware has several SERCOM instances that can be -//! configured to perform a variety of serial communication tasks. This -//! configuration is expressed through the use of type states to make it -//! difficult to misuse. Each sercom instance is associated with a group of IO -//! pins referred to as a Pad. When the pins are set to the appropriate -//! peripheral function mode they are routed to the sercom pad. - -pub mod i2c; -pub mod spi; -pub mod uart; - -pub use self::i2c::*; - -#[allow(deprecated)] -pub use self::spi::*; - -#[allow(deprecated)] -pub use self::uart::*; diff --git a/hal/src/thumbv7em/sercom/v1/i2c.rs b/hal/src/thumbv7em/sercom/v1/i2c.rs deleted file mode 100644 index b04b8d518919..000000000000 --- a/hal/src/thumbv7em/sercom/v1/i2c.rs +++ /dev/null @@ -1,427 +0,0 @@ -// Note: section 7.2.3 shows which pins support I2C Hs mode - -use crate::clock; -use crate::hal::blocking::i2c::{Read, Write, WriteRead}; -use crate::pac::sercom0::I2CM; -use crate::pac::{MCLK, SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5}; -#[cfg(feature = "min-samd51n")] -use crate::pac::{SERCOM6, SERCOM7}; -use crate::sercom::v1::pads::CompatiblePad; -use crate::sercom::v2::{Pad0, Pad1}; -use crate::time::Hertz; - -const BUS_STATE_IDLE: u8 = 1; -const BUS_STATE_OWNED: u8 = 2; - -const MASTER_ACT_READ: u8 = 2; -const MASTER_ACT_STOP: u8 = 3; - -/// Define an I2C master type for the given SERCOM and pad pair. -macro_rules! i2c { - ([ - $($Type:ident: - ( - $pad0:ident, // No longer used - $pad1:ident, // No longer used - $SERCOM:ident, - $powermask:ident, - $clock:ident, - $apmask:ident - ), - )+ - ]) => { - - $( - -/// Represents the Sercom instance configured to act as an I2C Master. -/// The embedded_hal blocking I2C traits are implemented by this instance. -pub struct $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - sda: P0, - scl: P1, - sercom: $SERCOM, -} - -impl $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - /// Configures the sercom instance to work as an I2C Master. - /// The clock is obtained via the `GenericClockGenerator` type. - /// `freq` specifies the bus frequency to use for I2C communication. - /// There are typically a handful of values that tend to be supported; - /// standard mode is 100.khz(), full speed mode is 400.khz(). - /// The hardware in the atsamd device supports fast mode at 1.mhz() - /// and fast mode, but there may be additional hardware configuration - /// missing from the current software implementation that prevents that - /// from working as-written today. - /// - /// ```no_run - /// let mut i2c = I2CMaster3::new( - /// &clocks.sercom3_core(&gclk0).unwrap(), - /// 400.khz(), - /// p.device.SERCOM3, - /// &mut p.device.MCLK, - /// // Metro M0 express has I2C on pins PA22, PA23 - /// pins.pa22.into_pad(&mut pins.port), - /// pins.pa23.into_pad(&mut pins.port), - /// ); - /// ``` - pub fn new>( - clock: &clock::$clock, - freq: F, - sercom: $SERCOM, - mclk: &mut MCLK, - sda: P0, - scl: P1, - ) -> Self { - // Power up the peripheral bus clock. - // safe because we're exclusively owning SERCOM - mclk.$apmask.modify(|_, w| w.$powermask().set_bit()); - - unsafe { - // reset the sercom instance - sercom.i2cm().ctrla.modify(|_, w| w.swrst().set_bit()); - // wait for reset to complete - while sercom.i2cm().syncbusy.read().swrst().bit_is_set() - || sercom.i2cm().ctrla.read().swrst().bit_is_set() - {} - - // Put the hardware into i2c master mode - sercom.i2cm().ctrla.modify(|_, w| w.mode().i2c_master()); - // wait for configuration to take effect - while sercom.i2cm().syncbusy.read().enable().bit_is_set() {} - - // set the baud rate - let gclk = clock.freq(); - let baud = (gclk.0 / (2 * freq.into().0) - 1) as u8; - sercom.i2cm().baud.modify(|_, w| w.baud().bits(baud)); - - sercom.i2cm().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for configuration to take effect - while sercom.i2cm().syncbusy.read().enable().bit_is_set() {} - - // set the bus idle - sercom - .i2cm() - .status - .modify(|_, w| w.busstate().bits(BUS_STATE_IDLE)); - // wait for it to take effect - while sercom.i2cm().syncbusy.read().sysop().bit_is_set() {} - } - - Self { sda, scl, sercom } - } - - /// Breaks the sercom device up into its constituent pins and the SERCOM - /// instance. Does not make any changes to power management. - pub fn free(self) -> (P0, P1, $SERCOM) { - (self.sda, self.scl, self.sercom) - } - - fn start_tx_write(&mut self, addr: u8) -> Result<(), I2CError> { - loop { - match self.i2cm().status.read().busstate().bits() { - BUS_STATE_IDLE | BUS_STATE_OWNED => break, - _ => continue, - } - } - - // Signal start and transmit encoded address. - unsafe { - self.i2cm() - .addr - .write(|w| w.addr().bits((addr as u16) << 1)); - } - - // wait for transmission to complete - while !self.i2cm().intflag.read().mb().bit_is_set() {} - - self.status_to_err() - } - - fn status_to_err(&mut self) -> Result<(), I2CError> { - let status = self.i2cm().status.read(); - if status.arblost().bit_is_set() { - return Err(I2CError::ArbitrationLost); - } - if status.buserr().bit_is_set() { - return Err(I2CError::BusError); - } - if status.rxnack().bit_is_set() { - return Err(I2CError::Nack); - } - if status.lowtout().bit_is_set() || status.sexttout().bit_is_set() - || status.mexttout().bit_is_set() - { - return Err(I2CError::Timeout); - } - - Ok(()) - } - - fn start_tx_read(&mut self, addr: u8) -> Result<(), I2CError> { - loop { - match self.i2cm().status.read().busstate().bits() { - BUS_STATE_IDLE | BUS_STATE_OWNED => break, - _ => continue, - } - } - - self.i2cm().intflag.modify(|_, w| w.error().clear_bit()); - - // Signal start (or rep start if appropriate) - // and transmit encoded address. - unsafe { - self.i2cm() - .addr - .write(|w| w.addr().bits(((addr as u16) << 1) | 1)); - } - - // wait for transmission to complete - loop { - let intflag = self.i2cm().intflag.read(); - // If arbitration was lost, it will be signalled via the mb bit - if intflag.mb().bit_is_set() { - return Err(I2CError::ArbitrationLost); - } - if intflag.sb().bit_is_set() || intflag.error().bit_is_set() { - break; - } - } - - self.status_to_err() - } - - fn wait_sync(&mut self) { - while self.i2cm().syncbusy.read().sysop().bit_is_set() {} - } - - fn cmd(&mut self, cmd: u8) { - unsafe { - self.i2cm().ctrlb.modify(|_, w| w.cmd().bits(cmd)); - } - self.wait_sync(); - } - - fn cmd_stop(&mut self) { - self.cmd(MASTER_ACT_STOP) - } - - fn cmd_read(&mut self) { - unsafe { - self.i2cm().ctrlb.modify(|_, w| { - // clear bit means send ack - w.ackact().clear_bit(); - w.cmd().bits(MASTER_ACT_READ) - }); - } - self.wait_sync(); - } - - fn i2cm(&mut self) -> &I2CM { - self.sercom.i2cm() - } - - fn send_bytes(&mut self, bytes: &[u8]) -> Result<(), I2CError> { - for b in bytes { - unsafe { - self.i2cm().data.write(|w| w.bits(*b)); - } - - loop { - let intflag = self.i2cm().intflag.read(); - if intflag.mb().bit_is_set() || intflag.error().bit_is_set() { - break; - } - } - self.status_to_err()?; - } - Ok(()) - } - - fn read_one(&mut self) -> u8 { - while !self.i2cm().intflag.read().sb().bit_is_set() {} - self.i2cm().data.read().bits() as u8 - } - - fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<(), I2CError> { - // Some manual iterator gumph because we need to ack bytes after the first. - let mut iter = buffer.iter_mut(); - *iter.next().expect("buffer len is at least 1") = self.read_one(); - - loop { - match iter.next() { - None => break, - Some(dest) => { - // Ack the last byte so that we can receive another one - self.cmd_read(); - *dest = self.read_one(); - } - } - } - - // arrange to send nack on next command to - // stop slave from transmitting more data - self.i2cm().ctrlb.modify(|_, w| w.ackact().set_bit()); - - Ok(()) - } - - fn do_write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), I2CError> { - self.start_tx_write(addr)?; - self.send_bytes(bytes) - } - - fn do_read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), I2CError> { - self.start_tx_read(addr)?; - self.fill_buffer(buffer) - } - - fn do_write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), I2CError> { - self.start_tx_write(addr)?; - self.send_bytes(bytes)?; - self.start_tx_read(addr)?; - self.fill_buffer(buffer) - } -} - -impl Write for $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - type Error = I2CError; - - /// Sends bytes to slave with address `addr` - fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> { - let res = self.do_write(addr, bytes); - self.cmd_stop(); - res - } -} - -impl Read for $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - type Error = I2CError; - - fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { - let res = self.do_read(addr, buffer); - self.cmd_stop(); - res - } -} - -impl WriteRead for $Type -where - P0: CompatiblePad, - P1: CompatiblePad, -{ - type Error = I2CError; - - fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> { - let res = self.do_write_read(addr, bytes, buffer); - self.cmd_stop(); - res - } -} - - )+ - - }; -} - -i2c!([ - I2CMaster0: - ( - Sercom0Pad0, - Sercom0Pad1, - SERCOM0, - sercom0_, - Sercom0CoreClock, - apbamask - ), - I2CMaster1: - ( - Sercom1Pad0, - Sercom1Pad1, - SERCOM1, - sercom1_, - Sercom1CoreClock, - apbamask - ), - I2CMaster2: - ( - Sercom2Pad0, - Sercom2Pad1, - SERCOM2, - sercom2_, - Sercom2CoreClock, - apbbmask - ), - I2CMaster3: - ( - Sercom3Pad0, - Sercom3Pad1, - SERCOM3, - sercom3_, - Sercom3CoreClock, - apbbmask - ), - I2CMaster4: - ( - Sercom4Pad0, - Sercom4Pad1, - SERCOM4, - sercom4_, - Sercom4CoreClock, - apbdmask - ), - I2CMaster5: - ( - Sercom5Pad0, - Sercom5Pad1, - SERCOM5, - sercom5_, - Sercom5CoreClock, - apbdmask - ), -]); - -#[cfg(feature = "min-samd51n")] -i2c!([ - I2CMaster6: - ( - Sercom6Pad0, - Sercom6Pad1, - SERCOM6, - sercom6_, - Sercom6CoreClock, - apbdmask - ), - I2CMaster7: - ( - Sercom7Pad0, - Sercom7Pad1, - SERCOM7, - sercom7_, - Sercom7CoreClock, - apbdmask - ), -]); - -#[derive(Debug)] -pub enum I2CError { - ArbitrationLost, - AddressError, - BusError, - Timeout, - Nack, -} diff --git a/hal/src/thumbv7em/sercom/v1/spi.rs b/hal/src/thumbv7em/sercom/v1/spi.rs deleted file mode 100644 index 7ad8f0760357..000000000000 --- a/hal/src/thumbv7em/sercom/v1/spi.rs +++ /dev/null @@ -1,293 +0,0 @@ -#![deprecated( - since = "0.13.0", - note = "The `sercom::v1::spi` module is deprecated, and will be removed in a subsequent release. - Please use the `sercom::v2::spi` module instead." -)] - -use core::marker::PhantomData; - -use crate::clock; -use crate::hal::spi::{FullDuplex, Mode, Phase, Polarity}; -use crate::pac::sercom0::SPIM; -use crate::pac::{MCLK, SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5}; -#[cfg(feature = "min-samd51n")] -use crate::pac::{SERCOM6, SERCOM7}; -use crate::sercom::v1::pads::CompatiblePad; -use crate::sercom::v2::*; -#[allow(deprecated)] -use crate::spi_common::CommonSpi; -use crate::time::Hertz; - -#[derive(Debug)] -pub enum Error { - Overrun, -} - -/// The DipoDopo trait defines a way to get the data in and data out pin out -/// values for a given SPIMasterXPadout configuration. You should not implement -/// this trait for yourself; only the implementations in the sercom module make -/// sense. -pub trait DipoDopo { - const DIPO: u8; - const DOPO: u8; - fn dipo_dopo(&self) -> (u8, u8) { - (Self::DIPO, Self::DOPO) - } -} - -/// Defines a DipoDopo instance for the constructed padout instance -/// that returns the values used to configure the sercom pads for the -/// appropriate function in the sercom register file. -macro_rules! padout { - ( ($dipo:literal, $dopo:literal) => $pad0:ident, $pad1:ident, $pad2:ident) => { - impl DipoDopo for ($pad0, $pad1, $pad2) { - const DIPO: u8 = $dipo; - const DOPO: u8 = $dopo; - } - }; -} - -// dipo In master operation, DI is MISO Pad number 0-3 -// dopo 0 MOSI PAD 0 -// dopo 2 MOSI PAD 3 -// SCK can only be on PAD 1 -// (dipo,dopo) => (MISO, MOSI, SCK) -padout!((0, 2) => Pad0, Pad3, Pad1); -padout!((2, 0) => Pad2, Pad0, Pad1); -padout!((2, 2) => Pad2, Pad3, Pad1); -padout!((3, 0) => Pad3, Pad0, Pad1); - -/// A pad mapping configuration for the SERCOM in SPI master mode. -/// -/// This type can only be constructed using the From implementations -/// in this module, which are restricted to valid configurations. -/// -/// Defines which sercom pad is mapped to which SPI function. -pub struct Padout -where - S: Sercom, -{ - sercom: PhantomData, - _miso: MISO, - _mosi: MOSI, - _sclk: SCLK, -} - -/// Convert from a tuple of (MISO, MOSI, SCK) to SPIMasterXPadout -impl From<(PAD0, PAD1, PAD2)> for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum): DipoDopo, -{ - fn from(pads: (PAD0, PAD1, PAD2)) -> Padout { - Padout { - sercom: PhantomData, - _miso: pads.0, - _mosi: pads.1, - _sclk: pads.2, - } - } -} - -impl DipoDopo for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum): DipoDopo, -{ - const DIPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum)>::DIPO; - const DOPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum)>::DOPO; -} - -/// Define an SPIMasterX type for the given Sercom number. -/// -/// Also defines the valid "pad to spi function" mappings for this instance so -/// that construction is restricted to correct configurations. -macro_rules! spi_master { - ( - $Type:ident: ($Sercom:ident, $SERCOM:ident, $powermask:ident, $clock:ident, $apmask:ident) - ) => { - $crate::paste::item! { - pub type [<$Type Padout>] = Padout<$Sercom, MISO, MOSI, SCLK>; - } - - /// SPIMasterX represents the corresponding SERCOMX instance - /// configured to act in the role of an SPI Master. - /// Objects of this type implement the HAL `FullDuplex` and blocking - /// SPI traits. - /// - /// This type is generic over any valid pad mapping where there is - /// a defined "data in pin out data out pin out" implementation. - pub struct $Type { - padout: Padout<$Sercom, MISO, MOSI, SCK>, - sercom: $SERCOM, - } - - #[allow(deprecated)] - impl CommonSpi for $Type { - /// Helper for accessing the spi member of the sercom instance - fn spi(&self) -> &SPIM { - &self.sercom.spim() - } - - /// Helper for accessing the spi member of the sercom instance - fn spi_mut(&mut self) -> &SPIM { - &self.sercom.spim() - } - } - - #[allow(deprecated)] - impl $Type { - /// Power on and configure SERCOMX to work as an SPI Master operating - /// with the specified frequency and SPI Mode. The pinout specifies - /// which pins are bound to the MISO, MOSI, SCK functions. - pub fn new, T: Into>>( - clock: &clock::$clock, - freq: F, - mode: Mode, - sercom: $SERCOM, - mclk: &mut MCLK, - padout: T, - ) -> Self - where - Padout<$Sercom, MISO, MOSI, SCK>: DipoDopo, - { - let padout = padout.into(); - - // Power up the peripheral bus clock. - // safe because we're exclusively owning SERCOM - mclk.$apmask.modify(|_, w| w.$powermask().set_bit()); - - // reset the sercom instance - sercom.spim().ctrla.modify(|_, w| w.swrst().set_bit()); - // wait for reset to complete - while sercom.spim().syncbusy.read().swrst().bit_is_set() - || sercom.spim().ctrla.read().swrst().bit_is_set() - {} - - // Put the hardware into spi master mode - sercom.spim().ctrla.modify(|_, w| w.mode().spi_master()); - // wait for configuration to take effect - while sercom.spim().syncbusy.read().enable().bit_is_set() {} - - // 8 bit data size and enable the receiver - unsafe { - sercom.spim().ctrlb.modify(|_, w| { - w.chsize().bits(0); - w.rxen().set_bit() - }); - } - - // set the baud rate - let baud = Self::calculate_baud(freq, clock.freq()); - unsafe { - sercom.spim().baud.modify(|_, w| w.baud().bits(baud)); - - sercom.spim().ctrla.modify(|_, w| { - match mode.polarity { - Polarity::IdleLow => w.cpol().clear_bit(), - Polarity::IdleHigh => w.cpol().set_bit(), - }; - - match mode.phase { - Phase::CaptureOnFirstTransition => w.cpha().clear_bit(), - Phase::CaptureOnSecondTransition => w.cpha().set_bit(), - }; - - let (dipo, dopo) = padout.dipo_dopo(); - w.dipo().bits(dipo); - w.dopo().bits(dopo); - - // MSB first - w.dord().clear_bit() - }); - } - - sercom.spim().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for configuration to take effect - while sercom.spim().syncbusy.read().enable().bit_is_set() {} - - Self { padout, sercom } - } - - /// Set the baud rate - pub fn set_baud>(&mut self, freq: F, clock: &clock::$clock) { - self.disable(); - let baud = Self::calculate_baud(freq, clock.freq()); - unsafe { - self.spi_mut().baud.modify(|_, w| w.baud().bits(baud)); - } - self.enable(); - } - - /// Tear down the SPI instance and yield the constituent pins and - /// SERCOM instance. No explicit de-initialization is performed. - pub fn free(self) -> (Padout<$Sercom, MISO, MOSI, SCK>, $SERCOM) { - (self.padout, self.sercom) - } - } - - #[allow(deprecated)] - impl FullDuplex for $Type { - type Error = Error; - - fn read(&mut self) -> nb::Result { - let status = self.spi().status.read(); - if status.bufovf().bit_is_set() { - return Err(nb::Error::Other(Error::Overrun)); - } - - let intflag = self.spi().intflag.read(); - // rxc is receive complete - if intflag.rxc().bit_is_set() { - Ok(self.spi().data.read().data().bits() as u8) - } else { - Err(nb::Error::WouldBlock) - } - } - - fn send(&mut self, byte: u8) -> nb::Result<(), Error> { - let intflag = self.spi().intflag.read(); - // dre is data register empty - if intflag.dre().bit_is_set() { - self.spi_mut() - .data - .write(|w| unsafe { w.data().bits(byte as u32) }); - Ok(()) - } else { - Err(nb::Error::WouldBlock) - } - } - } - - impl ::embedded_hal::blocking::spi::transfer::Default - for $Type - { - } - impl ::embedded_hal::blocking::spi::write::Default - for $Type - { - } - #[cfg(feature = "unproven")] - impl ::embedded_hal::blocking::spi::write_iter::Default - for $Type - { - } - }; -} - -spi_master!(SPIMaster0: (Sercom0, SERCOM0, sercom0_, Sercom0CoreClock, apbamask)); -spi_master!(SPIMaster1: (Sercom1, SERCOM1, sercom1_, Sercom1CoreClock, apbamask)); -spi_master!(SPIMaster2: (Sercom2, SERCOM2, sercom2_, Sercom2CoreClock, apbbmask)); -spi_master!(SPIMaster3: (Sercom3, SERCOM3, sercom3_, Sercom3CoreClock, apbbmask)); -spi_master!(SPIMaster4: (Sercom4, SERCOM4, sercom4_, Sercom4CoreClock, apbdmask)); -spi_master!(SPIMaster5: (Sercom5, SERCOM5, sercom5_, Sercom5CoreClock, apbdmask)); -#[cfg(feature = "min-samd51n")] -spi_master!(SPIMaster6: (Sercom6, SERCOM6, sercom6_, Sercom6CoreClock, apbdmask)); -#[cfg(feature = "min-samd51n")] -spi_master!(SPIMaster7: (Sercom7, SERCOM7, sercom7_, Sercom7CoreClock, apbdmask)); diff --git a/hal/src/thumbv7em/sercom/v1/uart.rs b/hal/src/thumbv7em/sercom/v1/uart.rs deleted file mode 100644 index 99765e604a2c..000000000000 --- a/hal/src/thumbv7em/sercom/v1/uart.rs +++ /dev/null @@ -1,628 +0,0 @@ -#![deprecated( - since = "0.13.0", - note = "The `sercom::v1::uart` module is deprecated, and will be removed in a subsequent release. - Please use the `sercom::v2::uart` module instead." -)] - -use crate::clock; -use crate::hal::blocking::serial::{write::Default, Write}; -use crate::hal::serial; -use crate::pac::sercom0::USART_INT; -use crate::pac::{MCLK, SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5}; -#[cfg(feature = "min-samd51n")] -use crate::pac::{SERCOM6, SERCOM7}; -use crate::sercom::v1::pads::CompatiblePad; -use crate::sercom::v2::*; -use crate::time::Hertz; -use core::fmt; -use core::marker::PhantomData; - -/// The RxpoTxpo trait defines a way to get the data in and data out pin out -/// values for a given UARTXPadout configuration. You should not implement -/// this trait for yourself; only the implementations in the sercom module make -/// sense. -pub trait RxpoTxpo { - const RXPO: u8; - const TXPO: u8; - fn rxpo_txpo(&self) -> (u8, u8) { - (Self::RXPO, Self::TXPO) - } -} - -macro_rules! padout { - ( ($rxpo:literal, $txpo:literal) => $pad0:ident, $pad1:ident) => { - impl RxpoTxpo for ($pad0, $pad1) { - const RXPO: u8 = $rxpo; - const TXPO: u8 = $txpo; - } - }; - ( ($rxpo:literal, $txpo:literal) => $pad0:ident, $pad1:ident, $pad2:ident, $pad3:ident) => { - impl RxpoTxpo for ($pad0, $pad1, $pad2, $pad3) { - const RXPO: u8 = $rxpo; - const TXPO: u8 = $txpo; - } - }; -} - -// rxpo 0-3 RX on PAD 0-3 -// TX always PAD 0 -// txpo 0 no RTS/CTS -// txpo 1 reserved and can't be used -// txpo 2 RTS PAD 2, CTS PAD 3 -// txpo 3 RTS PAD 2, no CTS -// (rxpo_txpo) => (RX, TX, RTS, CTS) -padout!((1, 0) => Pad1, Pad0); -padout!((1, 2) => Pad1, Pad0, Pad2, Pad3); - -// todo we could support an RTS without a CTS -// padout!((1, 3) => Pad1, Pad0, Pad2); - -padout!((2, 0) => Pad2, Pad0); -padout!((3, 0) => Pad3, Pad0); - -// todo we could support an RTS without a CTS -// padout!((3, 3) => Pad3, Pad0, Pad2); - -/// A pad mapping configuration for the SERCOM in UART mode. -/// -/// This type can only be constructed using the From implementations -/// in this module, which are restricted to valid configurations. -/// -/// Defines which sercom pad is mapped to which UART function. -pub struct Padout -where - S: Sercom, -{ - sercom: PhantomData, - rx: RX, - tx: TX, - rts: RTS, - cts: CTS, -} - -/// A pad mapping configuration for the receiving half of the SERCOM in UART -/// mode. -pub struct RxPadout -where - S: Sercom, -{ - sercom: PhantomData, - rx: RX, - cts: CTS, -} - -/// A pad mapping configuration for the transmitting half of the SERCOM in UART -/// mode. -pub struct TxPadout -where - S: Sercom, -{ - sercom: PhantomData, - tx: TX, - rts: RTS, -} - -impl Padout -where - S: Sercom, -{ - /// Splits the padout into transmit and receive halves - pub fn split(self) -> (TxPadout, RxPadout) { - ( - TxPadout { - sercom: PhantomData, - tx: self.tx, - rts: self.rts, - }, - RxPadout { - sercom: PhantomData, - rx: self.rx, - cts: self.cts, - }, - ) - } - - /// Combines transmit and receive halves back into a duplex padout - pub fn join(tx: TxPadout, rx: RxPadout) -> Self { - Self { - sercom: PhantomData, - rx: rx.rx, - tx: tx.tx, - rts: tx.rts, - cts: rx.cts, - } - } -} - -/// Convert from a tuple of (RX, TX) to UARTXPadout -impl From<(PAD0, PAD1)> for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum): RxpoTxpo, -{ - fn from(pads: (PAD0, PAD1)) -> Padout { - Padout { - sercom: PhantomData, - rx: pads.0, - tx: pads.1, - rts: (), - cts: (), - } - } -} - -impl RxpoTxpo for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum): RxpoTxpo, -{ - const RXPO: u8 = <(PAD0::PadNum, PAD1::PadNum)>::RXPO; - const TXPO: u8 = <(PAD0::PadNum, PAD1::PadNum)>::TXPO; -} - -/// Convert from a tuple of (RX, TX, RTS, CTS) to UARTXPadout -impl From<(PAD0, PAD1, PAD2, PAD3)> for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - PAD3: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum): RxpoTxpo, -{ - fn from(pads: (PAD0, PAD1, PAD2, PAD3)) -> Padout { - Padout { - sercom: PhantomData, - rx: pads.0, - tx: pads.1, - rts: pads.2, - cts: pads.3, - } - } -} - -impl RxpoTxpo for Padout -where - S: Sercom, - PAD0: CompatiblePad, - PAD1: CompatiblePad, - PAD2: CompatiblePad, - PAD3: CompatiblePad, - (PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum): RxpoTxpo, -{ - const RXPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum)>::RXPO; - const TXPO: u8 = <(PAD0::PadNum, PAD1::PadNum, PAD2::PadNum, PAD3::PadNum)>::TXPO; -} - -/// Define a UARTX type for the given Sercom. -/// -/// Also defines the valid "pad to uart function" mappings for this instance so -/// that construction is restricted to valid configurations. -macro_rules! uart { - ($Type:ident: ( - $Sercom:ident, - $SERCOM:ident, - $powermask:ident, - $clock:ident, - $apmask:ident, - $int0: ident, - $int1: ident, - $int2: ident) - ) => { - $crate::paste::item! { - pub type [<$Type Padout>] = Padout<$Sercom, RX, TX, RTS, CTS>; - pub type [<$Type TxPadout>] = TxPadout<$Sercom, TX, RTS>; - pub type [<$Type RxPadout>] = RxPadout<$Sercom, RX, CTS>; - } - - $crate::paste::item! { - /// UARTX represents the corresponding SERCOMX instance - /// configured to act in the role of a UART Master. - /// Objects of this type implement the HAL `serial::Read`, - /// `serial::Write` traits. - /// - /// This type is generic over any valid pad mapping where there is - /// a defined "receive pin out transmit pin out" implementation. - pub struct $Type { - padout: Padout<$Sercom, RX, TX, RTS, CTS>, - sercom: $SERCOM, - } - - impl $Type { - pub fn new, T: Into>>( - clock: &clock::$clock, - freq: F, - sercom: $SERCOM, - mclk: &mut MCLK, - padout: T, - ) -> Self where - Padout<$Sercom, RX, TX, RTS, CTS>: RxpoTxpo { - let padout = padout.into(); - - mclk.$apmask.modify(|_, w| w.$powermask().set_bit()); - - // Lots of union fields which require unsafe access - unsafe { - // Reset - sercom.usart_int().ctrla.modify(|_, w| w.swrst().set_bit()); - while sercom.usart_int().syncbusy.read().swrst().bit_is_set() - || sercom.usart_int().ctrla.read().swrst().bit_is_set() { - // wait for sync of CTRLA.SWRST - } - - // Unsafe b/c of direct call to bits on rxpo/txpo - sercom.usart_int().ctrla.modify(|_, w| { - w.dord().set_bit(); - - let (rxpo, txpo) = padout.rxpo_txpo(); - w.rxpo().bits(rxpo); // Uses pad 3 for rx - w.txpo().bits(txpo); // Uses pad 2 for tx (and pad 3 for xck) - - w.sampr().bits(0x00); // 16x oversample fractional - w.runstdby().set_bit(); // Run in standby - w.form().bits(0); // 0 is no parity bits - - w.mode().usart_int_clk(); // Internal clock mode - w.cmode().clear_bit() // Asynchronous mode - }); - - // Calculate value for BAUD register - let sample_rate: u8 = 16; - let fref = clock.freq().0; - - // TODO: Support fractional BAUD mode - // let mul_ratio = (fref.0 * 1000) / (freq.into().0 * 16); - // - // let baud = mul_ratio / 1000; - // let fp = ((mul_ratio - (baud*1000))*8)/1000; - // - // sercom.usart_int().baud.baud_frac_mode.modify(|_, w| { - // w.baud().bits(baud as u16); - // w.fp().bits(fp as u8) - // }); - - // Asynchronous arithmetic mode (Table 24-2 in datasheet) - let baud = calculate_baud_value(freq.into().0, fref, sample_rate); - - sercom.usart_int().baud().modify(|_, w| { - w.baud().bits(baud) - }); - - sercom.usart_int().ctrlb.modify(|_, w| { - w.sbmode().clear_bit(); // 0 is one stop bit see sec 25.8.2 - w.chsize().bits(0x0); - w.pmode().set_bit(); - w.txen().set_bit(); - w.rxen().set_bit() - }); - - while sercom.usart_int().syncbusy.read().ctrlb().bit_is_set() {} - - sercom.usart_int().ctrlc.modify(|_, w| { - w.gtime().bits(2); - w.maxiter().bits(7) - }); - - sercom.usart_int().ctrla.modify(|_, w| w.enable().set_bit()); - // wait for sync of ENABLE - while sercom.usart_int().syncbusy.read().enable().bit_is_set() {} - } - - Self { - padout, - sercom, - } - } - - pub fn free(self) -> (Padout<$Sercom, RX, TX, RTS, CTS>, $SERCOM) { - (self.padout, self.sercom) - } - - /// Splits the UART into transmit and receive halves - pub fn split(self) -> ([<$Type Tx>], [<$Type Rx>]) { - let (tx_pads, rx_pads) = self.padout.split(); - ( - [<$Type Tx>] { - padout: tx_pads, - sercom: self.sercom, - }, - [<$Type Rx>] { - padout: rx_pads, - sercom: PhantomData, - }, - ) - } - - /// Combines transmit and receive halves back into a duplex UART - pub fn join(tx: [<$Type Tx>], rx: [<$Type Rx>]) -> Self { - Self { - padout: Padout::join(tx.padout, rx.padout), - sercom: tx.sercom, - } - } - - fn usart(&self) -> &USART_INT { - return &self.sercom.usart_int(); - } - - pub fn intenset(&mut self, f: F) - where F: FnOnce(&mut crate::pac::sercom0::usart_int::intenset::W) - { - self.usart().intenset.write(|w| { - f(w); - w - }); - } - - pub fn intenclr(&mut self, f: F) - where F: FnOnce(&mut crate::pac::sercom0::usart_int::intenclr::W) - { - self.usart().intenclr.write(|w| { - f(w); - w - }); - } - - pub fn flags(&self) -> crate::pac::sercom0::usart_int::status::R { - self.usart().status.read() - } - } - - /// The transmitting half of the corresponding UARTX instance (as returned by `UARTX::split`) - pub struct [<$Type Tx>] { - padout: TxPadout<$Sercom, TX, RTS>, - /// We store the SERCOM object here so we can retrieve it later, - /// but conceptually, ownership is shared between the Rx and Tx halves. - sercom: $SERCOM, - } - - impl [<$Type Tx>] { - /// # Safety - /// - /// Only this struct instance should be able to access TX-related fields on this SERCOM. - unsafe fn usart(&self) -> &USART_INT { - (*$SERCOM::ptr()).usart_int() - } - - fn do_write(usart: &USART_INT, word: u8) -> nb::Result<(), ()> { - unsafe { - if !usart.intflag.read().dre().bit_is_set() { - return Err(nb::Error::WouldBlock); - } - - usart.data.write(|w| { - w.bits(word as u32) - }); - } - - Ok(()) - } - - fn do_flush(usart: &USART_INT) -> nb::Result<(), ()> { - // simply await DRE empty - if !usart.intflag.read().dre().bit_is_set() { - return Err(nb::Error::WouldBlock); - } - - Ok(()) - } - } - - impl serial::Write for [<$Type Tx>] { - type Error = (); - - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { - Self::do_write(unsafe { self.usart() }, word) - } - - fn flush(&mut self) -> nb::Result<(), Self::Error> { - Self::do_flush(unsafe { self.usart() }) - } - } - - impl serial::Write for $Type { - type Error = (); - - fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { - [<$Type Tx>]::::do_write(self.sercom.usart_int(), word) - } - - fn flush(&mut self) -> nb::Result<(), Self::Error> { - [<$Type Tx>]::::do_flush(self.sercom.usart_int()) - } - } - - /// The receiving half of the corresponding UARTX instance (as returned by `UARTX::split`) - pub struct [<$Type Rx>] { - padout: RxPadout<$Sercom, RX, CTS>, - sercom: PhantomData<$SERCOM>, - } - - impl [<$Type Rx>] { - /// # Safety - /// - /// Only this struct instance should be able to access RX-related fields on this SERCOM. - unsafe fn usart(&self) -> &USART_INT { - (*$SERCOM::ptr()).usart_int() - } - - fn do_read(usart: &USART_INT) -> nb::Result { - // A frame error occurred, so discard the byte in DATA. - if usart.status.read().ferr().bit_is_set() { - usart.data.read(); - usart.status.write(|w| w.ferr().set_bit()); - } - - let has_data = usart.intflag.read().rxc().bit_is_set(); - if !has_data { - return Err(nb::Error::WouldBlock); - } - - let data = usart.data.read().bits(); - Ok(data as u8) - } - } - - impl serial::Read for [<$Type Rx>] { - type Error = (); - - fn read(&mut self) -> nb::Result { - Self::do_read(unsafe { self.usart() }) - } - } - - impl serial::Read for $Type { - type Error = (); - - fn read(&mut self) -> nb::Result { - [<$Type Rx>]::::do_read(self.sercom.usart_int()) - } - } - - impl Default for [<$Type Tx>] {} - - impl Default for $Type {} - - impl fmt::Write for [<$Type Tx>] { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.bwrite_all(s.as_bytes()).map_err(|_| fmt::Error) - } - } - - impl fmt::Write for $Type { - fn write_str(&mut self, s: &str) -> fmt::Result { - self.bwrite_all(s.as_bytes()).map_err(|_| fmt::Error) - } - } - } - }; -} - -uart!( - UART0: - ( - Sercom0, - SERCOM0, - sercom0_, - Sercom0CoreClock, - apbamask, - SERCOM0_0, - SERCOM0_1, - SERCOM0_2 - ) -); - -uart!( - UART1: - ( - Sercom1, - SERCOM1, - sercom1_, - Sercom1CoreClock, - apbamask, - SERCOM1_0, - SERCOM1_1, - SERCOM1_2 - ) -); - -uart!( - UART2: - ( - Sercom2, - SERCOM2, - sercom2_, - Sercom2CoreClock, - apbbmask, - SERCOM2_0, - SERCOM2_1, - SERCOM2_2 - ) -); - -uart!( - UART3: - ( - Sercom3, - SERCOM3, - sercom3_, - Sercom3CoreClock, - apbbmask, - SERCOM3_0, - SERCOM3_1, - SERCOM3_2 - ) -); - -uart!( - UART4: - ( - Sercom4, - SERCOM4, - sercom4_, - Sercom4CoreClock, - apbdmask, - SERCOM4_0, - SERCOM4_1, - SERCOM4_2 - ) -); - -uart!( - UART5: - ( - Sercom5, - SERCOM5, - sercom5_, - Sercom5CoreClock, - apbdmask, - SERCOM5_0, - SERCOM5_1, - SERCOM5_2 - ) -); - -#[cfg(feature = "min-samd51n")] -uart!( - UART6: - ( - Sercom6, - SERCOM6, - sercom6_, - Sercom6CoreClock, - apbdmask, - SERCOM6_0, - SERCOM6_1, - SERCOM6_2 - ) -); - -#[cfg(feature = "min-samd51n")] -uart!( - UART7: - ( - Sercom7, - SERCOM7, - sercom7_, - Sercom7CoreClock, - apbdmask, - SERCOM7_0, - SERCOM7_1, - SERCOM7_2 - ) -); - -const SHIFT: u8 = 32; - -fn calculate_baud_value(baudrate: u32, clk_freq: u32, n_samples: u8) -> u16 { - let sample_rate = (n_samples as u64 * baudrate as u64) << 32; - let ratio = sample_rate / clk_freq as u64; - let scale = (1u64 << SHIFT) - ratio; - let baud_calculated = (65536u64 * scale) >> SHIFT; - - baud_calculated as u16 -} diff --git a/hal/src/thumbv7em/timer.rs b/hal/src/thumbv7em/timer.rs index cfe1793d91a9..7f973e77c9d6 100644 --- a/hal/src/thumbv7em/timer.rs +++ b/hal/src/thumbv7em/timer.rs @@ -1,5 +1,5 @@ //! Working with timer counter hardware -use crate::hal::timer::{CountDown, Periodic}; +use crate::ehal::timer::{CountDown, Periodic}; use crate::pac::tc0::COUNT16; #[allow(unused)] use crate::pac::{MCLK, TC2, TC3}; @@ -13,8 +13,6 @@ use crate::clock; use crate::time::{Hertz, Nanoseconds}; use void::Void; -use cortex_m::asm::delay as cycle_delay; - // Note: // TC3 + TC4 can be paired to make a 32-bit counter // TC5 + TC6 can be paired to make a 32-bit counter @@ -183,39 +181,3 @@ tc! { TimerCounter4: (TC4, tc4_, Tc4Tc5Clock, apbcmask), TimerCounter5: (TC5, tc5_, Tc4Tc5Clock, apbcmask), } - -#[deprecated( - since = "0.13.0", - note = "`SpinTimer` is deprecated, and will be removed in a subsequent release." -)] -#[derive(Clone, Copy)] -pub struct SpinTimer { - cycles: u32, -} - -#[allow(deprecated)] -impl SpinTimer { - pub fn new(cycles: u32) -> SpinTimer { - SpinTimer { cycles } - } -} - -#[allow(deprecated)] -impl Periodic for SpinTimer {} - -#[allow(deprecated)] -impl CountDown for SpinTimer { - type Time = u32; - - fn start(&mut self, cycles: T) - where - T: Into, - { - self.cycles = cycles.into(); - } - - fn wait(&mut self) -> nb::Result<(), void::Void> { - cycle_delay(self.cycles); - Ok(()) - } -} diff --git a/hal/src/thumbv7em/usb/bus.rs b/hal/src/thumbv7em/usb/bus.rs index 0e60f299053f..5f256666426c 100644 --- a/hal/src/thumbv7em/usb/bus.rs +++ b/hal/src/thumbv7em/usb/bus.rs @@ -8,7 +8,7 @@ use super::Descriptors; use crate::calibration::{usb_transn_cal, usb_transp_cal, usb_trim_cal}; use crate::clock; -use crate::gpio::v2::{AlternateH, AnyPin, Pin, PA24, PA25}; +use crate::gpio::{AlternateH, AnyPin, Pin, PA24, PA25}; use crate::pac; use crate::pac::usb::DEVICE; use crate::pac::{MCLK, USB}; diff --git a/hal/src/thumbv7em/usb/mod.rs b/hal/src/thumbv7em/usb/mod.rs index 7f80a614b7a2..10d22657214e 100644 --- a/hal/src/thumbv7em/usb/mod.rs +++ b/hal/src/thumbv7em/usb/mod.rs @@ -1,6 +1,9 @@ //! USB Device support -use crate::gpio; +use crate::gpio::{ + pin::{Pin, PA23, PA24, PA25}, + AlternateH, +}; pub use usb_device; @@ -11,11 +14,10 @@ mod devicedesc; use self::devicedesc::Descriptors; /// Default SOF pad -#[allow(deprecated)] -pub type SofPad = gpio::v1::Pa23; +pub type SofPad = Pin; + /// Default USB D- pad -#[allow(deprecated)] -pub type DmPad = gpio::v1::Pa24; +pub type DmPad = Pin; + /// Default USB D+ pad -#[allow(deprecated)] -pub type DpPad = gpio::v1::Pa25; +pub type DpPad = Pin; diff --git a/hal/src/timer_traits.rs b/hal/src/timer_traits.rs index f2201fd052da..335e73049600 100644 --- a/hal/src/timer_traits.rs +++ b/hal/src/timer_traits.rs @@ -1,4 +1,4 @@ -use crate::hal::timer::{CountDown, Periodic}; +use crate::ehal::timer::{CountDown, Periodic}; use crate::time; /// Trait for timers that can enable & disable an interrupt that fires