diff --git a/arduino-hal/Cargo.toml b/arduino-hal/Cargo.toml index 1f400c73f3..dc28d6a322 100644 --- a/arduino-hal/Cargo.toml +++ b/arduino-hal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "arduino-hal" -version = "0.1.0" +version = "0.4.0" authors = ["Rahix "] edition = "2021" @@ -16,24 +16,57 @@ rt = ["avr-device/rt"] critical-section-impl = ["avr-device/critical-section-impl"] -board-selected = [] -mcu-atmega = [] -mcu-attiny = [] -arduino-diecimila = ["mcu-atmega", "atmega-hal/atmega168", "board-selected"] -arduino-leonardo = ["mcu-atmega", "atmega-hal/atmega32u4", "board-selected"] -arduino-mega2560 = ["mcu-atmega", "atmega-hal/atmega2560", "board-selected"] -arduino-mega1280 = ["mcu-atmega", "atmega-hal/atmega1280", "board-selected"] -arduino-nano = ["mcu-atmega", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc", "board-selected"] -arduino-uno = ["mcu-atmega", "atmega-hal/atmega328p", "board-selected"] -trinket-pro = ["mcu-atmega", "atmega-hal/atmega328p", "board-selected"] -sparkfun-promicro = ["mcu-atmega", "atmega-hal/atmega32u4", "board-selected"] -sparkfun-promini-3v3 = ["mcu-atmega", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc", "board-selected"] -sparkfun-promini-5v = ["mcu-atmega", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc", "board-selected"] -trinket = ["mcu-attiny", "attiny-hal/attiny85", "board-selected"] -nano168 = ["mcu-atmega", "atmega-hal/atmega168", "atmega-hal/enable-extra-adc", "board-selected"] - -# We must select a board to build on docs.rs -docsrs = ["arduino-uno"] +# Board-specific targets. +arduino-diecimila = ["_board-arduino-diecimila"] +arduino-leonardo = ["_board-arduino-leonardo"] +arduino-mega2560 = ["_board-arduino-mega2560"] +arduino-mega1280 = ["_board-arduino-mega1280"] +arduino-nano = ["_board-arduino-nano"] +arduino-uno = ["_board-arduino-uno"] +trinket-pro = ["_board-trinket-pro"] +sparkfun-promicro = ["_board-sparkfun-promicro"] +sparkfun-promini-3v3 = ["_board-sparkfun-promini-3v3"] +sparkfun-promini-5v = ["_board-sparkfun-promini-5v"] +trinket = ["_board-trinket"] +nano168 = ["_board-nano168"] + +# When using this crate from another lib crate, you can use this feature to suppress the chip selection error in favor of your own error +disable-board-selection-error = ["_board-selected"] + +# MCU-specific implementation features +_board-arduino-diecimila = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega168"] +_board-arduino-leonardo = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega32u4"] +_board-arduino-mega2560 = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega2560"] +_board-arduino-mega1280 = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega1280"] +_board-arduino-nano = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc"] +_board-arduino-uno = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega328p"] +_board-trinket-pro = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega328p"] +_board-sparkfun-promicro = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega32u4"] +_board-sparkfun-promini-3v3 = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc"] +_board-sparkfun-promini-5v = ["_mcu-atmega", "_default-serial", "atmega-hal/atmega328p", "atmega-hal/enable-extra-adc"] +_board-trinket = ["_mcu-attiny", "attiny-hal/attiny85"] +_board-nano168 = ["_mcu-atmega", "atmega-hal/atmega168", "atmega-hal/enable-extra-adc"] + +_mcu-atmega = ["_board-selected"] +_mcu-attiny = ["_board-selected"] +_default-serial = [] + +_board-selected = [] + +docsrs = [ + "arduino-diecimila", + "arduino-leonardo", + "arduino-mega2560", + "arduino-mega1280", + "arduino-nano", + "arduino-uno", + "trinket-pro", + "sparkfun-promicro", + "sparkfun-promini-3v3", + "sparkfun-promini-5v", + "trinket", + "nano168", +] [dependencies] cfg-if = "1" @@ -51,12 +84,6 @@ path = "../avr-hal-generic/" path = "../mcu/atmega-hal/" optional = true -# Because this crate has its own check that at least one device is selected, we -# can safely "circumvent" the check in `atmega-hal`. Due to compile order, -# this allows us to show our error instead of the one from `atmega-hal` (which -# is much less helpful in this situation). -features = ["disable-device-selection-error"] - [dependencies.attiny-hal] path = "../mcu/attiny-hal/" optional = true diff --git a/arduino-hal/src/adafruit/mod.rs b/arduino-hal/src/adafruit/mod.rs new file mode 100644 index 0000000000..dbc6fee892 --- /dev/null +++ b/arduino-hal/src/adafruit/mod.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "_board-trinket")] +pub mod trinket; + +#[cfg(feature = "_board-trinket-pro")] +pub mod trinket_pro; diff --git a/arduino-hal/src/adafruit/trinket.rs b/arduino-hal/src/adafruit/trinket.rs new file mode 100644 index 0000000000..a5d67a42c5 --- /dev/null +++ b/arduino-hal/src/adafruit/trinket.rs @@ -0,0 +1,86 @@ +pub use attiny_hal::attiny85 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz8; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::adafruit::trinket + } +} + +pub mod port { + use crate::adafruit::trinket as board; + + pub use board::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + pub struct Pins { + /// `#0`: `PB0`, `DI`(SPI), `SDA`(I2C) + pub d0: board::hal::port::PB0 = pb0, + /// `#1`: `PB1`, `DO`(SPI), Builtin LED + pub d1: board::hal::port::PB1 = pb1, + /// `#2`: `PB2`, `SCK`(SPI), `SCL`(I2C) + pub d2: board::hal::port::PB2 = pb2, + /// `#3`: `PB3` + pub d3: board::hal::port::PB3 = pb3, + /// `#4`: `PB4` + pub d4: board::hal::port::PB4 = pb4, + } + + impl Pins { + type Pin = Pin; + type McuPins = board::hal::Pins; + } + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! adafruit_trinket_pins { + ($p:expr) => { + $crate::adafruit::trinket::Pins::with_mcu_pins($crate::adafruit::trinket::hal::pins!($p)) + }; + } + + pub use adafruit_trinket_pins as pins; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::adafruit::trinket + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::adafruit::trinket + } +} + +pub use { + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + port::{Pins, pins}, +}; diff --git a/arduino-hal/src/adafruit/trinket_pro.rs b/arduino-hal/src/adafruit/trinket_pro.rs new file mode 100644 index 0000000000..1cdc120f0a --- /dev/null +++ b/arduino-hal/src/adafruit/trinket_pro.rs @@ -0,0 +1,223 @@ +pub use atmega_hal::atmega328p as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz8; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::adafruit::trinket_pro + } +} + +pub mod port { + use crate::adafruit::trinket_pro as board; + pub use board::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + /// Pins of the **Trinket Pro**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. + pub struct Pins { + /// `A0` + /// + /// * ADC0 (ADC input channel 0) + /// * PCINT8 (pin change interrupt 8) + pub a0: board::hal::port::PC0 = pc0, + /// `A1` + /// + /// * ADC1 (ADC input channel 1) + /// * PCINT9 (pin change interrupt 9) + pub a1: board::hal::port::PC1 = pc1, + /// `A2` + /// + /// * ADC2 (ADC input channel 2) + /// * PCINT10 (pin change interrupt 10) + pub a2: board::hal::port::PC2 = pc2, + /// `A3` + /// + /// * ADC3 (ADC input channel 3) + /// * PCINT11 (pin change interrupt 11) + pub a3: board::hal::port::PC3 = pc3, + /// `A4` + /// + /// * ADC4 (ADC input channel 4) + /// * SDA (2-wire serial bus data input/output line) + /// * PCINT12 (pin change interrupt 12) + pub a4: board::hal::port::PC4 = pc4, + /// `A5` + /// + /// ADC5 (ADC input channel 5) + /// SCL (2-wire serial bus clock line) + /// PCINT13 (pin change interrupt 13) + pub a5: board::hal::port::PC5 = pc5, + + /// `D0` / `RX` + /// + /// * RXD (USART input pin) + /// * PCINT16 (pin change interrupt 16) + pub d0: board::hal::port::PD0 = pd0, + /// `D1` / `TX` + /// + /// * TXD (USART output pin) + /// * PCINT17 (pin change interrupt 17) + pub d1: board::hal::port::PD1 = pd1, + /// `D3` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * INT1 (external interrupt 1 input) + /// * OC2B (Timer/Counter2 output compare match B output) + /// * PCINT19 (pin change interrupt 19) + pub d3: board::hal::port::PD3 = pd3, + /// `D4` + /// + /// * XCK (USART external clock input/output) + /// * T0 (Timer/Counter 0 external counter input) + /// * PCINT20 (pin change interrupt 20) + pub d4: board::hal::port::PD4 = pd4, + /// `D5` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * T1 (Timer/Counter 1 external counter input) + /// * OC0B (Timer/Counter0 output compare match B output) + /// * PCINT21 (pin change interrupt 21) + pub d5: board::hal::port::PD5 = pd5, + /// `D6` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * AIN0 (analog comparator positive input) + /// * OC0A (Timer/Counter0 output compare match A output) + /// * PCINT22 (pin change interrupt 22) + pub d6: board::hal::port::PD6 = pd6, + /// `D8` + /// + /// * ICP1 (Timer/Counter1 input capture input) + /// * CLKO (divided system clock output) + /// * PCINT0 (pin change interrupt 0) + pub d8: board::hal::port::PB0 = pb0, + /// `D9` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * OC1A (Timer/Counter1 output compare match A output) + /// * PCINT1 (pin change interrupt 1) + pub d9: board::hal::port::PB1 = pb1, + /// `D10` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * SS (SPI bus master slave select) + /// * OC1B (Timer/Counter1 output compare match B output) + /// * PCINT2 (pin change interrupt 2) + pub d10: board::hal::port::PB2 = pb2, + /// `D11` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * MOSI (SPI bus master/slave input) + /// * OC2A (Timer/Counter2 output compare match A output) + /// * PCINT3 (pin change interrupt 3) + pub d11: board::hal::port::PB3 = pb3, + /// `D12` + /// + /// * MISO (SPI bus master input/slave output) + /// * PCINT4 (pin change interrupt 4) + pub d12: board::hal::port::PB4 = pb4, + /// `D13` + /// + /// * SCK (SPI bus master clock input) + /// * PCINT5 (pin change interrupt 5) + /// * L LED on Trinket Pro + pub d13: board::hal::port::PB5 = pb5, + } + + impl Pins { + type Pin = Pin; + type McuPins = board::hal::Pins; + } + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! adafruit_trinket_pro_pins { + ($p:expr) => { + $crate::adafruit::trinket_pro::Pins::with_mcu_pins($crate::adafruit::trinket_pro::hal::pins!($p)) + }; + } + + pub use adafruit_trinket_pro_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::adafruit::trinket_pro + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::adafruit::trinket_pro + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::adafruit::trinket_pro + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::adafruit::trinket_pro + } +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::adafruit::trinket_pro + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::adafruit::trinket_pro + } +} + +pub mod prelude { + use crate::adafruit::trinket_pro as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::Usart, +}; diff --git a/arduino-hal/src/arduino/diecimila.rs b/arduino-hal/src/arduino/diecimila.rs new file mode 100644 index 0000000000..c638343475 --- /dev/null +++ b/arduino-hal/src/arduino/diecimila.rs @@ -0,0 +1,272 @@ +pub use atmega_hal::atmega168 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::diecimila + } +} + +pub mod port { + use crate::arduino::diecimila as board; + pub use board::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + /// Pins of the **Arduino Diecimila**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. + pub struct Pins { + /// `A0` + /// + /// * ADC0 (ADC input channel 0) + /// * PCINT8 (pin change interrupt 8) + pub a0: board::hal::port::PC0 = pc0, + /// `A1` + /// + /// * ADC1 (ADC input channel 1) + /// * PCINT9 (pin change interrupt 9) + pub a1: board::hal::port::PC1 = pc1, + /// `A2` + /// + /// * ADC2 (ADC input channel 2) + /// * PCINT10 (pin change interrupt 10) + pub a2: board::hal::port::PC2 = pc2, + /// `A3` + /// + /// * ADC3 (ADC input channel 3) + /// * PCINT11 (pin change interrupt 11) + pub a3: board::hal::port::PC3 = pc3, + /// `A4` + /// + /// * ADC4 (ADC input channel 4) + /// * SDA (2-wire serial bus data input/output line) + /// * PCINT12 (pin change interrupt 12) + pub a4: board::hal::port::PC4 = pc4, + /// `A5` + /// + /// ADC5 (ADC input channel 5) + /// SCL (2-wire serial bus clock line) + /// PCINT13 (pin change interrupt 13) + pub a5: board::hal::port::PC5 = pc5, + + /// `D0` / `RX` + /// + /// * RXD (USART input pin) + /// * PCINT16 (pin change interrupt 16) + pub d0: board::hal::port::PD0 = pd0, + /// `D1` / `TX` + /// + /// * TXD (USART output pin) + /// * PCINT17 (pin change interrupt 17) + pub d1: board::hal::port::PD1 = pd1, + /// `D2` + /// + /// * INT0 (external interrupt 0 input) + /// * PCINT18 (pin change interrupt 18) + pub d2: board::hal::port::PD2 = pd2, + /// `D3` + /// + /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] + /// * INT1 (external interrupt 1 input) + /// * OC2B (Timer/Counter2 output compare match B output) + /// * PCINT19 (pin change interrupt 19) + pub d3: board::hal::port::PD3 = pd3, + /// `D4` + /// + /// * XCK (USART external clock input/output) + /// * T0 (Timer/Counter 0 external counter input) + /// * PCINT20 (pin change interrupt 20) + pub d4: board::hal::port::PD4 = pd4, + /// `D5` + /// + /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] + /// * T1 (Timer/Counter 1 external counter input) + /// * OC0B (Timer/Counter0 output compare match B output) + /// * PCINT21 (pin change interrupt 21) + pub d5: board::hal::port::PD5 = pd5, + /// `D6` + /// + /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] + /// * AIN0 (analog comparator positive input) + /// * OC0A (Timer/Counter0 output compare match A output) + /// * PCINT22 (pin change interrupt 22) + pub d6: board::hal::port::PD6 = pd6, + /// `D7` + /// + /// * AIN1 (analog comparator negative input) + /// * PCINT23 (pin change interrupt 23) + pub d7: board::hal::port::PD7 = pd7, + /// `D8` + /// + /// * ICP1 (Timer/Counter1 input capture input) + /// * CLKO (divided system clock output) + /// * PCINT0 (pin change interrupt 0) + pub d8: board::hal::port::PB0 = pb0, + /// `D9` + /// + /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] + /// * OC1A (Timer/Counter1 output compare match A output) + /// * PCINT1 (pin change interrupt 1) + pub d9: board::hal::port::PB1 = pb1, + /// `D10` + /// + /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] + /// * SS (SPI bus master slave select) + /// * OC1B (Timer/Counter1 output compare match B output) + /// * PCINT2 (pin change interrupt 2) + pub d10: board::hal::port::PB2 = pb2, + /// `D11` + /// + /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] + /// * MOSI (SPI bus master/slave input) + /// * OC2A (Timer/Counter2 output compare match A output) + /// * PCINT3 (pin change interrupt 3) + pub d11: board::hal::port::PB3 = pb3, + /// `D12` + /// + /// * MISO (SPI bus master input/slave output) + /// * PCINT4 (pin change interrupt 4) + pub d12: board::hal::port::PB4 = pb4, + /// `D13` + /// + /// * SCK (SPI bus master clock input) + /// * PCINT5 (pin change interrupt 5) + /// * L LED on Arduino Uno + pub d13: board::hal::port::PB5 = pb5, + } + + impl Pins { + type Pin = Pin; + type McuPins = board::hal::Pins; + } + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_diecimila_pins { + ($p:expr) => { + $crate::arduino::diecimila::Pins::with_mcu_pins($crate::arduino::diecimila::hal::pins!($p)) + }; + } + + pub use arduino_diecimila_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::diecimila + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::diecimila + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::diecimila + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::diecimila + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + /// + /// This is equivalent to manually configuring the driver: + /// + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::Usart::new( + /// dp.USART1, + /// pins.d0, + /// pins.d1.into_output(), + /// // See src/usart.rs for why some boards use the BaudrateArduinoExt trait + /// // instead of BaudrateExt. + /// arduino_hal::hal::usart::BaudrateArduinoExt::into_baudrate(57600), + /// ); + /// ``` + #[macro_export] + macro_rules! arduino_diecimila_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::diecimila::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + // See comment in avr-hal-generic/src/usart.rs for why these boards use the + // BaudrateArduinoExt trait instead of BaudrateExt + $crate::arduino::diecimila::hal::usart::BaudrateArduinoExt::into_baudrate($baud), + ) + }; + } + pub use arduino_diecimila_default_serial as default_serial; + +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::diecimila + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::diecimila + } +} + +pub mod prelude { + use crate::arduino::diecimila as board; + pub use board::hal::usart::BaudrateArduinoExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart,default_serial}, +}; diff --git a/arduino-hal/src/arduino/impl/mega.rs b/arduino-hal/src/arduino/impl/mega.rs new file mode 100644 index 0000000000..688581f4aa --- /dev/null +++ b/arduino-hal/src/arduino/impl/mega.rs @@ -0,0 +1,349 @@ +macro_rules! impl_port_mega { + (board: $($board:ident)::+ $(,)?) => { + pub use $($board)::+::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + /// Pins of the **Arduino Mega 2560** and **Arduino Mega 1280**. + /// + /// mega1280: + /// https://www.arduino.cc/en/uploads/Main/arduino-mega-schematic.pdf + /// mega2560: + /// https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. + pub struct Pins { + /// `D0` / `RX0` + /// + /// * `RXD0` (USART0) + /// * `PCINT8`: External Interrupt (Pin Change) + pub d0: $($board)::+::hal::port::PE0 = pe0, + /// `D1` / `TX0` + /// + /// * `TXD0` (USART0) + pub d1: $($board)::+::hal::port::PE1 = pe1, + /// `D2` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] + /// * `OC3B`: Output Compare Channel `B` for Timer/Counter3 + /// * `INT4`: External Interrupt + pub d2: $($board)::+::hal::port::PE4 = pe4, + /// `D3` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] + /// * `OC3C`: Output Compare Channel `C` for Timer/Counter3 + /// * `INT5`: External Interrupt + pub d3: $($board)::+::hal::port::PE5 = pe5, + /// `D4` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer0Pwm] + /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 + pub d4: $($board)::+::hal::port::PG5 = pg5, + /// `D5` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] + /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 + /// * `AIN1`: Analog Comparator Negative Input (Not Implemented) + pub d5: $($board)::+::hal::port::PE3 = pe3, + /// `D6` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] + /// * `OC4A`: Output Compare Channel `A` for Timer/Counter4 + pub d6: $($board)::+::hal::port::PH3 = ph3, + /// `D7` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] + /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 + pub d7: $($board)::+::hal::port::PH4 = ph4, + /// `D8` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] + /// * `OC4C`: Output Compare Channel `C` for Timer/Counter4 + pub d8: $($board)::+::hal::port::PH5 = ph5, + /// `D9` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer2Pwm] + /// * `OC2B`: Output Compare Channel `B` for Timer/Counter2 + pub d9: $($board)::+::hal::port::PH6 = ph6, + /// `D10` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer2Pwm] + /// * `OC2B`: Output Compare Channel `B` for Timer/Counter2 + /// * `PCINT4`: External Interrupt (Pin Change) + pub d10: $($board)::+::hal::port::PB4 = pb4, + /// `D11` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] + /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 + /// * `PCINT5`: External Interrupt (Pin Change) + pub d11: $($board)::+::hal::port::PB5 = pb5, + /// `D12` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] + /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 + /// * `PCINT6`: External Interrupt (Pin Change) + pub d12: $($board)::+::hal::port::PB6 = pb6, + /// `D13` + /// + /// * Onboard LED + /// * **PWM**: [atmega2560_hal::timer::Timer0Pwm] + /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] + /// * `OC0A`: Output Compare Channel `A` for Timer/Counter0 + /// * `OC1C`: Output Compare Channel `C` for Timer/Counter1 + /// * `PCINT7`: External Interrupt (Pin Change) + pub d13: $($board)::+::hal::port::PB7 = pb7, + /// `D14` / `TX3` + /// + /// * `TXD3` (USART3) + /// * `PCINT10`: External Interrupt (Pin Change) + pub d14: $($board)::+::hal::port::PJ1 = pj1, + /// `D15` / `RX3` + /// + /// * `RXD3` (USART3) + /// * `PCINT9`: External Interrupt (Pin Change) + pub d15: $($board)::+::hal::port::PJ0 = pj0, + /// `D16` / `TX2` + /// + /// * `TXD2` (USART2) + pub d16: $($board)::+::hal::port::PH1 = ph1, + /// `D17` / `RX2` + /// + /// * `RXD2` (USART2) + pub d17: $($board)::+::hal::port::PH0 = ph0, + /// `D18` / `TX1` + /// + /// * `TXD1` (USART1) + /// * `INT3`: External Interrupt + pub d18: $($board)::+::hal::port::PD3 = pd3, + /// `D19` / `RX1` + /// + /// * `RXD1` (USART1) + /// * `INT2`: External Interrupt + pub d19: $($board)::+::hal::port::PD2 = pd2, + /// `D20` / `SDA` + /// + /// * `SDA`: i2c/twi data + /// * `INT1`: External Interrupt + pub d20: $($board)::+::hal::port::PD1 = pd1, + /// `D21` / `SCL` + /// + /// * `SCL`: i2c/twi clock + /// * `INT0`: External Interrupt + pub d21: $($board)::+::hal::port::PD0= pd0, + /// `D22` + /// + /// * `AD0`: External memory interface + pub d22: $($board)::+::hal::port::PA0 = pa0, + /// `D23` + /// + /// * `AD1`: External memory interface + pub d23: $($board)::+::hal::port::PA1 = pa1, + /// `D24` + /// + /// * `AD2`: External memory interface + pub d24: $($board)::+::hal::port::PA2 = pa2, + /// `D25` + /// + /// * `AD3`: External memory interface + pub d25: $($board)::+::hal::port::PA3 = pa3, + /// `D26` + /// + /// * `AD4`: External memory interface + pub d26: $($board)::+::hal::port::PA4 = pa4, + /// `D27` + /// + /// * `AD5`: External memory interface + pub d27: $($board)::+::hal::port::PA5 = pa5, + /// `D28` + /// + /// * `AD6`: External memory interface + pub d28: $($board)::+::hal::port::PA6 = pa6, + /// `D29` + /// + /// * `AD7`: External memory interface + pub d29: $($board)::+::hal::port::PA7 = pa7, + /// `D30` + /// + /// * `AD15`: External memory interface + pub d30: $($board)::+::hal::port::PC7 = pc7, + /// `D31` + /// + /// * `AD14`: External memory interface + pub d31: $($board)::+::hal::port::PC6 = pc6, + /// `D32` + /// + /// * `AD13`: External memory interface + pub d32: $($board)::+::hal::port::PC5 = pc5, + /// `D33` + /// + /// * `AD12`: External memory interface + pub d33: $($board)::+::hal::port::PC4 = pc4, + /// `D34` + /// + /// * `AD11`: External memory interface + pub d34: $($board)::+::hal::port::PC3 = pc3, + /// `D35` + /// + /// * `AD10`: External memory interface + pub d35: $($board)::+::hal::port::PC2 = pc2, + /// `D36` + /// + /// * `AD9`: External memory interface + pub d36: $($board)::+::hal::port::PC1 = pc1, + /// `D37` + /// + /// * `AD8`: External memory interface + pub d37: $($board)::+::hal::port::PC0 = pc0, + /// `D38` + /// + /// * `T0`: Clock Input for Timer/Counter0 + pub d38: $($board)::+::hal::port::PD7 = pd7, + /// `D39` + /// + /// * `ALE`: External memory Address Latch Enable + pub d39: $($board)::+::hal::port::PG2 = pg2, + /// `D40` + /// + /// `RD`: External memory Read Strobe + pub d40: $($board)::+::hal::port::PG1 = pg1, + /// `D41` + /// + /// `WR`: External memory Write Strobe + pub d41: $($board)::+::hal::port::PG0 = pg0, + /// `D42` + pub d42: $($board)::+::hal::port::PL7 = pl7, + /// `D43` + pub d43: $($board)::+::hal::port::PL6 = pl6, + /// `D44` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] + /// * `OC5C`: Output Compare Channel `C` for Timer/Counter5 + pub d44: $($board)::+::hal::port::PL5 = pl5, + /// `D45` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] + /// * `OC5B`: Output Compare Channel `B` for Timer/Counter5 + pub d45: $($board)::+::hal::port::PL4 = pl4, + /// `D46` + /// + /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] + /// * `OC5A`: Output Compare Channel `A` for Timer/Counter5 + pub d46: $($board)::+::hal::port::PL3 = pl3, + /// `D47` + /// + /// * `T5`: Clock Input for Timer/Counter5 + pub d47: $($board)::+::hal::port::PL2 = pl2, + /// `D48` + /// + /// * `ICP5`: Input Capture Trigger for Timer/Counter5 + pub d48: $($board)::+::hal::port::PL1 = pl1, + /// `D49` + /// + /// * `ICP4`: Input Capture Trigger for Timer/Counter4 + pub d49: $($board)::+::hal::port::PL0 = pl0, + /// `D50` + /// + /// * `MISO`: SPI bus Master In/Slave Out + /// * `PCINT3`: External Interrupt (Pin Change) + pub d50: $($board)::+::hal::port::PB3 = pb3, + /// `D51` + /// + /// * `MOSI`: SPI bus Master Out/Slave In + /// * `PCINT2`: External Interrupt (Pin Change) + pub d51: $($board)::+::hal::port::PB2 = pb2, + /// `D52` + /// + /// * `SCK`: SPI bus Serial Clock + /// * `PCINT1`: External Interrupt (Pin Change) + pub d52: $($board)::+::hal::port::PB1 = pb1, + /// `D53` + /// + /// * `SS`: SPI bus Slave Select + /// * `PCINT0`: External Interrupt (Pin Change) + pub d53: $($board)::+::hal::port::PB0 = pb0, + /// `A0` + /// + /// * `ADC0`: A/D converter input 0 + pub a0: $($board)::+::hal::port::PF0 = pf0, + /// `A1` + /// + /// * `ADC1`: A/D converter input 1 + pub a1: $($board)::+::hal::port::PF1 = pf1, + /// `A2` + /// + /// * `ADC2`: A/D converter input 2 + pub a2: $($board)::+::hal::port::PF2 = pf2, + /// `A3` + /// + /// * `ADC3`: A/D converter input 3 + pub a3: $($board)::+::hal::port::PF3 = pf3, + /// `A4` + /// + /// * `ADC4`: A/D converter input 4 + /// * `TCK`: JTAG test clock + pub a4: $($board)::+::hal::port::PF4 = pf4, + /// `A5` + /// + /// * `ADC5`: A/D converter input 5 + /// * `TMS`: JTAG test mode select + pub a5: $($board)::+::hal::port::PF5 = pf5, + /// `A6` + /// + /// * `ADC6`: A/D converter input 6 + /// * `TDO`: JTAG test data output + pub a6: $($board)::+::hal::port::PF6 = pf6, + /// `A7` + /// + /// * `ADC7`: A/D converter input 7 + /// * `TDI`: JTAG test data input + pub a7: $($board)::+::hal::port::PF7 = pf7, + /// `A8` + /// + /// * `ADC8`: A/D converter input 8 + /// * `PCINT16`: External Interrupt (Pin Change) + pub a8: $($board)::+::hal::port::PK0 = pk0, + /// `A9` + /// + /// * `ADC9`: A/D converter input 9 + /// * `PCINT17`: External Interrupt (Pin Change) + pub a9: $($board)::+::hal::port::PK1 = pk1, + /// `A10` + /// + /// * `ADC10`: A/D converter input 10 + /// * `PCINT18`: External Interrupt (Pin Change) + pub a10: $($board)::+::hal::port::PK2 = pk2, + /// `A11` + /// + /// * `ADC11`: A/D converter input 11 + /// * `PCINT19`: External Interrupt (Pin Change) + pub a11: $($board)::+::hal::port::PK3 = pk3, + /// `A12` + /// + /// * `ADC12`: A/D converter input 12 + /// * `PCINT20`: External Interrupt (Pin Change) + pub a12: $($board)::+::hal::port::PK4 = pk4, + /// `A13` + /// + /// * `ADC13`: A/D converter input 13 + /// * `PCINT21`: External Interrupt (Pin Change) + pub a13: $($board)::+::hal::port::PK5 = pk5, + /// `A14` + /// + /// * `ADC14`: A/D converter input 14 + /// * `PCINT22`: External Interrupt (Pin Change) + pub a14: $($board)::+::hal::port::PK6 = pk6, + /// `A15` + /// + /// * `ADC15`: A/D converter input 15 + /// * `PCINT23`: External Interrupt (Pin Change) + pub a15: $($board)::+::hal::port::PK7 = pk7, + } + + impl Pins { + type Pin = Pin; + type McuPins = $($board)::+::hal::Pins; + } + } + }; +} + +pub(crate) use impl_port_mega; diff --git a/arduino-hal/src/arduino/impl/mod.rs b/arduino-hal/src/arduino/impl/mod.rs new file mode 100644 index 0000000000..05183dec84 --- /dev/null +++ b/arduino-hal/src/arduino/impl/mod.rs @@ -0,0 +1,29 @@ +#[cfg(any( + feature = "_board-arduino-mega1280", + feature = "_board-arduino-mega2560" +))] +mod mega; + +#[cfg(any( + feature = "_board-arduino-mega1280", + feature = "_board-arduino-mega2560" +))] +pub(crate) use mega::*; + +#[cfg(any( + feature = "_board-arduino-nano", + feature = "_board-arduino-uno", + feature = "_board-nano168", + feature = "_board-sparkfun-promini-3v3", + feature = "_board-sparkfun-promini-5v" +))] +mod uno; + +#[cfg(any( + feature = "_board-arduino-nano", + feature = "_board-arduino-uno", + feature = "_board-nano168", + feature = "_board-sparkfun-promini-3v3", + feature = "_board-sparkfun-promini-5v" +))] +pub(crate) use uno::*; diff --git a/arduino-hal/src/arduino/impl/uno.rs b/arduino-hal/src/arduino/impl/uno.rs new file mode 100644 index 0000000000..6306b2cb15 --- /dev/null +++ b/arduino-hal/src/arduino/impl/uno.rs @@ -0,0 +1,137 @@ +macro_rules! impl_port_uno { + (board: $($board:ident)::+ $(,)?) => { + pub use $($board)::+::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + /// Pins of the **Arduino Uno**, **Arduino Nano**, **SparkFun ProMini 3.3V (8Mhz)**, and **SparkFun ProMini 5V (16MHz)**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. + pub struct Pins { + /// `A0` + /// + /// * ADC0 (ADC input channel 0) + /// * PCINT8 (pin change interrupt 8) + pub a0: $($board)::+::hal::port::PC0 = pc0, + /// `A1` + /// + /// * ADC1 (ADC input channel 1) + /// * PCINT9 (pin change interrupt 9) + pub a1: $($board)::+::hal::port::PC1 = pc1, + /// `A2` + /// + /// * ADC2 (ADC input channel 2) + /// * PCINT10 (pin change interrupt 10) + pub a2: $($board)::+::hal::port::PC2 = pc2, + /// `A3` + /// + /// * ADC3 (ADC input channel 3) + /// * PCINT11 (pin change interrupt 11) + pub a3: $($board)::+::hal::port::PC3 = pc3, + /// `A4` + /// + /// * ADC4 (ADC input channel 4) + /// * SDA (2-wire serial bus data input/output line) + /// * PCINT12 (pin change interrupt 12) + pub a4: $($board)::+::hal::port::PC4 = pc4, + /// `A5` + /// + /// ADC5 (ADC input channel 5) + /// SCL (2-wire serial bus clock line) + /// PCINT13 (pin change interrupt 13) + pub a5: $($board)::+::hal::port::PC5 = pc5, + + /// `D0` / `RX` + /// + /// * RXD (USART input pin) + /// * PCINT16 (pin change interrupt 16) + pub d0: $($board)::+::hal::port::PD0 = pd0, + /// `D1` / `TX` + /// + /// * TXD (USART output pin) + /// * PCINT17 (pin change interrupt 17) + pub d1: $($board)::+::hal::port::PD1 = pd1, + /// `D2` + /// + /// * INT0 (external interrupt 0 input) + /// * PCINT18 (pin change interrupt 18) + pub d2: $($board)::+::hal::port::PD2 = pd2, + /// `D3` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * INT1 (external interrupt 1 input) + /// * OC2B (Timer/Counter2 output compare match B output) + /// * PCINT19 (pin change interrupt 19) + pub d3: $($board)::+::hal::port::PD3 = pd3, + /// `D4` + /// + /// * XCK (USART external clock input/output) + /// * T0 (Timer/Counter 0 external counter input) + /// * PCINT20 (pin change interrupt 20) + pub d4: $($board)::+::hal::port::PD4 = pd4, + /// `D5` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * T1 (Timer/Counter 1 external counter input) + /// * OC0B (Timer/Counter0 output compare match B output) + /// * PCINT21 (pin change interrupt 21) + pub d5: $($board)::+::hal::port::PD5 = pd5, + /// `D6` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * AIN0 (analog comparator positive input) + /// * OC0A (Timer/Counter0 output compare match A output) + /// * PCINT22 (pin change interrupt 22) + pub d6: $($board)::+::hal::port::PD6 = pd6, + /// `D7` + /// + /// * AIN1 (analog comparator negative input) + /// * PCINT23 (pin change interrupt 23) + pub d7: $($board)::+::hal::port::PD7 = pd7, + /// `D8` + /// + /// * ICP1 (Timer/Counter1 input capture input) + /// * CLKO (divided system clock output) + /// * PCINT0 (pin change interrupt 0) + pub d8: $($board)::+::hal::port::PB0 = pb0, + /// `D9` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * OC1A (Timer/Counter1 output compare match A output) + /// * PCINT1 (pin change interrupt 1) + pub d9: $($board)::+::hal::port::PB1 = pb1, + /// `D10` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * SS (SPI bus master slave select) + /// * OC1B (Timer/Counter1 output compare match B output) + /// * PCINT2 (pin change interrupt 2) + pub d10: $($board)::+::hal::port::PB2 = pb2, + /// `D11` + /// + /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] + /// * MOSI (SPI bus master/slave input) + /// * OC2A (Timer/Counter2 output compare match A output) + /// * PCINT3 (pin change interrupt 3) + pub d11: $($board)::+::hal::port::PB3 = pb3, + /// `D12` + /// + /// * MISO (SPI bus master input/slave output) + /// * PCINT4 (pin change interrupt 4) + pub d12: $($board)::+::hal::port::PB4 = pb4, + /// `D13` + /// + /// * SCK (SPI bus master clock input) + /// * PCINT5 (pin change interrupt 5) + /// * L LED on Arduino Uno + pub d13: $($board)::+::hal::port::PB5 = pb5, + } + + impl Pins { + type Pin = Pin; + type McuPins = $($board)::+::hal::Pins; + } + } + }; +} + +pub(crate) use impl_port_uno; diff --git a/arduino-hal/src/arduino/leonardo.rs b/arduino-hal/src/arduino/leonardo.rs new file mode 100644 index 0000000000..d04443ba8a --- /dev/null +++ b/arduino-hal/src/arduino/leonardo.rs @@ -0,0 +1,257 @@ +pub use atmega_hal::atmega32u4 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::leonardo + } +} + +pub mod port { + use crate::arduino::leonardo as board; + + pub use board::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + /// Pins of the **Arduino Leonardo**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. + pub struct Pins { + /// `D0` / `RX` + /// + /// * `RX` (UART) + /// * `INT2`: External Interrupt + pub d0: board::hal::port::PD2 = pd2, + /// `D1` / `TX` + /// + /// * `TX` (UART) + /// * `INT3`: External Interrupt + pub d1: board::hal::port::PD3 = pd3, + /// `D2` / `SDA` + /// + /// * `SDA`: i2c/twi data + /// * `INT1`: External Interrupt + pub d2: board::hal::port::PD1 = pd1, + /// `D3` / `SCL` + /// + /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] + /// * `SCL`: i2c/twi clock + /// * `INT0`: External Interrupt + /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 + pub d3: board::hal::port::PD0 = pd0, + /// `D4` + pub d4: board::hal::port::PD4 = pd4, + /// `D5` + /// + /// * **PWM**: [atmega32u4_hal::timer::Timer3Pwm] + /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 + /// * `#OC4A`: Inverted Output Compare Channel `A` for Timer/Counter4 (Not implemented) + pub d5: board::hal::port::PC6 = pc6, + /// `D6` + /// + /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] + /// * `OC4D`: Output Compare Channel `D` for Timer/Counter4 + pub d6: board::hal::port::PD7 = pd7, + /// `D7` + /// + /// * `INT6`: External Interrupt + pub d7: board::hal::port::PE6 = pe6, + /// `D8` + pub d8: board::hal::port::PB4 = pb4, + /// `D9` + /// + /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] + /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 + /// * `#OC4B`: Inverted Output Compare Channel `B` for Timer/Counter4 (Not implemented) + pub d9: board::hal::port::PB5 = pb5, + /// `D10` + /// + /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] + /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 + /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 (Not implemented) + pub d10: board::hal::port::PB6 = pb6, + /// `D11` + /// + /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] + /// * `OC0A`: Output Compare Channel `B` for Timer/Counter0 + /// * `OC1C`: Output Compare Channel `C` for Timer/Counter1 + pub d11: board::hal::port::PB7 = pb7, + /// `D12` + /// + /// * `#OC4D`: Inverted Output Compare Channel `D` for Timer/Counter4 (Not implemented) + pub d12: board::hal::port::PD6 = pd6, + /// `D13` / `LED_BUILTIN` + /// + /// * Onboard LED + /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] + /// * `OC4A`: Output Compare Channel `A` for Timer/Counter4 + pub d13: board::hal::port::PC7 = pc7, + /// `RX` + /// + /// Led for indicating inbound data. Also the CS pin. + pub led_rx: board::hal::port::PB0 = pb0, + /// `TX` + /// + /// Led for indicating outbound data + pub led_tx: board::hal::port::PD5 = pd5, + /// `SCLK` + /// + /// ICSP SCLK pin + pub sck: board::hal::port::PB1 = pb1, + /// `MOSI` + /// + /// ICSP MOSI pin + pub mosi: board::hal::port::PB2 = pb2, + /// `MISO` + /// + /// ICSP MISO pin + pub miso: board::hal::port::PB3 = pb3, + /// `A0` + /// + /// * `ADC7` channel + pub a0: board::hal::port::PF7 = pf7, + /// `A1` + /// + /// * `ADC6` channel + pub a1: board::hal::port::PF6 = pf6, + /// `A2` + /// + /// * `ADC5` channel + pub a2: board::hal::port::PF5 = pf5, + /// `A3` + /// + /// * `ADC4` channel + pub a3: board::hal::port::PF4 = pf4, + /// `A4` + /// + /// * `ADC1` channel + pub a4: board::hal::port::PF1 = pf1, + /// `A5` + /// + /// * `ADC0` channel + pub a5: board::hal::port::PF0 = pf0, + } + + impl Pins { + type Pin = Pin; + type McuPins = board::hal::Pins; + } + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_leonardo_pins { + ($p:expr) => { + $crate::arduino::leonardo::Pins::with_mcu_pins($crate::arduino::leonardo::hal::pins!($p)) + }; + } + + pub use arduino_leonardo_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::leonardo + + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::leonardo + + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::leonardo + + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::leonardo + + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + #[macro_export] + macro_rules! arduino_leonardo_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::leonardo::Usart::new( + $p.USART1, + $pins.d0, + $pins.d1.into_output(), + $crate::arduino::leonardo::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; + } + pub use arduino_leonardo_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::leonardo + + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::leonardo + + } +} + +pub mod prelude { + use crate::arduino::leonardo as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart, default_serial} +}; diff --git a/arduino-hal/src/arduino/mega1280.rs b/arduino-hal/src/arduino/mega1280.rs new file mode 100644 index 0000000000..f6ed78c1e6 --- /dev/null +++ b/arduino-hal/src/arduino/mega1280.rs @@ -0,0 +1,144 @@ +pub use atmega_hal::atmega1280 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::mega1280 + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_mega; + impl_port_mega! { + board: crate::arduino::mega1280 + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_mega1280_pins { + ($p:expr) => { + $crate::arduino::mega1280::Pins::with_mcu_pins($crate::arduino::mega1280::hal::pins!($p)) + }; + } + + pub use arduino_mega1280_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::mega1280 + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::mega1280 + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::mega1280 + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::mega1280 + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + /// + /// This is equivalent to manually configuring the driver: + /// + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::Usart::new( + /// dp.USART1, + /// pins.d0, + /// pins.d1.into_output(), + /// // See src/usart.rs for why some boards use the BaudrateArduinoExt trait + /// // instead of BaudrateExt. + /// arduino_hal::hal::usart::BaudrateArduinoExt::into_baudrate(57600), + /// ); + /// ``` + #[macro_export] + macro_rules! arduino_mega1280_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::mega1280::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + // See comment in avr-hal-generic/src/usart.rs for why these boards use the + // BaudrateArduinoExt trait instead of BaudrateExt + $crate::arduino::mega1280::hal::usart::BaudrateArduinoExt::into_baudrate($baud), + ) + }; + } + + pub use arduino_mega1280_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::mega1280 + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::mega1280 + } +} + +pub mod prelude { + use crate::arduino::mega1280 as board; + pub use board::hal::usart::BaudrateArduinoExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart, default_serial}, +}; diff --git a/arduino-hal/src/arduino/mega2560.rs b/arduino-hal/src/arduino/mega2560.rs new file mode 100644 index 0000000000..765652a2cc --- /dev/null +++ b/arduino-hal/src/arduino/mega2560.rs @@ -0,0 +1,144 @@ +pub use atmega_hal::atmega2560 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::mega2560 + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_mega; + impl_port_mega! { + board: crate::arduino::mega2560 + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_mega2560_pins { + ($p:expr) => { + $crate::arduino::mega2560::Pins::with_mcu_pins($crate::arduino::mega2560::hal::pins!($p)) + }; + } + + pub use arduino_mega2560_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::mega2560 + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::mega2560 + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::mega2560 + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::mega2560 + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + /// + /// This is equivalent to manually configuring the driver: + /// + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::Usart::new( + /// dp.USART1, + /// pins.d0, + /// pins.d1.into_output(), + /// // See src/usart.rs for why some boards use the BaudrateArduinoExt trait + /// // instead of BaudrateExt. + /// arduino_hal::hal::usart::BaudrateArduinoExt::into_baudrate(57600), + /// ); + /// ``` + #[macro_export] + macro_rules! arduino_mega2560_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::mega2560::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + // See comment in avr-hal-generic/src/usart.rs for why these boards use the + // BaudrateArduinoExt trait instead of BaudrateExt + $crate::arduino::mega2560::hal::usart::BaudrateArduinoExt::into_baudrate($baud), + ) + }; + } + pub use arduino_mega2560_default_serial as default_serial; + +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::mega2560 + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::mega2560 + } +} + +pub mod prelude { + use crate::arduino::mega2560 as board; + pub use board::hal::usart::BaudrateArduinoExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart,default_serial}, +}; diff --git a/arduino-hal/src/arduino/mod.rs b/arduino-hal/src/arduino/mod.rs new file mode 100644 index 0000000000..bb67fc85e1 --- /dev/null +++ b/arduino-hal/src/arduino/mod.rs @@ -0,0 +1,22 @@ +pub(crate) mod r#impl; + +#[cfg(feature = "_board-arduino-diecimila")] +pub mod diecimila; + +#[cfg(feature = "_board-arduino-leonardo")] +pub mod leonardo; + +#[cfg(feature = "_board-arduino-mega1280")] +pub mod mega1280; + +#[cfg(feature = "_board-arduino-mega2560")] +pub mod mega2560; + +#[cfg(feature = "_board-nano168")] +pub mod nano_v2; + +#[cfg(feature = "_board-arduino-nano")] +pub mod nano_v3; + +#[cfg(feature = "_board-arduino-uno")] +pub mod uno; diff --git a/arduino-hal/src/arduino/nano_v2.rs b/arduino-hal/src/arduino/nano_v2.rs new file mode 100644 index 0000000000..12f91957f7 --- /dev/null +++ b/arduino-hal/src/arduino/nano_v2.rs @@ -0,0 +1,126 @@ +pub use atmega_hal::atmega168 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::nano_v2 + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_uno; + impl_port_uno! { + board: crate::arduino::nano_v2 + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_nano_v2_pins { + ($p:expr) => { + $crate::arduino::nano_v2::Pins::with_mcu_pins($crate::arduino::nano_v2::hal::pins!($p)) + }; + } + + pub use arduino_nano_v2_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::nano_v2 + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::nano_v2 + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::nano_v2 + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::nano_v2 + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + #[macro_export] + macro_rules! arduino_nan_v3_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::nano_v2::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + $crate::arduino::nano_v2::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; + } + pub use arduino_nan_v3_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::nano_v2 + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::nano_v2 + } +} + +pub mod prelude { + use crate::arduino::nano_v2 as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart,default_serial}, +}; diff --git a/arduino-hal/src/arduino/nano_v3.rs b/arduino-hal/src/arduino/nano_v3.rs new file mode 100644 index 0000000000..df7ca6c822 --- /dev/null +++ b/arduino-hal/src/arduino/nano_v3.rs @@ -0,0 +1,126 @@ +pub use atmega_hal::atmega328p as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::nano_v3 + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_uno; + impl_port_uno! { + board: crate::arduino::nano_v3 + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_nano_v3_pins { + ($p:expr) => { + $crate::arduino::nano_v3::Pins::with_mcu_pins($crate::arduino::nano_v3::hal::pins!($p)) + }; + } + + pub use arduino_nano_v3_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::nano_v3 + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::nano_v3 + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::nano_v3 + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::nano_v3 + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + #[macro_export] + macro_rules! arduino_nano_v3_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::nano_v3::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + $crate::arduino::nano_v3::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; + } + pub use arduino_nano_v3_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::nano_v3 + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::nano_v3 + } +} + +pub mod prelude { + use crate::arduino::nano_v3 as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart,default_serial}, +}; diff --git a/arduino-hal/src/arduino/uno.rs b/arduino-hal/src/arduino/uno.rs new file mode 100644 index 0000000000..3dbe3059c6 --- /dev/null +++ b/arduino-hal/src/arduino/uno.rs @@ -0,0 +1,144 @@ +pub use atmega_hal::atmega328p as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::arduino::uno + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_uno; + impl_port_uno! { + board: crate::arduino::uno + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! arduino_uno_pins { + ($p:expr) => { + $crate::arduino::uno::Pins::with_mcu_pins($crate::arduino::uno::hal::pins!($p)) + }; + } + + pub use arduino_uno_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::arduino::uno + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::arduino::uno + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::arduino::uno + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::arduino::uno + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + /// + /// This is equivalent to manually configuring the driver: + /// + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::Usart::new( + /// dp.USART1, + /// pins.d0, + /// pins.d1.into_output(), + /// // See src/usart.rs for why some boards use the BaudrateArduinoExt trait + /// // instead of BaudrateExt. + /// arduino_hal::hal::usart::BaudrateArduinoExt::into_baudrate(57600), + /// ); + /// ``` + #[macro_export] + macro_rules! arduino_uno_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::arduino::uno::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + // See comment in avr-hal-generic/src/usart.rs for why these boards use the + // BaudrateArduinoExt trait instead of BaudrateExt + $crate::arduino::uno::hal::usart::BaudrateArduinoExt::into_baudrate($baud), + ) + }; + } + + pub use arduino_uno_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::arduino::uno + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::arduino::uno + } +} + +pub mod prelude { + use crate::arduino::uno as board; + pub use board::hal::usart::BaudrateArduinoExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart, default_serial}, +}; diff --git a/arduino-hal/src/clock.rs b/arduino-hal/src/clock.rs deleted file mode 100644 index 7c53088015..0000000000 --- a/arduino-hal/src/clock.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! MCU core clock support. -//! -//! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` -//! does not support changing the clock-speed at runtime. -//! -//! Most items in this module are re-exported from [`avr_hal_generic::clock`]. -pub use avr_hal_generic::clock::*; - -pub(crate) mod default { - /// Default clock speed for this board. - /// - /// `arduino-hal` contains a lot of type aliases for assuming this clock speed. As such it is - /// easiest to keep the processor at the selected default speed. - /// - /// However, you can of course still use other clock speeds but you'll then need to correctly - /// name the types from the HAL crate using your own clock definition. - #[cfg(any( - feature = "arduino-diecimila", - feature = "arduino-leonardo", - feature = "arduino-mega2560", - feature = "arduino-mega1280", - feature = "arduino-nano", - feature = "arduino-uno", - feature = "sparkfun-promicro", - feature = "sparkfun-promini-5v", - feature = "trinket-pro", - feature = "nano168", - ))] - pub type DefaultClock = avr_hal_generic::clock::MHz16; - #[cfg(any(feature = "trinket", feature = "sparkfun-promini-3v3"))] - pub type DefaultClock = avr_hal_generic::clock::MHz8; -} diff --git a/arduino-hal/src/delay.rs b/arduino-hal/src/delay.rs deleted file mode 100644 index f1b590724f..0000000000 --- a/arduino-hal/src/delay.rs +++ /dev/null @@ -1,23 +0,0 @@ -use embedded_hal_v0::blocking::delay::{DelayMs, DelayUs}; - -/// Delay type for `embedded-hal` compatibility. -/// -/// This type can be used to pass a generic delay utility to `embedded-hal` drivers. For direct -/// use in `arduino-hal` code, usage of [`delay_ms`] or [`delay_us`] is preferred. -pub type Delay = avr_hal_generic::delay::Delay; - -/// Delay execution for a number of milliseconds. -/// -/// Busy-loop for the given time. This function assumes the default clock speed defined by -/// [`arduino_hal::DefaultClock`][crate::DefaultClock]. -pub fn delay_ms(ms: u16) { - Delay::new().delay_ms(ms) -} - -/// Delay execution for a number of microseconds. -/// -/// Busy-loop for the given time. This function assumes the default clock speed defined by -/// [`arduino_hal::DefaultClock`][crate::DefaultClock]. -pub fn delay_us(us: u32) { - Delay::new().delay_us(us) -} diff --git a/arduino-hal/src/impl/adc.rs b/arduino-hal/src/impl/adc.rs new file mode 100644 index 0000000000..f839998adb --- /dev/null +++ b/arduino-hal/src/impl/adc.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "_mcu-atmega")] +macro_rules! impl_adc_atmega { + ( + board: $($board:ident)::+ $(,)? + ) => { + pub use $($board)::+::hal::adc::{ + channel, AdcChannel, AdcOps, AdcSettings, Channel, ClockDivider, ReferenceVoltage, + }; + + /// Check the [`avr_hal_generic::adc::Adc`] documentation. + pub type Adc = $($board)::+::hal::Adc<$($board)::+::clock::DefaultClock>; + + +} + +} + +#[cfg(feature = "_mcu-atmega")] +pub(crate) use impl_adc_atmega; diff --git a/arduino-hal/src/impl/delay.rs b/arduino-hal/src/impl/delay.rs new file mode 100644 index 0000000000..9f2ccd2678 --- /dev/null +++ b/arduino-hal/src/impl/delay.rs @@ -0,0 +1,33 @@ +macro_rules! impl_delay { + ( + board: $($board:ident)::+ $(,)? + ) => { + + use embedded_hal_v0::blocking::delay::{DelayMs, DelayUs}; + + /// Delay type for `embedded-hal` compatibility. + /// + /// This type can be used to pass a generic delay utility to `embedded-hal` drivers. For direct + /// use in `arduino-hal` code, usage of [`delay_ms`] or [`delay_us`] is preferred. + pub type Delay = avr_hal_generic::delay::Delay<$($board)::+::clock::DefaultClock>; + + /// Delay execution for a number of milliseconds. + /// + /// Busy-loop for the given time. This function assumes the default clock speed defined by + /// [`arduino_hal::DefaultClock`][crate::DefaultClock]. + pub fn delay_ms(ms: u16) { + Delay::new().delay_ms(ms) + } + + /// Delay execution for a number of microseconds. + /// + /// Busy-loop for the given time. This function assumes the default clock speed defined by + /// [`arduino_hal::DefaultClock`][crate::DefaultClock]. + pub fn delay_us(us: u32) { + Delay::new().delay_us(us) + } +} + +} + +pub(crate) use impl_delay; diff --git a/arduino-hal/src/impl/eeprom.rs b/arduino-hal/src/impl/eeprom.rs new file mode 100644 index 0000000000..148da9e088 --- /dev/null +++ b/arduino-hal/src/impl/eeprom.rs @@ -0,0 +1,11 @@ +macro_rules! impl_eeprom { + ( + board: $($board:ident)::+ $(,)? + ) => { + pub use $($board)::+::hal::eeprom::{Eeprom, EepromOps, OutOfBoundsError}; + +} + +} + +pub(crate) use impl_eeprom; diff --git a/arduino-hal/src/impl/i2c.rs b/arduino-hal/src/impl/i2c.rs new file mode 100644 index 0000000000..d88c5e752c --- /dev/null +++ b/arduino-hal/src/impl/i2c.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "_mcu-atmega")] +macro_rules! impl_i2c_atmega { + ( + board: $($board:ident)::+ $(,)? + ) => { + pub use $($board)::+::hal::i2c::*; + + pub type I2c = $($board)::+::hal::i2c::I2c<$($board)::+::clock::DefaultClock>; + +} + +} + +#[cfg(feature = "_mcu-atmega")] +pub(crate) use impl_i2c_atmega; diff --git a/arduino-hal/src/impl/mod.rs b/arduino-hal/src/impl/mod.rs new file mode 100644 index 0000000000..3ec62aa26e --- /dev/null +++ b/arduino-hal/src/impl/mod.rs @@ -0,0 +1,28 @@ +pub(crate) mod delay; +pub(crate) use delay::*; + +#[cfg(feature = "_mcu-atmega")] +pub(crate) mod adc; +#[cfg(feature = "_mcu-atmega")] +pub(crate) use adc::*; + +#[cfg(feature = "_mcu-atmega")] +pub(crate) mod i2c; +#[cfg(feature = "_mcu-atmega")] +pub(crate) use i2c::*; + +#[cfg(feature = "_mcu-atmega")] +pub(crate) mod spi; +#[cfg(feature = "_mcu-atmega")] +pub(crate) use spi::*; + +#[cfg(feature = "_mcu-atmega")] +pub(crate) mod usart; +#[cfg(feature = "_mcu-atmega")] +pub(crate) use usart::*; + +pub(crate) mod eeprom; +pub(crate) use eeprom::*; + +pub(crate) mod simple_pwm; +pub(crate) use simple_pwm::*; diff --git a/arduino-hal/src/impl/simple_pwm.rs b/arduino-hal/src/impl/simple_pwm.rs new file mode 100644 index 0000000000..8c65507f2a --- /dev/null +++ b/arduino-hal/src/impl/simple_pwm.rs @@ -0,0 +1,11 @@ +macro_rules! impl_simple_pwm { + ( + board: $($board:ident)::+ $(,)? + ) => { + pub use $($board)::+::hal::simple_pwm::*; + +} + +} + +pub(crate) use impl_simple_pwm; diff --git a/arduino-hal/src/impl/spi.rs b/arduino-hal/src/impl/spi.rs new file mode 100644 index 0000000000..3d9f2973af --- /dev/null +++ b/arduino-hal/src/impl/spi.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "_mcu-atmega")] +macro_rules! impl_spi_atmega { + ( + board: $($board:ident)::+ $(,)? + ) => { + pub use $($board)::+::hal::spi::*; + + pub type Spi = $($board)::+::hal::spi::Spi; + +} + +} + +#[cfg(feature = "_mcu-atmega")] +pub(crate) use impl_spi_atmega; diff --git a/arduino-hal/src/impl/usart.rs b/arduino-hal/src/impl/usart.rs new file mode 100644 index 0000000000..03ea35d82c --- /dev/null +++ b/arduino-hal/src/impl/usart.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "_mcu-atmega")] +macro_rules! impl_usart_atmega { + ( + board: $($board:ident)::+ $(,)? + ) => { + pub use $($board)::+::hal::usart::{Baudrate, UsartOps}; + + pub type Usart = $($board)::+::hal::usart::Usart; + pub type UsartWriter = + $($board)::+::hal::usart::UsartWriter; + pub type UsartReader = + $($board)::+::hal::usart::UsartReader; + } + +} + +#[cfg(feature = "_mcu-atmega")] +pub(crate) use impl_usart_atmega; + diff --git a/arduino-hal/src/lib.rs b/arduino-hal/src/lib.rs index 5e78dc3318..272a1d7aa9 100644 --- a/arduino-hal/src/lib.rs +++ b/arduino-hal/src/lib.rs @@ -5,34 +5,6 @@ //! ============= //! Common HAL (hardware abstraction layer) for Arduino boards. //! -//! **Note**: This version of the documentation was built for -#![cfg_attr(feature = "arduino-diecimila", doc = "**Arduino Diecimila**.")] -#![cfg_attr(feature = "arduino-leonardo", doc = "**Arduino Leonardo**.")] -#![cfg_attr(feature = "arduino-mega2560", doc = "**Arduino Mega 2560**.")] -#![cfg_attr(feature = "arduino-mega1280", doc = "**Arduino Mega 1280**.")] -#![cfg_attr(feature = "arduino-nano", doc = "**Arduino Nano**.")] -#![cfg_attr(feature = "arduino-uno", doc = "**Arduino Uno**.")] -#![cfg_attr(feature = "sparkfun-promicro", doc = "**SparkFun ProMicro**.")] -#![cfg_attr( - feature = "sparkfun-promini-3v3", - doc = "**SparkFun ProMini 3.3V (8MHz)**." -)] -#![cfg_attr( - feature = "sparkfun-promini-5v", - doc = "**SparkFun ProMini 5V (16MHz)**." -)] -#![cfg_attr(feature = "trinket-pro", doc = "**Trinket Pro**.")] -#![cfg_attr(feature = "trinket", doc = "**Trinket**.")] -#![cfg_attr(feature = "nano168", doc = "**Nano clone (ATmega168)**.")] -//! This means that only items which are available for this board are visible. If you are using a -//! different board, try building the documentation locally with -//! -//! ```text -//! cargo doc --open -//! ``` -//! -//! in your project (where `arduino-hal` is included with the feature-flag for your board). -//! //! ## Usage //! For setting up a new project, the [`avr-hal-template`](https://github.com/Rahix/avr-hal-template) //! is the recommended baseline. Applications should be built ontop of the following skeleton: @@ -54,11 +26,11 @@ //! //! For examples, please check the `avr-hal` examples: -#[cfg(not(feature = "board-selected"))] +#[cfg(not(feature = "_board-selected"))] compile_error!( "This crate requires you to specify your target Arduino board as a feature. - Please select one of the following + Please select at least one of the following features * arduino-diecimila * arduino-leonardo @@ -75,6 +47,12 @@ compile_error!( " ); +pub(crate) mod r#impl; + +pub mod adafruit; +pub mod arduino; +pub mod sparkfun; + /// Attribute to declare the entry point of the program /// /// Exactly one entry point must be declared in the entire dependency tree. @@ -94,249 +72,3 @@ compile_error!( #[doc(cfg(feature = "rt"))] pub use avr_device::entry; -#[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] -pub use atmega_hal as hal; -#[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] -pub use atmega_hal::pac; - -#[doc(no_inline)] -#[cfg(feature = "mcu-attiny")] -pub use attiny_hal as hal; -#[doc(no_inline)] -#[cfg(feature = "mcu-attiny")] -pub use attiny_hal::pac; - -#[doc(no_inline)] -#[cfg(feature = "board-selected")] -pub use hal::Peripherals; - -#[cfg(feature = "board-selected")] -pub mod clock; -#[cfg(feature = "board-selected")] -pub use clock::default::DefaultClock; - -#[cfg(feature = "board-selected")] -mod delay; -#[cfg(feature = "board-selected")] -pub use delay::{delay_ms, delay_us, Delay}; - -#[cfg(feature = "board-selected")] -pub mod port; - -#[doc(no_inline)] -#[cfg(feature = "board-selected")] -pub use port::Pins; - -/// Analog to Digital converter. -#[cfg(feature = "mcu-atmega")] -pub mod adc { - pub use crate::hal::adc::{ - channel, AdcChannel, AdcOps, AdcSettings, Channel, ClockDivider, ReferenceVoltage, - }; - - /// Check the [`avr_hal_generic::adc::Adc`] documentation. - pub type Adc = crate::hal::Adc; -} -#[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] -pub use adc::Adc; - -/// I2C bus controller. -#[cfg(feature = "mcu-atmega")] -pub mod i2c { - pub use crate::hal::i2c::*; - - pub type I2c = crate::hal::i2c::I2c; -} -#[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] -pub use i2c::I2c; - -/// SPI controller. -#[cfg(feature = "mcu-atmega")] -pub mod spi { - pub use crate::hal::spi::*; - - pub type Spi = crate::hal::spi::Spi; -} -#[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] -pub use spi::Spi; - -#[cfg(feature = "mcu-atmega")] -pub mod usart { - pub use crate::hal::usart::{Baudrate, UsartOps}; - - pub type Usart = crate::hal::usart::Usart; - pub type UsartWriter = - crate::hal::usart::UsartWriter; - pub type UsartReader = - crate::hal::usart::UsartReader; -} - -#[doc(no_inline)] -#[cfg(feature = "mcu-atmega")] -pub use usart::Usart; - -#[cfg(feature = "board-selected")] -pub mod eeprom { - pub use crate::hal::eeprom::{Eeprom, EepromOps, OutOfBoundsError}; -} -#[doc(no_inline)] -#[cfg(feature = "board-selected")] -pub use eeprom::Eeprom; - -#[cfg(feature = "board-selected")] -pub mod simple_pwm { - #[cfg(feature = "mcu-atmega")] - pub use atmega_hal::simple_pwm::*; - - #[cfg(feature = "mcu-attiny")] - pub use attiny_hal::simple_pwm::*; -} - -#[cfg(feature = "mcu-atmega")] -pub mod prelude { - pub use crate::hal::prelude::*; - - cfg_if::cfg_if! { - if #[cfg(any( - feature = "arduino-diecimila", - feature = "arduino-mega2560", - feature = "arduino-mega1280", - feature = "arduino-uno" - ))] { - pub use crate::hal::usart::BaudrateArduinoExt as _; - } else { - pub use crate::hal::usart::BaudrateExt as _; - } - } -} - -/// Convenience macro to instantiate the [`Pins`] struct for this board. -/// -/// # Example -/// ```no_run -/// let dp = arduino_hal::Peripherals::take().unwrap(); -/// let pins = arduino_hal::pins!(dp); -/// ``` -#[cfg(feature = "board-selected")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::with_mcu_pins($crate::hal::pins!($p)) - }; -} - -/// Convenience macro to instantiate the [`Usart`] driver for this board. -/// -/// # Example -/// ```no_run -/// let dp = arduino_hal::Peripherals::take().unwrap(); -/// let pins = arduino_hal::pins!(dp); -/// let serial = arduino_hal::default_serial!(dp, pins, 57600); -/// ``` -#[cfg(any(feature = "arduino-leonardo"))] -#[macro_export] -macro_rules! default_serial { - ($p:expr, $pins:expr, $baud:expr) => { - $crate::Usart::new( - $p.USART1, - $pins.d0, - $pins.d1.into_output(), - $crate::hal::usart::BaudrateExt::into_baudrate($baud), - ) - }; -} - -/// Convenience macro to instantiate the [`Usart`] driver for this board. -/// -/// # Example -/// ```no_run -/// let dp = arduino_hal::Peripherals::take().unwrap(); -/// let pins = arduino_hal::pins!(dp); -/// let serial = arduino_hal::default_serial!(dp, pins, 57600); -/// ``` -#[cfg(any(feature = "sparkfun-promicro"))] -#[macro_export] -macro_rules! default_serial { - ($p:expr, $pins:expr, $baud:expr) => { - $crate::Usart::new( - $p.USART1, - $pins.rx, - $pins.tx.into_output(), - $crate::hal::usart::BaudrateExt::into_baudrate($baud), - ) - }; -} - -/// Convenience macro to instantiate the [`Usart`] driver for this board. -/// -/// # Example -/// ```no_run -/// let dp = arduino_hal::Peripherals::take().unwrap(); -/// let pins = arduino_hal::pins!(dp); -/// let serial = arduino_hal::default_serial!(dp, pins, 57600); -/// ``` -/// -/// This is equivalent to manually configuring the driver: -/// -/// ```no_run -/// let dp = arduino_hal::Peripherals::take().unwrap(); -/// let pins = arduino_hal::pins!(dp); -/// let serial = arduino_hal::Usart::new( -/// dp.USART1, -/// pins.d0, -/// pins.d1.into_output(), -/// // See src/usart.rs for why some boards use the BaudrateArduinoExt trait -/// // instead of BaudrateExt. -/// arduino_hal::hal::usart::BaudrateArduinoExt::into_baudrate(57600), -/// ); -/// ``` -#[cfg(any( - feature = "arduino-diecimila", - feature = "arduino-mega2560", - feature = "arduino-mega1280", - feature = "arduino-uno" -))] -#[macro_export] -macro_rules! default_serial { - ($p:expr, $pins:expr, $baud:expr) => { - $crate::Usart::new( - $p.USART0, - $pins.d0, - $pins.d1.into_output(), - // See comment in avr-hal-generic/src/usart.rs for why these boards use the - // BaudrateArduinoExt trait instead of BaudrateExt - $crate::hal::usart::BaudrateArduinoExt::into_baudrate($baud), - ) - }; -} - -/// Convenience macro to instantiate the [`Usart`] driver for this board. -/// -/// # Example -/// ```no_run -/// let dp = arduino_hal::Peripherals::take().unwrap(); -/// let pins = arduino_hal::pins!(dp); -/// let serial = arduino_hal::default_serial!(dp, pins, 57600); -/// ``` -#[cfg(any( - feature = "arduino-nano", - feature = "nano168", - feature = "sparkfun-promini-3v3", - feature = "sparkfun-promini-5v", -))] -#[macro_export] -macro_rules! default_serial { - ($p:expr, $pins:expr, $baud:expr) => { - $crate::Usart::new( - $p.USART0, - $pins.d0, - $pins.d1.into_output(), - $crate::hal::usart::BaudrateExt::into_baudrate($baud), - ) - }; -} diff --git a/arduino-hal/src/port/diecimila.rs b/arduino-hal/src/port/diecimila.rs deleted file mode 100644 index a264172774..0000000000 --- a/arduino-hal/src/port/diecimila.rs +++ /dev/null @@ -1,131 +0,0 @@ -pub use atmega_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - /// Pins of the **Arduino Diecimila**. - /// - /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. - pub struct Pins { - /// `A0` - /// - /// * ADC0 (ADC input channel 0) - /// * PCINT8 (pin change interrupt 8) - pub a0: atmega_hal::port::PC0 = pc0, - /// `A1` - /// - /// * ADC1 (ADC input channel 1) - /// * PCINT9 (pin change interrupt 9) - pub a1: atmega_hal::port::PC1 = pc1, - /// `A2` - /// - /// * ADC2 (ADC input channel 2) - /// * PCINT10 (pin change interrupt 10) - pub a2: atmega_hal::port::PC2 = pc2, - /// `A3` - /// - /// * ADC3 (ADC input channel 3) - /// * PCINT11 (pin change interrupt 11) - pub a3: atmega_hal::port::PC3 = pc3, - /// `A4` - /// - /// * ADC4 (ADC input channel 4) - /// * SDA (2-wire serial bus data input/output line) - /// * PCINT12 (pin change interrupt 12) - pub a4: atmega_hal::port::PC4 = pc4, - /// `A5` - /// - /// ADC5 (ADC input channel 5) - /// SCL (2-wire serial bus clock line) - /// PCINT13 (pin change interrupt 13) - pub a5: atmega_hal::port::PC5 = pc5, - - /// `D0` / `RX` - /// - /// * RXD (USART input pin) - /// * PCINT16 (pin change interrupt 16) - pub d0: atmega_hal::port::PD0 = pd0, - /// `D1` / `TX` - /// - /// * TXD (USART output pin) - /// * PCINT17 (pin change interrupt 17) - pub d1: atmega_hal::port::PD1 = pd1, - /// `D2` - /// - /// * INT0 (external interrupt 0 input) - /// * PCINT18 (pin change interrupt 18) - pub d2: atmega_hal::port::PD2 = pd2, - /// `D3` - /// - /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] - /// * INT1 (external interrupt 1 input) - /// * OC2B (Timer/Counter2 output compare match B output) - /// * PCINT19 (pin change interrupt 19) - pub d3: atmega_hal::port::PD3 = pd3, - /// `D4` - /// - /// * XCK (USART external clock input/output) - /// * T0 (Timer/Counter 0 external counter input) - /// * PCINT20 (pin change interrupt 20) - pub d4: atmega_hal::port::PD4 = pd4, - /// `D5` - /// - /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] - /// * T1 (Timer/Counter 1 external counter input) - /// * OC0B (Timer/Counter0 output compare match B output) - /// * PCINT21 (pin change interrupt 21) - pub d5: atmega_hal::port::PD5 = pd5, - /// `D6` - /// - /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] - /// * AIN0 (analog comparator positive input) - /// * OC0A (Timer/Counter0 output compare match A output) - /// * PCINT22 (pin change interrupt 22) - pub d6: atmega_hal::port::PD6 = pd6, - /// `D7` - /// - /// * AIN1 (analog comparator negative input) - /// * PCINT23 (pin change interrupt 23) - pub d7: atmega_hal::port::PD7 = pd7, - /// `D8` - /// - /// * ICP1 (Timer/Counter1 input capture input) - /// * CLKO (divided system clock output) - /// * PCINT0 (pin change interrupt 0) - pub d8: atmega_hal::port::PB0 = pb0, - /// `D9` - /// - /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] - /// * OC1A (Timer/Counter1 output compare match A output) - /// * PCINT1 (pin change interrupt 1) - pub d9: atmega_hal::port::PB1 = pb1, - /// `D10` - /// - /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] - /// * SS (SPI bus master slave select) - /// * OC1B (Timer/Counter1 output compare match B output) - /// * PCINT2 (pin change interrupt 2) - pub d10: atmega_hal::port::PB2 = pb2, - /// `D11` - /// - /// * **PWM**: [atmega168_hal::timer::Timer3Pwm] - /// * MOSI (SPI bus master/slave input) - /// * OC2A (Timer/Counter2 output compare match A output) - /// * PCINT3 (pin change interrupt 3) - pub d11: atmega_hal::port::PB3 = pb3, - /// `D12` - /// - /// * MISO (SPI bus master input/slave output) - /// * PCINT4 (pin change interrupt 4) - pub d12: atmega_hal::port::PB4 = pb4, - /// `D13` - /// - /// * SCK (SPI bus master clock input) - /// * PCINT5 (pin change interrupt 5) - /// * L LED on Arduino Uno - pub d13: atmega_hal::port::PB5 = pb5, - } - - impl Pins { - type Pin = Pin; - type McuPins = atmega_hal::Pins; - } -} diff --git a/arduino-hal/src/port/leonardo.rs b/arduino-hal/src/port/leonardo.rs deleted file mode 100644 index c25b5a89b9..0000000000 --- a/arduino-hal/src/port/leonardo.rs +++ /dev/null @@ -1,127 +0,0 @@ -pub use atmega_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - /// Pins of the **Arduino Leonardo**. - /// - /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. - pub struct Pins { - /// `D0` / `RX` - /// - /// * `RX` (UART) - /// * `INT2`: External Interrupt - pub d0: atmega_hal::port::PD2 = pd2, - /// `D1` / `TX` - /// - /// * `TX` (UART) - /// * `INT3`: External Interrupt - pub d1: atmega_hal::port::PD3 = pd3, - /// `D2` / `SDA` - /// - /// * `SDA`: i2c/twi data - /// * `INT1`: External Interrupt - pub d2: atmega_hal::port::PD1 = pd1, - /// `D3` / `SCL` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] - /// * `SCL`: i2c/twi clock - /// * `INT0`: External Interrupt - /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 - pub d3: atmega_hal::port::PD0 = pd0, - /// `D4` - pub d4: atmega_hal::port::PD4 = pd4, - /// `D5` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer3Pwm] - /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 - /// * `#OC4A`: Inverted Output Compare Channel `A` for Timer/Counter4 (Not implemented) - pub d5: atmega_hal::port::PC6 = pc6, - /// `D6` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] - /// * `OC4D`: Output Compare Channel `D` for Timer/Counter4 - pub d6: atmega_hal::port::PD7 = pd7, - /// `D7` - /// - /// * `INT6`: External Interrupt - pub d7: atmega_hal::port::PE6 = pe6, - /// `D8` - pub d8: atmega_hal::port::PB4 = pb4, - /// `D9` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] - /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 - /// * `#OC4B`: Inverted Output Compare Channel `B` for Timer/Counter4 (Not implemented) - pub d9: atmega_hal::port::PB5 = pb5, - /// `D10` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer1Pwm] - /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 - /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 (Not implemented) - pub d10: atmega_hal::port::PB6 = pb6, - /// `D11` - /// - /// * **PWM**: [atmega32u4_hal::timer::Timer0Pwm] - /// * `OC0A`: Output Compare Channel `B` for Timer/Counter0 - /// * `OC1C`: Output Compare Channel `C` for Timer/Counter1 - pub d11: atmega_hal::port::PB7 = pb7, - /// `D12` - /// - /// * `#OC4D`: Inverted Output Compare Channel `D` for Timer/Counter4 (Not implemented) - pub d12: atmega_hal::port::PD6 = pd6, - /// `D13` / `LED_BUILTIN` - /// - /// * Onboard LED - /// * **PWM**: [atmega32u4_hal::timer::Timer4Pwm] - /// * `OC4A`: Output Compare Channel `A` for Timer/Counter4 - pub d13: atmega_hal::port::PC7 = pc7, - /// `RX` - /// - /// Led for indicating inbound data. Also the CS pin. - pub led_rx: atmega_hal::port::PB0 = pb0, - /// `TX` - /// - /// Led for indicating outbound data - pub led_tx: atmega_hal::port::PD5 = pd5, - /// `SCLK` - /// - /// ICSP SCLK pin - pub sck: atmega_hal::port::PB1 = pb1, - /// `MOSI` - /// - /// ICSP MOSI pin - pub mosi: atmega_hal::port::PB2 = pb2, - /// `MISO` - /// - /// ICSP MISO pin - pub miso: atmega_hal::port::PB3 = pb3, - /// `A0` - /// - /// * `ADC7` channel - pub a0: atmega_hal::port::PF7 = pf7, - /// `A1` - /// - /// * `ADC6` channel - pub a1: atmega_hal::port::PF6 = pf6, - /// `A2` - /// - /// * `ADC5` channel - pub a2: atmega_hal::port::PF5 = pf5, - /// `A3` - /// - /// * `ADC4` channel - pub a3: atmega_hal::port::PF4 = pf4, - /// `A4` - /// - /// * `ADC1` channel - pub a4: atmega_hal::port::PF1 = pf1, - /// `A5` - /// - /// * `ADC0` channel - pub a5: atmega_hal::port::PF0 = pf0, - } - - impl Pins { - type Pin = Pin; - type McuPins = atmega_hal::Pins; - } -} diff --git a/arduino-hal/src/port/mega.rs b/arduino-hal/src/port/mega.rs deleted file mode 100644 index fa64d02579..0000000000 --- a/arduino-hal/src/port/mega.rs +++ /dev/null @@ -1,343 +0,0 @@ -pub use atmega_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - /// Pins of the **Arduino Mega 2560** and **Arduino Mega 1280**. - /// - /// mega1280: - /// https://www.arduino.cc/en/uploads/Main/arduino-mega-schematic.pdf - /// mega2560: - /// https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf - /// - /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. - pub struct Pins { - /// `D0` / `RX0` - /// - /// * `RXD0` (USART0) - /// * `PCINT8`: External Interrupt (Pin Change) - pub d0: atmega_hal::port::PE0 = pe0, - /// `D1` / `TX0` - /// - /// * `TXD0` (USART0) - pub d1: atmega_hal::port::PE1 = pe1, - /// `D2` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] - /// * `OC3B`: Output Compare Channel `B` for Timer/Counter3 - /// * `INT4`: External Interrupt - pub d2: atmega_hal::port::PE4 = pe4, - /// `D3` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] - /// * `OC3C`: Output Compare Channel `C` for Timer/Counter3 - /// * `INT5`: External Interrupt - pub d3: atmega_hal::port::PE5 = pe5, - /// `D4` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer0Pwm] - /// * `OC0B`: Output Compare Channel `B` for Timer/Counter0 - pub d4: atmega_hal::port::PG5 = pg5, - /// `D5` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer3Pwm] - /// * `OC3A`: Output Compare Channel `A` for Timer/Counter3 - /// * `AIN1`: Analog Comparator Negative Input (Not Implemented) - pub d5: atmega_hal::port::PE3 = pe3, - /// `D6` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] - /// * `OC4A`: Output Compare Channel `A` for Timer/Counter4 - pub d6: atmega_hal::port::PH3 = ph3, - /// `D7` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] - /// * `OC4B`: Output Compare Channel `B` for Timer/Counter4 - pub d7: atmega_hal::port::PH4 = ph4, - /// `D8` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer4Pwm] - /// * `OC4C`: Output Compare Channel `C` for Timer/Counter4 - pub d8: atmega_hal::port::PH5 = ph5, - /// `D9` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer2Pwm] - /// * `OC2B`: Output Compare Channel `B` for Timer/Counter2 - pub d9: atmega_hal::port::PH6 = ph6, - /// `D10` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer2Pwm] - /// * `OC2B`: Output Compare Channel `B` for Timer/Counter2 - /// * `PCINT4`: External Interrupt (Pin Change) - pub d10: atmega_hal::port::PB4 = pb4, - /// `D11` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] - /// * `OC1A`: Output Compare Channel `A` for Timer/Counter1 - /// * `PCINT5`: External Interrupt (Pin Change) - pub d11: atmega_hal::port::PB5 = pb5, - /// `D12` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] - /// * `OC1B`: Output Compare Channel `B` for Timer/Counter1 - /// * `PCINT6`: External Interrupt (Pin Change) - pub d12: atmega_hal::port::PB6 = pb6, - /// `D13` - /// - /// * Onboard LED - /// * **PWM**: [atmega2560_hal::timer::Timer0Pwm] - /// * **PWM**: [atmega2560_hal::timer::Timer1Pwm] - /// * `OC0A`: Output Compare Channel `A` for Timer/Counter0 - /// * `OC1C`: Output Compare Channel `C` for Timer/Counter1 - /// * `PCINT7`: External Interrupt (Pin Change) - pub d13: atmega_hal::port::PB7 = pb7, - /// `D14` / `TX3` - /// - /// * `TXD3` (USART3) - /// * `PCINT10`: External Interrupt (Pin Change) - pub d14: atmega_hal::port::PJ1 = pj1, - /// `D15` / `RX3` - /// - /// * `RXD3` (USART3) - /// * `PCINT9`: External Interrupt (Pin Change) - pub d15: atmega_hal::port::PJ0 = pj0, - /// `D16` / `TX2` - /// - /// * `TXD2` (USART2) - pub d16: atmega_hal::port::PH1 = ph1, - /// `D17` / `RX2` - /// - /// * `RXD2` (USART2) - pub d17: atmega_hal::port::PH0 = ph0, - /// `D18` / `TX1` - /// - /// * `TXD1` (USART1) - /// * `INT3`: External Interrupt - pub d18: atmega_hal::port::PD3 = pd3, - /// `D19` / `RX1` - /// - /// * `RXD1` (USART1) - /// * `INT2`: External Interrupt - pub d19: atmega_hal::port::PD2 = pd2, - /// `D20` / `SDA` - /// - /// * `SDA`: i2c/twi data - /// * `INT1`: External Interrupt - pub d20: atmega_hal::port::PD1 = pd1, - /// `D21` / `SCL` - /// - /// * `SCL`: i2c/twi clock - /// * `INT0`: External Interrupt - pub d21: atmega_hal::port::PD0= pd0, - /// `D22` - /// - /// * `AD0`: External memory interface - pub d22: atmega_hal::port::PA0 = pa0, - /// `D23` - /// - /// * `AD1`: External memory interface - pub d23: atmega_hal::port::PA1 = pa1, - /// `D24` - /// - /// * `AD2`: External memory interface - pub d24: atmega_hal::port::PA2 = pa2, - /// `D25` - /// - /// * `AD3`: External memory interface - pub d25: atmega_hal::port::PA3 = pa3, - /// `D26` - /// - /// * `AD4`: External memory interface - pub d26: atmega_hal::port::PA4 = pa4, - /// `D27` - /// - /// * `AD5`: External memory interface - pub d27: atmega_hal::port::PA5 = pa5, - /// `D28` - /// - /// * `AD6`: External memory interface - pub d28: atmega_hal::port::PA6 = pa6, - /// `D29` - /// - /// * `AD7`: External memory interface - pub d29: atmega_hal::port::PA7 = pa7, - /// `D30` - /// - /// * `AD15`: External memory interface - pub d30: atmega_hal::port::PC7 = pc7, - /// `D31` - /// - /// * `AD14`: External memory interface - pub d31: atmega_hal::port::PC6 = pc6, - /// `D32` - /// - /// * `AD13`: External memory interface - pub d32: atmega_hal::port::PC5 = pc5, - /// `D33` - /// - /// * `AD12`: External memory interface - pub d33: atmega_hal::port::PC4 = pc4, - /// `D34` - /// - /// * `AD11`: External memory interface - pub d34: atmega_hal::port::PC3 = pc3, - /// `D35` - /// - /// * `AD10`: External memory interface - pub d35: atmega_hal::port::PC2 = pc2, - /// `D36` - /// - /// * `AD9`: External memory interface - pub d36: atmega_hal::port::PC1 = pc1, - /// `D37` - /// - /// * `AD8`: External memory interface - pub d37: atmega_hal::port::PC0 = pc0, - /// `D38` - /// - /// * `T0`: Clock Input for Timer/Counter0 - pub d38: atmega_hal::port::PD7 = pd7, - /// `D39` - /// - /// * `ALE`: External memory Address Latch Enable - pub d39: atmega_hal::port::PG2 = pg2, - /// `D40` - /// - /// `RD`: External memory Read Strobe - pub d40: atmega_hal::port::PG1 = pg1, - /// `D41` - /// - /// `WR`: External memory Write Strobe - pub d41: atmega_hal::port::PG0 = pg0, - /// `D42` - pub d42: atmega_hal::port::PL7 = pl7, - /// `D43` - pub d43: atmega_hal::port::PL6 = pl6, - /// `D44` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] - /// * `OC5C`: Output Compare Channel `C` for Timer/Counter5 - pub d44: atmega_hal::port::PL5 = pl5, - /// `D45` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] - /// * `OC5B`: Output Compare Channel `B` for Timer/Counter5 - pub d45: atmega_hal::port::PL4 = pl4, - /// `D46` - /// - /// * **PWM**: [atmega2560_hal::timer::Timer5Pwm] - /// * `OC5A`: Output Compare Channel `A` for Timer/Counter5 - pub d46: atmega_hal::port::PL3 = pl3, - /// `D47` - /// - /// * `T5`: Clock Input for Timer/Counter5 - pub d47: atmega_hal::port::PL2 = pl2, - /// `D48` - /// - /// * `ICP5`: Input Capture Trigger for Timer/Counter5 - pub d48: atmega_hal::port::PL1 = pl1, - /// `D49` - /// - /// * `ICP4`: Input Capture Trigger for Timer/Counter4 - pub d49: atmega_hal::port::PL0 = pl0, - /// `D50` - /// - /// * `MISO`: SPI bus Master In/Slave Out - /// * `PCINT3`: External Interrupt (Pin Change) - pub d50: atmega_hal::port::PB3 = pb3, - /// `D51` - /// - /// * `MOSI`: SPI bus Master Out/Slave In - /// * `PCINT2`: External Interrupt (Pin Change) - pub d51: atmega_hal::port::PB2 = pb2, - /// `D52` - /// - /// * `SCK`: SPI bus Serial Clock - /// * `PCINT1`: External Interrupt (Pin Change) - pub d52: atmega_hal::port::PB1 = pb1, - /// `D53` - /// - /// * `SS`: SPI bus Slave Select - /// * `PCINT0`: External Interrupt (Pin Change) - pub d53: atmega_hal::port::PB0 = pb0, - /// `A0` - /// - /// * `ADC0`: A/D converter input 0 - pub a0: atmega_hal::port::PF0 = pf0, - /// `A1` - /// - /// * `ADC1`: A/D converter input 1 - pub a1: atmega_hal::port::PF1 = pf1, - /// `A2` - /// - /// * `ADC2`: A/D converter input 2 - pub a2: atmega_hal::port::PF2 = pf2, - /// `A3` - /// - /// * `ADC3`: A/D converter input 3 - pub a3: atmega_hal::port::PF3 = pf3, - /// `A4` - /// - /// * `ADC4`: A/D converter input 4 - /// * `TCK`: JTAG test clock - pub a4: atmega_hal::port::PF4 = pf4, - /// `A5` - /// - /// * `ADC5`: A/D converter input 5 - /// * `TMS`: JTAG test mode select - pub a5: atmega_hal::port::PF5 = pf5, - /// `A6` - /// - /// * `ADC6`: A/D converter input 6 - /// * `TDO`: JTAG test data output - pub a6: atmega_hal::port::PF6 = pf6, - /// `A7` - /// - /// * `ADC7`: A/D converter input 7 - /// * `TDI`: JTAG test data input - pub a7: atmega_hal::port::PF7 = pf7, - /// `A8` - /// - /// * `ADC8`: A/D converter input 8 - /// * `PCINT16`: External Interrupt (Pin Change) - pub a8: atmega_hal::port::PK0 = pk0, - /// `A9` - /// - /// * `ADC9`: A/D converter input 9 - /// * `PCINT17`: External Interrupt (Pin Change) - pub a9: atmega_hal::port::PK1 = pk1, - /// `A10` - /// - /// * `ADC10`: A/D converter input 10 - /// * `PCINT18`: External Interrupt (Pin Change) - pub a10: atmega_hal::port::PK2 = pk2, - /// `A11` - /// - /// * `ADC11`: A/D converter input 11 - /// * `PCINT19`: External Interrupt (Pin Change) - pub a11: atmega_hal::port::PK3 = pk3, - /// `A12` - /// - /// * `ADC12`: A/D converter input 12 - /// * `PCINT20`: External Interrupt (Pin Change) - pub a12: atmega_hal::port::PK4 = pk4, - /// `A13` - /// - /// * `ADC13`: A/D converter input 13 - /// * `PCINT21`: External Interrupt (Pin Change) - pub a13: atmega_hal::port::PK5 = pk5, - /// `A14` - /// - /// * `ADC14`: A/D converter input 14 - /// * `PCINT22`: External Interrupt (Pin Change) - pub a14: atmega_hal::port::PK6 = pk6, - /// `A15` - /// - /// * `ADC15`: A/D converter input 15 - /// * `PCINT23`: External Interrupt (Pin Change) - pub a15: atmega_hal::port::PK7 = pk7, - } - - impl Pins { - type Pin = Pin; - type McuPins = atmega_hal::Pins; - } -} diff --git a/arduino-hal/src/port/mod.rs b/arduino-hal/src/port/mod.rs deleted file mode 100644 index 160d3f9811..0000000000 --- a/arduino-hal/src/port/mod.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! GPIO & Pin control. -//! -//! This module contains a [`Pins`] struct which represents all pins of the board. The [`Pins`] -//! struct is most easily constructed using the [`arduino_hal::pins!()`][crate::pins] macro: -//! -//! ```no_run -//! let dp = arduino_hal::Peripherals::take().unwrap(); -//! let pins = arduino_hal::pins!(dp); -//! ``` -//! -//! Additionally, the [`mode`] submodule contains all valid types for the `MODE` generic parameter -//! of a pin. The [`Pin`] type-alias represents a pin which can represent _any_ of the pins -//! dynamically (while usually each pin has its own type). -//! -//! Check the documentation for [`avr_hal_generic::port::Pin`] for a detailed explanation of GPIO -//! pins in `avr-hal`. - -#[cfg(feature = "arduino-diecimila")] -mod diecimila; -#[cfg(feature = "arduino-diecimila")] -pub use diecimila::*; -#[cfg(feature = "arduino-leonardo")] -mod leonardo; -#[cfg(feature = "arduino-leonardo")] -pub use leonardo::*; -#[cfg(any(feature = "arduino-mega2560", feature = "arduino-mega1280"))] -mod mega; -#[cfg(any(feature = "arduino-mega2560", feature = "arduino-mega1280"))] -pub use mega::*; -#[cfg(any( - feature = "arduino-nano", - feature = "arduino-uno", - feature = "nano168", - feature = "sparkfun-promini-3v3", - feature = "sparkfun-promini-5v" -))] -mod uno; -#[cfg(any( - feature = "arduino-nano", - feature = "arduino-uno", - feature = "nano168", - feature = "sparkfun-promini-3v3", - feature = "sparkfun-promini-5v" -))] -pub use uno::*; -#[cfg(feature = "sparkfun-promicro")] -mod promicro; -#[cfg(feature = "sparkfun-promicro")] -pub use promicro::*; -#[cfg(feature = "trinket-pro")] -mod trinket_pro; -#[cfg(feature = "trinket-pro")] -pub use trinket_pro::*; -#[cfg(feature = "trinket")] -mod trinket; -#[cfg(feature = "trinket")] -pub use trinket::*; diff --git a/arduino-hal/src/port/promicro.rs b/arduino-hal/src/port/promicro.rs deleted file mode 100644 index 5870749c47..0000000000 --- a/arduino-hal/src/port/promicro.rs +++ /dev/null @@ -1,80 +0,0 @@ -pub use atmega_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - /// Pins of the **SparkFun ProMicro**. - /// - /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. - pub struct Pins { - /// `RX` - /// - /// `RX` (UART) - pub rx: atmega_hal::port::PD2 = pd2, - /// `TX` - /// - /// `TX` (UART) - pub tx: atmega_hal::port::PD3 = pd3, - /// `D2` / `SDA` - /// - /// `SDA`: i2c/twi data - pub d2: atmega_hal::port::PD1 = pd1, - /// `D3` / `SCL` - /// - /// `SCL`: i2c/twi clock - pub d3: atmega_hal::port::PD0 = pd0, - /// `D4` - pub d4: atmega_hal::port::PD4 = pd4, - /// `D5` - pub d5: atmega_hal::port::PC6 = pc6, - /// `D6` - pub d6: atmega_hal::port::PD7 = pd7, - /// `D7` - pub d7: atmega_hal::port::PE6 = pe6, - /// `D8` - pub d8: atmega_hal::port::PB4 = pb4, - /// `D9` - pub d9: atmega_hal::port::PB5 = pb5, - /// `D10` - pub d10: atmega_hal::port::PB6 = pb6, - /// `LED_RX` - /// - /// Led for indicating inbound data (yellow). Also the CS pin for SPI. - pub led_rx: atmega_hal::port::PB0 = pb0, - /// `LED_TX` - /// - /// Led for indicating outbound data (green). - pub led_tx: atmega_hal::port::PD5 = pd5, - /// `D15`, `SCK` - /// - /// ICSP SCLK pin - pub d15: atmega_hal::port::PB1 = pb1, - /// `D14`, `MISO` - /// - /// ICSP MISO pin - pub d16: atmega_hal::port::PB3 = pb3, - /// `D16`, `MOSI` - /// - /// ICSP MOSI pin - pub d14: atmega_hal::port::PB2 = pb2, - /// `A0` - /// - /// `ADC7` channel - pub a0: atmega_hal::port::PF7 = pf7, - /// `A1` - /// - /// `ADC6` channel - pub a1: atmega_hal::port::PF6 = pf6, - /// `A2` - /// - /// `ADC5` channel - pub a2: atmega_hal::port::PF5 = pf5, - /// `A3` - /// - /// `ADC4` channel - pub a3: atmega_hal::port::PF4 = pf4, - } - - impl Pins { - type Pin = Pin; - type McuPins = atmega_hal::Pins; - } -} diff --git a/arduino-hal/src/port/trinket.rs b/arduino-hal/src/port/trinket.rs deleted file mode 100644 index 7a5b2debf1..0000000000 --- a/arduino-hal/src/port/trinket.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub use attiny_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - pub struct Pins { - /// `#0`: `PB0`, `DI`(SPI), `SDA`(I2C) - pub d0: attiny_hal::port::PB0 = pb0, - /// `#1`: `PB1`, `DO`(SPI), Builtin LED - pub d1: attiny_hal::port::PB1 = pb1, - /// `#2`: `PB2`, `SCK`(SPI), `SCL`(I2C) - pub d2: attiny_hal::port::PB2 = pb2, - /// `#3`: `PB3` - pub d3: attiny_hal::port::PB3 = pb3, - /// `#4`: `PB4` - pub d4: attiny_hal::port::PB4 = pb4, - } - - impl Pins { - type Pin = Pin; - type McuPins = attiny_hal::Pins; - } -} diff --git a/arduino-hal/src/port/trinket_pro.rs b/arduino-hal/src/port/trinket_pro.rs deleted file mode 100644 index 71792a6a68..0000000000 --- a/arduino-hal/src/port/trinket_pro.rs +++ /dev/null @@ -1,121 +0,0 @@ -pub use atmega_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - /// Pins of the **Trinket Pro**. - /// - /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. - pub struct Pins { - /// `A0` - /// - /// * ADC0 (ADC input channel 0) - /// * PCINT8 (pin change interrupt 8) - pub a0: atmega_hal::port::PC0 = pc0, - /// `A1` - /// - /// * ADC1 (ADC input channel 1) - /// * PCINT9 (pin change interrupt 9) - pub a1: atmega_hal::port::PC1 = pc1, - /// `A2` - /// - /// * ADC2 (ADC input channel 2) - /// * PCINT10 (pin change interrupt 10) - pub a2: atmega_hal::port::PC2 = pc2, - /// `A3` - /// - /// * ADC3 (ADC input channel 3) - /// * PCINT11 (pin change interrupt 11) - pub a3: atmega_hal::port::PC3 = pc3, - /// `A4` - /// - /// * ADC4 (ADC input channel 4) - /// * SDA (2-wire serial bus data input/output line) - /// * PCINT12 (pin change interrupt 12) - pub a4: atmega_hal::port::PC4 = pc4, - /// `A5` - /// - /// ADC5 (ADC input channel 5) - /// SCL (2-wire serial bus clock line) - /// PCINT13 (pin change interrupt 13) - pub a5: atmega_hal::port::PC5 = pc5, - - /// `D0` / `RX` - /// - /// * RXD (USART input pin) - /// * PCINT16 (pin change interrupt 16) - pub d0: atmega_hal::port::PD0 = pd0, - /// `D1` / `TX` - /// - /// * TXD (USART output pin) - /// * PCINT17 (pin change interrupt 17) - pub d1: atmega_hal::port::PD1 = pd1, - /// `D3` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * INT1 (external interrupt 1 input) - /// * OC2B (Timer/Counter2 output compare match B output) - /// * PCINT19 (pin change interrupt 19) - pub d3: atmega_hal::port::PD3 = pd3, - /// `D4` - /// - /// * XCK (USART external clock input/output) - /// * T0 (Timer/Counter 0 external counter input) - /// * PCINT20 (pin change interrupt 20) - pub d4: atmega_hal::port::PD4 = pd4, - /// `D5` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * T1 (Timer/Counter 1 external counter input) - /// * OC0B (Timer/Counter0 output compare match B output) - /// * PCINT21 (pin change interrupt 21) - pub d5: atmega_hal::port::PD5 = pd5, - /// `D6` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * AIN0 (analog comparator positive input) - /// * OC0A (Timer/Counter0 output compare match A output) - /// * PCINT22 (pin change interrupt 22) - pub d6: atmega_hal::port::PD6 = pd6, - /// `D8` - /// - /// * ICP1 (Timer/Counter1 input capture input) - /// * CLKO (divided system clock output) - /// * PCINT0 (pin change interrupt 0) - pub d8: atmega_hal::port::PB0 = pb0, - /// `D9` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * OC1A (Timer/Counter1 output compare match A output) - /// * PCINT1 (pin change interrupt 1) - pub d9: atmega_hal::port::PB1 = pb1, - /// `D10` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * SS (SPI bus master slave select) - /// * OC1B (Timer/Counter1 output compare match B output) - /// * PCINT2 (pin change interrupt 2) - pub d10: atmega_hal::port::PB2 = pb2, - /// `D11` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * MOSI (SPI bus master/slave input) - /// * OC2A (Timer/Counter2 output compare match A output) - /// * PCINT3 (pin change interrupt 3) - pub d11: atmega_hal::port::PB3 = pb3, - /// `D12` - /// - /// * MISO (SPI bus master input/slave output) - /// * PCINT4 (pin change interrupt 4) - pub d12: atmega_hal::port::PB4 = pb4, - /// `D13` - /// - /// * SCK (SPI bus master clock input) - /// * PCINT5 (pin change interrupt 5) - /// * L LED on Trinket Pro - pub d13: atmega_hal::port::PB5 = pb5, - } - - impl Pins { - type Pin = Pin; - type McuPins = atmega_hal::Pins; - } -} diff --git a/arduino-hal/src/port/uno.rs b/arduino-hal/src/port/uno.rs deleted file mode 100644 index ae193edd27..0000000000 --- a/arduino-hal/src/port/uno.rs +++ /dev/null @@ -1,131 +0,0 @@ -pub use atmega_hal::port::{mode, Pin, PinMode, PinOps}; - -avr_hal_generic::renamed_pins! { - /// Pins of the **Arduino Uno**, **Arduino Nano**, **SparkFun ProMini 3.3V (8Mhz)**, and **SparkFun ProMini 5V (16MHz)**. - /// - /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. - pub struct Pins { - /// `A0` - /// - /// * ADC0 (ADC input channel 0) - /// * PCINT8 (pin change interrupt 8) - pub a0: atmega_hal::port::PC0 = pc0, - /// `A1` - /// - /// * ADC1 (ADC input channel 1) - /// * PCINT9 (pin change interrupt 9) - pub a1: atmega_hal::port::PC1 = pc1, - /// `A2` - /// - /// * ADC2 (ADC input channel 2) - /// * PCINT10 (pin change interrupt 10) - pub a2: atmega_hal::port::PC2 = pc2, - /// `A3` - /// - /// * ADC3 (ADC input channel 3) - /// * PCINT11 (pin change interrupt 11) - pub a3: atmega_hal::port::PC3 = pc3, - /// `A4` - /// - /// * ADC4 (ADC input channel 4) - /// * SDA (2-wire serial bus data input/output line) - /// * PCINT12 (pin change interrupt 12) - pub a4: atmega_hal::port::PC4 = pc4, - /// `A5` - /// - /// ADC5 (ADC input channel 5) - /// SCL (2-wire serial bus clock line) - /// PCINT13 (pin change interrupt 13) - pub a5: atmega_hal::port::PC5 = pc5, - - /// `D0` / `RX` - /// - /// * RXD (USART input pin) - /// * PCINT16 (pin change interrupt 16) - pub d0: atmega_hal::port::PD0 = pd0, - /// `D1` / `TX` - /// - /// * TXD (USART output pin) - /// * PCINT17 (pin change interrupt 17) - pub d1: atmega_hal::port::PD1 = pd1, - /// `D2` - /// - /// * INT0 (external interrupt 0 input) - /// * PCINT18 (pin change interrupt 18) - pub d2: atmega_hal::port::PD2 = pd2, - /// `D3` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * INT1 (external interrupt 1 input) - /// * OC2B (Timer/Counter2 output compare match B output) - /// * PCINT19 (pin change interrupt 19) - pub d3: atmega_hal::port::PD3 = pd3, - /// `D4` - /// - /// * XCK (USART external clock input/output) - /// * T0 (Timer/Counter 0 external counter input) - /// * PCINT20 (pin change interrupt 20) - pub d4: atmega_hal::port::PD4 = pd4, - /// `D5` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * T1 (Timer/Counter 1 external counter input) - /// * OC0B (Timer/Counter0 output compare match B output) - /// * PCINT21 (pin change interrupt 21) - pub d5: atmega_hal::port::PD5 = pd5, - /// `D6` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * AIN0 (analog comparator positive input) - /// * OC0A (Timer/Counter0 output compare match A output) - /// * PCINT22 (pin change interrupt 22) - pub d6: atmega_hal::port::PD6 = pd6, - /// `D7` - /// - /// * AIN1 (analog comparator negative input) - /// * PCINT23 (pin change interrupt 23) - pub d7: atmega_hal::port::PD7 = pd7, - /// `D8` - /// - /// * ICP1 (Timer/Counter1 input capture input) - /// * CLKO (divided system clock output) - /// * PCINT0 (pin change interrupt 0) - pub d8: atmega_hal::port::PB0 = pb0, - /// `D9` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * OC1A (Timer/Counter1 output compare match A output) - /// * PCINT1 (pin change interrupt 1) - pub d9: atmega_hal::port::PB1 = pb1, - /// `D10` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * SS (SPI bus master slave select) - /// * OC1B (Timer/Counter1 output compare match B output) - /// * PCINT2 (pin change interrupt 2) - pub d10: atmega_hal::port::PB2 = pb2, - /// `D11` - /// - /// * **PWM**: [atmega328p_hal::timer::Timer3Pwm] - /// * MOSI (SPI bus master/slave input) - /// * OC2A (Timer/Counter2 output compare match A output) - /// * PCINT3 (pin change interrupt 3) - pub d11: atmega_hal::port::PB3 = pb3, - /// `D12` - /// - /// * MISO (SPI bus master input/slave output) - /// * PCINT4 (pin change interrupt 4) - pub d12: atmega_hal::port::PB4 = pb4, - /// `D13` - /// - /// * SCK (SPI bus master clock input) - /// * PCINT5 (pin change interrupt 5) - /// * L LED on Arduino Uno - pub d13: atmega_hal::port::PB5 = pb5, - } - - impl Pins { - type Pin = Pin; - type McuPins = atmega_hal::Pins; - } -} diff --git a/arduino-hal/src/sparkfun/mod.rs b/arduino-hal/src/sparkfun/mod.rs new file mode 100644 index 0000000000..12abdea874 --- /dev/null +++ b/arduino-hal/src/sparkfun/mod.rs @@ -0,0 +1,8 @@ +#[cfg(feature = "_board-sparkfun-promicro")] +pub mod pro_micro; + +#[cfg(feature = "_board-sparkfun-promini-5v")] +pub mod pro_mini_5v; + +#[cfg(feature = "_board-sparkfun-promini-3v3")] +pub mod pro_mini_3v3; diff --git a/arduino-hal/src/sparkfun/pro_micro.rs b/arduino-hal/src/sparkfun/pro_micro.rs new file mode 100644 index 0000000000..22233721e9 --- /dev/null +++ b/arduino-hal/src/sparkfun/pro_micro.rs @@ -0,0 +1,203 @@ +pub use atmega_hal::atmega32u4 as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::sparkfun::pro_micro + } +} + +pub mod port { + use crate::sparkfun::pro_micro as board; + pub use board::hal::port::{mode, Pin, PinMode, PinOps}; + + avr_hal_generic::renamed_pins! { + /// Pins of the **SparkFun ProMicro**. + /// + /// This struct is best initialized via the [`arduino_hal::pins!()`][crate::pins] macro. + pub struct Pins { + /// `RX` + /// + /// `RX` (UART) + pub rx: board::hal::port::PD2 = pd2, + /// `TX` + /// + /// `TX` (UART) + pub tx: board::hal::port::PD3 = pd3, + /// `D2` / `SDA` + /// + /// `SDA`: i2c/twi data + pub d2: board::hal::port::PD1 = pd1, + /// `D3` / `SCL` + /// + /// `SCL`: i2c/twi clock + pub d3: board::hal::port::PD0 = pd0, + /// `D4` + pub d4: board::hal::port::PD4 = pd4, + /// `D5` + pub d5: board::hal::port::PC6 = pc6, + /// `D6` + pub d6: board::hal::port::PD7 = pd7, + /// `D7` + pub d7: board::hal::port::PE6 = pe6, + /// `D8` + pub d8: board::hal::port::PB4 = pb4, + /// `D9` + pub d9: board::hal::port::PB5 = pb5, + /// `D10` + pub d10: board::hal::port::PB6 = pb6, + /// `LED_RX` + /// + /// Led for indicating inbound data (yellow). Also the CS pin for SPI. + pub led_rx: board::hal::port::PB0 = pb0, + /// `LED_TX` + /// + /// Led for indicating outbound data (green). + pub led_tx: board::hal::port::PD5 = pd5, + /// `D15`, `SCK` + /// + /// ICSP SCLK pin + pub d15: board::hal::port::PB1 = pb1, + /// `D14`, `MISO` + /// + /// ICSP MISO pin + pub d16: board::hal::port::PB3 = pb3, + /// `D16`, `MOSI` + /// + /// ICSP MOSI pin + pub d14: board::hal::port::PB2 = pb2, + /// `A0` + /// + /// `ADC7` channel + pub a0: board::hal::port::PF7 = pf7, + /// `A1` + /// + /// `ADC6` channel + pub a1: board::hal::port::PF6 = pf6, + /// `A2` + /// + /// `ADC5` channel + pub a2: board::hal::port::PF5 = pf5, + /// `A3` + /// + /// `ADC4` channel + pub a3: board::hal::port::PF4 = pf4, + } + + impl Pins { + type Pin = Pin; + type McuPins = board::hal::Pins; + } + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! sparkfun_pro_micro_pins { + ($p:expr) => { + $crate::sparkfun::pro_micro::Pins::with_mcu_pins($crate::sparkfun::pro_micro::hal::pins!($p)) + }; + } + + pub use sparkfun_pro_micro_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::sparkfun::pro_micro + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::sparkfun::pro_micro + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::sparkfun::pro_micro + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::sparkfun::pro_micro + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + #[macro_export] + macro_rules! sparkfun_pro_micro_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::sparkfun::pro_micro::Usart::new( + $p.USART1, + $pins.rx, + $pins.tx.into_output(), + $crate::sparkfun::pro_micro::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; + } + pub use sparkfun_pro_micro_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::sparkfun::pro_micro + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::sparkfun::pro_micro + } +} + +pub mod prelude { + use crate::sparkfun::pro_micro as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart, default_serial}, +}; diff --git a/arduino-hal/src/sparkfun/pro_mini_3v3.rs b/arduino-hal/src/sparkfun/pro_mini_3v3.rs new file mode 100644 index 0000000000..8191bf90ff --- /dev/null +++ b/arduino-hal/src/sparkfun/pro_mini_3v3.rs @@ -0,0 +1,126 @@ +pub use atmega_hal::atmega328p as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz8; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::sparkfun::pro_mini_3v3 + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_uno; + impl_port_uno! { + board: crate::sparkfun::pro_mini_3v3 + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! sparkfun_pro_mini_3v3_pins { + ($p:expr) => { + $crate::sparkfun::pro_mini_3v3::Pins::with_mcu_pins($crate::sparkfun::pro_mini_3v3::hal::pins!($p)) + }; + } + + pub use sparkfun_pro_mini_3v3_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::sparkfun::pro_mini_3v3 + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::sparkfun::pro_mini_3v3 + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::sparkfun::pro_mini_3v3 + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::sparkfun::pro_mini_3v3 + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + #[macro_export] + macro_rules! sparkfun_pro_mini_3v3_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; + } + pub use sparkfun_pro_mini_3v3_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::sparkfun::pro_mini_3v3 + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::sparkfun::pro_mini_3v3 + } +} + +pub mod prelude { + use crate::sparkfun::pro_mini_3v3 as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart,default_serial}, +}; diff --git a/arduino-hal/src/sparkfun/pro_mini_5v.rs b/arduino-hal/src/sparkfun/pro_mini_5v.rs new file mode 100644 index 0000000000..40bcb2acf1 --- /dev/null +++ b/arduino-hal/src/sparkfun/pro_mini_5v.rs @@ -0,0 +1,126 @@ +pub use atmega_hal::atmega328p as hal; + +pub use hal::{pac, Peripherals}; + +pub mod clock { + + //! MCU core clock support. + //! + //! This module contains common definitions to abtract over the MCU core clock speed. `avr-hal` + //! does not support changing the clock-speed at runtime. + //! + //! Most items in this module are re-exported from [`avr_hal_generic::clock`]. + pub use avr_hal_generic::clock::*; + + pub type DefaultClock = avr_hal_generic::clock::MHz16; +} + +pub mod delay { + use crate::r#impl::impl_delay; + impl_delay! { + board: crate::sparkfun::pro_mini_5v + } +} + +pub mod port { + use crate::arduino::r#impl::impl_port_uno; + impl_port_uno! { + board: crate::sparkfun::pro_mini_5v + } + + /// Convenience macro to instantiate the [`Pins`] struct for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// ``` + #[macro_export] + macro_rules! sparkfun_pro_mini_5v_pins { + ($p:expr) => { + $crate::sparkfun::pro_mini_5v::Pins::with_mcu_pins($crate::sparkfun::pro_mini_5v::hal::pins!($p)) + }; + } + + pub use sparkfun_pro_mini_5v_pins as pins; +} + +pub mod adc { + use crate::r#impl::impl_adc_atmega; + impl_adc_atmega! { + board: crate::sparkfun::pro_mini_5v + } +} + +pub mod i2c { + use crate::r#impl::impl_i2c_atmega; + impl_i2c_atmega! { + board: crate::sparkfun::pro_mini_5v + } +} + +pub mod spi { + use crate::r#impl::impl_spi_atmega; + impl_spi_atmega! { + board: crate::sparkfun::pro_mini_5v + } +} + +pub mod usart { + use crate::r#impl::impl_usart_atmega; + impl_usart_atmega! { + board: crate::sparkfun::pro_mini_5v + } + + /// Convenience macro to instantiate the [`Usart`] driver for this board. + /// + /// # Example + /// ```no_run + /// let dp = arduino_hal::Peripherals::take().unwrap(); + /// let pins = arduino_hal::pins!(dp); + /// let serial = arduino_hal::default_serial!(dp, pins, 57600); + /// ``` + #[macro_export] + macro_rules! sparkfun_pro_mini_5v_default_serial { + ($p:expr, $pins:expr, $baud:expr) => { + $crate::Usart::new( + $p.USART0, + $pins.d0, + $pins.d1.into_output(), + $crate::hal::usart::BaudrateExt::into_baudrate($baud), + ) + }; + } + pub use sparkfun_pro_mini_5v_default_serial as default_serial; +} + +pub mod eeprom { + use crate::r#impl::impl_eeprom; + impl_eeprom! { + board: crate::sparkfun::pro_mini_5v + } +} + +pub mod simple_pwm { + use crate::r#impl::impl_simple_pwm; + impl_simple_pwm! { + board: crate::sparkfun::pro_mini_5v + } +} + +pub mod prelude { + use crate::sparkfun::pro_mini_5v as board; + pub use board::hal::usart::BaudrateExt as _; + pub use atmega_hal::prelude::*; +} + +pub use { + adc::Adc, + clock::DefaultClock, + delay::{delay_ms, delay_us, Delay}, + eeprom::Eeprom, + i2c::I2c, + port::{Pins, pins}, + spi::Spi, + usart::{Usart,default_serial}, +}; diff --git a/avr-hal-generic/src/simple_pwm.rs b/avr-hal-generic/src/simple_pwm.rs index 93b4081bf5..4952e3e925 100644 --- a/avr-hal-generic/src/simple_pwm.rs +++ b/avr-hal-generic/src/simple_pwm.rs @@ -123,7 +123,7 @@ macro_rules! impl_simple_pwm { timer: $TIMER:ty, init: |$init_timer:ident, $prescaler:ident| $init_block:block, pins: {$( - $PXi:ident: { + $PXi:ty: { ocr: $ocr:ident, $into_pwm:ident: |$pin_timer:ident| if enable $pin_enable_block:block else $pin_disable_block:block, diff --git a/examples/arduino-diecimila/src/bin/diecimila-adc.rs b/examples/arduino-diecimila/src/bin/diecimila-adc.rs index 0de00c4ba3..88e63eeb24 100644 --- a/examples/arduino-diecimila/src/bin/diecimila-adc.rs +++ b/examples/arduino-diecimila/src/bin/diecimila-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use arduino_hal::arduino::diecimila as board; +use board::prelude::*; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd) = ( adc.read_blocking(&adc::channel::Vbg), @@ -38,6 +39,6 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-diecimila/src/bin/diecimila-blink.rs b/examples/arduino-diecimila/src/bin/diecimila-blink.rs index 3dac392b1f..5d8d0ec73c 100644 --- a/examples/arduino-diecimila/src/bin/diecimila-blink.rs +++ b/examples/arduino-diecimila/src/bin/diecimila-blink.rs @@ -3,15 +3,17 @@ use panic_halt as _; +use arduino_hal::arduino::diecimila as board; + #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut led = pins.d13.into_output().downgrade(); loop { led.toggle(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs b/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs index ae2bf7ef18..a78ed230bb 100644 --- a/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs +++ b/examples/arduino-diecimila/src/bin/diecimila-i2cdetect.rs @@ -1,16 +1,18 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; use panic_halt as _; +use arduino_hal::arduino::diecimila as board; +use board::prelude::*; + #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), @@ -18,10 +20,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop {} diff --git a/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs b/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs index 95f0be133a..ec51791a6b 100644 --- a/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs +++ b/examples/arduino-diecimila/src/bin/diecimila-spi-feedback.rs @@ -15,21 +15,22 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; -use arduino_hal::spi; +use arduino_hal::arduino::diecimila as board; +use board::prelude::*; +use board::spi; use embedded_hal_v0::spi::FullDuplex; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // set up serial interface for text output - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = arduino_hal::Spi::new( + let (mut spi, _) = board::Spi::new( dp.SPI, pins.d13.into_output(), pins.d11.into_output(), @@ -45,6 +46,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-diecimila/src/bin/diecimila-usart.rs b/examples/arduino-diecimila/src/bin/diecimila-usart.rs index ed6a719d41..18398390f9 100644 --- a/examples/arduino-diecimila/src/bin/diecimila-usart.rs +++ b/examples/arduino-diecimila/src/bin/diecimila-usart.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; use panic_halt as _; +use arduino_hal::arduino::diecimila as board; +use board::prelude::*; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/arduino-leonardo/src/bin/leonardo-adc.rs b/examples/arduino-leonardo/src/bin/leonardo-adc.rs index aef03002e4..da52c43eaa 100644 --- a/examples/arduino-leonardo/src/bin/leonardo-adc.rs +++ b/examples/arduino-leonardo/src/bin/leonardo-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::leonardo as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd, tmp) = ( adc.read_blocking(&adc::channel::Vbg), @@ -45,6 +46,6 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-leonardo/src/bin/leonardo-blink.rs b/examples/arduino-leonardo/src/bin/leonardo-blink.rs index 43c5862e58..3a81045afa 100644 --- a/examples/arduino-leonardo/src/bin/leonardo-blink.rs +++ b/examples/arduino-leonardo/src/bin/leonardo-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::arduino::leonardo as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut leds = [ pins.led_rx.into_output().downgrade(), @@ -23,7 +24,7 @@ fn main() -> ! { loop { for i in 0..3 { leds[i].toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); leds[i].toggle(); } } diff --git a/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs b/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs index e6af7f4f4b..c13ab36230 100644 --- a/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs +++ b/examples/arduino-leonardo/src/bin/leonardo-i2cdetect.rs @@ -1,16 +1,18 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::leonardo as board; + +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.d2.into_pull_up_input(), pins.d3.into_pull_up_input(), @@ -18,10 +20,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop {} diff --git a/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs b/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs index 11551f83da..10f88e2b94 100644 --- a/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs +++ b/examples/arduino-leonardo/src/bin/leonardo-spi-feedback.rs @@ -15,21 +15,23 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; -use arduino_hal::spi; +use arduino_hal::arduino::leonardo as board; + +use board::prelude::*; +use board::spi; use embedded_hal_v0::spi::FullDuplex; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // set up serial interface for text output - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = arduino_hal::Spi::new( + let (mut spi, _) = board::Spi::new( dp.SPI, pins.sck.into_output(), pins.mosi.into_output(), @@ -45,6 +47,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-leonardo/src/bin/leonardo-usart.rs b/examples/arduino-leonardo/src/bin/leonardo-usart.rs index a8c2339555..bf4978630a 100644 --- a/examples/arduino-leonardo/src/bin/leonardo-usart.rs +++ b/examples/arduino-leonardo/src/bin/leonardo-usart.rs @@ -1,16 +1,18 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::leonardo as board; + +use board::prelude::*; use panic_halt as _; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/arduino-mega1280/src/bin/mega1280-adc.rs b/examples/arduino-mega1280/src/bin/mega1280-adc.rs index 76139665c4..ef4793f2c2 100644 --- a/examples/arduino-mega1280/src/bin/mega1280-adc.rs +++ b/examples/arduino-mega1280/src/bin/mega1280-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::mega1280 as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd) = ( adc.read_blocking(&adc::channel::Vbg), @@ -48,6 +49,6 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-mega1280/src/bin/mega1280-blink.rs b/examples/arduino-mega1280/src/bin/mega1280-blink.rs index 3dac392b1f..412400130e 100644 --- a/examples/arduino-mega1280/src/bin/mega1280-blink.rs +++ b/examples/arduino-mega1280/src/bin/mega1280-blink.rs @@ -1,17 +1,18 @@ #![no_std] #![no_main] +use arduino_hal::arduino::mega1280 as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut led = pins.d13.into_output().downgrade(); loop { led.toggle(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-mega1280/src/bin/mega1280-i2cdetect.rs b/examples/arduino-mega1280/src/bin/mega1280-i2cdetect.rs index 59946ede22..7130fd9287 100644 --- a/examples/arduino-mega1280/src/bin/mega1280-i2cdetect.rs +++ b/examples/arduino-mega1280/src/bin/mega1280-i2cdetect.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::mega1280 as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.d20.into_pull_up_input(), pins.d21.into_pull_up_input(), @@ -18,10 +19,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop {} diff --git a/examples/arduino-mega1280/src/bin/mega1280-usart.rs b/examples/arduino-mega1280/src/bin/mega1280-usart.rs index a8c2339555..ecf0c4a9e8 100644 --- a/examples/arduino-mega1280/src/bin/mega1280-usart.rs +++ b/examples/arduino-mega1280/src/bin/mega1280-usart.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::mega1280 as board; +use board::prelude::*; use panic_halt as _; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/arduino-mega1280/src/bin/mega1280spi-feedback.rs b/examples/arduino-mega1280/src/bin/mega1280spi-feedback.rs index 6024ae46b0..04887c2ad5 100644 --- a/examples/arduino-mega1280/src/bin/mega1280spi-feedback.rs +++ b/examples/arduino-mega1280/src/bin/mega1280spi-feedback.rs @@ -15,21 +15,22 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; -use arduino_hal::spi; +use arduino_hal::arduino::mega1280 as board; +use board::prelude::*; +use board::spi; use embedded_hal_v0::spi::FullDuplex; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // set up serial interface for text output - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = arduino_hal::Spi::new( + let (mut spi, _) = board::Spi::new( dp.SPI, pins.d52.into_output(), pins.d51.into_output(), @@ -45,6 +46,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-mega2560/src/bin/mega2560-adc.rs b/examples/arduino-mega2560/src/bin/mega2560-adc.rs index 76139665c4..9c838552da 100644 --- a/examples/arduino-mega2560/src/bin/mega2560-adc.rs +++ b/examples/arduino-mega2560/src/bin/mega2560-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::mega2560 as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd) = ( adc.read_blocking(&adc::channel::Vbg), @@ -48,6 +49,6 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-mega2560/src/bin/mega2560-blink.rs b/examples/arduino-mega2560/src/bin/mega2560-blink.rs index 3dac392b1f..24dd398c04 100644 --- a/examples/arduino-mega2560/src/bin/mega2560-blink.rs +++ b/examples/arduino-mega2560/src/bin/mega2560-blink.rs @@ -1,17 +1,18 @@ #![no_std] #![no_main] +use arduino_hal::arduino::mega2560 as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut led = pins.d13.into_output().downgrade(); loop { led.toggle(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs b/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs index 59946ede22..2e91e45df1 100644 --- a/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs +++ b/examples/arduino-mega2560/src/bin/mega2560-i2cdetect.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::mega2560 as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.d20.into_pull_up_input(), pins.d21.into_pull_up_input(), @@ -18,10 +19,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop {} diff --git a/examples/arduino-mega2560/src/bin/mega2560-rgb-led.rs b/examples/arduino-mega2560/src/bin/mega2560-rgb-led.rs index 6fd5e80756..93f1b89528 100644 --- a/examples/arduino-mega2560/src/bin/mega2560-rgb-led.rs +++ b/examples/arduino-mega2560/src/bin/mega2560-rgb-led.rs @@ -12,15 +12,16 @@ #![no_std] #![no_main] +use arduino_hal::arduino::mega2560 as board; use panic_halt as _; -use arduino_hal::simple_pwm::IntoPwmPin; -use arduino_hal::simple_pwm::Prescaler; -use arduino_hal::simple_pwm::{Timer3Pwm, Timer4Pwm}; +use board::simple_pwm::IntoPwmPin; +use board::simple_pwm::Prescaler; +use board::simple_pwm::{Timer3Pwm, Timer4Pwm}; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let timer0 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64); let timer1 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64); @@ -43,19 +44,19 @@ fn main() -> ! { // Fade in/out red for i in (0..=max_duty_d6).chain((0..=max_duty_d6 - 1).rev()) { d6.set_duty(i); - arduino_hal::delay_ms(delay_time); + board::delay_ms(delay_time); } // Fade in/out green for i in (0..=max_duty_d5).chain((0..=max_duty_d5 - 1).rev()) { d5.set_duty(i); - arduino_hal::delay_ms(delay_time); + board::delay_ms(delay_time); } // Fade in/out blue for i in (0..=max_duty_d3).chain((0..=max_duty_d3 - 1).rev()) { d3.set_duty(i); - arduino_hal::delay_ms(delay_time); + board::delay_ms(delay_time); } } } \ No newline at end of file diff --git a/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs b/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs index d05fa025f7..73194cd8cb 100644 --- a/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs +++ b/examples/arduino-mega2560/src/bin/mega2560-spi-feedback.rs @@ -15,21 +15,22 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; -use arduino_hal::spi; +use arduino_hal::arduino::mega2560 as board; +use board::prelude::*; +use board::spi; use embedded_hal_v0::spi::FullDuplex; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // set up serial interface for text output - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = arduino_hal::Spi::new( + let (mut spi, _) = board::Spi::new( dp.SPI, pins.d52.into_output(), pins.d51.into_output(), @@ -45,6 +46,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-mega2560/src/bin/mega2560-usart.rs b/examples/arduino-mega2560/src/bin/mega2560-usart.rs index a8c2339555..e5c1e3f3fe 100644 --- a/examples/arduino-mega2560/src/bin/mega2560-usart.rs +++ b/examples/arduino-mega2560/src/bin/mega2560-usart.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::mega2560 as board; +use board::prelude::*; use panic_halt as _; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/arduino-nano/src/bin/nano-adc.rs b/examples/arduino-nano/src/bin/nano-adc.rs index 00105e959b..328aeb9d05 100644 --- a/examples/arduino-nano/src/bin/nano-adc.rs +++ b/examples/arduino-nano/src/bin/nano-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v3 as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd, tmp) = ( adc.read_blocking(&adc::channel::Vbg), @@ -53,6 +54,6 @@ fn main() -> ! { ufmt::uwrite!(&mut serial, "A6: {} A7: {}", a6, a7).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-nano/src/bin/nano-blink.rs b/examples/arduino-nano/src/bin/nano-blink.rs index 8650f1274d..232c81653f 100644 --- a/examples/arduino-nano/src/bin/nano-blink.rs +++ b/examples/arduino-nano/src/bin/nano-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::arduino::nano_v3 as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); @@ -14,12 +15,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/arduino-nano/src/bin/nano-panic.rs b/examples/arduino-nano/src/bin/nano-panic.rs index a2047094cf..b599bc117a 100644 --- a/examples/arduino-nano/src/bin/nano-panic.rs +++ b/examples/arduino-nano/src/bin/nano-panic.rs @@ -7,7 +7,8 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v3 as board; +use board::prelude::*; // Documentation build does not like this and fails with the following error, even though // everything is fine when compiling the binary. @@ -27,9 +28,9 @@ fn panic(info: &core::panic::PanicInfo) -> ! { // SAFETY: Because main() already has references to the peripherals this is an unsafe // operation - but because no other code can run after the panic handler was called, // we know it is okay. - let dp = unsafe { arduino_hal::Peripherals::steal() }; - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = unsafe { board::Peripherals::steal() }; + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); // Print out panic location ufmt::uwriteln!(&mut serial, "Firmware panic!\r").unwrap_infallible(); @@ -48,20 +49,20 @@ fn panic(info: &core::panic::PanicInfo) -> ! { let mut led = pins.d13.into_output(); loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); } } #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); ufmt::uwriteln!(&mut serial, "Panic in 5 seconds!\r").unwrap_infallible(); - arduino_hal::delay_ms(5000); + board::delay_ms(5000); // Panic messages cannot yet be captured because they rely on core::fmt // which is way too big for AVR diff --git a/examples/arduino-uno/src/bin/uno-16chan-servo-driver.rs b/examples/arduino-uno/src/bin/uno-16chan-servo-driver.rs index b30ebc7c73..175dbfdb38 100644 --- a/examples/arduino-uno/src/bin/uno-16chan-servo-driver.rs +++ b/examples/arduino-uno/src/bin/uno-16chan-servo-driver.rs @@ -16,18 +16,19 @@ #![no_std] #![no_main] +use arduino_hal::arduino::uno as board; use panic_halt as _; use pwm_pca9685::{Address, Channel, Pca9685}; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); - let i2c = arduino_hal::I2c::new( + let i2c = board::I2c::new( dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), @@ -52,9 +53,9 @@ fn main() -> ! { loop { // Blink the LED to indicate that everything is working properly. led.toggle(); - arduino_hal::delay_ms(500); + board::delay_ms(500); led.toggle(); - arduino_hal::delay_ms(500); + board::delay_ms(500); pwm.set_channel_off(Channel::C0, current).unwrap(); pwm.set_channel_off(Channel::C1, servo_min + (servo_max - current)) diff --git a/examples/arduino-uno/src/bin/uno-74hc595.rs b/examples/arduino-uno/src/bin/uno-74hc595.rs index 97a64c3d9d..1f4e1461a4 100644 --- a/examples/arduino-uno/src/bin/uno-74hc595.rs +++ b/examples/arduino-uno/src/bin/uno-74hc595.rs @@ -14,9 +14,10 @@ #![no_std] #![no_main] +use arduino_hal::arduino::uno as board; use panic_halt as _; -use arduino_hal::{ +use board::{ hal::port::{PD4, PD5, PD6}, port::{mode::Output, Pin}, }; @@ -51,8 +52,8 @@ fn update_shift_register( #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut data_pin = pins.d4.into_output(); let mut latch_pin = pins.d5.into_output(); @@ -62,13 +63,13 @@ fn main() -> ! { let mut data: u8 = 0; update_shift_register(&mut data_pin, &mut latch_pin, &mut clock_pin, &data); - arduino_hal::delay_ms(500); + board::delay_ms(500); for i in 0..8 { data |= 1 << i; update_shift_register(&mut data_pin, &mut latch_pin, &mut clock_pin, &data); - arduino_hal::delay_ms(500); + board::delay_ms(500); } } } diff --git a/examples/arduino-uno/src/bin/uno-adc.rs b/examples/arduino-uno/src/bin/uno-adc.rs index 57ad302314..b4a5d8c309 100644 --- a/examples/arduino-uno/src/bin/uno-adc.rs +++ b/examples/arduino-uno/src/bin/uno-adc.rs @@ -12,18 +12,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd, tmp) = ( adc.read_blocking(&adc::channel::Vbg), @@ -56,6 +57,6 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-uno/src/bin/uno-blink-embedded-hal.rs b/examples/arduino-uno/src/bin/uno-blink-embedded-hal.rs index 69647af7a5..4472ba3023 100644 --- a/examples/arduino-uno/src/bin/uno-blink-embedded-hal.rs +++ b/examples/arduino-uno/src/bin/uno-blink-embedded-hal.rs @@ -5,6 +5,7 @@ #![no_std] #![no_main] +use arduino_hal::arduino::uno as board; use embedded_hal::delay::DelayNs; use embedded_hal::digital::StatefulOutputPin; @@ -25,14 +26,14 @@ fn blink(led: &mut impl StatefulOutputPin, delay: &mut impl DelayNs) -> ! { #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); led.set_high(); - let mut delay = arduino_hal::Delay::new(); + let mut delay = board::Delay::new(); blink(&mut led, &mut delay); } diff --git a/examples/arduino-uno/src/bin/uno-blink.rs b/examples/arduino-uno/src/bin/uno-blink.rs index a9fb1e612d..e41a953e78 100644 --- a/examples/arduino-uno/src/bin/uno-blink.rs +++ b/examples/arduino-uno/src/bin/uno-blink.rs @@ -4,12 +4,13 @@ #![no_std] #![no_main] +use arduino_hal::arduino::uno as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); @@ -17,12 +18,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/arduino-uno/src/bin/uno-eeprom.rs b/examples/arduino-uno/src/bin/uno-eeprom.rs index 5f0e04960f..2e4d30a012 100644 --- a/examples/arduino-uno/src/bin/uno-eeprom.rs +++ b/examples/arduino-uno/src/bin/uno-eeprom.rs @@ -4,16 +4,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut ep = arduino_hal::Eeprom::new(dp.EEPROM); + let mut ep = board::Eeprom::new(dp.EEPROM); let ep_capacity = ep.capacity(); ufmt::uwriteln!(&mut serial, "eeprom capacity is:{}\r", ep_capacity).unwrap_infallible(); @@ -33,7 +34,7 @@ fn main() -> ! { ufmt::uwriteln!(&mut serial, "{}", i).unwrap_infallible(); } - let _ = ep.erase(0, arduino_hal::Eeprom::CAPACITY); + let _ = ep.erase(0, board::Eeprom::CAPACITY); loop {} } diff --git a/examples/arduino-uno/src/bin/uno-ext-interrupt.rs b/examples/arduino-uno/src/bin/uno-ext-interrupt.rs index 2279841dfa..09b5d76a36 100644 --- a/examples/arduino-uno/src/bin/uno-ext-interrupt.rs +++ b/examples/arduino-uno/src/bin/uno-ext-interrupt.rs @@ -9,7 +9,8 @@ #![no_main] #![feature(abi_avr_interrupt)] -use arduino_hal::port::{mode, Pin}; +use arduino_hal::arduino::uno as board; +use board::port::{mode, Pin}; use core::sync::atomic::{AtomicBool, Ordering}; use either::*; use panic_halt as _; @@ -35,15 +36,15 @@ fn blink_for_range(range: impl Iterator, leds: &mut [Pin ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // thanks to tsemczyszyn and Rahix: https://github.com/Rahix/avr-hal/issues/240 // Configure INT0 for falling edge. 0x03 would be rising edge. diff --git a/examples/arduino-uno/src/bin/uno-hc-sr04.rs b/examples/arduino-uno/src/bin/uno-hc-sr04.rs index 336aa78d66..c4d3a06864 100644 --- a/examples/arduino-uno/src/bin/uno-hc-sr04.rs +++ b/examples/arduino-uno/src/bin/uno-hc-sr04.rs @@ -13,14 +13,15 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); let mut trig = pins.d2.into_output(); let echo = pins.d3; // pin is input by default @@ -38,7 +39,7 @@ fn main() -> ! { // the trigger must be set to high under 10 µs as per the HC-SR04 datasheet trig.set_high(); - arduino_hal::delay_us(10); + board::delay_us(10); trig.set_low(); while echo.is_low() { diff --git a/examples/arduino-uno/src/bin/uno-i2cdetect.rs b/examples/arduino-uno/src/bin/uno-i2cdetect.rs index 54d7f37301..af89eb8382 100644 --- a/examples/arduino-uno/src/bin/uno-i2cdetect.rs +++ b/examples/arduino-uno/src/bin/uno-i2cdetect.rs @@ -17,16 +17,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), @@ -34,13 +35,13 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop { - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-uno/src/bin/uno-infrared.rs b/examples/arduino-uno/src/bin/uno-infrared.rs index 6cc2a5a89c..c7e308037b 100644 --- a/examples/arduino-uno/src/bin/uno-infrared.rs +++ b/examples/arduino-uno/src/bin/uno-infrared.rs @@ -19,10 +19,11 @@ #![no_main] #![feature(abi_avr_interrupt)] +use arduino_hal::arduino::uno as board; use core::cell::Cell; use panic_halt as _; -use arduino_hal::{ +use board::{ hal::port::{PD2, PD6, PD7}, pac::tc0::tccr0b::CS0_A, port::mode::{Floating, Input, Output}, @@ -46,9 +47,9 @@ static CMD: Mutex>> = Mutex::new(Cell::new(None)); #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); // Monotonic clock to keep track of the time CLOCK.start(dp.TC0); @@ -92,7 +93,7 @@ fn main() -> ! { .unwrap_infallible(); } - arduino_hal::delay_ms(100); + board::delay_ms(100); } } @@ -139,7 +140,7 @@ impl Clock { } } - pub fn start(&self, tc0: arduino_hal::pac::TC0) { + pub fn start(&self, tc0: board::pac::TC0) { // Configure the timer for the above interval (in CTC mode) tc0.tccr0a.write(|w| w.wgm0().ctc()); tc0.ocr0a.write(|w| w.bits(Self::TOP)); diff --git a/examples/arduino-uno/src/bin/uno-manual-servo.rs b/examples/arduino-uno/src/bin/uno-manual-servo.rs index 9402446e7d..960e9e18ba 100644 --- a/examples/arduino-uno/src/bin/uno-manual-servo.rs +++ b/examples/arduino-uno/src/bin/uno-manual-servo.rs @@ -16,12 +16,13 @@ #![no_std] #![no_main] +use arduino_hal::arduino::uno as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Important because this sets the bit in the DDR register! pins.d9.into_output(); @@ -41,7 +42,7 @@ fn main() -> ! { // 700 counts => 2.8ms for duty in 100..=700 { tc1.ocr1a.write(|w| w.bits(duty)); - arduino_hal::delay_ms(20); + board::delay_ms(20); } } } diff --git a/examples/arduino-uno/src/bin/uno-millis.rs b/examples/arduino-uno/src/bin/uno-millis.rs index bcde86af8f..d352ad88e5 100644 --- a/examples/arduino-uno/src/bin/uno-millis.rs +++ b/examples/arduino-uno/src/bin/uno-millis.rs @@ -12,7 +12,8 @@ #![no_main] #![feature(abi_avr_interrupt)] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; use core::cell; use panic_halt as _; @@ -37,7 +38,7 @@ const MILLIS_INCREMENT: u32 = PRESCALER * TIMER_COUNTS / 16000; static MILLIS_COUNTER: avr_device::interrupt::Mutex> = avr_device::interrupt::Mutex::new(cell::Cell::new(0)); -fn millis_init(tc0: arduino_hal::pac::TC0) { +fn millis_init(tc0: board::pac::TC0) { // Configure the timer for the above interval (in CTC mode) // and enable its interrupt. tc0.tccr0a.write(|w| w.wgm0().ctc()); @@ -74,9 +75,9 @@ fn millis() -> u32 { #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); millis_init(dp.TC0); diff --git a/examples/arduino-uno/src/bin/uno-panic.rs b/examples/arduino-uno/src/bin/uno-panic.rs index a2047094cf..77d71edc74 100644 --- a/examples/arduino-uno/src/bin/uno-panic.rs +++ b/examples/arduino-uno/src/bin/uno-panic.rs @@ -7,7 +7,8 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; // Documentation build does not like this and fails with the following error, even though // everything is fine when compiling the binary. @@ -27,9 +28,9 @@ fn panic(info: &core::panic::PanicInfo) -> ! { // SAFETY: Because main() already has references to the peripherals this is an unsafe // operation - but because no other code can run after the panic handler was called, // we know it is okay. - let dp = unsafe { arduino_hal::Peripherals::steal() }; - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = unsafe { board::Peripherals::steal() }; + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); // Print out panic location ufmt::uwriteln!(&mut serial, "Firmware panic!\r").unwrap_infallible(); @@ -48,20 +49,20 @@ fn panic(info: &core::panic::PanicInfo) -> ! { let mut led = pins.d13.into_output(); loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); } } #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); ufmt::uwriteln!(&mut serial, "Panic in 5 seconds!\r").unwrap_infallible(); - arduino_hal::delay_ms(5000); + board::delay_ms(5000); // Panic messages cannot yet be captured because they rely on core::fmt // which is way too big for AVR diff --git a/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs b/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs index b731b528a0..404454f747 100644 --- a/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs +++ b/examples/arduino-uno/src/bin/uno-pin-change-interrupt.rs @@ -9,6 +9,7 @@ #![no_main] #![feature(abi_avr_interrupt)] +use arduino_hal::arduino::uno as board; use panic_halt as _; use core::sync::atomic::{AtomicBool, Ordering}; @@ -35,8 +36,8 @@ fn rotate(flag: &AtomicBool) -> bool { #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); //Pins used to drive the stepper motor let mut dir_pin = pins.d4.into_output(); @@ -69,9 +70,9 @@ fn main() -> ! { //Move the stepper motor for _ in 0..=50 { step_pin.set_high(); - arduino_hal::delay_us(2000); + board::delay_us(2000); step_pin.set_low(); - arduino_hal::delay_us(2000); + board::delay_us(2000); } } } diff --git a/examples/arduino-uno/src/bin/uno-println.rs b/examples/arduino-uno/src/bin/uno-println.rs index 2cac4c9a93..710ebb5e81 100644 --- a/examples/arduino-uno/src/bin/uno-println.rs +++ b/examples/arduino-uno/src/bin/uno-println.rs @@ -8,12 +8,13 @@ #![no_std] #![no_main] +use arduino_hal::arduino::uno as board; use panic_halt as _; use avr_device::interrupt; use core::cell::RefCell; -type Console = arduino_hal::hal::usart::Usart0; +type Console = board::hal::usart::Usart0; static CONSOLE: interrupt::Mutex>> = interrupt::Mutex::new(RefCell::new(None)); @@ -60,9 +61,9 @@ fn demo_print_without_ln() { #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let serial = board::default_serial!(dp, pins, 57600); put_console(serial); println!("Hello from main!"); diff --git a/examples/arduino-uno/src/bin/uno-simple-pwm-embedded-hal.rs b/examples/arduino-uno/src/bin/uno-simple-pwm-embedded-hal.rs index e0e0e2a786..0426b4d4c9 100644 --- a/examples/arduino-uno/src/bin/uno-simple-pwm-embedded-hal.rs +++ b/examples/arduino-uno/src/bin/uno-simple-pwm-embedded-hal.rs @@ -5,7 +5,8 @@ #![no_std] #![no_main] -use arduino_hal::simple_pwm::*; +use arduino_hal::arduino::uno as board; +use board::simple_pwm::*; use embedded_hal::delay::DelayNs; use embedded_hal::pwm::SetDutyCycle; use panic_halt as _; @@ -21,8 +22,8 @@ fn fade(led: &mut impl SetDutyCycle, delay: &mut impl DelayNs) -> ! { #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); @@ -30,7 +31,7 @@ fn main() -> ! { let mut pwm_led = pins.d5.into_output().into_pwm(&timer0); pwm_led.enable(); - let mut delay = arduino_hal::Delay::new(); + let mut delay = board::Delay::new(); fade(&mut pwm_led, &mut delay); } diff --git a/examples/arduino-uno/src/bin/uno-simple-pwm.rs b/examples/arduino-uno/src/bin/uno-simple-pwm.rs index c7f39f7e59..19f13a1c54 100644 --- a/examples/arduino-uno/src/bin/uno-simple-pwm.rs +++ b/examples/arduino-uno/src/bin/uno-simple-pwm.rs @@ -4,13 +4,14 @@ #![no_std] #![no_main] -use arduino_hal::simple_pwm::*; +use arduino_hal::arduino::uno as board; +use board::simple_pwm::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); @@ -21,7 +22,7 @@ fn main() -> ! { loop { for x in (0..=255).chain((0..=254).rev()) { pwm_led.set_duty(x); - arduino_hal::delay_ms(10); + board::delay_ms(10); } } } diff --git a/examples/arduino-uno/src/bin/uno-spi-feedback.rs b/examples/arduino-uno/src/bin/uno-spi-feedback.rs index 944e307efb..f7a8b30abc 100644 --- a/examples/arduino-uno/src/bin/uno-spi-feedback.rs +++ b/examples/arduino-uno/src/bin/uno-spi-feedback.rs @@ -14,21 +14,22 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; -use arduino_hal::spi; +use arduino_hal::arduino::uno as board; +use board::prelude::*; +use board::spi; use embedded_hal_v0::spi::FullDuplex; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // set up serial interface for text output - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = arduino_hal::Spi::new( + let (mut spi, _) = board::Spi::new( dp.SPI, pins.d13.into_output(), pins.d11.into_output(), @@ -44,6 +45,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/arduino-uno/src/bin/uno-timer.rs b/examples/arduino-uno/src/bin/uno-timer.rs index bb315464a5..988d0b2dca 100644 --- a/examples/arduino-uno/src/bin/uno-timer.rs +++ b/examples/arduino-uno/src/bin/uno-timer.rs @@ -9,9 +9,10 @@ and then modernized to account for API drift since 2020 */ -use arduino_hal::port::mode::Output; -use arduino_hal::port::Pin; -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::port::mode::Output; +use board::port::Pin; +use board::prelude::*; use avr_device::atmega328p::tc1::tccr1b::CS1_A; use avr_device::atmega328p::TC1; use core::mem; @@ -26,10 +27,10 @@ static mut INTERRUPT_STATE: mem::MaybeUninit = mem::MaybeUninit: #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); let led = pins.d13.into_output(); @@ -82,9 +83,9 @@ pub fn rig_timer>(tmr1: &TC1, ser https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf section 15.11 */ - use arduino_hal::clock::Clock; + use board::clock::Clock; - const ARDUINO_UNO_CLOCK_FREQUENCY_HZ: u32 = arduino_hal::DefaultClock::FREQ; + const ARDUINO_UNO_CLOCK_FREQUENCY_HZ: u32 = board::DefaultClock::FREQ; const CLOCK_SOURCE: CS1_A = CS1_A::PRESCALE_256; let clock_divisor: u32 = match CLOCK_SOURCE { CS1_A::DIRECT => 1, diff --git a/examples/arduino-uno/src/bin/uno-usart.rs b/examples/arduino-uno/src/bin/uno-usart.rs index e46fac1c41..c5d53653c6 100644 --- a/examples/arduino-uno/src/bin/uno-usart.rs +++ b/examples/arduino-uno/src/bin/uno-usart.rs @@ -4,16 +4,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::uno as board; +use board::prelude::*; use panic_halt as _; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/arduino-uno/src/bin/uno-watchdog.rs b/examples/arduino-uno/src/bin/uno-watchdog.rs index 4871210e6a..4089082d35 100644 --- a/examples/arduino-uno/src/bin/uno-watchdog.rs +++ b/examples/arduino-uno/src/bin/uno-watchdog.rs @@ -8,20 +8,21 @@ #![no_std] #![no_main] -use arduino_hal::hal::wdt; +use arduino_hal::arduino::uno as board; +use board::hal::wdt; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut led = pins.d13.into_output(); led.set_high(); for _ in 0..20 { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); } let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr); @@ -29,7 +30,7 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); watchdog.feed(); } } diff --git a/examples/atmega2560/src/bin/atmega2560-adc.rs b/examples/atmega2560/src/bin/atmega2560-adc.rs index ce801d19cc..c141511c4f 100644 --- a/examples/atmega2560/src/bin/atmega2560-adc.rs +++ b/examples/atmega2560/src/bin/atmega2560-adc.rs @@ -1,21 +1,22 @@ #![no_std] #![no_main] -use atmega_hal::adc::channel; +use atmega_hal::atmega2560 as hal; +use hal::adc::channel; use atmega_hal::delay::Delay; -use atmega_hal::usart::{Baudrate, Usart}; +use hal::usart::{Baudrate, Usart}; use embedded_hal::delay::DelayNs; use panic_halt as _; // Define core clock in the root crate type CoreClock = atmega_hal::clock::MHz16; // Use it as follows in the rest of the project -type Adc = atmega_hal::adc::Adc; +type Adc = hal::adc::Adc; #[avr_device::entry] fn main() -> ! { - let dp = atmega_hal::Peripherals::take().unwrap(); - let pins = atmega_hal::pins!(dp); + let dp = hal::Peripherals::take().unwrap(); + let pins = hal::pins!(dp); let mut delay = Delay::::new(); @@ -37,7 +38,7 @@ fn main() -> ! { ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap(); // To store multiple channels in an array, we use the `into_channel()` method. - let channels: [atmega_hal::adc::Channel; 16] = [ + let channels: [hal::adc::Channel; 16] = [ pins.pf0.into_analog_input(&mut adc).into_channel(), pins.pf1.into_analog_input(&mut adc).into_channel(), pins.pf2.into_analog_input(&mut adc).into_channel(), diff --git a/examples/atmega2560/src/bin/atmega2560-blink.rs b/examples/atmega2560/src/bin/atmega2560-blink.rs index e0bd3301f1..5658ce53a3 100644 --- a/examples/atmega2560/src/bin/atmega2560-blink.rs +++ b/examples/atmega2560/src/bin/atmega2560-blink.rs @@ -1,6 +1,7 @@ #![no_std] #![no_main] +use atmega_hal::atmega2560 as hal; use embedded_hal::delay::DelayNs; use panic_halt as _; @@ -20,8 +21,8 @@ fn delay_us(us: u32) { #[avr_device::entry] fn main() -> ! { - let dp = atmega_hal::Peripherals::take().unwrap(); - let pins = atmega_hal::pins!(dp); + let dp = hal::Peripherals::take().unwrap(); + let pins = hal::pins!(dp); let mut led = pins.pb7.into_output(); diff --git a/examples/atmega2560/src/bin/atmega2560-eeprom.rs b/examples/atmega2560/src/bin/atmega2560-eeprom.rs index 28912ceaed..31e379cacf 100644 --- a/examples/atmega2560/src/bin/atmega2560-eeprom.rs +++ b/examples/atmega2560/src/bin/atmega2560-eeprom.rs @@ -1,9 +1,10 @@ #![no_std] #![no_main] +use atmega_hal::atmega2560 as hal; use atmega_hal::delay::Delay; -use atmega_hal::usart::{Baudrate, Usart}; -use atmega_hal::Eeprom; +use hal::usart::{Baudrate, Usart}; +use hal::Eeprom; use embedded_hal::delay::DelayNs; use panic_halt as _; @@ -14,8 +15,8 @@ const BOOT_COUNT_OFFSET: u16 = 0; #[avr_device::entry] fn main() -> ! { - let dp = atmega_hal::Peripherals::take().unwrap(); - let pins = atmega_hal::pins!(dp); + let dp = hal::Peripherals::take().unwrap(); + let pins = hal::pins!(dp); let mut delay = Delay::::new(); diff --git a/examples/atmega2560/src/bin/atmega2560-i2cdetect.rs b/examples/atmega2560/src/bin/atmega2560-i2cdetect.rs index 35f3e136cc..d6488b1765 100644 --- a/examples/atmega2560/src/bin/atmega2560-i2cdetect.rs +++ b/examples/atmega2560/src/bin/atmega2560-i2cdetect.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use atmega_hal::usart::{Baudrate, Usart}; +use atmega_hal::atmega2560 as hal; +use hal::usart::{Baudrate, Usart}; use panic_halt as _; // Define core clock in the root crate type CoreClock = atmega_hal::clock::MHz16; // Use it as follows in the rest of the project -type I2c = atmega_hal::i2c::I2c; +type I2c = hal::i2c::I2c; #[avr_device::entry] fn main() -> ! { - let dp = atmega_hal::Peripherals::take().unwrap(); - let pins = atmega_hal::pins!(dp); + let dp = hal::Peripherals::take().unwrap(); + let pins = hal::pins!(dp); // set up serial interface for text output let mut serial = Usart::new( @@ -30,10 +31,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap(); - i2c.i2cdetect(&mut serial, atmega_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, hal::i2c::Direction::Write) .unwrap(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap(); - i2c.i2cdetect(&mut serial, atmega_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, hal::i2c::Direction::Read) .unwrap(); loop {} diff --git a/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs b/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs index b4c657eb2c..f43275ab8a 100644 --- a/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs +++ b/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs @@ -9,9 +9,10 @@ #![no_std] #![no_main] +use atmega_hal::atmega2560 as hal; use atmega_hal::delay::Delay; -use atmega_hal::spi; -use atmega_hal::usart::{Baudrate, Usart}; +use hal::spi; +use hal::usart::{Baudrate, Usart}; use embedded_hal::delay::DelayNs; use embedded_hal::spi::SpiBus; use panic_halt as _; @@ -21,8 +22,8 @@ type CoreClock = atmega_hal::clock::MHz16; #[avr_device::entry] fn main() -> ! { - let dp = atmega_hal::Peripherals::take().unwrap(); - let pins = atmega_hal::pins!(dp); + let dp = hal::Peripherals::take().unwrap(); + let pins = hal::pins!(dp); let mut delay = Delay::::new(); diff --git a/examples/atmega2560/src/bin/atmega2560-usart.rs b/examples/atmega2560/src/bin/atmega2560-usart.rs index 30781e7fbd..fdb00ccb88 100644 --- a/examples/atmega2560/src/bin/atmega2560-usart.rs +++ b/examples/atmega2560/src/bin/atmega2560-usart.rs @@ -1,8 +1,9 @@ #![no_std] #![no_main] +use atmega_hal::atmega2560 as hal; use atmega_hal::prelude::*; -use atmega_hal::usart::{Baudrate, Usart}; +use hal::usart::{Baudrate, Usart}; use panic_halt as _; // Define core clock. This can be used in the rest of the project. @@ -10,8 +11,8 @@ type CoreClock = atmega_hal::clock::MHz16; #[avr_device::entry] fn main() -> ! { - let dp = atmega_hal::Peripherals::take().unwrap(); - let pins = atmega_hal::pins!(dp); + let dp = hal::Peripherals::take().unwrap(); + let pins = hal::pins!(dp); let mut serial = Usart::new( dp.USART0, pins.pe0, diff --git a/examples/nano168/src/bin/nano168-adc.rs b/examples/nano168/src/bin/nano168-adc.rs index 4476f134c0..42eb406eb9 100644 --- a/examples/nano168/src/bin/nano168-adc.rs +++ b/examples/nano168/src/bin/nano168-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v2 as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd) = ( adc.read_blocking(&adc::channel::Vbg), @@ -52,6 +53,6 @@ fn main() -> ! { ufmt::uwrite!(&mut serial, "A6: {} A7: {}", a6, a7).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/nano168/src/bin/nano168-blink.rs b/examples/nano168/src/bin/nano168-blink.rs index 8650f1274d..4cd66dd3cb 100644 --- a/examples/nano168/src/bin/nano168-blink.rs +++ b/examples/nano168/src/bin/nano168-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::arduino::nano_v2 as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); @@ -14,12 +15,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/nano168/src/bin/nano168-i2cdetect.rs b/examples/nano168/src/bin/nano168-i2cdetect.rs index ae2bf7ef18..4a6fc42015 100644 --- a/examples/nano168/src/bin/nano168-i2cdetect.rs +++ b/examples/nano168/src/bin/nano168-i2cdetect.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v2 as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), @@ -18,10 +19,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop {} diff --git a/examples/nano168/src/bin/nano168-ldr.rs b/examples/nano168/src/bin/nano168-ldr.rs index 1af1b1789a..bb199c941f 100644 --- a/examples/nano168/src/bin/nano168-ldr.rs +++ b/examples/nano168/src/bin/nano168-ldr.rs @@ -25,18 +25,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v2 as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); + let dp = board::Peripherals::take().unwrap(); // setup the pins - let pins = arduino_hal::pins!(dp); + let pins = board::pins!(dp); // setup the serial connection for the output. - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // setup the analog digital converter - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); // in this example we only need pin a5 let a5 = pins.a5.into_analog_input(&mut adc); @@ -61,6 +62,6 @@ fn main() -> ! { ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); // wait for half a second then measure again - arduino_hal::delay_ms(500); + board::delay_ms(500); } } diff --git a/examples/nano168/src/bin/nano168-millis.rs b/examples/nano168/src/bin/nano168-millis.rs index e957e62614..1d5a4f0500 100644 --- a/examples/nano168/src/bin/nano168-millis.rs +++ b/examples/nano168/src/bin/nano168-millis.rs @@ -10,7 +10,8 @@ #![no_main] #![feature(abi_avr_interrupt)] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v2 as board; +use board::prelude::*; use core::cell; use panic_halt as _; @@ -35,7 +36,7 @@ const MILLIS_INCREMENT: u32 = PRESCALER * TIMER_COUNTS / 16000; static MILLIS_COUNTER: avr_device::interrupt::Mutex> = avr_device::interrupt::Mutex::new(cell::Cell::new(0)); -fn millis_init(tc0: arduino_hal::pac::TC0) { +fn millis_init(tc0: board::pac::TC0) { // Configure the timer for the above interval (in CTC mode) // and enable its interrupt. tc0.tccr0a.write(|w| w.wgm0().ctc()); @@ -72,9 +73,9 @@ fn millis() -> u32 { #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); millis_init(dp.TC0); diff --git a/examples/nano168/src/bin/nano168-usart.rs b/examples/nano168/src/bin/nano168-usart.rs index a8c2339555..613d7e020d 100644 --- a/examples/nano168/src/bin/nano168-usart.rs +++ b/examples/nano168/src/bin/nano168-usart.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v2 as board; +use board::prelude::*; use panic_halt as _; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/nano168/src/bin/nano168-watchdog.rs b/examples/nano168/src/bin/nano168-watchdog.rs index aac0426ea3..a1ccf6025c 100644 --- a/examples/nano168/src/bin/nano168-watchdog.rs +++ b/examples/nano168/src/bin/nano168-watchdog.rs @@ -1,15 +1,16 @@ #![no_std] #![no_main] -use arduino_hal::hal::wdt; -use arduino_hal::prelude::*; +use arduino_hal::arduino::nano_v2 as board; +use board::hal::wdt; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); let mut led = pins.d13.into_output(); led.set_high(); @@ -19,7 +20,7 @@ fn main() -> ! { for _ in 0..20 { ufmt::uwrite!(&mut serial, ".").unwrap_infallible(); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); } ufmt::uwriteln!(&mut serial, "\nEnabling watchdog...").unwrap_infallible(); @@ -32,7 +33,7 @@ fn main() -> ! { ufmt::uwriteln!(&mut serial, "\nWaiting...").unwrap_infallible(); led.toggle(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); //watchdog.feed(); } } diff --git a/examples/sparkfun-promicro/src/bin/promicro-adc.rs b/examples/sparkfun-promicro/src/bin/promicro-adc.rs index f7340aaf0a..e1301c1091 100644 --- a/examples/sparkfun-promicro/src/bin/promicro-adc.rs +++ b/examples/sparkfun-promicro/src/bin/promicro-adc.rs @@ -1,18 +1,19 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::sparkfun::pro_micro as board; +use board::prelude::*; use panic_halt as _; -use arduino_hal::adc; +use board::adc; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); + let mut adc = board::Adc::new(dp.ADC, Default::default()); let (vbg, gnd, tmp) = ( adc.read_blocking(&adc::channel::Vbg), @@ -41,6 +42,6 @@ fn main() -> ! { } ufmt::uwriteln!(&mut serial, "").unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/sparkfun-promicro/src/bin/promicro-blink.rs b/examples/sparkfun-promicro/src/bin/promicro-blink.rs index 4ab740c232..c68a3800e8 100644 --- a/examples/sparkfun-promicro/src/bin/promicro-blink.rs +++ b/examples/sparkfun-promicro/src/bin/promicro-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::sparkfun::pro_micro as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let mut led1 = pins.led_rx.into_output(); let mut led2 = pins.led_tx.into_output(); @@ -14,9 +15,9 @@ fn main() -> ! { loop { led1.set_high(); led2.set_low(); - arduino_hal::delay_ms(300); + board::delay_ms(300); led1.set_low(); led2.set_high(); - arduino_hal::delay_ms(300); + board::delay_ms(300); } } diff --git a/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs b/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs index e6af7f4f4b..b8c71212ec 100644 --- a/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs +++ b/examples/sparkfun-promicro/src/bin/promicro-i2cdetect.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::sparkfun::pro_micro as board; +use board::prelude::*; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); - let mut i2c = arduino_hal::I2c::new( + let mut i2c = board::I2c::new( dp.TWI, pins.d2.into_pull_up_input(), pins.d3.into_pull_up_input(), @@ -18,10 +19,10 @@ fn main() -> ! { ); ufmt::uwriteln!(&mut serial, "Write direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Write) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Write) .unwrap_infallible(); ufmt::uwriteln!(&mut serial, "\r\nRead direction test:\r").unwrap_infallible(); - i2c.i2cdetect(&mut serial, arduino_hal::i2c::Direction::Read) + i2c.i2cdetect(&mut serial, board::i2c::Direction::Read) .unwrap_infallible(); loop {} diff --git a/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs b/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs index 00cb37406e..6c3c764553 100644 --- a/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs +++ b/examples/sparkfun-promicro/src/bin/promicro-spi-feedback.rs @@ -15,21 +15,22 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; -use arduino_hal::spi; +use arduino_hal::sparkfun::pro_micro as board; +use board::prelude::*; +use board::spi; use embedded_hal_v0::spi::FullDuplex; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // set up serial interface for text output - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let mut serial = board::default_serial!(dp, pins, 57600); // Create SPI interface. - let (mut spi, _) = arduino_hal::Spi::new( + let (mut spi, _) = board::Spi::new( dp.SPI, pins.d15.into_output(), pins.d14.into_output(), @@ -45,6 +46,6 @@ fn main() -> ! { let data = nb::block!(spi.read()).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "data: {}\r", data).unwrap_infallible(); - arduino_hal::delay_ms(1000); + board::delay_ms(1000); } } diff --git a/examples/sparkfun-promicro/src/bin/promicro-usart.rs b/examples/sparkfun-promicro/src/bin/promicro-usart.rs index a8c2339555..55a8d05ac6 100644 --- a/examples/sparkfun-promicro/src/bin/promicro-usart.rs +++ b/examples/sparkfun-promicro/src/bin/promicro-usart.rs @@ -1,16 +1,17 @@ #![no_std] #![no_main] -use arduino_hal::prelude::*; +use arduino_hal::sparkfun::pro_micro as board; +use board::prelude::*; use panic_halt as _; use embedded_hal_v0::serial::Read; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); - let mut serial = arduino_hal::default_serial!(dp, pins, 57600); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); + let mut serial = board::default_serial!(dp, pins, 57600); ufmt::uwriteln!(&mut serial, "Hello from Arduino!\r").unwrap_infallible(); diff --git a/examples/sparkfun-promini-3v3/src/bin/promini-3v3-blink.rs b/examples/sparkfun-promini-3v3/src/bin/promini-3v3-blink.rs index 8650f1274d..5f7ced4c8b 100644 --- a/examples/sparkfun-promini-3v3/src/bin/promini-3v3-blink.rs +++ b/examples/sparkfun-promini-3v3/src/bin/promini-3v3-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::sparkfun::pro_mini_3v3 as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); @@ -14,12 +15,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/sparkfun-promini-5v/src/bin/promini-5v-blink.rs b/examples/sparkfun-promini-5v/src/bin/promini-5v-blink.rs index 8650f1274d..e94196ffa9 100644 --- a/examples/sparkfun-promini-5v/src/bin/promini-5v-blink.rs +++ b/examples/sparkfun-promini-5v/src/bin/promini-5v-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::sparkfun::pro_mini_5v as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); @@ -14,12 +15,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/trinket-pro/src/bin/trinket-pro-blink.rs b/examples/trinket-pro/src/bin/trinket-pro-blink.rs index 8650f1274d..eb0f65b60f 100644 --- a/examples/trinket-pro/src/bin/trinket-pro-blink.rs +++ b/examples/trinket-pro/src/bin/trinket-pro-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::adafruit::trinket_pro as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 13 is also connected to an onboard LED marked "L" let mut led = pins.d13.into_output(); @@ -14,12 +15,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/trinket/src/bin/trinket-blink.rs b/examples/trinket/src/bin/trinket-blink.rs index 3a7d7f2a9e..7465e7fcad 100644 --- a/examples/trinket/src/bin/trinket-blink.rs +++ b/examples/trinket/src/bin/trinket-blink.rs @@ -1,12 +1,13 @@ #![no_std] #![no_main] +use arduino_hal::adafruit::trinket as board; use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); // Digital pin 1 is also connected to an onboard LED marked "L" let mut led = pins.d1.into_output(); @@ -14,12 +15,12 @@ fn main() -> ! { loop { led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(100); + board::delay_ms(100); led.toggle(); - arduino_hal::delay_ms(800); + board::delay_ms(800); } } diff --git a/examples/trinket/src/bin/trinket-simple-pwm.rs b/examples/trinket/src/bin/trinket-simple-pwm.rs index 6e8c62336c..06ddb521d8 100644 --- a/examples/trinket/src/bin/trinket-simple-pwm.rs +++ b/examples/trinket/src/bin/trinket-simple-pwm.rs @@ -5,13 +5,15 @@ #![no_std] #![no_main] -use arduino_hal::simple_pwm::*; use panic_halt as _; +use arduino_hal::adafruit::trinket as board; +use board::simple_pwm::*; + #[arduino_hal::entry] fn main() -> ! { - let dp = arduino_hal::Peripherals::take().unwrap(); - let pins = arduino_hal::pins!(dp); + let dp = board::Peripherals::take().unwrap(); + let pins = board::pins!(dp); let timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); @@ -22,7 +24,7 @@ fn main() -> ! { loop { for x in (0..=255).chain((0..=254).rev()) { pwm_led.set_duty(x); - arduino_hal::delay_ms(10); + board::delay_ms(10); } } } diff --git a/mcu/atmega-hal/Cargo.toml b/mcu/atmega-hal/Cargo.toml index ebe5a12a4b..7ed8c06ba7 100644 --- a/mcu/atmega-hal/Cargo.toml +++ b/mcu/atmega-hal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "atmega-hal" -version = "0.1.0" +version = "0.4.0" authors = ["Rahix "] edition = "2021" @@ -12,28 +12,104 @@ categories = ["no-std", "embedded", "hardware-support"] [features] rt = ["avr-device/rt"] -device-selected = [] enable-extra-adc = [] -atmega48p = ["avr-device/atmega48p", "device-selected"] -atmega164pa = ["avr-device/atmega164pa", "device-selected"] -atmega168 = ["avr-device/atmega168", "device-selected"] -atmega328p = ["avr-device/atmega328p", "device-selected"] -atmega328pb = ["avr-device/atmega328pb", "device-selected"] -atmega32a = ["avr-device/atmega32a", "device-selected"] -atmega32u4 = ["avr-device/atmega32u4", "device-selected"] -atmega2560 = ["avr-device/atmega2560", "device-selected"] -atmega128a = ["avr-device/atmega128a", "device-selected"] -atmega1280 = ["avr-device/atmega1280", "device-selected"] -atmega1284p = ["avr-device/atmega1284p", "device-selected"] -atmega8 = ["avr-device/atmega8", "device-selected"] + +# MCU-specific targets. +atmega48p = ["_mcu-atmega48p"] +atmega164pa = ["_mcu-atmega164pa"] +atmega168 = ["_mcu-atmega168"] +atmega328p = ["_mcu-atmega328p"] +atmega328pb = ["_mcu-atmega328pb"] +atmega32a = ["_mcu-atmega32a"] +atmega32u4 = ["_mcu-atmega32u4"] +atmega2560 = ["_mcu-atmega2560"] +atmega128a = ["_mcu-atmega128a"] +atmega1280 = ["_mcu-atmega1280"] +atmega1284p = ["_mcu-atmega1284p"] +atmega8 = ["_mcu-atmega8"] critical-section-impl = ["avr-device/critical-section-impl"] -# Allow certain downstream crates to overwrite the device selection error by themselves. +default = [] + +docsrs = [ + "atmega48p", + "atmega164pa", + "atmega168", + "atmega328p", + "atmega328pb", + "atmega32a", + "atmega32u4", + "atmega2560", + "atmega128a", + "atmega1280", + "atmega1284p", + "atmega8", +] + +# If using this crate from another library crate you may want to suppress this error and provide your own disable-device-selection-error = [] -# We must select a microcontroller to build on docs.rs -docsrs = ["atmega328p"] +# MCU-specific implementation features +_mcu-atmega48p = ["_mcu-selected", "_peripheral-spi", "_peripheral-simple-pwm", "avr-device/atmega48p"] +_mcu-atmega164pa = ["_mcu-selected", "_peripheral-usart", "_peripheral-simple-pwm", "avr-device/atmega164pa"] +_mcu-atmega168 = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega168", +] +_mcu-atmega328p = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega328p", +] +_mcu-atmega328pb = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega328pb", +] +_mcu-atmega32a = ["_mcu-selected", "_peripheral-usart", "_peripheral-spi", "avr-device/atmega32a"] +_mcu-atmega32u4 = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega32u4", +] +_mcu-atmega2560 = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega2560", +] +_mcu-atmega128a = ["_mcu-selected", "_peripheral-usart", "_peripheral-spi", "avr-device/atmega128a"] +_mcu-atmega1280 = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega1280", +] +_mcu-atmega1284p = [ + "_mcu-selected", + "_peripheral-usart", + "_peripheral-spi", + "_peripheral-simple-pwm", + "avr-device/atmega1284p", +] +_mcu-atmega8 = ["_mcu-selected", "_peripheral-usart", "_peripheral-spi", "_peripheral-simple-pwm", "avr-device/atmega8"] + +_mcu-selected = [] +_peripheral-simple-pwm = [] +_peripheral-spi = [] +_peripheral-usart = [] [dependencies] avr-hal-generic = { path = "../../avr-hal-generic/" } diff --git a/mcu/atmega-hal/src/adc.rs b/mcu/atmega-hal/src/adc.rs deleted file mode 100644 index 97df94018b..0000000000 --- a/mcu/atmega-hal/src/adc.rs +++ /dev/null @@ -1,398 +0,0 @@ -//! Analog-to-Digital Converter -//! -//! # Example -//! -//! Complete example source code can be found in the repository: -//! [`atmega2560-adc.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-adc.rs) -//! -//! ``` -//! let dp = atmega_hal::Peripherals::take().unwrap(); -//! let pins = atmega_hal::pins!(dp); -//! -//! let mut adc = Adc::new(dp.ADC, Default::default()); -//! -//! let channels: [atmega_hal::adc::Channel; 4] = [ -//! pins.pf0.into_analog_input(&mut adc).into_channel(), -//! pins.pf1.into_analog_input(&mut adc).into_channel(), -//! pins.pf2.into_analog_input(&mut adc).into_channel(), -//! pins.pf3.into_analog_input(&mut adc).into_channel(), -//! ]; -//! -//! for (index, channel) in channels.iter().enumerate() { -//! let value = adc.read_blocking(channel); -//! ufmt::uwrite!(&mut serial, "CH{}: {} ", index, value).unwrap(); -//! } -//! ``` - -use crate::port; -pub use avr_hal_generic::adc::{AdcChannel, AdcOps, ClockDivider}; - -/// Select the voltage reference for the ADC peripheral -/// -/// The internal voltage reference options may not be used if an external reference voltage is -/// being applied to the AREF pin. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(u8)] -pub enum ReferenceVoltage { - /// Voltage applied to AREF pin. - Aref, - /// Default reference voltage (default). - AVcc, - /// Internal reference voltage. - Internal, -} - -impl Default for ReferenceVoltage { - fn default() -> Self { - Self::AVcc - } -} - -/// Configuration for the ADC peripheral. -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] -pub struct AdcSettings { - pub clock_divider: ClockDivider, - pub ref_voltage: ReferenceVoltage, -} - -fn apply_settings(peripheral: &crate::pac::ADC, settings: AdcSettings) { - peripheral.adcsra.write(|w| { - w.aden().set_bit(); - match settings.clock_divider { - ClockDivider::Factor2 => w.adps().prescaler_2(), - ClockDivider::Factor4 => w.adps().prescaler_4(), - ClockDivider::Factor8 => w.adps().prescaler_8(), - ClockDivider::Factor16 => w.adps().prescaler_16(), - ClockDivider::Factor32 => w.adps().prescaler_32(), - ClockDivider::Factor64 => w.adps().prescaler_64(), - ClockDivider::Factor128 => w.adps().prescaler_128(), - } - }); - peripheral.admux.write(|w| match settings.ref_voltage { - ReferenceVoltage::Aref => w.refs().aref(), - ReferenceVoltage::AVcc => w.refs().avcc(), - ReferenceVoltage::Internal => w.refs().internal(), - }); -} - -/// Check the [`avr_hal_generic::adc::Adc`] documentation. -pub type Adc = avr_hal_generic::adc::Adc; - -/// Check the [`avr_hal_generic::adc::Channel`] documentation. -pub type Channel = avr_hal_generic::adc::Channel; - -/// Additional channels -/// -/// Some channels are not directly connected to pins. This module provides types which can be used -/// to access them. -/// -/// # Example -/// ``` -/// let dp = atmega_hal::Peripherals::take().unwrap(); -/// let mut adc = atmega_hal::Adc::new(dp.ADC, Default::default()); -/// -/// let value = adc.read_blocking(&channel::Vbg); -/// ``` -pub mod channel { - #[cfg(all( - any( - feature = "atmega168", - feature = "atmega32a", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega48p", - feature = "atmega128a", - feature = "atmega1284p", - feature = "atmega8", - ), - feature = "enable-extra-adc", - ))] - pub struct ADC6; - #[cfg(all( - any( - feature = "atmega168", - feature = "atmega32a", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega48p", - feature = "atmega128a", - feature = "atmega1284p", - feature = "atmega8", - ), - feature = "enable-extra-adc", - ))] - pub struct ADC7; - #[cfg(any( - feature = "atmega1280", - feature = "atmega168", - feature = "atmega2560", - feature = "atmega32a", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega32u4", - feature = "atmega48p", - feature = "atmega128a", - feature = "atmega1284p", - feature = "atmega8", - feature = "atmega164pa", - ))] - pub struct Vbg; - #[cfg(any( - feature = "atmega1280", - feature = "atmega168", - feature = "atmega2560", - feature = "atmega32a", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega32u4", - feature = "atmega48p", - feature = "atmega128a", - feature = "atmega1284p", - feature = "atmega8", - feature = "atmega164pa", - ))] - pub struct Gnd; - #[cfg(any( - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega32u4", - feature = "atmega48p", - ))] - pub struct Temperature; -} - -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega48p", -))] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), - port::PC1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), - port::PC2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), - port::PC3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), - port::PC4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), - port::PC5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), - }, - channels: { - #[cfg(feature = "enable-extra-adc")] - channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6, - #[cfg(feature = "enable-extra-adc")] - channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7, - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - #[cfg(any(feature = "atmega328p", feature = "atmega328pb", feature = "atmega48p"))] - channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS, - }, -} - -#[cfg(any(feature = "atmega32a"))] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PA0: (crate::pac::adc::admux::MUX_A::ADC0), - port::PA1: (crate::pac::adc::admux::MUX_A::ADC1), - port::PA2: (crate::pac::adc::admux::MUX_A::ADC2), - port::PA3: (crate::pac::adc::admux::MUX_A::ADC3), - port::PA4: (crate::pac::adc::admux::MUX_A::ADC4), - port::PA5: (crate::pac::adc::admux::MUX_A::ADC5), - port::PA6: (crate::pac::adc::admux::MUX_A::ADC6), - port::PA7: (crate::pac::adc::admux::MUX_A::ADC7), - }, - channels: { - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - }, -} - -#[cfg(feature = "atmega32u4")] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: u8, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); - peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); - }, - pins: { - port::PF0: (0b000000, didr0::adc0d), - port::PF1: (0b000001, didr0::adc1d), - port::PF4: (0b000100, didr0::adc4d), - port::PF5: (0b000101, didr0::adc5d), - port::PF6: (0b000110, didr0::adc6d), - port::PF7: (0b000111, didr0::adc7d), - port::PD4: (0b100000, didr2::adc8d), - port::PD6: (0b100001, didr2::adc9d), - port::PD7: (0b100010, didr2::adc10d), - port::PB4: (0b100011, didr2::adc11d), - port::PB5: (0b100100, didr2::adc12d), - port::PB6: (0b100101, didr2::adc13d), - }, - channels: { - channel::Vbg: 0b011110, - channel::Gnd: 0b011111, - channel::Temperature: 0b100111, - }, -} - -#[cfg(feature = "atmega128a")] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PF0: (crate::pac::adc::admux::MUX_A::ADC0), - port::PF1: (crate::pac::adc::admux::MUX_A::ADC1), - port::PF2: (crate::pac::adc::admux::MUX_A::ADC2), - port::PF3: (crate::pac::adc::admux::MUX_A::ADC3), - port::PF4: (crate::pac::adc::admux::MUX_A::ADC4), - port::PF5: (crate::pac::adc::admux::MUX_A::ADC5), - port::PF6: (crate::pac::adc::admux::MUX_A::ADC6), - port::PF7: (crate::pac::adc::admux::MUX_A::ADC7), - }, - channels: { - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - }, -} - -#[cfg(any(feature = "atmega2560", feature = "atmega1280"))] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: u8, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); - peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); - }, - pins: { - port::PF0: (0b000000, didr0::adc0d), - port::PF1: (0b000001, didr0::adc1d), - port::PF2: (0b000010, didr0::adc2d), - port::PF3: (0b000011, didr0::adc3d), - port::PF4: (0b000100, didr0::adc4d), - port::PF5: (0b000101, didr0::adc5d), - port::PF6: (0b000110, didr0::adc6d), - port::PF7: (0b000111, didr0::adc7d), - port::PK0: (0b100000, didr2::adc8d), - port::PK1: (0b100001, didr2::adc9d), - port::PK2: (0b100010, didr2::adc10d), - port::PK3: (0b100011, didr2::adc11d), - port::PK4: (0b100100, didr2::adc12d), - port::PK5: (0b100101, didr2::adc13d), - port::PK6: (0b100110, didr2::adc14d), - port::PK7: (0b100111, didr2::adc15d), - }, - channels: { - channel::Vbg: 0b011110, - channel::Gnd: 0b011111, - }, -} - -#[cfg(any(feature = "atmega1284p"))] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), - port::PA1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), - port::PA2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), - port::PA3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), - port::PA4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), - port::PA5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), - }, - channels: { - #[cfg(feature = "enable-extra-adc")] - channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6, - #[cfg(feature = "enable-extra-adc")] - channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7, - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - }, -} - -#[cfg(any(feature = "atmega8"))] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PC0: (crate::pac::adc::admux::MUX_A::ADC0), - port::PC1: (crate::pac::adc::admux::MUX_A::ADC1), - port::PC2: (crate::pac::adc::admux::MUX_A::ADC2), - port::PC3: (crate::pac::adc::admux::MUX_A::ADC3), - port::PC4: (crate::pac::adc::admux::MUX_A::ADC4), - port::PC5: (crate::pac::adc::admux::MUX_A::ADC5), - }, - channels: { - #[cfg(feature = "enable-extra-adc")] - channel::ADC6: crate::pac::adc::admux::MUX_A::ADC6, - #[cfg(feature = "enable-extra-adc")] - channel::ADC7: crate::pac::adc::admux::MUX_A::ADC7, - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - }, -} - -#[cfg(any(feature = "atmega164pa"))] -avr_hal_generic::impl_adc! { - hal: crate::Atmega, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), - port::PA1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), - port::PA2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), - port::PA3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), - port::PA4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), - port::PA5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), - port::PA6: (crate::pac::adc::admux::MUX_A::ADC6, didr0::adc6d), - port::PA7: (crate::pac::adc::admux::MUX_A::ADC7, didr0::adc7d), - }, - channels: { - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - }, -} diff --git a/mcu/atmega-hal/src/atmega1280.rs b/mcu/atmega-hal/src/atmega1280.rs new file mode 100644 index 0000000000..840ea1b55d --- /dev/null +++ b/mcu/atmega-hal/src/atmega1280.rs @@ -0,0 +1,139 @@ +pub use avr_device::atmega1280 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega1280 as hal; + impl_adc_channels!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: u8, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); + peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + }, + pins: { + hal::port::PF0: (0b000000, didr0::adc0d), + hal::port::PF1: (0b000001, didr0::adc1d), + hal::port::PF2: (0b000010, didr0::adc2d), + hal::port::PF3: (0b000011, didr0::adc3d), + hal::port::PF4: (0b000100, didr0::adc4d), + hal::port::PF5: (0b000101, didr0::adc5d), + hal::port::PF6: (0b000110, didr0::adc6d), + hal::port::PF7: (0b000111, didr0::adc7d), + hal::port::PK0: (0b100000, didr2::adc8d), + hal::port::PK1: (0b100001, didr2::adc9d), + hal::port::PK2: (0b100010, didr2::adc10d), + hal::port::PK3: (0b100011, didr2::adc11d), + hal::port::PK4: (0b100100, didr2::adc12d), + hal::port::PK5: (0b100101, didr2::adc13d), + hal::port::PK6: (0b100110, didr2::adc14d), + hal::port::PK7: (0b100111, didr2::adc15d), + }, + channels: { + channel::Vbg: 0b011110, + channel::Gnd: 0b011111, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega1280, + capacity: 4096, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega1280 as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PD1, + scl: hal::port::PD0, + } +} + +impl_mod_port! { + use crate::atmega1280 as hal; + impl_port_peripheral_a8_b8_c8_d8_e8_f8_g6_h8_j8_k8_l8! { + } + + #[macro_export] + macro_rules! atmega1280_pins { + ($p:expr) => { + $crate::atmega1280::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF, $p.PORTG, $p.PORTH, $p.PORTJ, $p.PORTK, $p.PORTL) + }; + } + + pub use atmega1280_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega1280 as hal; + impl_simple_pwm_peripheral_1280_2560! { + } +} + +impl_mod_spi! { + use crate::atmega1280 as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB1, + mosi: hal::port::PB2, + miso: hal::port::PB3, + cs: hal::port::PB0, + } +} + +impl_mod_usart! { + use crate::atmega1280 as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PE0, + tx: hal::port::PE1, + usart_type: Usart0, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART1, + register_suffix: 1, + rx: hal::port::PD2, + tx: hal::port::PD3, + usart_type: Usart1, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART2, + register_suffix: 2, + rx: hal::port::PH0, + tx: hal::port::PH1, + usart_type: Usart2, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART3, + register_suffix: 3, + rx: hal::port::PJ0, + tx: hal::port::PJ1, + usart_type: Usart3, + } +} + +impl_mod_wdt! { + use crate::atmega1280 as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} diff --git a/mcu/atmega-hal/src/atmega1284p.rs b/mcu/atmega-hal/src/atmega1284p.rs new file mode 100644 index 0000000000..51b4a0dd9f --- /dev/null +++ b/mcu/atmega-hal/src/atmega1284p.rs @@ -0,0 +1,299 @@ +pub use avr_device::atmega1284p as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega1284p as hal; + impl_adc_channels_extra!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PA0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PA1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PA2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PA3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PA4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PA5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: hal::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: hal::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega1284p, + capacity: 4096, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega1284p as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC1, + scl: hal::port::PC0, + } +} + +impl_mod_port! { + use crate::atmega1284p as hal; + impl_port_peripheral_a8_b8_c8_d8! { + } + + #[macro_export] + macro_rules! atmega1284_pins { + ($p:expr) => { + $crate::atmega1284::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega1284_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega1284p as hal; + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB3`, `PB4`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut b3 = pins.b3.into_output().into_pwm(&mut timer0); + /// let mut b4 = pins.b4.into_output().into_pwm(&mut timer0); + /// + /// b3.set_duty(128); + /// b4.enable(); + /// ``` + pub struct Timer0Pwm { + timer: hal::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().direct(), + Prescaler::Prescale8 => w.cs0().prescale_8(), + Prescaler::Prescale64 => w.cs0().prescale_64(), + Prescaler::Prescale256 => w.cs0().prescale_256(), + Prescaler::Prescale1024 => w.cs0().prescale_1024(), + }); + }, + pins: { + hal::port::PB3: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + }, + }, + + hal::port::PB4: { + ocr: ocr0b, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PD5`, `PD4`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer1); + /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1); + /// + /// d5.set_duty(128); + /// d5.enable(); + /// ``` + pub struct Timer1Pwm { + timer: hal::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_r, w| { + w.wgm1().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + } + }); + }, + pins: { + hal::port::PD5: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + }, + }, + + hal::port::PD4: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC2` for PWM (pins `PD7`, `PD6`) + /// + /// # Example + /// ``` + /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); + /// + /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer2); + /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer2); + /// + /// d7.set_duty(128); + /// d7.enable(); + /// ``` + pub struct Timer2Pwm { + timer: hal::pac::TC2, + init: |tim, prescaler| { + tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast()); + tim.tccr2b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs2().direct(), + Prescaler::Prescale8 => w.cs2().prescale_8(), + Prescaler::Prescale64 => w.cs2().prescale_64(), + Prescaler::Prescale256 => w.cs2().prescale_256(), + Prescaler::Prescale1024 => w.cs2().prescale_1024(), + }); + }, + pins: { + hal::port::PD7: { + ocr: ocr2a, + into_pwm: |tim| if enable { + tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); + } else { + tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); + }, + }, + + hal::port::PD6: { + ocr: ocr2b, + into_pwm: |tim| if enable { + tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); + } else { + tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC3` for PWM (pins `PB6`, `PB7`) + pub struct Timer3Pwm { + timer: hal::pac::TC3, + init: |tim, prescaler| { + tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); + tim.tccr3b.modify(|_r, w| { + w.wgm3().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs3().direct(), + Prescaler::Prescale8 => w.cs3().prescale_8(), + Prescaler::Prescale64 => w.cs3().prescale_64(), + Prescaler::Prescale256 => w.cs3().prescale_256(), + Prescaler::Prescale1024 => w.cs3().prescale_1024(), + } + }); + }, + pins: { + hal::port::PB6: { + ocr: ocr3a, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + }, + }, + + hal::port::PB7: { + ocr: ocr3b, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_spi! { + use crate::atmega1284p as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB7, + mosi: hal::port::PB5, + miso: hal::port::PB6, + cs: hal::port::PB4, + } +} + +impl_mod_usart! { + use crate::atmega1284p as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART1, + register_suffix: 1, + rx: hal::port::PD2, + tx: hal::port::PD3, + usart_type: Usart1, + } +} + +impl_mod_wdt! { + use crate::atmega1284p as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} diff --git a/mcu/atmega-hal/src/atmega128a.rs b/mcu/atmega-hal/src/atmega128a.rs new file mode 100644 index 0000000000..42cb3b484c --- /dev/null +++ b/mcu/atmega-hal/src/atmega128a.rs @@ -0,0 +1,266 @@ +pub use avr_device::atmega128a as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega128a as hal; + impl_adc_channels_extra!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PF0: (hal::pac::adc::admux::MUX_A::ADC0), + hal::port::PF1: (hal::pac::adc::admux::MUX_A::ADC1), + hal::port::PF2: (hal::pac::adc::admux::MUX_A::ADC2), + hal::port::PF3: (hal::pac::adc::admux::MUX_A::ADC3), + hal::port::PF4: (hal::pac::adc::admux::MUX_A::ADC4), + hal::port::PF5: (hal::pac::adc::admux::MUX_A::ADC5), + hal::port::PF6: (hal::pac::adc::admux::MUX_A::ADC6), + hal::port::PF7: (hal::pac::adc::admux::MUX_A::ADC7), + }, + channels: { + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega128a, + capacity: 4096, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega_old, +} + +impl_mod_i2c! { + use crate::atmega128a as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PD1, + scl: hal::port::PD0, + } +} + +impl_mod_port! { + use crate::atmega128a as hal; + + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + E: hal::pac::PORTE = [0, 1, 2, 3, 4, 5, 6, 7], + F: hal::pac::PORTF = [0, 1, 2, 3, 4, 5, 6, 7], + G: hal::pac::PORTG = [0, 1, 2, 3, 4], + } + } + + #[macro_export] + macro_rules! atmega128a_pins { + ($p:expr) => { + $crate::atmega128a::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF, $p.PORTG) + }; + } + + pub use atmega128a_pins as pins; +} + +impl_mod_spi! { + use crate::atmega128a as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB1, + mosi: hal::port::PB2, + miso: hal::port::PB3, + cs: hal::port::PB0, + } +} + +impl_mod_usart! { + use crate::atmega128a as hal; + impl_usart_peripheral_type! { + peripheral: hal::pac::USART0, + rx: hal::port::PE0, + tx: hal::port::PE1, + usart_type: Usart0, + } + + impl_usart_peripheral_type! { + peripheral: hal::pac::USART1, + rx: hal::port::PD2, + tx: hal::port::PD3, + usart_type: Usart1, + } + + // TODO: ATmega128A USART1 is also different from other atmegas + // Mainly needed because ubrr1 is split in ubrr1h and ubrr1l + impl + avr_hal_generic::usart::UsartOps< + hal::Hal, + hal::port::Pin, + hal::port::Pin, + > for hal::pac::USART1 + { + fn raw_init(&mut self, baudrate: Baudrate) { + let ubrr1h: u8 = (baudrate.ubrr >> 8) as u8; + let ubrr1l: u8 = baudrate.ubrr as u8; + self.ubrr1h.write(|w| w.bits(ubrr1h)); + self.ubrr1l.write(|w| w.bits(ubrr1l)); + self.ucsr1a.write(|w| w.u2x1().bit(baudrate.u2x)); + + // Enable receiver and transmitter but leave interrupts disabled. + #[rustfmt::skip] + self.ucsr1b.write(|w| w + .txen1().set_bit() + .rxen1().set_bit() + ); + + // Set frame format to 8n1 for now. At some point, this should be made + // configurable, similar to what is done in other HALs. + #[rustfmt::skip] + self.ucsr1c.write(|w| w + .umsel1().usart_async() + .ucsz1().chr8() + .usbs1().stop1() + .upm1().disabled() + ); + } + + fn raw_deinit(&mut self) { + // Wait for any ongoing transfer to finish. + avr_hal_generic::nb::block!(self.raw_flush()).ok(); + self.ucsr1b.reset(); + } + + fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { + if self.ucsr1a.read().udre1().bit_is_clear() { + Err(avr_hal_generic::nb::Error::WouldBlock) + } else { + Ok(()) + } + } + + fn raw_write( + &mut self, + byte: u8, + ) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { + // Call flush to make sure the data-register is empty + self.raw_flush()?; + + self.udr1.write(|w| w.bits(byte)); + Ok(()) + } + + fn raw_read(&mut self) -> avr_hal_generic::nb::Result { + if self.ucsr1a.read().rxc1().bit_is_clear() { + return Err(avr_hal_generic::nb::Error::WouldBlock); + } + + Ok(self.udr1.read().bits()) + } + + fn raw_interrupt(&mut self, event: Event, state: bool) { + match event { + Event::RxComplete => self.ucsr1b.modify(|_, w| w.rxcie1().bit(state)), + Event::TxComplete => self.ucsr1b.modify(|_, w| w.txcie1().bit(state)), + Event::DataRegisterEmpty => self.ucsr1b.modify(|_, w| w.udrie1().bit(state)), + } + } + } + + // TODO: ATmega128A USART0 is also different from other atmegas + // Mainly needed because ubrr1 is split in ubrr1h and ubrr1l + // For USART0 they are not even close to eachother in memory + impl + avr_hal_generic::usart::UsartOps< + hal::Hal, + hal::port::Pin, + hal::port::Pin, + > for hal::pac::USART0 + { + fn raw_init(&mut self, baudrate: Baudrate) { + let ubrr0h: u8 = (baudrate.ubrr >> 8) as u8; + let ubrr0l: u8 = baudrate.ubrr as u8; + self.ubrr0h.write(|w| w.bits(ubrr0h)); + self.ubrr0l.write(|w| w.bits(ubrr0l)); + self.ucsr0a.write(|w| w.u2x0().bit(baudrate.u2x)); + + // Enable receiver and transmitter but leave interrupts disabled. + self.ucsr0b.write(|w| w.txen0().set_bit().rxen0().set_bit()); + + // Set frame format to 8n1 for now. At some point, this should be made + // configurable, similar to what is done in other HALs. + #[rustfmt::skip] + self.ucsr0c.write(|w| w + .umsel0().usart_async() + .ucsz0().chr8() + .usbs0().stop1() + .upm0().disabled() + ); + } + + fn raw_deinit(&mut self) { + // Wait for any ongoing transfer to finish. + avr_hal_generic::nb::block!(self.raw_flush()).ok(); + self.ucsr0b.reset(); + } + + fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { + if self.ucsr0a.read().udre0().bit_is_clear() { + Err(avr_hal_generic::nb::Error::WouldBlock) + } else { + Ok(()) + } + } + + fn raw_write( + &mut self, + byte: u8, + ) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { + // Call flush to make sure the data-register is empty + self.raw_flush()?; + + self.udr0.write(|w| w.bits(byte)); + Ok(()) + } + + fn raw_read(&mut self) -> avr_hal_generic::nb::Result { + if self.ucsr0a.read().rxc0().bit_is_clear() { + return Err(avr_hal_generic::nb::Error::WouldBlock); + } + + Ok(self.udr0.read().bits()) + } + + fn raw_interrupt(&mut self, event: Event, state: bool) { + match event { + Event::RxComplete => self.ucsr0b.modify(|_, w| w.rxcie0().bit(state)), + Event::TxComplete => self.ucsr0b.modify(|_, w| w.txcie0().bit(state)), + Event::DataRegisterEmpty => self.ucsr0b.modify(|_, w| w.udrie0().bit(state)), + } + } + } +} + +impl_mod_wdt! { + use crate::atmega128a as hal; + impl_wdt_peripheral_ms2000! { + mcusr: hal::pac::cpu::MCUCSR, + wdtcsr_name: wdtcr, + } +} + diff --git a/mcu/atmega-hal/src/atmega164pa.rs b/mcu/atmega-hal/src/atmega164pa.rs new file mode 100644 index 0000000000..197b7a92d7 --- /dev/null +++ b/mcu/atmega-hal/src/atmega164pa.rs @@ -0,0 +1,196 @@ +pub use avr_device::atmega164pa as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega164pa as hal; + impl_adc_channels!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PA0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PA1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PA2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PA3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PA4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PA5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + hal::port::PA6: (hal::pac::adc::admux::MUX_A::ADC6, didr0::adc6d), + hal::port::PA7: (hal::pac::adc::admux::MUX_A::ADC7, didr0::adc7d), + }, + channels: { + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega164pa, + capacity: 512, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega164pa as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC1, + scl: hal::port::PC0, + } +} + +impl_mod_port! { + use crate::atmega164pa as hal; + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3, 4, 5, 6 ,7], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6 ,7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6 ,7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6 ,7], + } + } + + #[macro_export] + macro_rules! atmega164pa_pins { + ($p:expr) => { + $crate::atmega164pa::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega164pa_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega164pa as hal; + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB3`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut b3 = pins.pb3.into_output().into_pwm(&mut timer0); + /// + /// b3.set_duty(128); + /// b3.enable(); + /// ``` + pub struct Timer0Pwm { + timer: hal::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().bits(0b11)); + tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); + + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().running_no_prescaling(), + Prescaler::Prescale8 => w.cs0().running_clk_8(), + Prescaler::Prescale64 => w.cs0().running_clk_64(), + Prescaler::Prescale256 => w.cs0().running_clk_256(), + Prescaler::Prescale1024 => w.cs0().running_clk_1024(), + }); + }, + pins: { + hal::port::PB3: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().bits(0b11)); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PD4`, `PD5`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d4 = pins.pd4.into_output().into_pwm(&mut timer1); + /// let mut d5 = pins.pd5.into_output().into_pwm(&mut timer1); + /// + /// d4.set_duty(128); + /// d4.enable(); + /// d5.set_duty(64); + /// d5.enable(); + /// ``` + pub struct Timer1Pwm { + timer: hal::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); + tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); + tim.tccr1b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().running_no_prescaling(), + Prescaler::Prescale8 => w.cs1().running_clk_8(), + Prescaler::Prescale64 => w.cs1().running_clk_64(), + Prescaler::Prescale256 => w.cs1().running_clk_256(), + Prescaler::Prescale1024 => w.cs1().running_clk_1024(), + }); + }, + pins: { + hal::port::PD4: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().bits(0b11)); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); + }, + }, + hal::port::PD5: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().bits(0b11)); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); + }, + }, + }, + } + } +} + +impl_mod_usart! { + use crate::atmega164pa as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART1, + register_suffix: 1, + rx: hal::port::PD2, + tx: hal::port::PD3, + usart_type: Usart1, + } +} + +impl_mod_wdt! { + use crate::atmega164pa as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} + diff --git a/mcu/atmega-hal/src/atmega168.rs b/mcu/atmega-hal/src/atmega168.rs new file mode 100644 index 0000000000..1b04d45dfc --- /dev/null +++ b/mcu/atmega-hal/src/atmega168.rs @@ -0,0 +1,110 @@ +pub use avr_device::atmega168 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega168 as hal; + impl_adc_channels_extra!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PC0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PC1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PC2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PC3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PC4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PC5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: hal::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: hal::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega168, + capacity: 512, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega168 as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC4, + scl: hal::port::PC5, + } +} + +impl_mod_port! { + use crate::atmega168 as hal; + impl_port_peripheral_b8_c7_d8! { + } + + #[macro_export] + macro_rules! atmega168_pins { + ($p:expr) => { + $crate::atmega168::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega168_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega168 as hal; + impl_simple_pwm_peripheral_48p_168_328p_328pb! { + } +} + +impl_mod_spi! { + use crate::atmega168 as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB5, + mosi: hal::port::PB3, + miso: hal::port::PB4, + cs: hal::port::PB2, + + } +} + +impl_mod_usart! { + use crate::atmega168 as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } +} + +impl_mod_wdt! { + use crate::atmega168 as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} + diff --git a/mcu/atmega-hal/src/atmega2560.rs b/mcu/atmega-hal/src/atmega2560.rs new file mode 100644 index 0000000000..f386a2e65b --- /dev/null +++ b/mcu/atmega-hal/src/atmega2560.rs @@ -0,0 +1,124 @@ +pub use avr_device::atmega2560 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega2560 as hal; + impl_adc_channels!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: u8, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); + peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + }, + pins: { + hal::port::PF0: (0b000000, didr0::adc0d), + hal::port::PF1: (0b000001, didr0::adc1d), + hal::port::PF2: (0b000010, didr0::adc2d), + hal::port::PF3: (0b000011, didr0::adc3d), + hal::port::PF4: (0b000100, didr0::adc4d), + hal::port::PF5: (0b000101, didr0::adc5d), + hal::port::PF6: (0b000110, didr0::adc6d), + hal::port::PF7: (0b000111, didr0::adc7d), + hal::port::PK0: (0b100000, didr2::adc8d), + hal::port::PK1: (0b100001, didr2::adc9d), + hal::port::PK2: (0b100010, didr2::adc10d), + hal::port::PK3: (0b100011, didr2::adc11d), + hal::port::PK4: (0b100100, didr2::adc12d), + hal::port::PK5: (0b100101, didr2::adc13d), + hal::port::PK6: (0b100110, didr2::adc14d), + hal::port::PK7: (0b100111, didr2::adc15d), + }, + channels: { + channel::Vbg: 0b011110, + channel::Gnd: 0b011111, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega2560, + capacity: 4096, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega2560 as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PD1, + scl: hal::port::PD0, + } +} + +impl_mod_port! { + use crate::atmega2560 as hal; + impl_port_peripheral_a8_b8_c8_d8_e8_f8_g6_h8_j8_k8_l8! { + } + + #[macro_export] + macro_rules! atmega2560_pins { + ($p:expr) => { + $crate::atmega2560::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF, $p.PORTG, $p.PORTH, $p.PORTJ, $p.PORTK, $p.PORTL) + }; + } + + pub use atmega2560_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega2560 as hal; + impl_simple_pwm_peripheral_1280_2560! { + } +} + +impl_mod_spi! { + use crate::atmega2560 as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB1, + mosi: hal::port::PB2, + miso: hal::port::PB3, + cs: hal::port::PB0, + } +} + +impl_mod_usart! { + use crate::atmega2560 as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PE0, + tx: hal::port::PE1, + usart_type: Usart0, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART1, + register_suffix: 1, + rx: hal::port::PD2, + tx: hal::port::PD3, + usart_type: Usart1, + } +} + +impl_mod_wdt! { + use crate::atmega2560 as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} + diff --git a/mcu/atmega-hal/src/atmega328p.rs b/mcu/atmega-hal/src/atmega328p.rs new file mode 100644 index 0000000000..b77cf72433 --- /dev/null +++ b/mcu/atmega-hal/src/atmega328p.rs @@ -0,0 +1,109 @@ +pub use avr_device::atmega328p as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega328p as hal; + impl_adc_channels_extra_temp!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PC0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PC1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PC2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PC3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PC4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PC5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: hal::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: hal::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + channel::Temperature: hal::pac::adc::admux::MUX_A::TEMPSENS, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega328p, + capacity: 1024, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega328p as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC4, + scl: hal::port::PC5, + } +} + +impl_mod_port! { + use crate::atmega328p as hal; + impl_port_peripheral_b8_c7_d8! { + } + + #[macro_export] + macro_rules! atmega328p_pins { + ($p:expr) => { + $crate::atmega328p::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega328p_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega328p as hal; + impl_simple_pwm_peripheral_48p_168_328p_328pb! { + } +} + +impl_mod_spi! { + use crate::atmega328p as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB5, + mosi: hal::port::PB3, + miso: hal::port::PB4, + cs: hal::port::PB2, + } +} + +impl_mod_usart! { + use crate::atmega328p as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } +} + +impl_mod_wdt! { + use crate::atmega328p as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} diff --git a/mcu/atmega-hal/src/atmega328pb.rs b/mcu/atmega-hal/src/atmega328pb.rs new file mode 100644 index 0000000000..8e84de3932 --- /dev/null +++ b/mcu/atmega-hal/src/atmega328pb.rs @@ -0,0 +1,221 @@ +pub use avr_device::atmega328pb as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega328pb as hal; + impl_adc_channels_extra_temp!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PC0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PC1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PC2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PC3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PC4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PC5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: hal::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: hal::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + channel::Temperature: hal::pac::adc::admux::MUX_A::TEMPSENS, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega328pb, + capacity: 1024, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega328pb as hal; + impl_i2c_peripheral! { + i2c_type: I2c0, + peripheral: hal::pac::TWI0, + sda: hal::port::PC4, + scl: hal::port::PC5, + } + + impl_i2c_peripheral! { + i2c_type: I2c1, + peripheral: hal::pac::TWI1, + sda: hal::port::PE0, + scl: hal::port::PE1, + } +} + +impl_mod_port! { + use crate::atmega328pb as hal; + avr_hal_generic::impl_port_traditional! { + enum Ports { + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + E: hal::pac::PORTE = [0, 1, 2, 3], + } + } + + #[macro_export] + macro_rules! atmega328pb_pins { + ($p:expr) => { + $crate::atmega328pb::Pins::new($p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE) + }; + } + + pub use atmega328pb_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega328pb as hal; + impl_simple_pwm_peripheral_48p_168_328p_328pb! { + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC3` for PWM (pins `PD0`, `PD2`) + pub struct Timer3Pwm { + timer: hal::pac::TC3, + init: |tim, prescaler| { + tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); + tim.tccr3b.modify(|_r, w| { + unsafe { w.wgm3().bits(0b01) }; + + match prescaler { + Prescaler::Direct => w.cs3().direct(), + Prescaler::Prescale8 => w.cs3().prescale_8(), + Prescaler::Prescale64 => w.cs3().prescale_64(), + Prescaler::Prescale256 => w.cs3().prescale_256(), + Prescaler::Prescale1024 => w.cs3().prescale_1024(), + } + }); + }, + pins: { + hal::port::PD0: { + ocr: ocr3a, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + }, + }, + + hal::port::PD2: { + ocr: ocr3b, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC4` for PWM (pins `PD1`, `PD2`) + pub struct Timer4Pwm { + timer: hal::pac::TC4, + init: |tim, prescaler| { + tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01)); + tim.tccr4b.modify(|_r, w| { + unsafe { w.wgm4().bits(0b01) }; + + match prescaler { + Prescaler::Direct => w.cs4().direct(), + Prescaler::Prescale8 => w.cs4().prescale_8(), + Prescaler::Prescale64 => w.cs4().prescale_64(), + Prescaler::Prescale256 => w.cs4().prescale_256(), + Prescaler::Prescale1024 => w.cs4().prescale_1024(), + } + }); + }, + pins: { + hal::port::PD1: { + ocr: ocr4a, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); + }, + }, + + hal::port::PD2: { + ocr: ocr4b, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_spi! { + use crate::atmega328pb as hal; + impl_spi_peripheral! { + spi: Spi0, + peripheral: hal::pac::SPI0, + sclk: hal::port::PB5, + mosi: hal::port::PB3, + miso: hal::port::PB4, + cs: hal::port::PB2, + } + + impl_spi_peripheral! { + spi: Spi1, + peripheral: hal::pac::SPI1, + sclk: hal::port::PC1, + mosi: hal::port::PE3, + miso: hal::port::PC0, + cs: hal::port::PE2, + } +} + +impl_mod_usart! { + use crate::atmega328pb as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART0, + register_suffix: 0, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } + + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART1, + register_suffix: 1, + rx: hal::port::PB4, + tx: hal::port::PB3, + usart_type: Usart1, + } +} + +impl_mod_wdt! { + use crate::atmega328pb as hal; + + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} + diff --git a/mcu/atmega-hal/src/atmega32a.rs b/mcu/atmega-hal/src/atmega32a.rs new file mode 100644 index 0000000000..0c43e84c23 --- /dev/null +++ b/mcu/atmega-hal/src/atmega32a.rs @@ -0,0 +1,104 @@ +pub use avr_device::atmega32a as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega32a as hal; + + impl_adc_channels_extra!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PA0: (hal::pac::adc::admux::MUX_A::ADC0), + hal::port::PA1: (hal::pac::adc::admux::MUX_A::ADC1), + hal::port::PA2: (hal::pac::adc::admux::MUX_A::ADC2), + hal::port::PA3: (hal::pac::adc::admux::MUX_A::ADC3), + hal::port::PA4: (hal::pac::adc::admux::MUX_A::ADC4), + hal::port::PA5: (hal::pac::adc::admux::MUX_A::ADC5), + hal::port::PA6: (hal::pac::adc::admux::MUX_A::ADC6), + hal::port::PA7: (hal::pac::adc::admux::MUX_A::ADC7), + }, + channels: { + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega32a, + capacity: 1024, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega_old, +} + +impl_mod_i2c! { + use crate::atmega32a as hal; + + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC1, + scl: hal::port::PC0, + } +} + +impl_mod_port! { + use crate::atmega32a as hal; + + impl_port_peripheral_a8_b8_c8_d8! { + } + + #[macro_export] + macro_rules! atmega32a_pins { + ($p:expr) => { + $crate::atmega32a::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega32a_pins as pins; +} + +impl_mod_spi! { + use crate::atmega32a as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB7, + mosi: hal::port::PB5, + miso: hal::port::PB6, + cs: hal::port::PB4, + } +} + +impl_mod_usart! { + use crate::atmega32a as hal; + impl_usart_peripheral_ubrrh_ucsrc! { + peripheral: hal::pac::USART, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } +} + +impl_mod_wdt! { + use crate::atmega32a as hal; + + impl_wdt_peripheral_ms2000! { + mcusr: hal::pac::cpu::MCUCSR, + wdtcsr_name: wdtcr, + } +} + diff --git a/mcu/atmega-hal/src/atmega32u4.rs b/mcu/atmega-hal/src/atmega32u4.rs new file mode 100644 index 0000000000..9bbf730add --- /dev/null +++ b/mcu/atmega-hal/src/atmega32u4.rs @@ -0,0 +1,327 @@ +pub use avr_device::atmega32u4 as pac; + +pub struct Hal; + +use crate::r#impl::*; +impl_mod_adc! { + use crate::atmega32u4 as hal; + + impl_adc_channels_temp!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: u8, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().bits(id & 0x1f)); + peripheral.adcsrb.modify(|_, w| w.mux5().bit(id & 0x20 != 0)); + }, + pins: { + hal::port::PF0: (0b000000, didr0::adc0d), + hal::port::PF1: (0b000001, didr0::adc1d), + hal::port::PF4: (0b000100, didr0::adc4d), + hal::port::PF5: (0b000101, didr0::adc5d), + hal::port::PF6: (0b000110, didr0::adc6d), + hal::port::PF7: (0b000111, didr0::adc7d), + hal::port::PD4: (0b100000, didr2::adc8d), + hal::port::PD6: (0b100001, didr2::adc9d), + hal::port::PD7: (0b100010, didr2::adc10d), + hal::port::PB4: (0b100011, didr2::adc11d), + hal::port::PB5: (0b100100, didr2::adc12d), + hal::port::PB6: (0b100101, didr2::adc13d), + }, + channels: { + channel::Vbg: 0b011110, + channel::Gnd: 0b011111, + channel::Temperature: 0b100111, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega32u4, + capacity: 1024, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega32u4 as hal; + + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PD1, + scl: hal::port::PD0, + } +} + +impl_mod_port! { + use crate::atmega32u4 as hal; + + avr_hal_generic::impl_port_traditional! { + enum Ports { + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [6, 7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + E: hal::pac::PORTE = [2, 6], + F: hal::pac::PORTF = [0, 1, 4, 5, 6, 7], + } + } + + #[macro_export] + macro_rules! atmega32u4_pins { + ($p:expr) => { + $crate::atmega32u4::Pins::new($p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF) + }; + } + + pub use atmega32u4_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega32u4 as hal; + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB7`, `PD0`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer0); + /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer0); + /// + /// d11.set_duty(128); + /// d11.enable(); + /// ``` + pub struct Timer0Pwm { + timer: hal::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().direct(), + Prescaler::Prescale8 => w.cs0().prescale_8(), + Prescaler::Prescale64 => w.cs0().prescale_64(), + Prescaler::Prescale256 => w.cs0().prescale_256(), + Prescaler::Prescale1024 => w.cs0().prescale_1024(), + }); + }, + pins: { + hal::port::PB7: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + }, + }, + + hal::port::PD0: { + ocr: ocr0b, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1); + /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1); + /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1); + /// + /// d9.set_duty(128); + /// d9.enable(); + /// ``` + pub struct Timer1Pwm { + timer: hal::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_r, w| w.wgm1().bits(0b01)); + + tim.tccr1b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + }); + }, + pins: { + hal::port::PB5: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + }, + }, + + hal::port::PB6: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + }, + }, + + hal::port::PB7: { + ocr: ocr1c, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1c().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1c().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC3` for PWM (pins `PC6`) + /// + /// # Example + /// ``` + /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64); + /// + /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3); + /// + /// d5.set_duty(128); + /// d5.enable(); + /// ``` + pub struct Timer3Pwm { + timer: hal::pac::TC3, + init: |tim, prescaler| { + tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); + tim.tccr3b.modify(|_r, w| w.wgm3().bits(0b01)); + + tim.tccr3b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs3().direct(), + Prescaler::Prescale8 => w.cs3().prescale_8(), + Prescaler::Prescale64 => w.cs3().prescale_64(), + Prescaler::Prescale256 => w.cs3().prescale_256(), + Prescaler::Prescale1024 => w.cs3().prescale_1024(), + }); + }, + pins: { + hal::port::PC6: { + ocr: ocr3a, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC4` for PWM (pins `PB6`, `PC7`, `PD7`) + /// + /// # Example + /// ``` + /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64); + /// + /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4); + /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer4); + /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer4); + /// + /// d6.set_duty(128); + /// d6.enable(); + /// ``` + pub struct Timer4Pwm { + timer: hal::pac::TC4, + init: |tim, prescaler| { + tim.tccr4a.modify(|_r, w| w.pwm4a().set_bit()); + tim.tccr4a.modify(|_r, w| w.pwm4b().set_bit()); + tim.tccr4c.modify(|_r, w| w.pwm4d().set_bit()); + + tim.tccr4b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs4().direct(), + Prescaler::Prescale8 => w.cs4().prescale_8(), + Prescaler::Prescale64 => w.cs4().prescale_64(), + Prescaler::Prescale256 => w.cs4().prescale_256(), + Prescaler::Prescale1024 => w.cs4().prescale_1024(), + }); + }, + pins: { + hal::port::PB6: { + ocr: ocr4b, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); + }, + }, + + hal::port::PC7: { + ocr: ocr4a, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); + }, + }, + + hal::port::PD7: { + ocr: ocr4d, + into_pwm: |tim| if enable { + tim.tccr4c.modify(|_r, w| w.com4d().match_clear()); + } else { + tim.tccr4c.modify(|_r, w| w.com4d().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_spi! { + use crate::atmega32u4 as hal; + + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB1, + mosi: hal::port::PB2, + miso: hal::port::PB3, + cs: hal::port::PB0, + } +} + +impl_mod_usart! { + use crate::atmega32u4 as hal; + impl_usart_peripheral_traditional! { + peripheral: hal::pac::USART1, + register_suffix: 1, + rx: hal::port::PD2, + tx: hal::port::PD3, + usart_type: Usart1, + } +} + +impl_mod_wdt! { + use crate::atmega32u4 as hal; + + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} + diff --git a/mcu/atmega-hal/src/atmega48p.rs b/mcu/atmega-hal/src/atmega48p.rs new file mode 100644 index 0000000000..519791f8eb --- /dev/null +++ b/mcu/atmega-hal/src/atmega48p.rs @@ -0,0 +1,100 @@ +pub use avr_device::atmega48p as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega48p as hal; + impl_adc_channels_extra_temp!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PC0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PC1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PC2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PC3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PC4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PC5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: hal::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: hal::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + channel::Temperature: hal::pac::adc::admux::MUX_A::TEMPSENS, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega48p, + capacity: 256, + addr_width: u8, + addr_reg: eearl, + variant: impl_eeprom_atmega, +} + +impl_mod_i2c! { + use crate::atmega48p as hal; + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC4, + scl: hal::port::PC5, + } +} + +impl_mod_port! { + use crate::atmega48p as hal; + impl_port_peripheral_b8_c7_d8! { + } + + #[macro_export] + macro_rules! atmega48p_pins { + ($p:expr) => { + $crate::atmega48p::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega48p_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega48p as hal; + impl_simple_pwm_peripheral_48p_168_328p_328pb! { + } +} + +impl_mod_spi! { + use crate::atmega48p as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB5, + mosi: hal::port::PB3, + miso: hal::port::PB4, + cs: hal::port::PB2, + + } +} + +impl_mod_wdt! { + use crate::atmega48p as hal; + impl_wdt_peripheral_ms8000! { + mcusr: hal::pac::cpu::MCUSR, + wdtcsr_name: wdtcsr, + } +} + diff --git a/mcu/atmega-hal/src/atmega8.rs b/mcu/atmega-hal/src/atmega8.rs new file mode 100644 index 0000000000..2657e3bb51 --- /dev/null +++ b/mcu/atmega-hal/src/atmega8.rs @@ -0,0 +1,198 @@ +pub use avr_device::atmega8 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::atmega8 as hal; + + impl_adc_channels_extra!(); + impl_adc!(); + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { apply_settings(peripheral, settings) }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PC0: (hal::pac::adc::admux::MUX_A::ADC0), + hal::port::PC1: (hal::pac::adc::admux::MUX_A::ADC1), + hal::port::PC2: (hal::pac::adc::admux::MUX_A::ADC2), + hal::port::PC3: (hal::pac::adc::admux::MUX_A::ADC3), + hal::port::PC4: (hal::pac::adc::admux::MUX_A::ADC4), + hal::port::PC5: (hal::pac::adc::admux::MUX_A::ADC5), + }, + channels: { + #[cfg(feature = "enable-extra-adc")] + channel::ADC6: hal::pac::adc::admux::MUX_A::ADC6, + #[cfg(feature = "enable-extra-adc")] + channel::ADC7: hal::pac::adc::admux::MUX_A::ADC7, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + }, + } +} + +impl_mod_eeprom! { + hal: crate::atmega8, + capacity: 512, + addr_width: u16, + addr_reg: eear, + variant: impl_eeprom_atmega_old, +} + +impl_mod_i2c! { + use crate::atmega8 as hal; + + impl_i2c_peripheral! { + i2c_type: I2c, + peripheral: hal::pac::TWI, + sda: hal::port::PC4, + scl: hal::port::PC5, + } +} + +impl_mod_port! { + use crate::atmega8 as hal; + + impl_port_peripheral_b8_c7_d8! { + } + + #[macro_export] + macro_rules! atmega8_pins { + ($p:expr) => { + $crate::atmega8::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use atmega8_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::atmega8 as hal; + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PB1`, `PB2`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut b1 = pins.b1.into_output().into_pwm(&mut timer1); + /// let mut b2 = pins.b2.into_output().into_pwm(&mut timer1); + /// + /// d9.set_duty(128); + /// d9.enable(); + /// ``` + pub struct Timer1Pwm { + timer: hal::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_r, w| { + w.wgm1().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + } + }); + }, + pins: { + hal::port::PB1: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + }, + }, + + hal::port::PB2: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC2` for PWM (pins `PB3`, `PD3`) + /// + /// # Example + /// ``` + /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); + /// + /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2); + /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2); + /// + /// d11.set_duty(128); + /// d11.enable(); + /// ``` + pub struct Timer2Pwm { + timer: hal::pac::TC2, + init: |tim, prescaler| { + tim.tccr2.modify(|_r, w| w.wgm20().set_bit().wgm21().set_bit()); + tim.tccr2.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs2().direct(), + Prescaler::Prescale8 => w.cs2().prescale_8(), + Prescaler::Prescale64 => w.cs2().prescale_64(), + Prescaler::Prescale256 => w.cs2().prescale_256(), + Prescaler::Prescale1024 => w.cs2().prescale_1024(), + }); + }, + pins: { + hal::port::PB3: { + ocr: ocr2, + into_pwm: |tim| if enable { + tim.tccr2.modify(|_r, w| w.com2().match_clear()); + } else { + tim.tccr2.modify(|_r, w| w.com2().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_spi! { + use crate::atmega8 as hal; + impl_spi_peripheral! { + spi: Spi, + peripheral: hal::pac::SPI, + sclk: hal::port::PB5, + mosi: hal::port::PB3, + miso: hal::port::PB4, + cs: hal::port::PB2, + + } +} + +impl_mod_usart! { + use crate::atmega8 as hal; + impl_usart_peripheral_ubrrh_ucsrc! { + peripheral: hal::pac::USART, + rx: hal::port::PD0, + tx: hal::port::PD1, + usart_type: Usart0, + } +} + +impl_mod_wdt! { + use crate::atmega8 as hal; + impl_wdt_peripheral_ms2000! { + mcusr: hal::pac::cpu::MCUCSR, + wdtcsr_name: wdtcr, + } +} \ No newline at end of file diff --git a/mcu/atmega-hal/src/eeprom.rs b/mcu/atmega-hal/src/eeprom.rs deleted file mode 100644 index bcddc02fa1..0000000000 --- a/mcu/atmega-hal/src/eeprom.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! EEPROM -//! -//! # Example -//! -//! Complete example source code can be found in the repository: -//! [`atmega2560-eeprom.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-eeprom.rs) -//! -//! ``` -//! const BOOT_COUNT_OFFSET: u16 = 0; -//! -//! let dp = atmega_hal::Peripherals::take().unwrap(); -//! let mut eeprom = Eeprom::new(dp.EEPROM); -//! -//! let mut boot_count = eeprom.read_byte(BOOT_COUNT_OFFSET); -//! boot_count = boot_count.wrapping_add(1); -//! eeprom.write_byte(BOOT_COUNT_OFFSET, boot_count); -//! -//! ufmt::uwriteln!(&mut serial, "Boot count: {}", boot_count).unwrap(); -//! ``` - -pub use avr_hal_generic::eeprom::{EepromOps, OutOfBoundsError}; - -pub type Eeprom = avr_hal_generic::eeprom::Eeprom; - -/////////////////////////////////////////////////////////// -#[cfg(feature = "atmega48p")] -avr_hal_generic::impl_eeprom_atmega! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 256, - addr_width: u8, - set_address: |peripheral, address| { - peripheral.eearl.write(|w| w.bits(address)); - }, -} - -#[cfg(any(feature = "atmega168", feature = "atmega164pa"))] -avr_hal_generic::impl_eeprom_atmega! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 512, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(any( - feature = "atmega328pb", - feature = "atmega328p", - feature = "atmega32u4" -))] -avr_hal_generic::impl_eeprom_atmega! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 1024, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(any( - feature = "atmega2560", - feature = "atmega1280", - feature = "atmega1284p" -))] -avr_hal_generic::impl_eeprom_atmega! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 4096, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(any(feature = "atmega8"))] -avr_hal_generic::impl_eeprom_atmega_old! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 512, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(any(feature = "atmega32a"))] -avr_hal_generic::impl_eeprom_atmega_old! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 1024, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(any(feature = "atmega128a",))] -avr_hal_generic::impl_eeprom_atmega_old! { - hal: crate::Atmega, - peripheral: crate::pac::EEPROM, - capacity: 4096, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} diff --git a/mcu/atmega-hal/src/i2c.rs b/mcu/atmega-hal/src/i2c.rs deleted file mode 100644 index 192b1a1b3d..0000000000 --- a/mcu/atmega-hal/src/i2c.rs +++ /dev/null @@ -1,139 +0,0 @@ -//! I2C -//! -//! # Example -//! -//! Complete example source code can be found in the repository: -//! [`atmega2560-i2cdetect.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-i2cdetect.rs) -//! -//! ``` -//! let dp = atmega_hal::Peripherals::take().unwrap(); -//! let pins = atmega_hal::pins!(dp); -//! -//! let mut i2c = I2c::new( -//! dp.TWI, -//! pins.pd1.into_pull_up_input(), -//! pins.pd0.into_pull_up_input(), -//! 50_000, -//! ); -//! -//! i2c.i2cdetect(&mut serial, atmega_hal::i2c::Direction::Read).unwrap(); -//! ``` - -#[allow(unused_imports)] -use crate::port; -pub use avr_hal_generic::i2c::*; - -#[cfg(any( - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega32u4" -))] -pub type I2c = avr_hal_generic::i2c::I2c< - crate::Atmega, - crate::pac::TWI, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any( - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega32u4" -))] -avr_hal_generic::impl_i2c_twi! { - hal: crate::Atmega, - peripheral: crate::pac::TWI, - sda: port::PD1, - scl: port::PD0, -} - -#[cfg(any(feature = "atmega164pa"))] -pub type I2c = avr_hal_generic::i2c::I2c< - crate::Atmega, - crate::pac::TWI, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega164pa"))] -avr_hal_generic::impl_i2c_twi! { - hal: crate::Atmega, - peripheral: crate::pac::TWI, - sda: port::PC1, - scl: port::PC0, -} - -#[cfg(any( - feature = "atmega328p", - feature = "atmega168", - feature = "atmega48p", - feature = "atmega8" -))] -pub type I2c = avr_hal_generic::i2c::I2c< - crate::Atmega, - crate::pac::TWI, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any( - feature = "atmega328p", - feature = "atmega168", - feature = "atmega48p", - feature = "atmega8" -))] -avr_hal_generic::impl_i2c_twi! { - hal: crate::Atmega, - peripheral: crate::pac::TWI, - sda: port::PC4, - scl: port::PC5, -} - -#[cfg(any(feature = "atmega328pb"))] -pub type I2c0 = avr_hal_generic::i2c::I2c< - crate::Atmega, - crate::pac::TWI0, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega328pb"))] -avr_hal_generic::impl_i2c_twi! { - hal: crate::Atmega, - peripheral: crate::pac::TWI0, - sda: port::PC4, - scl: port::PC5, -} -#[cfg(any(feature = "atmega328pb"))] -pub type I2c1 = avr_hal_generic::i2c::I2c< - crate::Atmega, - crate::pac::TWI1, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega328pb"))] -avr_hal_generic::impl_i2c_twi! { - hal: crate::Atmega, - peripheral: crate::pac::TWI1, - sda: port::PE0, - scl: port::PE1, -} - -#[cfg(any(feature = "atmega1284p", feature = "atmega32a"))] -pub type I2c = avr_hal_generic::i2c::I2c< - crate::Atmega, - crate::pac::TWI, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega1284p", feature = "atmega32a"))] -avr_hal_generic::impl_i2c_twi! { - hal: crate::Atmega, - peripheral: crate::pac::TWI, - sda: port::PC1, - scl: port::PC0, -} diff --git a/mcu/atmega-hal/src/impl/adc.rs b/mcu/atmega-hal/src/impl/adc.rs new file mode 100644 index 0000000000..739b577b6c --- /dev/null +++ b/mcu/atmega-hal/src/impl/adc.rs @@ -0,0 +1,165 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_adc { + ($($mod:item)*) => { + pub mod adc { + //! Analog-to-Digital Converter + //! + //! # Example + //! + //! Complete example source code can be found in the repository: + //! [`atmega2560-adc.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-adc.rs) + //! + //! ``` + //! let dp = atmega_hal::Peripherals::take().unwrap(); + //! let pins = atmega_hal::pins!(dp); + //! + //! let mut adc = Adc::new(dp.ADC, Default::default()); + //! + //! let channels: [atmega_hal::adc::Channel; 4] = [ + //! pins.pf0.into_analog_input(&mut adc).into_channel(), + //! pins.pf1.into_analog_input(&mut adc).into_channel(), + //! pins.pf2.into_analog_input(&mut adc).into_channel(), + //! pins.pf3.into_analog_input(&mut adc).into_channel(), + //! ]; + //! + //! for (index, channel) in channels.iter().enumerate() { + //! let value = adc.read_blocking(channel); + //! ufmt::uwrite!(&mut serial, "CH{}: {} ", index, value).unwrap(); + //! } + //! ``` + + #[allow(unused_imports)] + use crate::r#impl::{impl_adc, impl_adc_channels,impl_adc_channels_extra_temp,impl_adc_channels_extra,impl_adc_channels_temp}; + + $($mod)* + } + + pub use adc::Adc; + } +} +pub(crate) use impl_mod_adc; + +/// Additional channels +/// +/// Some channels are not directly connected to pins. This module provides types which can be used +/// to access them. +/// +/// # Example +/// ``` +/// let dp = atmega_hal::Peripherals::take().unwrap(); +/// let mut adc = atmega_hal::Adc::new(dp.ADC, Default::default()); +/// +/// let value = adc.read_blocking(&channel::Vbg); +/// ``` + +macro_rules! impl_adc_channels { + () => { + pub mod channel { + pub struct Vbg; + pub struct Gnd; + } + }; +} +pub(crate) use impl_adc_channels; + +macro_rules! impl_adc_channels_temp { + () => { + pub mod channel { + pub struct Vbg; + pub struct Gnd; + pub struct Temperature; + } + }; +} +pub(crate) use impl_adc_channels_temp; + +macro_rules! impl_adc_channels_extra { + () => { + pub mod channel { + #[cfg(feature = "enable-extra-adc")] + pub struct ADC6; + #[cfg(feature = "enable-extra-adc")] + pub struct ADC7; + pub struct Vbg; + pub struct Gnd; + } + }; +} +pub(crate) use impl_adc_channels_extra; + +macro_rules! impl_adc_channels_extra_temp { + () => { + pub mod channel { + #[cfg(feature = "enable-extra-adc")] + pub struct ADC6; + #[cfg(feature = "enable-extra-adc")] + pub struct ADC7; + pub struct Vbg; + pub struct Gnd; + pub struct Temperature; + } + }; +} +pub(crate) use impl_adc_channels_extra_temp; + +macro_rules! impl_adc { + () => { + pub use avr_hal_generic::adc::{AdcChannel, AdcOps, ClockDivider}; + + impl Default for ReferenceVoltage { + fn default() -> Self { + Self::AVcc + } + } + + /// Configuration for the ADC peripheral. + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] + pub struct AdcSettings { + pub clock_divider: ClockDivider, + pub ref_voltage: ReferenceVoltage, + } + + /// Select the voltage reference for the ADC peripheral + /// + /// The internal voltage reference options may not be used if an external reference voltage is + /// being applied to the AREF pin. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(u8)] + pub enum ReferenceVoltage { + /// Voltage applied to AREF pin. + Aref, + /// Default reference voltage (default). + AVcc, + /// Internal reference voltage. + Internal, + } + + /// Check the [`avr_hal_generic::adc::Adc`] documentation. + pub type Adc = avr_hal_generic::adc::Adc; + + /// Check the [`avr_hal_generic::adc::Channel`] documentation. + pub type Channel = avr_hal_generic::adc::Channel; + + fn apply_settings(peripheral: &hal::pac::ADC, settings: AdcSettings) { + peripheral.adcsra.write(|w| { + w.aden().set_bit(); + match settings.clock_divider { + ClockDivider::Factor2 => w.adps().prescaler_2(), + ClockDivider::Factor4 => w.adps().prescaler_4(), + ClockDivider::Factor8 => w.adps().prescaler_8(), + ClockDivider::Factor16 => w.adps().prescaler_16(), + ClockDivider::Factor32 => w.adps().prescaler_32(), + ClockDivider::Factor64 => w.adps().prescaler_64(), + ClockDivider::Factor128 => w.adps().prescaler_128(), + } + }); + peripheral.admux.write(|w| match settings.ref_voltage { + ReferenceVoltage::Aref => w.refs().aref(), + ReferenceVoltage::AVcc => w.refs().avcc(), + ReferenceVoltage::Internal => w.refs().internal(), + }); + } + }; +} +pub(crate) use impl_adc; diff --git a/mcu/atmega-hal/src/impl/eeprom.rs b/mcu/atmega-hal/src/impl/eeprom.rs new file mode 100644 index 0000000000..61107abbc2 --- /dev/null +++ b/mcu/atmega-hal/src/impl/eeprom.rs @@ -0,0 +1,50 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_eeprom { + ( + hal: $($mcu:ident)::+, + capacity: $capacity:expr, + addr_width: $addr_width:ty, + addr_reg: $addr_reg:ident, + variant: $variant:ident $(,)? + ) => { + pub mod eeprom { + //! EEPROM + //! + //! # Example + //! + //! Complete example source code can be found in the repository: + //! [`atmega2560-eeprom.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-eeprom.rs) + //! + //! ``` + //! const BOOT_COUNT_OFFSET: u16 = 0; + //! + //! let dp = atmega_hal::Peripherals::take().unwrap(); + //! let mut eeprom = Eeprom::new(dp.EEPROM); + //! + //! let mut boot_count = eeprom.read_byte(BOOT_COUNT_OFFSET); + //! boot_count = boot_count.wrapping_add(1); + //! eeprom.write_byte(BOOT_COUNT_OFFSET, boot_count); + //! + //! ufmt::uwriteln!(&mut serial, "Boot count: {}", boot_count).unwrap(); + //! ``` + pub use avr_hal_generic::eeprom::{EepromOps, OutOfBoundsError}; + + pub type Eeprom = + avr_hal_generic::eeprom::Eeprom<$($mcu)::+::Hal, $($mcu)::+::pac::EEPROM>; + + avr_hal_generic::$variant! { + hal: $($mcu)::+::Hal, + peripheral: $($mcu)::+::pac::EEPROM, + capacity: $capacity, + addr_width: $addr_width, + set_address: |peripheral, address| { + peripheral.$addr_reg.write(|w| w.bits(address)); + }, + } + } + + pub use eeprom::Eeprom; + } +} +pub(crate) use impl_mod_eeprom; diff --git a/mcu/atmega-hal/src/impl/i2c.rs b/mcu/atmega-hal/src/impl/i2c.rs new file mode 100644 index 0000000000..e6a61cde8c --- /dev/null +++ b/mcu/atmega-hal/src/impl/i2c.rs @@ -0,0 +1,58 @@ +macro_rules! impl_mod_i2c { + ($($mod:item)*) => { + pub mod i2c { + //! I2C + //! + //! # Example + //! + //! Complete example source code can be found in the repository: + //! [`atmega2560-i2cdetect.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-i2cdetect.rs) + //! + //! ``` + //! let dp = atmega_hal::Peripherals::take().unwrap(); + //! let pins = atmega_hal::pins!(dp); + //! + //! let mut i2c = I2c::new( + //! dp.TWI, + //! pins.pd1.into_pull_up_input(), + //! pins.pd0.into_pull_up_input(), + //! 50_000, + //! ); + //! + //! i2c.i2cdetect(&mut serial, atmega_hal::i2c::Direction::Read).unwrap(); + //! ``` + + pub use avr_hal_generic::i2c::*; + use crate::r#impl::{impl_i2c_peripheral}; + + $($mod)* + } + + pub use i2c::I2c; + } +} +pub(crate) use impl_mod_i2c; + +macro_rules! impl_i2c_peripheral { + ( + i2c_type: $i2c_type:ident, + peripheral: $($peripheral:ident)::+, + sda: $($sda:ident)::+, + scl: $($scl:ident)::+ $(,)? + ) => { + pub type $i2c_type = avr_hal_generic::i2c::I2c< + hal::Hal, + $($peripheral)::+, + hal::port::Pin, + hal::port::Pin, + CLOCK, + >; + avr_hal_generic::impl_i2c_twi! { + hal: hal::Hal, + peripheral: $($peripheral)::+, + sda: $($sda)::+, + scl: $($scl)::+, + } + } +} +pub(crate) use impl_i2c_peripheral; diff --git a/mcu/atmega-hal/src/impl/mod.rs b/mcu/atmega-hal/src/impl/mod.rs new file mode 100644 index 0000000000..31035fd873 --- /dev/null +++ b/mcu/atmega-hal/src/impl/mod.rs @@ -0,0 +1,25 @@ +#![allow(unused_imports)] + +mod adc; +pub(crate) use adc::*; + +mod eeprom; +pub(crate) use eeprom::*; + +mod i2c; +pub(crate) use i2c::*; + +mod port; +pub(crate) use port::*; + +mod simple_pwm; +pub(crate) use simple_pwm::*; + +mod spi; +pub(crate) use spi::*; + +mod usart; +pub(crate) use usart::*; + +mod wdt; +pub(crate) use wdt::*; diff --git a/mcu/atmega-hal/src/impl/port.rs b/mcu/atmega-hal/src/impl/port.rs new file mode 100644 index 0000000000..556b9e3083 --- /dev/null +++ b/mcu/atmega-hal/src/impl/port.rs @@ -0,0 +1,84 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_port { + ($($mod:item)*) => { + pub mod port { + //! Port + //! + //! # Example + //! + //! Complete example source code can be found in the repository: + //! [`atmega2560-blink.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-blink.rs) + //! + //! ``` + //! let dp = atmega_hal::Peripherals::take().unwrap(); + //! let pins = atmega_hal::pins!(dp); + //! + //! let mut led = pins.pb7.into_output(); + //! + //! loop { + //! led.toggle(); + //! delay_ms(1000); + //! } + //! ``` + pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + + #[allow(unused_imports)] + use crate::r#impl::{impl_port_peripheral_b8_c7_d8,impl_port_peripheral_a8_b8_c8_d8,impl_port_peripheral_a8_b8_c8_d8_e8_f8_g6_h8_j8_k8_l8}; + + $($mod)* + } + + pub use pac::Peripherals; + pub use port::{Pins, pins}; + } +} +pub(crate) use impl_mod_port; + +macro_rules! impl_port_peripheral_b8_c7_d8 { + () => { + avr_hal_generic::impl_port_traditional! { + enum Ports { + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + } + } + } +} +pub(crate) use impl_port_peripheral_b8_c7_d8; + +macro_rules! impl_port_peripheral_a8_b8_c8_d8 { + () => { + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + } + } + } +} +pub(crate) use impl_port_peripheral_a8_b8_c8_d8; + +macro_rules! impl_port_peripheral_a8_b8_c8_d8_e8_f8_g6_h8_j8_k8_l8 { + () => { + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + E: hal::pac::PORTE = [0, 1, 2, 3, 4, 5, 6, 7], + F: hal::pac::PORTF = [0, 1, 2, 3, 4, 5, 6, 7], + G: hal::pac::PORTG = [0, 1, 2, 3, 4, 5], + H: hal::pac::PORTH = [0, 1, 2, 3, 4, 5, 6, 7], + J: hal::pac::PORTJ = [0, 1, 2, 3, 4, 5, 6, 7], + K: hal::pac::PORTK = [0, 1, 2, 3, 4, 5, 6, 7], + L: hal::pac::PORTL = [0, 1, 2, 3, 4, 5, 6, 7], + } + } + } +} +pub(crate) use impl_port_peripheral_a8_b8_c8_d8_e8_f8_g6_h8_j8_k8_l8; diff --git a/mcu/atmega-hal/src/impl/simple_pwm.rs b/mcu/atmega-hal/src/impl/simple_pwm.rs new file mode 100644 index 0000000000..31fd3f68db --- /dev/null +++ b/mcu/atmega-hal/src/impl/simple_pwm.rs @@ -0,0 +1,513 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_simple_pwm { + ($($mod:item)*) => { + pub mod simple_pwm { + pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps}; + + #[allow(unused_imports)] + use crate::r#impl::{impl_simple_pwm_peripheral_48p_168_328p_328pb, impl_simple_pwm_peripheral_1280_2560}; + + $($mod)* + } + } +} +pub(crate) use impl_mod_simple_pwm; + +macro_rules! impl_simple_pwm_peripheral_48p_168_328p_328pb { + () => { + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PD5`, `PD6`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer0); + /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer0); + /// + /// d5.set_duty(128); + /// d5.enable(); + /// ``` + pub struct Timer0Pwm { + timer: hal::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().direct(), + Prescaler::Prescale8 => w.cs0().prescale_8(), + Prescaler::Prescale64 => w.cs0().prescale_64(), + Prescaler::Prescale256 => w.cs0().prescale_256(), + Prescaler::Prescale1024 => w.cs0().prescale_1024(), + }); + }, + pins: { + hal::port::PD6: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + }, + }, + + hal::port::PD5: { + ocr: ocr0b, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PB1`, `PB2`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1); + /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1); + /// + /// d9.set_duty(128); + /// d9.enable(); + /// ``` + pub struct Timer1Pwm { + timer: hal::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_r, w| { + w.wgm1().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + } + }); + }, + pins: { + hal::port::PB1: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + }, + }, + + hal::port::PB2: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC2` for PWM (pins `PB3`, `PD3`) + /// + /// # Example + /// ``` + /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); + /// + /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2); + /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2); + /// + /// d11.set_duty(128); + /// d11.enable(); + /// ``` + pub struct Timer2Pwm { + timer: hal::pac::TC2, + init: |tim, prescaler| { + tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast()); + tim.tccr2b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs2().direct(), + Prescaler::Prescale8 => w.cs2().prescale_8(), + Prescaler::Prescale64 => w.cs2().prescale_64(), + Prescaler::Prescale256 => w.cs2().prescale_256(), + Prescaler::Prescale1024 => w.cs2().prescale_1024(), + }); + }, + pins: { + hal::port::PB3: { + ocr: ocr2a, + into_pwm: |tim| if enable { + tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); + } else { + tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); + }, + }, + + hal::port::PD3: { + ocr: ocr2b, + into_pwm: |tim| if enable { + tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); + } else { + tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); + }, + }, + }, + } + } + }; +} +pub(crate) use impl_simple_pwm_peripheral_48p_168_328p_328pb; + +macro_rules! impl_simple_pwm_peripheral_1280_2560 { + () => { + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB7`, `PG5`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer0); + /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer0); + /// + /// d13.set_duty(128); + /// d13.enable(); + /// ``` + pub struct Timer0Pwm { + timer: hal::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().direct(), + Prescaler::Prescale8 => w.cs0().prescale_8(), + Prescaler::Prescale64 => w.cs0().prescale_64(), + Prescaler::Prescale256 => w.cs0().prescale_256(), + Prescaler::Prescale1024 => w.cs0().prescale_1024(), + }); + }, + pins: { + hal::port::PB7: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + }, + }, + + hal::port::PG5: { + ocr: ocr0b, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1); + /// let mut d12 = pins.d12.into_output().into_pwm(&mut timer1); + /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer1); + /// + /// d11.set_duty(128); + /// d11.enable(); + /// ``` + pub struct Timer1Pwm { + timer: hal::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + }); + }, + pins: { + hal::port::PB5: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); + }, + }, + + hal::port::PB6: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); + }, + }, + + hal::port::PB7: { + ocr: ocr1c, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_r, w| w.com1c().match_clear()); + } else { + tim.tccr1a.modify(|_r, w| w.com1c().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC2` for PWM (pins `PB4`, `PH6`) + /// + /// # Example + /// ``` + /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); + /// + /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer2); + /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer2); + /// + /// d10.set_duty(128); + /// d10.enable(); + /// ``` + + pub struct Timer2Pwm { + timer: hal::pac::TC2, + init: |tim, prescaler| { + tim.tccr2a.modify(|_r, w| w.wgm2().bits(0b01)); + tim.tccr2b.modify(|_r, w| { + w.wgm22().clear_bit(); + + match prescaler { + Prescaler::Direct => w.cs2().direct(), + Prescaler::Prescale8 => w.cs2().prescale_8(), + Prescaler::Prescale64 => w.cs2().prescale_64(), + Prescaler::Prescale256 => w.cs2().prescale_256(), + Prescaler::Prescale1024 => w.cs2().prescale_1024(), + } + }); + }, + pins: { + hal::port::PB4: { + ocr: ocr2a, + into_pwm: |tim| if enable { + tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); + } else { + tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); + }, + }, + + hal::port::PH6: { + ocr: ocr2b, + into_pwm: |tim| if enable { + tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); + } else { + tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC3` for PWM (pins `PE3`, `PE4`, `PE5`) + /// + /// # Example + /// ``` + /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64); + /// + /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3); + /// let mut d2 = pins.d2.into_output().into_pwm(&mut timer3); + /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer3); + /// + /// d5.set_duty(128); + /// d5.enable(); + /// ``` + pub struct Timer3Pwm { + timer: hal::pac::TC3, + init: |tim, prescaler| { + tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); + tim.tccr3b.modify(|_r, w| { + w.wgm3().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs3().direct(), + Prescaler::Prescale8 => w.cs3().prescale_8(), + Prescaler::Prescale64 => w.cs3().prescale_64(), + Prescaler::Prescale256 => w.cs3().prescale_256(), + Prescaler::Prescale1024 => w.cs3().prescale_1024(), + } + }); + }, + pins: { + hal::port::PE3: { + ocr: ocr3a, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); + }, + }, + + hal::port::PE4: { + ocr: ocr3b, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); + }, + }, + + hal::port::PE5: { + ocr: ocr3c, + into_pwm: |tim| if enable { + tim.tccr3a.modify(|_r, w| w.com3c().match_clear()); + } else { + tim.tccr3a.modify(|_r, w| w.com3c().disconnected()); + }, + }, + + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC4` for PWM (pins `PH3`, `PH4`, `PH5`) + /// + /// # Example + /// ``` + /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64); + /// + /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4); + /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer4); + /// let mut d8 = pins.d8.into_output().into_pwm(&mut timer4); + /// + /// d6.set_duty(128); + /// d6.enable(); + /// ``` + pub struct Timer4Pwm { + timer: hal::pac::TC4, + init: |tim, prescaler| { + tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01)); + tim.tccr4b.modify(|_r, w| { + w.wgm4().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs4().direct(), + Prescaler::Prescale8 => w.cs4().prescale_8(), + Prescaler::Prescale64 => w.cs4().prescale_64(), + Prescaler::Prescale256 => w.cs4().prescale_256(), + Prescaler::Prescale1024 => w.cs4().prescale_1024(), + } + }); + }, + pins: { + hal::port::PH3: { + ocr: ocr4a, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); + }, + }, + + hal::port::PH4: { + ocr: ocr4b, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); + }, + }, + + hal::port::PH5: { + ocr: ocr4c, + into_pwm: |tim| if enable { + tim.tccr4a.modify(|_r, w| w.com4c().match_clear()); + } else { + tim.tccr4a.modify(|_r, w| w.com4c().disconnected()); + }, + }, + + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC5` for PWM (pins `PL3`, `PL4`, `PL5`) + /// + /// # Example + /// ``` + /// let mut timer5 = Timer5Pwm::new(dp.TC5, Prescaler::Prescale64); + /// + /// let mut d46 = pins.d46.into_output().into_pwm(&mut timer5); + /// let mut d45 = pins.d45.into_output().into_pwm(&mut timer5); + /// let mut d44 = pins.d44.into_output().into_pwm(&mut timer5); + /// + /// d46.set_duty(128); + /// d46.enable(); + /// ``` + pub struct Timer5Pwm { + timer: hal::pac::TC5, + init: |tim, prescaler| { + tim.tccr5a.modify(|_r, w| w.wgm5().bits(0b01)); + tim.tccr5b.modify(|_r, w| { + w.wgm5().bits(0b01); + + match prescaler { + Prescaler::Direct => w.cs5().direct(), + Prescaler::Prescale8 => w.cs5().prescale_8(), + Prescaler::Prescale64 => w.cs5().prescale_64(), + Prescaler::Prescale256 => w.cs5().prescale_256(), + Prescaler::Prescale1024 => w.cs5().prescale_1024(), + } + }); + }, + pins: { + hal::port::PL3: { + ocr: ocr5a, + into_pwm: |tim| if enable { + tim.tccr5a.modify(|_r, w| w.com5a().match_clear()); + } else { + tim.tccr5a.modify(|_r, w| w.com5a().disconnected()); + }, + }, + + hal::port::PL4: { + ocr: ocr5b, + into_pwm: |tim| if enable { + tim.tccr5a.modify(|_r, w| w.com5b().match_clear()); + } else { + tim.tccr5a.modify(|_r, w| w.com5b().disconnected()); + }, + }, + + hal::port::PL5: { + ocr: ocr5c, + into_pwm: |tim| if enable { + tim.tccr5a.modify(|_r, w| w.com5c().match_clear()); + } else { + tim.tccr5a.modify(|_r, w| w.com5c().disconnected()); + }, + }, + + }, + } + } + + } +} +pub(crate) use impl_simple_pwm_peripheral_1280_2560; diff --git a/mcu/atmega-hal/src/impl/spi.rs b/mcu/atmega-hal/src/impl/spi.rs new file mode 100644 index 0000000000..98c5b3f382 --- /dev/null +++ b/mcu/atmega-hal/src/impl/spi.rs @@ -0,0 +1,75 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_spi { + ($($mod:item)*) => { + pub mod spi { + //! SPI + //! + //! # Example + //! + //! Complete example source code can be found in the repository + //! [`atmega2560-spi-feedback.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs) + //! + //! ``` + //! let dp = atmega_hal::Peripherals::take().unwrap(); + //! let pins = atmega_hal::pins!(dp); + //! + //! let (mut spi, mut cs) = spi::Spi::new( + //! dp.SPI, + //! pins.pb1.into_output(), + //! pins.pb2.into_output(), + //! pins.pb3.into_pull_up_input(), + //! pins.pb0.into_output(), + //! spi::Settings::default(), + //! ); + //! + //! let data_out = b"Hello World!"; + //! let mut data_in = [0u8; 12]; + //! + //! cs.set_low().unwrap(); + //! spi.transfer(&mut data_in, data_out).unwrap(); + //! cs.set_high().unwrap(); + //! + //! ufmt::uwriteln!(&mut serial, "data: {:?}", data_in).unwrap(); + //! ``` + + pub use avr_hal_generic::spi::*; + use crate::r#impl::impl_spi_peripheral; + + $($mod)* + } + pub use spi::Spi; + } +} +pub(crate) use impl_mod_spi; + +macro_rules! impl_spi_peripheral { + ( + spi: $spi:ident, + peripheral: $($peripheral:ident)::+, + sclk: $($sclk:ident)::+, + mosi: $($mosi:ident)::+, + miso: $($miso:ident)::+, + cs: $($cs:ident)::+ $(,)? + ) => { + pub type $spi = avr_hal_generic::spi::Spi< + hal::Hal, + $($peripheral)::+, + $($sclk)::+, + $($mosi)::+, + $($miso)::+, + $($cs)::+, + >; + + avr_hal_generic::impl_spi! { + hal: hal::Hal, + peripheral: $($peripheral)::+, + sclk: $($sclk)::+, + mosi: $($mosi)::+, + miso: $($miso)::+, + cs: $($cs)::+, + } + + } +} +pub(crate) use impl_spi_peripheral; diff --git a/mcu/atmega-hal/src/impl/usart.rs b/mcu/atmega-hal/src/impl/usart.rs new file mode 100644 index 0000000000..c4b28a1047 --- /dev/null +++ b/mcu/atmega-hal/src/impl/usart.rs @@ -0,0 +1,202 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_usart { + ($($mod:item)*) => { + pub mod usart { + //! USART + //! + //! # Example + //! + //! Complete example source code can be found in the repository: + //! [`atmega2560-usart.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-usart.rs) + //! + //! *Note: [ufmt](https://crates.io/crates/ufmt/) is used instead of `core::fmt` because + //! `core::fmt` code quickly grows too large for AVR platforms.* + //! + //! ``` + //! let dp = atmega_hal::Peripherals::take().unwrap(); + //! let pins = atmega_hal::pins!(dp); + //! + //! let mut serial = Usart::new( + //! dp.USART0, + //! pins.pe0, + //! pins.pe1.into_output(), + //! Baudrate::::new(57600), + //! ); + //! + //! ufmt::uwriteln!(&mut serial, "Hello from ATmega!").unwrap(); + //! + //! loop { + //! // Read a byte from the serial connection + //! let b = nb::block!(serial.read()).unwrap(); + //! // Answer + //! ufmt::uwriteln!(&mut serial, "Got {}!", b).unwrap(); + //! } + //! ``` + + #[allow(unused_imports)] + use crate::r#impl::{impl_usart_peripheral_type,impl_usart_peripheral_traditional,impl_usart_peripheral_ubrrh_ucsrc}; + + pub type Usart = + avr_hal_generic::usart::Usart; + pub type UsartWriter = + avr_hal_generic::usart::UsartWriter; + pub type UsartReader = + avr_hal_generic::usart::UsartReader; + + pub use avr_hal_generic::usart::*; + $($mod)* + } + pub use usart::Usart; + } +} +pub(crate) use impl_mod_usart; + +macro_rules! impl_usart_peripheral_type { + ( + peripheral: $($peripheral:ident)::+, + rx: $($rx:ident)::+, + tx: $($tx:ident)::+, + usart_type: $usart_type:ident $(,)? + ) => { + pub type $usart_type = Usart< + $($peripheral)::+, + hal::port::Pin, + hal::port::Pin, + CLOCK, + >; + } +} +pub(crate) use impl_usart_peripheral_type; + +macro_rules! impl_usart_peripheral_traditional { + ( + peripheral: $($peripheral:ident)::+, + register_suffix: $register_suffix:expr, + rx: $($rx:ident)::+, + tx: $($tx:ident)::+ , + usart_type: $usart_type:ident $(,)? + ) => { + impl_usart_peripheral_type! { + peripheral: $($peripheral)::+, + rx: $($rx)::+, + tx: $($tx)::+, + usart_type: $usart_type, + } + + avr_hal_generic::impl_usart_traditional! { + hal: hal::Hal, + peripheral: $($peripheral)::+, + register_suffix: $register_suffix, + rx: $($rx)::+, + tx: $($tx)::+, + } + } +} +pub(crate) use impl_usart_peripheral_traditional; + +// TODO: atmega8 USART is different from other atmegas +// implemented so far. It uses the same register address +// for UBRRH and UCSRC, the way to select which register +// to write to, msb has to be 1 (for UCSRC) +// or 0 (for UBRRH). Because of the same address, +// these two are exposed as functions instead of +// fields. +macro_rules! impl_usart_peripheral_ubrrh_ucsrc { + ( + peripheral: $($peripheral:ident)::+, + rx: $($rx:ident)::+, + tx: $($tx:ident)::+, + usart_type: $usart_type:ident $(,)? + ) => { + impl_usart_peripheral_type! { + peripheral: $($peripheral)::+, + rx: $($rx)::+, + tx: $($tx)::+, + usart_type: $usart_type, + } + + impl + avr_hal_generic::usart::UsartOps< + hal::Hal, + hal::port::Pin, + hal::port::Pin, + > for $($peripheral)::+ + { + fn raw_init(&mut self, baudrate: avr_hal_generic::usart::Baudrate) { + // msb of ubrrh has to be 0 to set ubrrh register. (see atmega8 datasheet) + let ubrrh: u8 = ((baudrate.ubrr >> 8) & 0x0F) as u8; + let ubrrl: u8 = (baudrate.ubrr & 0xFF) as u8; + self.ubrrh().write(|w| w.bits(ubrrh)); + self.ubrrl.write(|w| w.bits(ubrrl)); + self.ucsra.write(|w| w.u2x().bit(baudrate.u2x)); + + // Enable receiver and transmitter but leave interrupts disabled. + #[rustfmt::skip] + self.ucsrb.write(|w| w + .txen().set_bit() + .rxen().set_bit() + ); + + // Set frame format to 8n1 for now. At some point, this should be made + // configurable, similar to what is done in other HALs. + #[rustfmt::skip] + self.ucsrc().write(|w| w + .ursel().set_bit() // sets the ucsrc instead of ubrrh (ubrrh and ucsrc share same location on ATmega8, see atmega8 datasheet) + .umsel().usart_async() + .ucsz().chr8() + .usbs().stop1() + .upm().disabled() + ); + } + + fn raw_deinit(&mut self) { + // Wait for any ongoing transfer to finish. + avr_hal_generic::nb::block!(self.raw_flush()).ok(); + self.ucsrb.reset(); + } + + fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { + if self.ucsra.read().udre().bit_is_clear() { + Err(avr_hal_generic::nb::Error::WouldBlock) + } else { + Ok(()) + } + } + + fn raw_write( + &mut self, + byte: u8, + ) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { + // Call flush to make sure the data-register is empty + self.raw_flush()?; + + self.udr.write(|w| w.bits(byte)); + Ok(()) + } + + fn raw_read(&mut self) -> avr_hal_generic::nb::Result { + if self.ucsra.read().rxc().bit_is_clear() { + return Err(avr_hal_generic::nb::Error::WouldBlock); + } + + Ok(self.udr.read().bits()) + } + + fn raw_interrupt(&mut self, event: avr_hal_generic::usart::Event, state: bool) { + match event { + avr_hal_generic::usart::Event::RxComplete => { + self.ucsrb.modify(|_, w| w.rxcie().bit(state)) + } + avr_hal_generic::usart::Event::TxComplete => { + self.ucsrb.modify(|_, w| w.txcie().bit(state)) + } + avr_hal_generic::usart::Event::DataRegisterEmpty => { + self.ucsrb.modify(|_, w| w.udrie().bit(state)) + } + } + } + } + }; +} +pub(crate) use impl_usart_peripheral_ubrrh_ucsrc; diff --git a/mcu/atmega-hal/src/impl/wdt.rs b/mcu/atmega-hal/src/impl/wdt.rs new file mode 100644 index 0000000000..371b898911 --- /dev/null +++ b/mcu/atmega-hal/src/impl/wdt.rs @@ -0,0 +1,88 @@ +#![allow(unused_macros)] + +macro_rules! impl_mod_wdt { + ($($mod:item)*) => { + pub mod wdt { + #[allow(unused_imports)] + use crate::r#impl::{impl_wdt_peripheral_ms2000, impl_wdt_peripheral_ms8000, impl_wdt_peripheral}; + + pub use avr_hal_generic::wdt::{Timeout, WdtOps}; + + $($mod)* + } + + pub use wdt::Wdt; + } +} +pub(crate) use impl_mod_wdt; + +macro_rules! impl_wdt_peripheral { + ( + mcusr: $($mcusr:ident)::+, + wdtcsr_name: $wdtcsr_name:ident, + timeout: |$to:ident, $w:ident| $to_match:expr $(,)? +) => { + + avr_hal_generic::impl_wdt! { + hal: hal::Hal, + peripheral: hal::pac::WDT, + mcusr: $($mcusr)::+, + wdtcsr_name: $wdtcsr_name, + timeout: |$to, $w| $to_match, + } + + pub type Wdt = avr_hal_generic::wdt::Wdt; + }; +} +pub(crate) use impl_wdt_peripheral; + +macro_rules! impl_wdt_peripheral_ms8000 { + ( + mcusr: $($mcusr:ident)::+, + wdtcsr_name: $wdtcsr_name:ident, +) => { + impl_wdt_peripheral! { + mcusr: $($mcusr)::+, + wdtcsr_name: $wdtcsr_name, + timeout: |to, w| match to { + Timeout::Ms16 => w.wdpl().cycles_2k_512k(), + Timeout::Ms32 => w.wdpl().cycles_4k_1024k(), + Timeout::Ms64 => w.wdpl().cycles_8k(), + Timeout::Ms125 => w.wdpl().cycles_16k(), + Timeout::Ms250 => w.wdpl().cycles_32k(), + Timeout::Ms500 => w.wdpl().cycles_64k(), + Timeout::Ms1000 => w.wdpl().cycles_128k(), + Timeout::Ms2000 => w.wdpl().cycles_256k(), + Timeout::Ms4000 => w.wdph().set_bit().wdpl().cycles_2k_512k(), + Timeout::Ms8000 => w.wdph().set_bit().wdpl().cycles_4k_1024k(), + }, + } + + }; +} +pub(crate) use impl_wdt_peripheral_ms8000; + +macro_rules! impl_wdt_peripheral_ms2000 { + ( + mcusr: $($mcusr:ident)::+, + wdtcsr_name: $wdtcsr_name:ident, + ) => { + impl_wdt_peripheral! { + mcusr: $($mcusr)::+, + wdtcsr_name: $wdtcsr_name, + timeout: |to, w| match to { + Timeout::Ms16 => w.wdpl().cycles_16k(), + Timeout::Ms32 => w.wdpl().cycles_32k(), + Timeout::Ms64 => w.wdpl().cycles_64k(), + Timeout::Ms125 => w.wdpl().cycles_128k(), + Timeout::Ms250 => w.wdpl().cycles_256k(), + Timeout::Ms500 => w.wdpl().cycles_512k(), + Timeout::Ms1000 => w.wdpl().cycles_1024k(), + Timeout::Ms2000 => w.wdpl().cycles_2048k(), + Timeout::Ms4000 => panic!(), // Does not exist on this MCU ... + Timeout::Ms8000 => panic!() // Does not exist on this MCU ... + }, + } + }; +} +pub(crate) use impl_wdt_peripheral_ms2000; diff --git a/mcu/atmega-hal/src/lib.rs b/mcu/atmega-hal/src/lib.rs index e2ce9bf2e1..c26f470a29 100644 --- a/mcu/atmega-hal/src/lib.rs +++ b/mcu/atmega-hal/src/lib.rs @@ -4,211 +4,75 @@ //! ============= //! Common HAL (hardware abstraction layer) for ATmega* microcontrollers. //! -//! **Note**: This version of the documentation was built for -#![cfg_attr(feature = "atmega48p", doc = "**ATmega48P**.")] -#![cfg_attr(feature = "atmega164pa", doc = "**ATmega164PA**.")] -#![cfg_attr(feature = "atmega168", doc = "**ATmega168**.")] -#![cfg_attr(feature = "atmega328p", doc = "**ATmega328P**.")] -#![cfg_attr(feature = "atmega328pb", doc = "**ATmega328PB**.")] -#![cfg_attr(feature = "atmega32a", doc = "**ATmega32a**.")] -#![cfg_attr(feature = "atmega32u4", doc = "**ATmega32U4**.")] -#![cfg_attr(feature = "atmega2560", doc = "**ATmega2560**.")] -#![cfg_attr(feature = "atmega128a", doc = "**ATmega128A**.")] -#![cfg_attr(feature = "atmega1280", doc = "**ATmega1280**.")] -#![cfg_attr(feature = "atmega1284p", doc = "**ATmega1284P**.")] -#![cfg_attr(feature = "atmega8", doc = "**ATmega8**.")] -//! This means that only items which are available for this MCU are visible. If you are using -//! a different chip, try building the documentation locally with: -//! -//! ```text -//! cargo doc --features --open -//! ``` #[cfg(all( - not(feature = "device-selected"), + not(feature = "_mcu-selected"), not(feature = "disable-device-selection-error") ))] compile_error!( - "This crate requires you to specify your target chip as a feature. + "You must specify your target chips as a feature. - Please select one of the following + Please select at least one of the following features * atmega48p * atmega164pa * atmega168 * atmega328p * atmega328pb + * atmega32a * atmega32u4 + * atmega2560 * atmega128a * atmega1280 - * atmega2560 * atmega1284p * atmega8 " ); -/// Reexport of `atmega1280` from `avr-device` -/// -#[cfg(feature = "atmega1280")] -pub use avr_device::atmega1280 as pac; -/// Reexport of `atmega1284p` from `avr-device` -/// -#[cfg(feature = "atmega1284p")] -pub use avr_device::atmega1284p as pac; -/// Reexport of `atmega128a` from `avr-device` -/// -#[cfg(feature = "atmega128a")] -pub use avr_device::atmega128a as pac; -/// Reexport of `atmega164pa` from `avr-device` -/// -#[cfg(feature = "atmega164pa")] -pub use avr_device::atmega164pa as pac; -/// Reexport of `atmega168` from `avr-device` -/// -#[cfg(feature = "atmega168")] -pub use avr_device::atmega168 as pac; -/// Reexport of `atmega2560` from `avr-device` -/// -#[cfg(feature = "atmega2560")] -pub use avr_device::atmega2560 as pac; -/// Reexport of `atmega328p` from `avr-device` -/// -#[cfg(feature = "atmega328p")] -pub use avr_device::atmega328p as pac; -/// Reexport of `atmega328pb` from `avr-device` -/// -#[cfg(feature = "atmega328pb")] -pub use avr_device::atmega328pb as pac; -/// Reexport of `atmega32a` from `avr-device` -/// -#[cfg(feature = "atmega32a")] -pub use avr_device::atmega32a as pac; -/// Reexport of `atmega32u4` from `avr-device` -/// -#[cfg(feature = "atmega32u4")] -pub use avr_device::atmega32u4 as pac; -/// Reexport of `atmega48p` from `avr-device` -/// -#[cfg(feature = "atmega48p")] -pub use avr_device::atmega48p as pac; -/// Reexport of `atmega8` from `avr-device` -/// -#[cfg(feature = "atmega8")] -pub use avr_device::atmega8 as pac; - /// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). #[cfg(feature = "rt")] pub use avr_device::entry; -#[cfg(feature = "device-selected")] -pub use pac::Peripherals; - pub use avr_hal_generic::clock; pub use avr_hal_generic::delay; pub use avr_hal_generic::prelude; -#[cfg(feature = "device-selected")] -pub mod adc; -#[cfg(feature = "device-selected")] -pub use adc::Adc; - -#[cfg(feature = "device-selected")] -pub mod i2c; -#[cfg(feature = "device-selected")] -pub use i2c::I2c; - -#[cfg(feature = "device-selected")] -pub mod spi; -#[cfg(feature = "device-selected")] -pub use spi::Spi; - -#[cfg(feature = "device-selected")] -pub mod port; -#[cfg(feature = "device-selected")] -pub use port::Pins; - -#[cfg(feature = "device-selected")] -pub mod simple_pwm; - -#[cfg(feature = "device-selected")] -pub mod usart; -#[cfg(feature = "device-selected")] -pub use usart::Usart; - -#[cfg(feature = "device-selected")] -pub mod wdt; -#[cfg(feature = "device-selected")] -pub use wdt::Wdt; - -#[cfg(feature = "device-selected")] -pub mod eeprom; -#[cfg(feature = "device-selected")] -pub use eeprom::Eeprom; - -pub struct Atmega; - -#[cfg(any(feature = "atmega48p", feature = "atmega168", feature = "atmega328p"))] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) - }; -} -#[cfg(any(feature = "atmega164pa"))] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) - }; -} -#[cfg(feature = "atmega328pb")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE) - }; -} -#[cfg(feature = "atmega32u4")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF) - }; -} - -#[cfg(any(feature = "atmega128a"))] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new( - $p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF, $p.PORTG, - ) - }; -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new( - $p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD, $p.PORTE, $p.PORTF, $p.PORTG, $p.PORTH, - $p.PORTJ, $p.PORTK, $p.PORTL, - ) - }; -} - -#[cfg(any(feature = "atmega1284p", feature = "atmega32a"))] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) - }; -} - -#[cfg(any(feature = "atmega8"))] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTB, $p.PORTC, $p.PORTD) - }; -} +#[cfg(feature = "_mcu-atmega48p")] +pub mod atmega48p; + +#[cfg(feature = "_mcu-atmega164pa")] +pub mod atmega164pa; + +#[cfg(feature = "_mcu-atmega168")] +pub mod atmega168; + +#[cfg(feature = "_mcu-atmega328p")] +pub mod atmega328p; + +#[cfg(feature = "_mcu-atmega328pb")] +pub mod atmega328pb; + +#[cfg(feature = "_mcu-atmega32a")] +pub mod atmega32a; + +#[cfg(feature = "_mcu-atmega32u4")] +pub mod atmega32u4; + +#[cfg(feature = "_mcu-atmega2560")] +pub mod atmega2560; + +#[cfg(feature = "_mcu-atmega128a")] +pub mod atmega128a; + +#[cfg(feature = "_mcu-atmega1280")] +pub mod atmega1280; + +#[cfg(feature = "_mcu-atmega1284p")] +pub mod atmega1284p; + +#[cfg(feature = "_mcu-atmega8")] +pub mod atmega8; + + +pub(crate) mod r#impl; + diff --git a/mcu/atmega-hal/src/port.rs b/mcu/atmega-hal/src/port.rs deleted file mode 100644 index 746c0f09a0..0000000000 --- a/mcu/atmega-hal/src/port.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! Port -//! -//! # Example -//! -//! Complete example source code can be found in the repository: -//! [`atmega2560-blink.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-blink.rs) -//! -//! ``` -//! let dp = atmega_hal::Peripherals::take().unwrap(); -//! let pins = atmega_hal::pins!(dp); -//! -//! let mut led = pins.pb7.into_output(); -//! -//! loop { -//! led.toggle(); -//! delay_ms(1000); -//! } -//! ``` - -pub use avr_hal_generic::port::{mode, PinMode, PinOps}; - -#[cfg(any(feature = "atmega48p", feature = "atmega168", feature = "atmega328p"))] -avr_hal_generic::impl_port_traditional! { - enum Ports { - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - } -} - -#[cfg(any(feature = "atmega164pa"))] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6 ,7], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6 ,7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6 ,7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6 ,7], - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - E: crate::pac::PORTE = [0, 1, 2, 3], - } -} - -#[cfg(feature = "atmega32u4")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [6, 7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - E: crate::pac::PORTE = [2, 6], - F: crate::pac::PORTF = [0, 1, 4, 5, 6, 7], - } -} - -#[cfg(any(feature = "atmega128a"))] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - E: crate::pac::PORTE = [0, 1, 2, 3, 4, 5, 6, 7], - F: crate::pac::PORTF = [0, 1, 2, 3, 4, 5, 6, 7], - G: crate::pac::PORTG = [0, 1, 2, 3, 4], - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - E: crate::pac::PORTE = [0, 1, 2, 3, 4, 5, 6, 7], - F: crate::pac::PORTF = [0, 1, 2, 3, 4, 5, 6, 7], - G: crate::pac::PORTG = [0, 1, 2, 3, 4, 5], - H: crate::pac::PORTH = [0, 1, 2, 3, 4, 5, 6, 7], - J: crate::pac::PORTJ = [0, 1, 2, 3, 4, 5, 6, 7], - K: crate::pac::PORTK = [0, 1, 2, 3, 4, 5, 6, 7], - L: crate::pac::PORTL = [0, 1, 2, 3, 4, 5, 6, 7], - } -} - -#[cfg(any(feature = "atmega1284p", feature = "atmega32a"))] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - } -} - -#[cfg(any(feature = "atmega8"))] -avr_hal_generic::impl_port_traditional! { - enum Ports { - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - } -} diff --git a/mcu/atmega-hal/src/simple_pwm.rs b/mcu/atmega-hal/src/simple_pwm.rs deleted file mode 100644 index d0bda71be0..0000000000 --- a/mcu/atmega-hal/src/simple_pwm.rs +++ /dev/null @@ -1,1177 +0,0 @@ -pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps}; - -#[allow(unused_imports)] -use crate::port::*; - -#[cfg(any( - feature = "atmega48p", - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb" -))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PD5`, `PD6`) - /// - /// # Example - /// ``` - /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); - /// - /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer0); - /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer0); - /// - /// d5.set_duty(128); - /// d5.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - PD6: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); - }, - }, - - PD5: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any( - feature = "atmega48p", - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb" -))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PB1`, `PB2`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1); - /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1); - /// - /// d9.set_duty(128); - /// d9.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| { - w.wgm1().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - PB1: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); - }, - }, - - PB2: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any( - feature = "atmega48p", - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb" -))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC2` for PWM (pins `PB3`, `PD3`) - /// - /// # Example - /// ``` - /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); - /// - /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2); - /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2); - /// - /// d11.set_duty(128); - /// d11.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - }); - }, - pins: { - PB3: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); - }, - }, - - PD3: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC3` for PWM (pins `PD0`, `PD2`) - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| { - unsafe { w.wgm3().bits(0b01) }; - - match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - } - }); - }, - pins: { - PD0: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); - }, - }, - - PD2: { - ocr: ocr3b, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC4` for PWM (pins `PD1`, `PD2`) - pub struct Timer4Pwm { - timer: crate::pac::TC4, - init: |tim, prescaler| { - tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01)); - tim.tccr4b.modify(|_r, w| { - unsafe { w.wgm4().bits(0b01) }; - - match prescaler { - Prescaler::Direct => w.cs4().direct(), - Prescaler::Prescale8 => w.cs4().prescale_8(), - Prescaler::Prescale64 => w.cs4().prescale_64(), - Prescaler::Prescale256 => w.cs4().prescale_256(), - Prescaler::Prescale1024 => w.cs4().prescale_1024(), - } - }); - }, - pins: { - PD1: { - ocr: ocr4a, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); - }, - }, - - PD2: { - ocr: ocr4b, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PB7`, `PG5`) - /// - /// # Example - /// ``` - /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); - /// - /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer0); - /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer0); - /// - /// d13.set_duty(128); - /// d13.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - PB7: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); - }, - }, - - PG5: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1); - /// let mut d12 = pins.d12.into_output().into_pwm(&mut timer1); - /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer1); - /// - /// d11.set_duty(128); - /// d11.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - }); - }, - pins: { - PB5: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); - }, - }, - - PB6: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); - }, - }, - - PB7: { - ocr: ocr1c, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1c().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1c().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC2` for PWM (pins `PB4`, `PH6`) - /// - /// # Example - /// ``` - /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); - /// - /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer2); - /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer2); - /// - /// d10.set_duty(128); - /// d10.enable(); - /// ``` - - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_r, w| w.wgm2().bits(0b01)); - tim.tccr2b.modify(|_r, w| { - w.wgm22().clear_bit(); - - match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - } - }); - }, - pins: { - PB4: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); - }, - }, - - PH6: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC3` for PWM (pins `PE3`, `PE4`, `PE5`) - /// - /// # Example - /// ``` - /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64); - /// - /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3); - /// let mut d2 = pins.d2.into_output().into_pwm(&mut timer3); - /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer3); - /// - /// d5.set_duty(128); - /// d5.enable(); - /// ``` - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| { - w.wgm3().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - } - }); - }, - pins: { - PE3: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); - }, - }, - - PE4: { - ocr: ocr3b, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); - }, - }, - - PE5: { - ocr: ocr3c, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3c().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3c().disconnected()); - }, - }, - - }, - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC4` for PWM (pins `PH3`, `PH4`, `PH5`) - /// - /// # Example - /// ``` - /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64); - /// - /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4); - /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer4); - /// let mut d8 = pins.d8.into_output().into_pwm(&mut timer4); - /// - /// d6.set_duty(128); - /// d6.enable(); - /// ``` - pub struct Timer4Pwm { - timer: crate::pac::TC4, - init: |tim, prescaler| { - tim.tccr4a.modify(|_r, w| w.wgm4().bits(0b01)); - tim.tccr4b.modify(|_r, w| { - w.wgm4().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs4().direct(), - Prescaler::Prescale8 => w.cs4().prescale_8(), - Prescaler::Prescale64 => w.cs4().prescale_64(), - Prescaler::Prescale256 => w.cs4().prescale_256(), - Prescaler::Prescale1024 => w.cs4().prescale_1024(), - } - }); - }, - pins: { - PH3: { - ocr: ocr4a, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); - }, - }, - - PH4: { - ocr: ocr4b, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); - }, - }, - - PH5: { - ocr: ocr4c, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4c().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4c().disconnected()); - }, - }, - - }, - } -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC5` for PWM (pins `PL3`, `PL4`, `PL5`) - /// - /// # Example - /// ``` - /// let mut timer5 = Timer5Pwm::new(dp.TC5, Prescaler::Prescale64); - /// - /// let mut d46 = pins.d46.into_output().into_pwm(&mut timer5); - /// let mut d45 = pins.d45.into_output().into_pwm(&mut timer5); - /// let mut d44 = pins.d44.into_output().into_pwm(&mut timer5); - /// - /// d46.set_duty(128); - /// d46.enable(); - /// ``` - pub struct Timer5Pwm { - timer: crate::pac::TC5, - init: |tim, prescaler| { - tim.tccr5a.modify(|_r, w| w.wgm5().bits(0b01)); - tim.tccr5b.modify(|_r, w| { - w.wgm5().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs5().direct(), - Prescaler::Prescale8 => w.cs5().prescale_8(), - Prescaler::Prescale64 => w.cs5().prescale_64(), - Prescaler::Prescale256 => w.cs5().prescale_256(), - Prescaler::Prescale1024 => w.cs5().prescale_1024(), - } - }); - }, - pins: { - PL3: { - ocr: ocr5a, - into_pwm: |tim| if enable { - tim.tccr5a.modify(|_r, w| w.com5a().match_clear()); - } else { - tim.tccr5a.modify(|_r, w| w.com5a().disconnected()); - }, - }, - - PL4: { - ocr: ocr5b, - into_pwm: |tim| if enable { - tim.tccr5a.modify(|_r, w| w.com5b().match_clear()); - } else { - tim.tccr5a.modify(|_r, w| w.com5b().disconnected()); - }, - }, - - PL5: { - ocr: ocr5c, - into_pwm: |tim| if enable { - tim.tccr5a.modify(|_r, w| w.com5c().match_clear()); - } else { - tim.tccr5a.modify(|_r, w| w.com5c().disconnected()); - }, - }, - - }, - } -} - -#[cfg(any(feature = "atmega32u4"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PB7`, `PD0`) - /// - /// # Example - /// ``` - /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); - /// - /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer0); - /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer0); - /// - /// d11.set_duty(128); - /// d11.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - PB7: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); - }, - }, - - PD0: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega32u4"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PB5`, `PB6`, `PB7`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1); - /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1); - /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer1); - /// - /// d9.set_duty(128); - /// d9.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| w.wgm1().bits(0b01)); - - tim.tccr1b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - }); - }, - pins: { - PB5: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); - }, - }, - - PB6: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); - }, - }, - - PB7: { - ocr: ocr1c, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1c().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1c().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega32u4"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC3` for PWM (pins `PC6`) - /// - /// # Example - /// ``` - /// let mut timer3 = Timer3Pwm::new(dp.TC3, Prescaler::Prescale64); - /// - /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer3); - /// - /// d5.set_duty(128); - /// d5.enable(); - /// ``` - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| w.wgm3().bits(0b01)); - - tim.tccr3b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - }); - }, - pins: { - PC6: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega32u4"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC4` for PWM (pins `PB6`, `PC7`, `PD7`) - /// - /// # Example - /// ``` - /// let mut timer4 = Timer4Pwm::new(dp.TC4, Prescaler::Prescale64); - /// - /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer4); - /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer4); - /// let mut d13 = pins.d13.into_output().into_pwm(&mut timer4); - /// - /// d6.set_duty(128); - /// d6.enable(); - /// ``` - pub struct Timer4Pwm { - timer: crate::pac::TC4, - init: |tim, prescaler| { - tim.tccr4a.modify(|_r, w| w.pwm4a().set_bit()); - tim.tccr4a.modify(|_r, w| w.pwm4b().set_bit()); - tim.tccr4c.modify(|_r, w| w.pwm4d().set_bit()); - - tim.tccr4b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs4().direct(), - Prescaler::Prescale8 => w.cs4().prescale_8(), - Prescaler::Prescale64 => w.cs4().prescale_64(), - Prescaler::Prescale256 => w.cs4().prescale_256(), - Prescaler::Prescale1024 => w.cs4().prescale_1024(), - }); - }, - pins: { - PB6: { - ocr: ocr4b, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4b().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4b().disconnected()); - }, - }, - - PC7: { - ocr: ocr4a, - into_pwm: |tim| if enable { - tim.tccr4a.modify(|_r, w| w.com4a().match_clear()); - } else { - tim.tccr4a.modify(|_r, w| w.com4a().disconnected()); - }, - }, - - PD7: { - ocr: ocr4d, - into_pwm: |tim| if enable { - tim.tccr4c.modify(|_r, w| w.com4d().match_clear()); - } else { - tim.tccr4c.modify(|_r, w| w.com4d().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1284p"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PB3`, `PB4`) - /// - /// # Example - /// ``` - /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); - /// - /// let mut b3 = pins.b3.into_output().into_pwm(&mut timer0); - /// let mut b4 = pins.b4.into_output().into_pwm(&mut timer0); - /// - /// b3.set_duty(128); - /// b4.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - PB3: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); - }, - }, - - PB4: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1284p"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PD5`, `PD4`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d5 = pins.d5.into_output().into_pwm(&mut timer1); - /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1); - /// - /// d5.set_duty(128); - /// d5.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| { - w.wgm1().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - PD5: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); - }, - }, - - PD4: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1284p"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC2` for PWM (pins `PD7`, `PD6`) - /// - /// # Example - /// ``` - /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); - /// - /// let mut d7 = pins.d7.into_output().into_pwm(&mut timer2); - /// let mut d6 = pins.d6.into_output().into_pwm(&mut timer2); - /// - /// d7.set_duty(128); - /// d7.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2a.modify(|_r, w| w.wgm2().pwm_fast()); - tim.tccr2b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - }); - }, - pins: { - PD7: { - ocr: ocr2a, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2a().match_clear()); - } else { - tim.tccr2a.modify(|_r, w| w.com2a().disconnected()); - }, - }, - - PD6: { - ocr: ocr2b, - into_pwm: |tim| if enable { - tim.tccr2a.modify(|_r, w| w.com2b().match_clear()); - } else { - tim.tccr2a.modify(|_r, w| w.com2b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega1284p"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC3` for PWM (pins `PB6`, `PB7`) - pub struct Timer3Pwm { - timer: crate::pac::TC3, - init: |tim, prescaler| { - tim.tccr3a.modify(|_r, w| w.wgm3().bits(0b01)); - tim.tccr3b.modify(|_r, w| { - w.wgm3().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs3().direct(), - Prescaler::Prescale8 => w.cs3().prescale_8(), - Prescaler::Prescale64 => w.cs3().prescale_64(), - Prescaler::Prescale256 => w.cs3().prescale_256(), - Prescaler::Prescale1024 => w.cs3().prescale_1024(), - } - }); - }, - pins: { - PB6: { - ocr: ocr3a, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3a().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3a().disconnected()); - }, - }, - - PB7: { - ocr: ocr3b, - into_pwm: |tim| if enable { - tim.tccr3a.modify(|_r, w| w.com3b().match_clear()); - } else { - tim.tccr3a.modify(|_r, w| w.com3b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega8",))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PB1`, `PB2`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut b1 = pins.b1.into_output().into_pwm(&mut timer1); - /// let mut b2 = pins.b2.into_output().into_pwm(&mut timer1); - /// - /// d9.set_duty(128); - /// d9.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_r, w| { - w.wgm1().bits(0b01); - - match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - } - }); - }, - pins: { - PB1: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1a().disconnected()); - }, - }, - - PB2: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().match_clear()); - } else { - tim.tccr1a.modify(|_r, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega8",))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC2` for PWM (pins `PB3`, `PD3`) - /// - /// # Example - /// ``` - /// let mut timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale64); - /// - /// let mut d11 = pins.d11.into_output().into_pwm(&mut timer2); - /// let mut d3 = pins.d3.into_output().into_pwm(&mut timer2); - /// - /// d11.set_duty(128); - /// d11.enable(); - /// ``` - pub struct Timer2Pwm { - timer: crate::pac::TC2, - init: |tim, prescaler| { - tim.tccr2.modify(|_r, w| w.wgm20().set_bit().wgm21().set_bit()); - tim.tccr2.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs2().direct(), - Prescaler::Prescale8 => w.cs2().prescale_8(), - Prescaler::Prescale64 => w.cs2().prescale_64(), - Prescaler::Prescale256 => w.cs2().prescale_256(), - Prescaler::Prescale1024 => w.cs2().prescale_1024(), - }); - }, - pins: { - PB3: { - ocr: ocr2, - into_pwm: |tim| if enable { - tim.tccr2.modify(|_r, w| w.com2().match_clear()); - } else { - tim.tccr2.modify(|_r, w| w.com2().disconnected()); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega164pa"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PB3`) - /// - /// # Example - /// ``` - /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); - /// - /// let mut b3 = pins.pb3.into_output().into_pwm(&mut timer0); - /// - /// b3.set_duty(128); - /// b3.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().bits(0b11)); - tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); - - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().running_no_prescaling(), - Prescaler::Prescale8 => w.cs0().running_clk_8(), - Prescaler::Prescale64 => w.cs0().running_clk_64(), - Prescaler::Prescale256 => w.cs0().running_clk_256(), - Prescaler::Prescale1024 => w.cs0().running_clk_1024(), - }); - }, - pins: { - PB3: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().bits(0b11)); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().bits(0b00)); - }, - }, - }, - } -} - -#[cfg(any(feature = "atmega164pa"))] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PD4`, `PD5`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d4 = pins.pd4.into_output().into_pwm(&mut timer1); - /// let mut d5 = pins.pd5.into_output().into_pwm(&mut timer1); - /// - /// d4.set_duty(128); - /// d4.enable(); - /// d5.set_duty(64); - /// d5.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_r, w| w.wgm1().bits(0b01)); - tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); - tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); - tim.tccr1b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs1().running_no_prescaling(), - Prescaler::Prescale8 => w.cs1().running_clk_8(), - Prescaler::Prescale64 => w.cs1().running_clk_64(), - Prescaler::Prescale256 => w.cs1().running_clk_256(), - Prescaler::Prescale1024 => w.cs1().running_clk_1024(), - }); - }, - pins: { - PD4: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1a().bits(0b11)); - } else { - tim.tccr1a.modify(|_r, w| w.com1a().bits(0b00)); - }, - }, - PD5: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_r, w| w.com1b().bits(0b11)); - } else { - tim.tccr1a.modify(|_r, w| w.com1b().bits(0b00)); - }, - }, - }, - } -} diff --git a/mcu/atmega-hal/src/spi.rs b/mcu/atmega-hal/src/spi.rs deleted file mode 100644 index bb42147491..0000000000 --- a/mcu/atmega-hal/src/spi.rs +++ /dev/null @@ -1,147 +0,0 @@ -//! SPI -//! -//! # Example -//! -//! Complete example source code can be found in the repository -//! [`atmega2560-spi-feedback.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs) -//! -//! ``` -//! let dp = atmega_hal::Peripherals::take().unwrap(); -//! let pins = atmega_hal::pins!(dp); -//! -//! let (mut spi, mut cs) = spi::Spi::new( -//! dp.SPI, -//! pins.pb1.into_output(), -//! pins.pb2.into_output(), -//! pins.pb3.into_pull_up_input(), -//! pins.pb0.into_output(), -//! spi::Settings::default(), -//! ); -//! -//! let data_out = b"Hello World!"; -//! let mut data_in = [0u8; 12]; -//! -//! cs.set_low().unwrap(); -//! spi.transfer(&mut data_in, data_out).unwrap(); -//! cs.set_high().unwrap(); -//! -//! ufmt::uwriteln!(&mut serial, "data: {:?}", data_in).unwrap(); -//! ``` - -#[allow(unused_imports)] -use crate::port; -pub use avr_hal_generic::spi::*; - -#[cfg(any( - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega32u4" -))] -pub type Spi = avr_hal_generic::spi::Spi< - crate::Atmega, - crate::pac::SPI, - port::PB1, - port::PB2, - port::PB3, - port::PB0, ->; -#[cfg(any( - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega32u4" -))] -avr_hal_generic::impl_spi! { - hal: crate::Atmega, - peripheral: crate::pac::SPI, - sclk: port::PB1, - mosi: port::PB2, - miso: port::PB3, - cs: port::PB0, -} - -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega48p", - feature = "atmega8" -))] -pub type Spi = avr_hal_generic::spi::Spi< - crate::Atmega, - crate::pac::SPI, - port::PB5, - port::PB3, - port::PB4, - port::PB2, ->; -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega48p", - feature = "atmega8" -))] -avr_hal_generic::impl_spi! { - hal: crate::Atmega, - peripheral: crate::pac::SPI, - sclk: port::PB5, - mosi: port::PB3, - miso: port::PB4, - cs: port::PB2, -} - -#[cfg(feature = "atmega328pb")] -pub type Spi0 = avr_hal_generic::spi::Spi< - crate::Atmega, - crate::pac::SPI0, - port::PB5, - port::PB3, - port::PB4, - port::PB2, ->; -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_spi! { - hal: crate::Atmega, - peripheral: crate::pac::SPI0, - sclk: port::PB5, - mosi: port::PB3, - miso: port::PB4, - cs: port::PB2, -} -#[cfg(feature = "atmega328pb")] -pub type Spi1 = avr_hal_generic::spi::Spi< - crate::Atmega, - crate::pac::SPI1, - port::PC1, - port::PE3, - port::PC0, - port::PE2, ->; -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_spi! { - hal: crate::Atmega, - peripheral: crate::pac::SPI1, - sclk: port::PC1, - mosi: port::PE3, - miso: port::PC0, - cs: port::PE2, -} - -#[cfg(any(feature = "atmega1284p", feature = "atmega32a"))] -pub type Spi = avr_hal_generic::spi::Spi< - crate::Atmega, - crate::pac::SPI, - port::PB7, - port::PB5, - port::PB6, - port::PB4, ->; -#[cfg(any(feature = "atmega1284p", feature = "atmega32a"))] -avr_hal_generic::impl_spi! { - hal: crate::Atmega, - peripheral: crate::pac::SPI, - sclk: port::PB7, - mosi: port::PB5, - miso: port::PB6, - cs: port::PB4, -} diff --git a/mcu/atmega-hal/src/usart.rs b/mcu/atmega-hal/src/usart.rs deleted file mode 100644 index 7a8aaeaea7..0000000000 --- a/mcu/atmega-hal/src/usart.rs +++ /dev/null @@ -1,411 +0,0 @@ -//! USART -//! -//! # Example -//! -//! Complete example source code can be found in the repository: -//! [`atmega2560-usart.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-usart.rs) -//! -//! *Note: [ufmt](https://crates.io/crates/ufmt/) is used instead of `core::fmt` because -//! `core::fmt` code quickly grows too large for AVR platforms.* -//! -//! ``` -//! let dp = atmega_hal::Peripherals::take().unwrap(); -//! let pins = atmega_hal::pins!(dp); -//! -//! let mut serial = Usart::new( -//! dp.USART0, -//! pins.pe0, -//! pins.pe1.into_output(), -//! Baudrate::::new(57600), -//! ); -//! -//! ufmt::uwriteln!(&mut serial, "Hello from ATmega!").unwrap(); -//! -//! loop { -//! // Read a byte from the serial connection -//! let b = nb::block!(serial.read()).unwrap(); -//! // Answer -//! ufmt::uwriteln!(&mut serial, "Got {}!", b).unwrap(); -//! } -//! ``` - -#[allow(unused_imports)] -use crate::port; -pub use avr_hal_generic::usart::*; - -pub type Usart = - avr_hal_generic::usart::Usart; -pub type UsartWriter = - avr_hal_generic::usart::UsartWriter; -pub type UsartReader = - avr_hal_generic::usart::UsartReader; - -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega1284p", - feature = "atmega164pa" -))] -pub type Usart0 = Usart< - crate::pac::USART0, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any( - feature = "atmega168", - feature = "atmega328p", - feature = "atmega328pb", - feature = "atmega1284p", - feature = "atmega164pa" -))] -avr_hal_generic::impl_usart_traditional! { - hal: crate::Atmega, - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: port::PD0, - tx: port::PD1, -} - -#[cfg(feature = "atmega328pb")] -pub type Usart1 = Usart< - crate::pac::USART1, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(feature = "atmega328pb")] -avr_hal_generic::impl_usart_traditional! { - hal: crate::Atmega, - peripheral: crate::pac::USART1, - register_suffix: 1, - rx: port::PB4, - tx: port::PB3, -} - -#[cfg(any( - feature = "atmega32u4", - feature = "atmega128a", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega1284p", - feature = "atmega164pa" -))] -pub type Usart1 = Usart< - crate::pac::USART1, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any( - feature = "atmega32u4", - feature = "atmega1280", - feature = "atmega2560", - feature = "atmega1284p", - feature = "atmega164pa" -))] -avr_hal_generic::impl_usart_traditional! { - hal: crate::Atmega, - peripheral: crate::pac::USART1, - register_suffix: 1, - rx: port::PD2, - tx: port::PD3, -} - -#[cfg(any(feature = "atmega128A", feature = "atmega1280", feature = "atmega2560"))] -pub type Usart0 = Usart< - crate::pac::USART0, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_traditional! { - hal: crate::Atmega, - peripheral: crate::pac::USART0, - register_suffix: 0, - rx: port::PE0, - tx: port::PE1, -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -pub type Usart2 = Usart< - crate::pac::USART2, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_traditional! { - hal: crate::Atmega, - peripheral: crate::pac::USART2, - register_suffix: 2, - rx: port::PH0, - tx: port::PH1, -} - -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -pub type Usart3 = Usart< - crate::pac::USART3, - port::Pin, - port::Pin, - CLOCK, ->; -#[cfg(any(feature = "atmega1280", feature = "atmega2560"))] -avr_hal_generic::impl_usart_traditional! { - hal: crate::Atmega, - peripheral: crate::pac::USART3, - register_suffix: 3, - rx: port::PJ0, - tx: port::PJ1, -} - -#[cfg(any(feature = "atmega8", feature = "atmega32a"))] -pub type Usart0 = Usart< - crate::pac::USART, - port::Pin, - port::Pin, - CLOCK, ->; - -// TODO: atmega8 USART is different from other atmegas -// implemented so far. It uses the same register address -// for UBRRH and UCSRC, the way to select which register -// to write to, msb has to be 1 (for UCSRC) -// or 0 (for UBRRH). Because of the same address, -// these two are exposed as functions instead of -// fields. -#[cfg(any(feature = "atmega8", feature = "atmega32a"))] -impl - crate::usart::UsartOps< - crate::Atmega, - crate::port::Pin, - crate::port::Pin, - > for crate::pac::USART -{ - fn raw_init(&mut self, baudrate: crate::usart::Baudrate) { - // msb of ubrrh has to be 0 to set ubrrh register. (see atmega8 datasheet) - let ubrrh: u8 = ((baudrate.ubrr >> 8) & 0x0F) as u8; - let ubrrl: u8 = (baudrate.ubrr & 0xFF) as u8; - self.ubrrh().write(|w| w.bits(ubrrh)); - self.ubrrl.write(|w| w.bits(ubrrl)); - self.ucsra.write(|w| w.u2x().bit(baudrate.u2x)); - - // Enable receiver and transmitter but leave interrupts disabled. - #[rustfmt::skip] - self.ucsrb.write(|w| w - .txen().set_bit() - .rxen().set_bit() - ); - - // Set frame format to 8n1 for now. At some point, this should be made - // configurable, similar to what is done in other HALs. - #[rustfmt::skip] - self.ucsrc().write(|w| w - .ursel().set_bit() // sets the ucsrc instead of ubrrh (ubrrh and ucsrc share same location on ATmega8, see atmega8 datasheet) - .umsel().usart_async() - .ucsz().chr8() - .usbs().stop1() - .upm().disabled() - ); - } - - fn raw_deinit(&mut self) { - // Wait for any ongoing transfer to finish. - avr_hal_generic::nb::block!(self.raw_flush()).ok(); - self.ucsrb.reset(); - } - - fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - if self.ucsra.read().udre().bit_is_clear() { - Err(avr_hal_generic::nb::Error::WouldBlock) - } else { - Ok(()) - } - } - - fn raw_write( - &mut self, - byte: u8, - ) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - // Call flush to make sure the data-register is empty - self.raw_flush()?; - - self.udr.write(|w| w.bits(byte)); - Ok(()) - } - - fn raw_read(&mut self) -> avr_hal_generic::nb::Result { - if self.ucsra.read().rxc().bit_is_clear() { - return Err(avr_hal_generic::nb::Error::WouldBlock); - } - - Ok(self.udr.read().bits()) - } - - fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { - match event { - crate::usart::Event::RxComplete => self.ucsrb.modify(|_, w| w.rxcie().bit(state)), - crate::usart::Event::TxComplete => self.ucsrb.modify(|_, w| w.txcie().bit(state)), - crate::usart::Event::DataRegisterEmpty => { - self.ucsrb.modify(|_, w| w.udrie().bit(state)) - } - } - } -} - -// TODO: ATmega128A USART1 is also different from other atmegas -// Mainly needed because ubrr1 is split in ubrr1h and ubrr1l -#[cfg(any(feature = "atmega128a"))] -impl - crate::usart::UsartOps< - crate::Atmega, - crate::port::Pin, - crate::port::Pin, - > for crate::pac::USART1 -{ - fn raw_init(&mut self, baudrate: crate::usart::Baudrate) { - let ubrr1h: u8 = (baudrate.ubrr >> 8) as u8; - let ubrr1l: u8 = baudrate.ubrr as u8; - self.ubrr1h.write(|w| w.bits(ubrr1h)); - self.ubrr1l.write(|w| w.bits(ubrr1l)); - self.ucsr1a.write(|w| w.u2x1().bit(baudrate.u2x)); - - // Enable receiver and transmitter but leave interrupts disabled. - #[rustfmt::skip] - self.ucsr1b.write(|w| w - .txen1().set_bit() - .rxen1().set_bit() - ); - - // Set frame format to 8n1 for now. At some point, this should be made - // configurable, similar to what is done in other HALs. - #[rustfmt::skip] - self.ucsr1c.write(|w| w - .umsel1().usart_async() - .ucsz1().chr8() - .usbs1().stop1() - .upm1().disabled() - ); - } - - fn raw_deinit(&mut self) { - // Wait for any ongoing transfer to finish. - avr_hal_generic::nb::block!(self.raw_flush()).ok(); - self.ucsr1b.reset(); - } - - fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - if self.ucsr1a.read().udre1().bit_is_clear() { - Err(avr_hal_generic::nb::Error::WouldBlock) - } else { - Ok(()) - } - } - - fn raw_write( - &mut self, - byte: u8, - ) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - // Call flush to make sure the data-register is empty - self.raw_flush()?; - - self.udr1.write(|w| w.bits(byte)); - Ok(()) - } - - fn raw_read(&mut self) -> avr_hal_generic::nb::Result { - if self.ucsr1a.read().rxc1().bit_is_clear() { - return Err(avr_hal_generic::nb::Error::WouldBlock); - } - - Ok(self.udr1.read().bits()) - } - - fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { - match event { - crate::usart::Event::RxComplete => self.ucsr1b.modify(|_, w| w.rxcie1().bit(state)), - crate::usart::Event::TxComplete => self.ucsr1b.modify(|_, w| w.txcie1().bit(state)), - crate::usart::Event::DataRegisterEmpty => { - self.ucsr1b.modify(|_, w| w.udrie1().bit(state)) - } - } - } -} - -// TODO: ATmega128A USART0 is also different from other atmegas -// Mainly needed because ubrr1 is split in ubrr1h and ubrr1l -// For USART0 they are not even close to eachother in memory -#[cfg(any(feature = "atmega128a"))] -impl - crate::usart::UsartOps< - crate::Atmega, - crate::port::Pin, - crate::port::Pin, - > for crate::pac::USART0 -{ - fn raw_init(&mut self, baudrate: crate::usart::Baudrate) { - let ubrr0h: u8 = (baudrate.ubrr >> 8) as u8; - let ubrr0l: u8 = baudrate.ubrr as u8; - self.ubrr0h.write(|w| w.bits(ubrr0h)); - self.ubrr0l.write(|w| w.bits(ubrr0l)); - self.ucsr0a.write(|w| w.u2x0().bit(baudrate.u2x)); - - // Enable receiver and transmitter but leave interrupts disabled. - self.ucsr0b.write(|w| w.txen0().set_bit().rxen0().set_bit()); - - // Set frame format to 8n1 for now. At some point, this should be made - // configurable, similar to what is done in other HALs. - #[rustfmt::skip] - self.ucsr0c.write(|w| w - .umsel0().usart_async() - .ucsz0().chr8() - .usbs0().stop1() - .upm0().disabled() - ); - } - - fn raw_deinit(&mut self) { - // Wait for any ongoing transfer to finish. - avr_hal_generic::nb::block!(self.raw_flush()).ok(); - self.ucsr0b.reset(); - } - - fn raw_flush(&mut self) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - if self.ucsr0a.read().udre0().bit_is_clear() { - Err(avr_hal_generic::nb::Error::WouldBlock) - } else { - Ok(()) - } - } - - fn raw_write( - &mut self, - byte: u8, - ) -> avr_hal_generic::nb::Result<(), core::convert::Infallible> { - // Call flush to make sure the data-register is empty - self.raw_flush()?; - - self.udr0.write(|w| w.bits(byte)); - Ok(()) - } - - fn raw_read(&mut self) -> avr_hal_generic::nb::Result { - if self.ucsr0a.read().rxc0().bit_is_clear() { - return Err(avr_hal_generic::nb::Error::WouldBlock); - } - - Ok(self.udr0.read().bits()) - } - - fn raw_interrupt(&mut self, event: crate::usart::Event, state: bool) { - match event { - crate::usart::Event::RxComplete => self.ucsr0b.modify(|_, w| w.rxcie0().bit(state)), - crate::usart::Event::TxComplete => self.ucsr0b.modify(|_, w| w.txcie0().bit(state)), - crate::usart::Event::DataRegisterEmpty => { - self.ucsr0b.modify(|_, w| w.udrie0().bit(state)) - } - } - } -} diff --git a/mcu/atmega-hal/src/wdt.rs b/mcu/atmega-hal/src/wdt.rs deleted file mode 100644 index 434189a82e..0000000000 --- a/mcu/atmega-hal/src/wdt.rs +++ /dev/null @@ -1,44 +0,0 @@ -#[allow(unused_imports)] -pub use avr_hal_generic::wdt::{Timeout, WdtOps}; - -pub type Wdt = avr_hal_generic::wdt::Wdt; - -#[cfg(not(any(feature = "atmega8", feature = "atmega32a", feature = "atmega128a")))] -avr_hal_generic::impl_wdt! { - hal: crate::Atmega, - peripheral: crate::pac::WDT, - mcusr: crate::pac::cpu::MCUSR, - wdtcsr_name: wdtcsr, - timeout: |to, w| match to { - Timeout::Ms16 => w.wdpl().cycles_2k_512k(), - Timeout::Ms32 => w.wdpl().cycles_4k_1024k(), - Timeout::Ms64 => w.wdpl().cycles_8k(), - Timeout::Ms125 => w.wdpl().cycles_16k(), - Timeout::Ms250 => w.wdpl().cycles_32k(), - Timeout::Ms500 => w.wdpl().cycles_64k(), - Timeout::Ms1000 => w.wdpl().cycles_128k(), - Timeout::Ms2000 => w.wdpl().cycles_256k(), - Timeout::Ms4000 => w.wdph().set_bit().wdpl().cycles_2k_512k(), - Timeout::Ms8000 => w.wdph().set_bit().wdpl().cycles_4k_1024k(), - }, -} - -#[cfg(any(feature = "atmega8", feature = "atmega32a", feature = "atmega128a"))] -avr_hal_generic::impl_wdt! { - hal: crate::Atmega, - peripheral: crate::pac::WDT, - mcusr: crate::pac::cpu::MCUCSR, - wdtcsr_name: wdtcr, - timeout: |to, w| match to { - Timeout::Ms16 => w.wdpl().cycles_16k(), - Timeout::Ms32 => w.wdpl().cycles_32k(), - Timeout::Ms64 => w.wdpl().cycles_64k(), - Timeout::Ms125 => w.wdpl().cycles_128k(), - Timeout::Ms250 => w.wdpl().cycles_256k(), - Timeout::Ms500 => w.wdpl().cycles_512k(), - Timeout::Ms1000 => w.wdpl().cycles_1024k(), - Timeout::Ms2000 => w.wdpl().cycles_2048k(), - Timeout::Ms4000 => panic!(), // Does not exist for ATmega8 ... - Timeout::Ms8000 => panic!() // Does not exist for ATmega8 ... - }, -} diff --git a/mcu/attiny-hal/Cargo.toml b/mcu/attiny-hal/Cargo.toml index 4e11377dcb..268ab0bf08 100644 --- a/mcu/attiny-hal/Cargo.toml +++ b/mcu/attiny-hal/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "attiny-hal" -version = "0.1.0" +version = "0.4.0" authors = ["Rahix "] edition = "2021" @@ -12,33 +12,41 @@ categories = ["no-std", "embedded", "hardware-support"] [features] rt = ["avr-device/rt"] -device-selected = [] -attiny84 = ["avr-device/attiny84", "device-selected"] -attiny85 = ["avr-device/attiny85", "device-selected"] -attiny88 = ["avr-device/attiny88", "device-selected"] -attiny167 = ["avr-device/attiny167", "device-selected"] -attiny2313 = ["avr-device/attiny2313", "device-selected"] + +# MCU-specific targets. +attiny84 = ["_mcu-attiny84"] +attiny85 = ["_mcu-attiny85"] +attiny88 = ["_mcu-attiny88"] +attiny167 = ["_mcu-attiny167"] +attiny2313 = ["_mcu-attiny2313"] critical-section-impl = ["avr-device/critical-section-impl"] -# Allow certain downstream crates to overwrite the device selection error by themselves. -disable-device-selection-error = [] +default = [] + +docsrs = ["attiny84", "attiny85", "attiny88", "attiny167", "attiny2313"] + +# When using this crate from another lib crate, you can use this feature to turn suppress the chip selection error in favor of your own error +disable-device-selection-error = ["_mcu-selected"] + +# MCU-specific implementation features +_mcu-attiny84 = ["_mcu-selected", "_peripheral-simple-pwm", "avr-device/attiny84"] +_mcu-attiny85 = ["_mcu-selected", "_peripheral-adc", "_peripheral-simple-pwm", "avr-device/attiny85"] +_mcu-attiny88 = ["_mcu-selected", "_peripheral-adc", "_peripheral-spi", "_peripheral-simple-pwm", "avr-device/attiny88"] +_mcu-attiny167 = ["_mcu-selected", "_peripheral-adc", "_peripheral-spi", "avr-device/attiny167"] +_mcu-attiny2313 = ["_mcu-selected", "avr-device/attiny2313"] + +_mcu-selected = [] +_peripheral-adc = [] +_peripheral-spi = [] +_peripheral-simple-pwm = [] -# We must select a microcontroller to build on docs.rs -docsrs = ["attiny85"] [dependencies] avr-hal-generic = { path = "../../avr-hal-generic/" } [dependencies.avr-device] version = "0.5.4" - -# Because this crate has its own check that at least one device is selected, we -# can safely "circumvent" the check in `avr-device`. -# -# Why would we want that? Otherwise, as `avr-device` is compiled first, its -# error will be shown and ours won't which leads to a degraded user experience -# as the displayed error message does not really tell what needs to be done... features = ["device-selected"] [package.metadata.docs.rs] diff --git a/mcu/attiny-hal/src/adc.rs b/mcu/attiny-hal/src/adc.rs deleted file mode 100644 index 0856312086..0000000000 --- a/mcu/attiny-hal/src/adc.rs +++ /dev/null @@ -1,209 +0,0 @@ -#![allow(non_camel_case_types)] -//! Analog-to-Digital Converter -//! -//! # Example -//! -//! For full source code, please refer to the ATmega ADC example: -//! [`atmega2560-adc.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-adc.rs) -//! -//! ``` -//! let dp = attiny_hal::Peripherals::take().unwrap(); -//! let pins = attiny_hal::pins!(dp); -//! -//! let mut adc = Adc::new(dp.ADC, Default::default()); -//! -//! let channels: [attiny_hal::adc::Channel; 4] = [ -//! pins.pa0.into_analog_input(&mut adc).into_channel(), -//! pins.pa1.into_analog_input(&mut adc).into_channel(), -//! pins.pa2.into_analog_input(&mut adc).into_channel(), -//! pins.pa3.into_analog_input(&mut adc).into_channel(), -//! ]; -//! -//! for (index, channel) in channels.iter().enumerate() { -//! let value = adc.read_blocking(channel); -//! ufmt::uwrite!(&mut serial, "CH{}: {} ", index, value).unwrap(); -//! } -//! ``` - -use crate::port; -pub use avr_hal_generic::adc::{AdcChannel, AdcOps, ClockDivider}; - -/// Select the voltage reference for the ADC peripheral -/// -/// The internal voltage reference options may not be used if an external reference voltage is -/// being applied to the AREF pin. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(u8)] -pub enum ReferenceVoltage { - /// Voltage applied to AREF pin. - #[cfg(any(feature = "attiny85", feature = "attiny167",))] - Aref, - /// Default reference voltage (default). - AVcc, - /// Internal 1.1V reference. - Internal1_1, - /// Internal 2.56V reference. - #[cfg(any(feature = "attiny85", feature = "attiny167",))] - Internal2_56, -} - -impl Default for ReferenceVoltage { - fn default() -> Self { - Self::AVcc - } -} - -/// Configuration for the ADC peripheral. -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] -pub struct AdcSettings { - pub clock_divider: ClockDivider, - pub ref_voltage: ReferenceVoltage, -} - -/// Check the [`avr_hal_generic::adc::Adc`] documentation. -pub type Adc = avr_hal_generic::adc::Adc; - -/// Check the [`avr_hal_generic::adc::Channel`] documentation. -pub type Channel = avr_hal_generic::adc::Channel; - -/// Additional channels -/// -/// Some channels are not directly connected to pins. This module provides types which can be used -/// to access them. -/// -/// # Example -/// ``` -/// let dp = attiny_hal::Peripherals::take().unwrap(); -/// let mut adc = attiny_hal::Adc::new(dp.ADC, Default::default()); -/// -/// let value = adc.read_blocking(&channel::Vbg); -/// ``` -pub mod channel { - #[cfg(feature = "attiny167")] - pub struct AVcc_4; - pub struct Vbg; - pub struct Gnd; - pub struct Temperature; -} - -fn apply_clock(peripheral: &crate::pac::ADC, settings: AdcSettings) { - peripheral.adcsra.write(|w| { - w.aden().set_bit(); - match settings.clock_divider { - ClockDivider::Factor2 => w.adps().prescaler_2(), - ClockDivider::Factor4 => w.adps().prescaler_4(), - ClockDivider::Factor8 => w.adps().prescaler_8(), - ClockDivider::Factor16 => w.adps().prescaler_16(), - ClockDivider::Factor32 => w.adps().prescaler_32(), - ClockDivider::Factor64 => w.adps().prescaler_64(), - ClockDivider::Factor128 => w.adps().prescaler_128(), - } - }); -} - -#[cfg(feature = "attiny85")] -avr_hal_generic::impl_adc! { - hal: crate::Attiny, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { - apply_clock(peripheral, settings); - peripheral.admux.write(|w| match settings.ref_voltage { - ReferenceVoltage::Aref => w.refs().aref(), - ReferenceVoltage::AVcc => w.refs().vcc(), - ReferenceVoltage::Internal1_1 => w.refs().internal().refs2().clear_bit(), - ReferenceVoltage::Internal2_56 => w.refs().internal().refs2().set_bit(), - }); - }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PB5: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), - port::PB2: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), - port::PB4: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), - port::PB3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), - }, - channels: { - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS, - }, -} - -#[cfg(feature = "attiny88")] -avr_hal_generic::impl_adc! { - hal: crate::Attiny, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { - apply_clock(peripheral, settings); - peripheral.admux.write(|w| match settings.ref_voltage { - ReferenceVoltage::AVcc => w.refs0().avcc(), - ReferenceVoltage::Internal1_1 => w.refs0().internal(), - }); - }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PC0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), - port::PC1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), - port::PC2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), - port::PC3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), - port::PC4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), - port::PC5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), - port::PA0: (crate::pac::adc::admux::MUX_A::ADC6, didr0::adc6d), - port::PA1: (crate::pac::adc::admux::MUX_A::ADC7, didr0::adc7d), - }, - channels: { - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS, - }, -} - -#[cfg(feature = "attiny167")] -avr_hal_generic::impl_adc! { - hal: crate::Attiny, - peripheral: crate::pac::ADC, - settings: AdcSettings, - apply_settings: |peripheral, settings| { - apply_clock(peripheral, settings); - peripheral.amiscr.write(|w| match settings.ref_voltage { - ReferenceVoltage::Aref => w.arefen().set_bit(), - _ => w.arefen().clear_bit(), - }); - peripheral.admux.write(|w| match settings.ref_voltage { - ReferenceVoltage::Aref => w.refs().avcc(), - ReferenceVoltage::AVcc => w.refs().avcc(), - ReferenceVoltage::Internal1_1 => w.refs().internal_11(), - ReferenceVoltage::Internal2_56 => w.refs().internal_256(), - }); - }, - channel_id: crate::pac::adc::admux::MUX_A, - set_channel: |peripheral, id| { - peripheral.admux.modify(|_, w| w.mux().variant(id)); - }, - pins: { - port::PA0: (crate::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), - port::PA1: (crate::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), - port::PA2: (crate::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), - port::PA3: (crate::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), - port::PA4: (crate::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), - port::PA5: (crate::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), - port::PA6: (crate::pac::adc::admux::MUX_A::ADC6, didr0::adc6d), - port::PA7: (crate::pac::adc::admux::MUX_A::ADC7, didr0::adc7d), - port::PB5: (crate::pac::adc::admux::MUX_A::ADC8, didr1::adc8d), - port::PB6: (crate::pac::adc::admux::MUX_A::ADC9, didr1::adc9d), - port::PB7: (crate::pac::adc::admux::MUX_A::ADC10, didr1::adc10d), - }, - channels: { - channel::AVcc_4: crate::pac::adc::admux::MUX_A::ADC_AVCC_4, - channel::Vbg: crate::pac::adc::admux::MUX_A::ADC_VBG, - channel::Gnd: crate::pac::adc::admux::MUX_A::ADC_GND, - channel::Temperature: crate::pac::adc::admux::MUX_A::TEMPSENS, - }, -} diff --git a/mcu/attiny-hal/src/attiny167.rs b/mcu/attiny-hal/src/attiny167.rs new file mode 100644 index 0000000000..53407d9aa9 --- /dev/null +++ b/mcu/attiny-hal/src/attiny167.rs @@ -0,0 +1,118 @@ +pub use avr_device::attiny167 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::attiny167 as hal; + + impl_adc_reference_voltage! { + pub enum ReferenceVoltage { + /// Voltage applied to AREF pin. + Aref, + /// Default reference voltage (default). + AVcc, + /// Internal 1.1V reference. + Internal1_1, + /// Internal 2.56V reference. + Internal2_56, + } + } + + impl_adc_channels! { + pub struct AVcc_4; + pub struct Vbg; + pub struct Gnd; + pub struct Temperature; + } + + impl_adc_peripheral! { + pac: crate::attiny167::pac, + hal: crate::attiny167::Hal, + } + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { + apply_clock(peripheral, settings); + peripheral.amiscr.write(|w| match settings.ref_voltage { + ReferenceVoltage::Aref => w.arefen().set_bit(), + _ => w.arefen().clear_bit(), + }); + peripheral.admux.write(|w| match settings.ref_voltage { + ReferenceVoltage::Aref => w.refs().avcc(), + ReferenceVoltage::AVcc => w.refs().avcc(), + ReferenceVoltage::Internal1_1 => w.refs().internal_11(), + ReferenceVoltage::Internal2_56 => w.refs().internal_256(), + }); + }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PA0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PA1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PA2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PA3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PA4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PA5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + hal::port::PA6: (hal::pac::adc::admux::MUX_A::ADC6, didr0::adc6d), + hal::port::PA7: (hal::pac::adc::admux::MUX_A::ADC7, didr0::adc7d), + hal::port::PB5: (hal::pac::adc::admux::MUX_A::ADC8, didr1::adc8d), + hal::port::PB6: (hal::pac::adc::admux::MUX_A::ADC9, didr1::adc9d), + hal::port::PB7: (hal::pac::adc::admux::MUX_A::ADC10, didr1::adc10d), + }, + channels: { + channel::AVcc_4: hal::pac::adc::admux::MUX_A::ADC_AVCC_4, + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + channel::Temperature: hal::pac::adc::admux::MUX_A::TEMPSENS, + }, + } +} + +impl_mod_eeprom! { + hal: crate::attiny167, + capacity: 512, + addr_width: u16, + addr_reg: eear, +} + +impl_mod_port! { + use crate::attiny167 as hal; + + pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + } + } + + #[macro_export] + macro_rules! attiny167_pins { + ($p:expr) => { + $crate::attiny167_pins::Pins::new($p.PORTA, $p.PORTB) + }; + } + + pub use attiny167_pins as pins; +} + +impl_mod_spi! { + hal: crate::attiny167, + sclk: hal::port::PA5, + mosi: hal::port::PA4, + miso: hal::port::PA2, + cs: hal::port::PA6, +} + +impl_mod_wdt! { + hal: crate::attiny167, + wdtcsr_name: wdtcr, +} + diff --git a/mcu/attiny-hal/src/attiny2313.rs b/mcu/attiny-hal/src/attiny2313.rs new file mode 100644 index 0000000000..328bbe788a --- /dev/null +++ b/mcu/attiny-hal/src/attiny2313.rs @@ -0,0 +1,40 @@ +pub use avr_device::attiny2313 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_eeprom! { + hal: crate::attiny2313, + capacity: 128, + addr_width: u8, + addr_reg: eear, +} + +impl_mod_port! { + use crate::attiny2313 as hal; + + pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6], + } + } + + #[macro_export] + macro_rules! attiny2313_pins { + ($p:expr) => { + $crate::attiny2313_pins::Pins::new($p.PORTA, $p.PORTB, $p.PORTD) + }; + } + + pub use attiny2313_pins as pins; +} + +impl_mod_wdt! { + hal: crate::attiny2313, + wdtcsr_name: wdtcr, +} + diff --git a/mcu/attiny-hal/src/attiny84.rs b/mcu/attiny-hal/src/attiny84.rs new file mode 100644 index 0000000000..fed0484583 --- /dev/null +++ b/mcu/attiny-hal/src/attiny84.rs @@ -0,0 +1,119 @@ +pub use avr_device::attiny84 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_eeprom! { + hal: crate::attiny84, + capacity: 512, + addr_width: u16, + addr_reg: eear, +} + +impl_mod_port! { + use crate::attiny84 as hal; + + pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], + B: hal::pac::PORTB = [0, 1, 2, 3], + } + } + + #[macro_export] + macro_rules! attiny84_pins { + ($p:expr) => { + $crate::attiny84_pins::Pins::new($p.PORTA, $p.PORTB) + }; + } + + pub use attiny84_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::attiny84 as hal; + + pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps}; + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB2`, `PA7`) + pub struct Timer0Pwm { + timer: crate::attiny84::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().direct(), + Prescaler::Prescale8 => w.cs0().prescale_8(), + Prescaler::Prescale64 => w.cs0().prescale_64(), + Prescaler::Prescale256 => w.cs0().prescale_256(), + Prescaler::Prescale1024 => w.cs0().prescale_1024(), + }); + }, + pins: { + hal::port::PB2: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + }, + }, + + hal::port::PA7: { + ocr: ocr0b, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PA6`, 'PA5') + pub struct Timer1Pwm { + timer: crate::attiny84::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01)); + + tim.tccr1b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + }); + }, + pins: { + hal::port::PA6: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_, w| w.com1a().bits(0b10)); + } else { + tim.tccr1a.modify(|_, w| w.com1a().disconnected()); + }, + }, + + hal::port::PA5: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_, w| w.com1b().bits(0b10)); + } else { + tim.tccr1a.modify(|_, w| w.com1b().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_wdt! { + hal: crate::attiny84, + wdtcsr_name: wdtcsr, +} + diff --git a/mcu/attiny-hal/src/attiny85.rs b/mcu/attiny-hal/src/attiny85.rs new file mode 100644 index 0000000000..1011534c51 --- /dev/null +++ b/mcu/attiny-hal/src/attiny85.rs @@ -0,0 +1,186 @@ +pub use avr_device::attiny85 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::attiny85 as hal; + + impl_adc_reference_voltage! { + pub enum ReferenceVoltage { + /// Voltage applied to AREF pin. + Aref, + /// Default reference voltage (default). + AVcc, + /// Internal 1.1V reference. + Internal1_1, + /// Internal 2.56V reference. + Internal2_56, + } + } + + impl_adc_channels! { + pub struct Vbg; + pub struct Gnd; + pub struct Temperature; + } + + impl_adc_peripheral! { + pac: crate::attiny85::pac, + hal: crate::attiny85::Hal, + } + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { + apply_clock(peripheral, settings); + peripheral.admux.write(|w| match settings.ref_voltage { + ReferenceVoltage::Aref => w.refs().aref(), + ReferenceVoltage::AVcc => w.refs().vcc(), + ReferenceVoltage::Internal1_1 => w.refs().internal().refs2().clear_bit(), + ReferenceVoltage::Internal2_56 => w.refs().internal().refs2().set_bit(), + }); + }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PB5: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PB2: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PB4: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PB3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + }, + channels: { + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + channel::Temperature: hal::pac::adc::admux::MUX_A::TEMPSENS, + }, + } +} + +impl_mod_eeprom! { + hal: crate::attiny85, + capacity: 512, + addr_width: u16, + addr_reg: eear, +} + +impl_mod_port! { + use crate::attiny85 as hal; + + pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + avr_hal_generic::impl_port_traditional! { + enum Ports { + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5], + } + } + + #[macro_export] + macro_rules! attiny85_pins { + ($p:expr) => { + $crate::attiny85::Pins::new($p.PORTB) + }; + } + + pub use attiny85_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::attiny85 as hal; + + pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps}; + avr_hal_generic::impl_simple_pwm! { + /// Use `TC0` for PWM (pins `PB0`, `PB1`) + /// + /// # Example + /// ``` + /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); + /// + /// let mut d0 = pins.d0.into_output().into_pwm(&mut timer0); + /// let mut d1 = pins.d1.into_output().into_pwm(&mut timer0); + /// + /// d0.set_duty(128); + /// d0.enable(); + /// ``` + pub struct Timer0Pwm { + timer: crate::attiny85::pac::TC0, + init: |tim, prescaler| { + tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); + tim.tccr0b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs0().direct(), + Prescaler::Prescale8 => w.cs0().prescale_8(), + Prescaler::Prescale64 => w.cs0().prescale_64(), + Prescaler::Prescale256 => w.cs0().prescale_256(), + Prescaler::Prescale1024 => w.cs0().prescale_1024(), + }); + }, + pins: { + hal::port::PB0: { + ocr: ocr0a, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); + }, + }, + + hal::port::PB1: { + ocr: ocr0b, + into_pwm: |tim| if enable { + tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); + } else { + tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); + }, + }, + }, + } + } + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PB4`) + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1); + /// + /// d4.set_duty(128); + /// d4.enable(); + /// ``` + pub struct Timer1Pwm { + timer: crate::attiny85::pac::TC1, + init: |tim, prescaler| { + tim.gtccr.modify(|_, w| w.pwm1b().bit(true)); + + tim.tccr1.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + }); + }, + pins: { + hal::port::PB4: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.gtccr.modify(|_, w| w.com1b().bits(0b10)); + } else { + tim.gtccr.modify(|_, w| w.com1b().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_wdt! { + hal: crate::attiny85, + wdtcsr_name: wdtcr, +} + diff --git a/mcu/attiny-hal/src/attiny88.rs b/mcu/attiny-hal/src/attiny88.rs new file mode 100644 index 0000000000..bfd0da9981 --- /dev/null +++ b/mcu/attiny-hal/src/attiny88.rs @@ -0,0 +1,159 @@ +pub use avr_device::attiny88 as pac; + +pub struct Hal; + +use crate::r#impl::*; + +impl_mod_adc! { + use crate::attiny88 as hal; + + impl_adc_reference_voltage! { + pub enum ReferenceVoltage { + /// Default reference voltage (default). + AVcc, + /// Internal 1.1V reference. + Internal1_1, + } + } + + impl_adc_channels! { + pub struct Vbg; + pub struct Gnd; + pub struct Temperature; + } + + impl_adc_peripheral! { + pac: crate::attiny88::pac, + hal: crate::attiny88::Hal, + } + + avr_hal_generic::impl_adc! { + hal: hal::Hal, + peripheral: hal::pac::ADC, + settings: AdcSettings, + apply_settings: |peripheral, settings| { + apply_clock(peripheral, settings); + peripheral.admux.write(|w| match settings.ref_voltage { + ReferenceVoltage::AVcc => w.refs0().avcc(), + ReferenceVoltage::Internal1_1 => w.refs0().internal(), + }); + }, + channel_id: hal::pac::adc::admux::MUX_A, + set_channel: |peripheral, id| { + peripheral.admux.modify(|_, w| w.mux().variant(id)); + }, + pins: { + hal::port::PC0: (hal::pac::adc::admux::MUX_A::ADC0, didr0::adc0d), + hal::port::PC1: (hal::pac::adc::admux::MUX_A::ADC1, didr0::adc1d), + hal::port::PC2: (hal::pac::adc::admux::MUX_A::ADC2, didr0::adc2d), + hal::port::PC3: (hal::pac::adc::admux::MUX_A::ADC3, didr0::adc3d), + hal::port::PC4: (hal::pac::adc::admux::MUX_A::ADC4, didr0::adc4d), + hal::port::PC5: (hal::pac::adc::admux::MUX_A::ADC5, didr0::adc5d), + hal::port::PA0: (hal::pac::adc::admux::MUX_A::ADC6, didr0::adc6d), + hal::port::PA1: (hal::pac::adc::admux::MUX_A::ADC7, didr0::adc7d), + }, + channels: { + channel::Vbg: hal::pac::adc::admux::MUX_A::ADC_VBG, + channel::Gnd: hal::pac::adc::admux::MUX_A::ADC_GND, + channel::Temperature: hal::pac::adc::admux::MUX_A::TEMPSENS, + }, + } +} + +impl_mod_eeprom! { + hal: crate::attiny88, + capacity: 64, + addr_width: u8, + addr_reg: eearl, +} + +impl_mod_port! { + use crate::attiny88 as hal; + + pub use avr_hal_generic::port::{mode, PinMode, PinOps}; + avr_hal_generic::impl_port_traditional! { + enum Ports { + A: hal::pac::PORTA = [0, 1, 2, 3], + B: hal::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], + C: hal::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], + D: hal::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], + } + } + + #[macro_export] + macro_rules! attiny88_pins { + ($p:expr) => { + $crate::attiny88_pins::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) + }; + } + + pub use attiny88_pins as pins; +} + +impl_mod_simple_pwm! { + use crate::attiny88 as hal; + pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps}; + + avr_hal_generic::impl_simple_pwm! { + /// Use `TC1` for PWM (pins `PB1`, 'PB2') + /// + /// # Example + /// ``` + /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); + /// + /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1); + /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1); + /// + /// d9.set_duty(128); + /// d9.enable(); + /// ``` + pub struct Timer1Pwm { + timer: crate::attiny88::pac::TC1, + init: |tim, prescaler| { + tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); + tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01)); + + tim.tccr1b.modify(|_r, w| match prescaler { + Prescaler::Direct => w.cs1().direct(), + Prescaler::Prescale8 => w.cs1().prescale_8(), + Prescaler::Prescale64 => w.cs1().prescale_64(), + Prescaler::Prescale256 => w.cs1().prescale_256(), + Prescaler::Prescale1024 => w.cs1().prescale_1024(), + }); + }, + pins: { + hal::port::PB1: { + ocr: ocr1a, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_, w| w.com1a().bits(0b10)); + } else { + tim.tccr1a.modify(|_, w| w.com1a().disconnected()); + }, + }, + + hal::port::PB2: { + ocr: ocr1b, + into_pwm: |tim| if enable { + tim.tccr1a.modify(|_, w| w.com1b().bits(0b10)); + } else { + tim.tccr1a.modify(|_, w| w.com1b().disconnected()); + }, + }, + }, + } + } +} + +impl_mod_spi! { + hal: crate::attiny88, + sclk: hal::port::PB5, + mosi: hal::port::PB3, + miso: hal::port::PB4, + cs: hal::port::PB2, +} + +impl_mod_wdt! { + hal: crate::attiny88, + wdtcsr_name: wdtcsr, +} + diff --git a/mcu/attiny-hal/src/eeprom.rs b/mcu/attiny-hal/src/eeprom.rs deleted file mode 100644 index f325215dfb..0000000000 --- a/mcu/attiny-hal/src/eeprom.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! EEPROM -//! -//! # Example -//! -//! For full source code, please refer to the ATmega EEPROM example: -//! [`atmega2560-eeprom.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-eeprom.rs) -//! -//! ``` -//! const BOOT_COUNT_OFFSET: u16 = 0; -//! -//! let dp = attiny_hal::Peripherals::take().unwrap(); -//! let mut eeprom = Eeprom::new(dp.EEPROM); -//! -//! let mut boot_count = eeprom.read_byte(BOOT_COUNT_OFFSET); -//! boot_count = boot_count.wrapping_add(1); -//! eeprom.write_byte(BOOT_COUNT_OFFSET, boot_count); -//! -//! ufmt::uwriteln!(&mut serial, "Boot count: {}", boot_count).unwrap(); -//! ``` - -pub use avr_hal_generic::eeprom::{EepromOps, OutOfBoundsError}; - -pub type Eeprom = avr_hal_generic::eeprom::Eeprom; - -#[cfg(feature = "attiny2313")] -avr_hal_generic::impl_eeprom_attiny! { - hal: crate::Attiny, - peripheral: crate::pac::EEPROM, - capacity: 128, - addr_width: u8, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(any(feature = "attiny167", feature = "attiny85"))] -avr_hal_generic::impl_eeprom_attiny! { - hal: crate::Attiny, - peripheral: crate::pac::EEPROM, - capacity: 512, - addr_width: u16, - set_address: |peripheral, address| { - peripheral.eear.write(|w| w.bits(address)); - }, -} - -#[cfg(feature = "attiny88")] -avr_hal_generic::impl_eeprom_attiny! { - hal: crate::Attiny, - peripheral: crate::pac::EEPROM, - capacity: 64, - addr_width: u8, - set_address: |peripheral, address| { - peripheral.eearl.write(|w| w.bits(address)); - }, -} diff --git a/mcu/attiny-hal/src/impl/adc.rs b/mcu/attiny-hal/src/impl/adc.rs new file mode 100644 index 0000000000..00af9375db --- /dev/null +++ b/mcu/attiny-hal/src/impl/adc.rs @@ -0,0 +1,118 @@ +macro_rules! impl_mod_adc { + ($($mod:item)*) => { + pub mod adc { + //! Analog-to-Digital Converter + //! + //! # Example + //! + //! For full source code, please refer to the ATmega ADC example: + //! [`atmega2560-adc.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-adc.rs) + //! + //! ``` + //! let dp = attiny_hal::Peripherals::take().unwrap(); + //! let pins = attiny_hal::pins!(dp); + //! + //! let mut adc = Adc::new(dp.ADC, Default::default()); + //! + //! let channels: [attiny_hal::adc::Channel; 4] = [ + //! pins.pa0.into_analog_input(&mut adc).into_channel(), + //! pins.pa1.into_analog_input(&mut adc).into_channel(), + //! pins.pa2.into_analog_input(&mut adc).into_channel(), + //! pins.pa3.into_analog_input(&mut adc).into_channel(), + //! ]; + //! + //! for (index, channel) in channels.iter().enumerate() { + //! let value = adc.read_blocking(channel); + //! ufmt::uwrite!(&mut serial, "CH{}: {} ", index, value).unwrap(); + //! } + //! ``` + + use crate::r#impl::{impl_adc_reference_voltage,impl_adc_channels,impl_adc_peripheral}; + + $($mod)* + } + pub use adc::Adc; + } +} +pub(crate) use impl_mod_adc; + +macro_rules! impl_adc_reference_voltage { + ($enum:item) => { + /// Select the voltage reference for the ADC peripheral + /// + /// The internal voltage reference options may not be used if an external reference voltage is + /// being applied to the AREF pin. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(u8)] + $enum + } +} +pub(crate) use impl_adc_reference_voltage; + +macro_rules! impl_adc_channels { + ($($channel:item)*) => { + /// Additional channels + /// + /// Some channels are not directly connected to pins. This module provides types which can be used + /// to access them. + /// + /// # Example + /// ``` + /// let dp = attiny_hal::Peripherals::take().unwrap(); + /// let mut adc = attiny_hal::Adc::new(dp.ADC, Default::default()); + /// + /// let value = adc.read_blocking(&channel::Vbg); + /// ``` + #[allow(non_camel_case_types)] + pub mod channel { + $($channel)* + } + } +} +pub(crate) use impl_adc_channels; + +macro_rules! impl_adc_peripheral { + ( + pac: $($pac:ident)::+, + hal: $($hal:ident)::+ $(,)? + ) => { + pub use avr_hal_generic::adc::{AdcChannel, AdcOps, ClockDivider}; + + impl Default for ReferenceVoltage { + fn default() -> Self { + Self::AVcc + } + } + + /// Configuration for the ADC peripheral. + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] + pub struct AdcSettings { + pub clock_divider: ClockDivider, + pub ref_voltage: ReferenceVoltage, + } + + /// Check the [`avr_hal_generic::adc::Adc`] documentation. + pub type Adc = + avr_hal_generic::adc::Adc<$($hal)::+, $($pac)::+::ADC, CLOCK>; + + /// Check the [`avr_hal_generic::adc::Channel`] documentation. + pub type Channel = avr_hal_generic::adc::Channel<$($hal)::+, $($pac)::+::ADC>; + + fn apply_clock(peripheral: &$($pac)::+::ADC, settings: AdcSettings) { + peripheral.adcsra.write(|w| { + w.aden().set_bit(); + match settings.clock_divider { + ClockDivider::Factor2 => w.adps().prescaler_2(), + ClockDivider::Factor4 => w.adps().prescaler_4(), + ClockDivider::Factor8 => w.adps().prescaler_8(), + ClockDivider::Factor16 => w.adps().prescaler_16(), + ClockDivider::Factor32 => w.adps().prescaler_32(), + ClockDivider::Factor64 => w.adps().prescaler_64(), + ClockDivider::Factor128 => w.adps().prescaler_128(), + } + }); + } + }; +} + +pub(crate) use impl_adc_peripheral; diff --git a/mcu/attiny-hal/src/impl/eeprom.rs b/mcu/attiny-hal/src/impl/eeprom.rs new file mode 100644 index 0000000000..4c7c626166 --- /dev/null +++ b/mcu/attiny-hal/src/impl/eeprom.rs @@ -0,0 +1,48 @@ +macro_rules! impl_mod_eeprom { + ( + hal: $($hal:ident)::+, + capacity: $capacity:expr, + addr_width: $addr_width:ty, + addr_reg: $addr_reg:ident $(,)? + ) => { + pub mod eeprom { + //! EEPROM + //! + //! # Example + //! + //! For full source code, please refer to the ATmega EEPROM example: + //! [`atmega2560-eeprom.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-eeprom.rs) + //! + //! ``` + //! const BOOT_COUNT_OFFSET: u16 = 0; + //! + //! let dp = attiny_hal::Peripherals::take().unwrap(); + //! let mut eeprom = Eeprom::new(dp.EEPROM); + //! + //! let mut boot_count = eeprom.read_byte(BOOT_COUNT_OFFSET); + //! boot_count = boot_count.wrapping_add(1); + //! eeprom.write_byte(BOOT_COUNT_OFFSET, boot_count); + //! + //! ufmt::uwriteln!(&mut serial, "Boot count: {}", boot_count).unwrap(); + //! ``` + + pub use avr_hal_generic::eeprom::{EepromOps, OutOfBoundsError}; + + pub type Eeprom = + avr_hal_generic::eeprom::Eeprom<$($hal)::+::Hal, $($hal)::+::pac::EEPROM>; + + avr_hal_generic::impl_eeprom_attiny! { + hal: $($hal)::+::Hal, + peripheral: $($hal)::+::pac::EEPROM, + capacity: $capacity, + addr_width: $addr_width, + set_address: |peripheral, address| { + peripheral.$addr_reg.write(|w| w.bits(address)); + }, + } + } + pub use eeprom::Eeprom; + } +} + +pub(crate) use impl_mod_eeprom; diff --git a/mcu/attiny-hal/src/impl/mod.rs b/mcu/attiny-hal/src/impl/mod.rs new file mode 100644 index 0000000000..4328369349 --- /dev/null +++ b/mcu/attiny-hal/src/impl/mod.rs @@ -0,0 +1,23 @@ +#[cfg(feature = "_peripheral-adc")] +mod adc; +#[cfg(feature = "_peripheral-adc")] +pub(crate) use adc::*; + +mod eeprom; +pub(crate) use eeprom::*; + +mod port; +pub(crate) use port::*; + +#[cfg(feature = "_peripheral-simple-pwm")] +mod simple_pwm; +#[cfg(feature = "_peripheral-simple-pwm")] +pub(crate) use simple_pwm::*; + +#[cfg(feature = "_peripheral-spi")] +mod spi; +#[cfg(feature = "_peripheral-spi")] +pub(crate) use spi::*; + +mod wdt; +pub(crate) use wdt::*; diff --git a/mcu/attiny-hal/src/impl/port.rs b/mcu/attiny-hal/src/impl/port.rs new file mode 100644 index 0000000000..440ff8880c --- /dev/null +++ b/mcu/attiny-hal/src/impl/port.rs @@ -0,0 +1,30 @@ +macro_rules! impl_mod_port { + ($($mod:item)*) => { + pub mod port { + //! Port + //! + //! # Example + //! + //! For full source code, please refer to the ATmega port example: + //! [`atmega2560-blink.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-blink.rs) + //! + //! ``` + //! let dp = attiny_hal::Peripherals::take().unwrap(); + //! let pins = attiny_hal::pins!(dp); + //! + //! let mut led = pins.pb2.into_output(); + //! + //! loop { + //! led.toggle(); + //! delay_ms(1000); + //! } + //! ``` + + $($mod)* + } + + pub use {pac::Peripherals, port::Pins, port::pins}; + } +} + +pub(crate) use impl_mod_port; diff --git a/mcu/attiny-hal/src/impl/simple_pwm.rs b/mcu/attiny-hal/src/impl/simple_pwm.rs new file mode 100644 index 0000000000..3af849d5fd --- /dev/null +++ b/mcu/attiny-hal/src/impl/simple_pwm.rs @@ -0,0 +1,9 @@ +macro_rules! impl_mod_simple_pwm { + ($($mod:item)*) => { + pub mod simple_pwm { + $($mod)* + } + } +} + +pub(crate) use impl_mod_simple_pwm; diff --git a/mcu/attiny-hal/src/impl/spi.rs b/mcu/attiny-hal/src/impl/spi.rs new file mode 100644 index 0000000000..2d1f28ada8 --- /dev/null +++ b/mcu/attiny-hal/src/impl/spi.rs @@ -0,0 +1,65 @@ +macro_rules! impl_mod_spi { + ( + hal: $($hal:ident)::+, + sclk: $($sclk:ident)::+, + mosi: $($mosi:ident)::+, + miso: $($miso:ident)::+, + cs: $($cs:ident)::+ $(,)? + ) => { + pub mod spi { + //! SPI + //! + //! # Example + //! + //! For full source code, please refer to the ATmega SPI example: + //! [`atmega2560-spi-feedback.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs) + //! + //! ``` + //! let dp = attiny_hal::Peripherals::take().unwrap(); + //! let pins = attiny_hal::pins!(dp); + //! + //! let (mut spi, mut cs) = spi::Spi::new( + //! dp.SPI, + //! pins.pa4.into_output(), + //! pins.pa6.into_output(), + //! pins.pa5.into_pull_up_input(), + //! pins.pa3.into_output(), + //! spi::Settings::default(), + //! ); + //! + //! let data_out = b"Hello World!"; + //! let mut data_in = [0u8; 12]; + //! + //! cs.set_low().unwrap(); + //! spi.transfer(&mut data_in, data_out).unwrap(); + //! cs.set_high().unwrap(); + //! + //! ufmt::uwriteln!(&mut serial, "data: {:?}", data_in).unwrap(); + //! ``` + + pub use avr_hal_generic::spi::*; + use $($hal)::+ as hal; + + pub type Spi = avr_hal_generic::spi::Spi< + $($hal)::+::Hal, + $($hal)::+::pac::SPI, + $($sclk)::+, + $($mosi)::+, + $($miso)::+, + $($cs)::+, + >; + + avr_hal_generic::impl_spi! { + hal: $($hal)::+::Hal, + peripheral: $($hal)::+::pac::SPI, + sclk: $($sclk)::+, + mosi: $($mosi)::+, + miso: $($miso)::+, + cs: $($cs)::+, + } + } + pub use spi::Spi; + } +} + +pub(crate) use impl_mod_spi; diff --git a/mcu/attiny-hal/src/impl/wdt.rs b/mcu/attiny-hal/src/impl/wdt.rs new file mode 100644 index 0000000000..5790fd7343 --- /dev/null +++ b/mcu/attiny-hal/src/impl/wdt.rs @@ -0,0 +1,34 @@ +macro_rules! impl_mod_wdt { + ( + hal: $($hal:ident)::+, + wdtcsr_name: $wdtcsr_name:ident $(,)? + ) => { + pub mod wdt { + pub use avr_hal_generic::wdt::{Timeout, WdtOps}; + + avr_hal_generic::impl_wdt! { + hal: $($hal)::+::Hal, + peripheral: $($hal)::+::pac::WDT, + mcusr: $($hal)::+::pac::cpu::MCUSR, + wdtcsr_name: $wdtcsr_name, + timeout: |to, w| match to { + Timeout::Ms16 => w.wdpl().cycles_2k_512k(), + Timeout::Ms32 => w.wdpl().cycles_4k_1024k(), + Timeout::Ms64 => w.wdpl().cycles_8k(), + Timeout::Ms125 => w.wdpl().cycles_16k(), + Timeout::Ms250 => w.wdpl().cycles_32k(), + Timeout::Ms500 => w.wdpl().cycles_64k(), + Timeout::Ms1000 => w.wdpl().cycles_128k(), + Timeout::Ms2000 => w.wdpl().cycles_256k(), + Timeout::Ms4000 => w.wdph().set_bit().wdpl().cycles_2k_512k(), + Timeout::Ms8000 => w.wdph().set_bit().wdpl().cycles_4k_1024k(), + }, + } + + pub type Wdt = avr_hal_generic::wdt::Wdt<$($hal)::+::Hal, $($hal)::+::pac::WDT>; + } + pub use wdt::Wdt; + }; +} + +pub(crate) use impl_mod_wdt; diff --git a/mcu/attiny-hal/src/lib.rs b/mcu/attiny-hal/src/lib.rs index a8bf1541e0..026c08d28b 100644 --- a/mcu/attiny-hal/src/lib.rs +++ b/mcu/attiny-hal/src/lib.rs @@ -3,28 +3,17 @@ //! `attiny-hal` //! ============= //! Common HAL (hardware abstraction layer) for ATtiny* microcontrollers. -//! -//! **Note**: This version of the documentation was built for -#![cfg_attr(feature = "attiny85", doc = "**ATtiny85**.")] -#![cfg_attr(feature = "attiny88", doc = "**ATtiny88**.")] -#![cfg_attr(feature = "attiny167", doc = "**ATtiny167**.")] -#![cfg_attr(feature = "attiny2313", doc = "**ATtiny2313**.")] -//! This means that only items which are available for this MCU are visible. If you are using -//! a different chip, try building the documentation locally with: -//! -//! ```text -//! cargo doc --features --open -//! ``` #[cfg(all( - not(feature = "device-selected"), + not(feature = "_mcu-selected"), not(feature = "disable-device-selection-error") ))] compile_error!( - "This crate requires you to specify your target chip as a feature. + "You must specify your target chips as a feature. - Please select one of the following + Please select at least one of the following features + * attiny84 * attiny85 * attiny88 * attiny167 @@ -32,101 +21,24 @@ compile_error!( " ); -/// Reexport of `attiny167` from `avr-device` -/// -#[cfg(feature = "attiny167")] -pub use avr_device::attiny167 as pac; -/// Reexport of `attiny2313` from `avr-device` -/// -#[cfg(feature = "attiny2313")] -pub use avr_device::attiny2313 as pac; -/// Reexport of `attiny84` from `avr-device` -/// -#[cfg(feature = "attiny84")] -pub use avr_device::attiny84 as pac; -/// Reexport of `attiny85` from `avr-device` -/// -#[cfg(feature = "attiny85")] -pub use avr_device::attiny85 as pac; -/// Reexport of `attiny88` from `avr-device` -/// -#[cfg(feature = "attiny88")] -pub use avr_device::attiny88 as pac; - /// See [`avr_device::entry`](https://docs.rs/avr-device/latest/avr_device/attr.entry.html). #[cfg(feature = "rt")] pub use avr_device::entry; -#[cfg(feature = "device-selected")] -pub use pac::Peripherals; - pub use avr_hal_generic::clock; pub use avr_hal_generic::delay; pub use avr_hal_generic::prelude; -// ATtiny2313 does not have ADC and will not compile with this module -#[cfg(all(feature = "device-selected", not(feature = "attiny2313")))] -pub mod adc; -#[cfg(all(feature = "device-selected", not(feature = "attiny2313")))] -pub use adc::Adc; - -#[cfg(feature = "device-selected")] -pub mod port; -#[cfg(feature = "device-selected")] -pub use port::Pins; - -#[cfg(feature = "device-selected")] -pub mod simple_pwm; - -#[cfg(feature = "device-selected")] -pub mod wdt; -#[cfg(feature = "device-selected")] -pub use wdt::Wdt; - -#[cfg(feature = "device-selected")] -pub mod eeprom; -#[cfg(feature = "device-selected")] -pub use eeprom::Eeprom; - -#[cfg(feature = "device-selected")] -pub mod spi; -#[cfg(feature = "device-selected")] -pub use spi::Spi; +pub(crate) mod r#impl; -pub struct Attiny; +#[cfg(feature = "_mcu-attiny167")] +pub mod attiny167; +#[cfg(feature = "_mcu-attiny2313")] +pub mod attiny2313; +#[cfg(feature = "_mcu-attiny84")] +pub mod attiny84; +#[cfg(feature = "_mcu-attiny85")] +pub mod attiny85; +#[cfg(feature = "_mcu-attiny88")] +pub mod attiny88; -#[cfg(feature = "attiny84")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTA, $p.PORTB) - }; -} -#[cfg(feature = "attiny85")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTB) - }; -} -#[cfg(feature = "attiny88")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTA, $p.PORTB, $p.PORTC, $p.PORTD) - }; -} -#[cfg(feature = "attiny167")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTA, $p.PORTB) - }; -} -#[cfg(feature = "attiny2313")] -#[macro_export] -macro_rules! pins { - ($p:expr) => { - $crate::Pins::new($p.PORTA, $p.PORTB, $p.PORTD) - }; -} diff --git a/mcu/attiny-hal/src/port.rs b/mcu/attiny-hal/src/port.rs deleted file mode 100644 index eaa0818ff1..0000000000 --- a/mcu/attiny-hal/src/port.rs +++ /dev/null @@ -1,62 +0,0 @@ -//! Port -//! -//! # Example -//! -//! For full source code, please refer to the ATmega port example: -//! [`atmega2560-blink.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-blink.rs) -//! -//! ``` -//! let dp = attiny_hal::Peripherals::take().unwrap(); -//! let pins = attiny_hal::pins!(dp); -//! -//! let mut led = pins.pb2.into_output(); -//! -//! loop { -//! led.toggle(); -//! delay_ms(1000); -//! } -//! ``` - -pub use avr_hal_generic::port::{mode, PinMode, PinOps}; - -#[cfg(feature = "attiny2313")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6], - } -} - -#[cfg(feature = "attiny167")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - } -} - -#[cfg(feature = "attiny84")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3, 4, 5, 6, 7], - B: crate::pac::PORTB = [0, 1, 2, 3], - } -} - -#[cfg(feature = "attiny85")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5], - } -} - -#[cfg(feature = "attiny88")] -avr_hal_generic::impl_port_traditional! { - enum Ports { - A: crate::pac::PORTA = [0, 1, 2, 3], - B: crate::pac::PORTB = [0, 1, 2, 3, 4, 5, 6, 7], - C: crate::pac::PORTC = [0, 1, 2, 3, 4, 5, 6, 7], - D: crate::pac::PORTD = [0, 1, 2, 3, 4, 5, 6, 7], - } -} diff --git a/mcu/attiny-hal/src/simple_pwm.rs b/mcu/attiny-hal/src/simple_pwm.rs deleted file mode 100644 index f16a89c9c0..0000000000 --- a/mcu/attiny-hal/src/simple_pwm.rs +++ /dev/null @@ -1,217 +0,0 @@ -pub use avr_hal_generic::simple_pwm::{IntoPwmPin, Prescaler, PwmPinOps}; - -#[cfg(any(feature = "attiny85", feature = "attiny84", feature = "attiny88"))] -use crate::port::*; - -#[cfg(feature = "attiny84")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PB2`, `PA7`) - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - PB2: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); - }, - }, - - PA7: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "attiny84")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PA6`, 'PA5') - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01)); - - tim.tccr1b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - }); - }, - pins: { - PA6: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().bits(0b10)); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - - PA5: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().bits(0b10)); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "attiny85")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC0` for PWM (pins `PB0`, `PB1`) - /// - /// # Example - /// ``` - /// let mut timer0 = Timer0Pwm::new(dp.TC0, Prescaler::Prescale64); - /// - /// let mut d0 = pins.d0.into_output().into_pwm(&mut timer0); - /// let mut d1 = pins.d1.into_output().into_pwm(&mut timer0); - /// - /// d0.set_duty(128); - /// d0.enable(); - /// ``` - pub struct Timer0Pwm { - timer: crate::pac::TC0, - init: |tim, prescaler| { - tim.tccr0a.modify(|_r, w| w.wgm0().pwm_fast()); - tim.tccr0b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs0().direct(), - Prescaler::Prescale8 => w.cs0().prescale_8(), - Prescaler::Prescale64 => w.cs0().prescale_64(), - Prescaler::Prescale256 => w.cs0().prescale_256(), - Prescaler::Prescale1024 => w.cs0().prescale_1024(), - }); - }, - pins: { - PB0: { - ocr: ocr0a, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0a().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0a().disconnected()); - }, - }, - - PB1: { - ocr: ocr0b, - into_pwm: |tim| if enable { - tim.tccr0a.modify(|_r, w| w.com0b().match_clear()); - } else { - tim.tccr0a.modify(|_r, w| w.com0b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "attiny85")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PB4`) - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d4 = pins.d4.into_output().into_pwm(&mut timer1); - /// - /// d4.set_duty(128); - /// d4.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.gtccr.modify(|_, w| w.pwm1b().bit(true)); - - tim.tccr1.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - }); - }, - pins: { - PB4: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.gtccr.modify(|_, w| w.com1b().bits(0b10)); - } else { - tim.gtccr.modify(|_, w| w.com1b().disconnected()); - }, - }, - }, - } -} - -#[cfg(feature = "attiny88")] -avr_hal_generic::impl_simple_pwm! { - /// Use `TC1` for PWM (pins `PB1`, 'PB2') - /// - /// # Example - /// ``` - /// let mut timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale64); - /// - /// let mut d9 = pins.d9.into_output().into_pwm(&mut timer1); - /// let mut d10 = pins.d10.into_output().into_pwm(&mut timer1); - /// - /// d9.set_duty(128); - /// d9.enable(); - /// ``` - pub struct Timer1Pwm { - timer: crate::pac::TC1, - init: |tim, prescaler| { - tim.tccr1a.modify(|_, w| w.wgm1().bits(0b01)); - tim.tccr1b.modify(|_, w| w.wgm1().bits(0b01)); - - tim.tccr1b.modify(|_r, w| match prescaler { - Prescaler::Direct => w.cs1().direct(), - Prescaler::Prescale8 => w.cs1().prescale_8(), - Prescaler::Prescale64 => w.cs1().prescale_64(), - Prescaler::Prescale256 => w.cs1().prescale_256(), - Prescaler::Prescale1024 => w.cs1().prescale_1024(), - }); - }, - pins: { - PB1: { - ocr: ocr1a, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1a().bits(0b10)); - } else { - tim.tccr1a.modify(|_, w| w.com1a().disconnected()); - }, - }, - - PB2: { - ocr: ocr1b, - into_pwm: |tim| if enable { - tim.tccr1a.modify(|_, w| w.com1b().bits(0b10)); - } else { - tim.tccr1a.modify(|_, w| w.com1b().disconnected()); - }, - }, - }, - } -} diff --git a/mcu/attiny-hal/src/spi.rs b/mcu/attiny-hal/src/spi.rs deleted file mode 100644 index 65ae277263..0000000000 --- a/mcu/attiny-hal/src/spi.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! SPI -//! -//! # Example -//! -//! For full source code, please refer to the ATmega SPI example: -//! [`atmega2560-spi-feedback.rs`](https://github.com/Rahix/avr-hal/blob/main/examples/atmega2560/src/bin/atmega2560-spi-feedback.rs) -//! -//! ``` -//! let dp = attiny_hal::Peripherals::take().unwrap(); -//! let pins = attiny_hal::pins!(dp); -//! -//! let (mut spi, mut cs) = spi::Spi::new( -//! dp.SPI, -//! pins.pa4.into_output(), -//! pins.pa6.into_output(), -//! pins.pa5.into_pull_up_input(), -//! pins.pa3.into_output(), -//! spi::Settings::default(), -//! ); -//! -//! let data_out = b"Hello World!"; -//! let mut data_in = [0u8; 12]; -//! -//! cs.set_low().unwrap(); -//! spi.transfer(&mut data_in, data_out).unwrap(); -//! cs.set_high().unwrap(); -//! -//! ufmt::uwriteln!(&mut serial, "data: {:?}", data_in).unwrap(); -//! ``` - - -#[allow(unused_imports)] -use crate::port; -pub use avr_hal_generic::spi::*; - -#[cfg(feature = "attiny88")] -pub type Spi = avr_hal_generic::spi::Spi< - crate::Attiny, - crate::pac::SPI, - port::PB5, - port::PB3, - port::PB4, - port::PB2, ->; -#[cfg(feature = "attiny88")] -avr_hal_generic::impl_spi! { - hal: crate::Attiny, - peripheral: crate::pac::SPI, - sclk: port::PB5, - mosi: port::PB3, - miso: port::PB4, - cs: port::PB2, -} - -#[cfg(feature = "attiny167")] -pub type Spi = avr_hal_generic::spi::Spi< - crate::Attiny, - crate::pac::SPI, - port::PA5, - port::PA4, - port::PA2, - port::PA6, ->; -#[cfg(feature = "attiny167")] -avr_hal_generic::impl_spi! { - hal: crate::Attiny, - peripheral: crate::pac::SPI, - sclk: port::PA5, - mosi: port::PA4, - miso: port::PA2, - cs: port::PA6, -} diff --git a/mcu/attiny-hal/src/wdt.rs b/mcu/attiny-hal/src/wdt.rs deleted file mode 100644 index 1693051483..0000000000 --- a/mcu/attiny-hal/src/wdt.rs +++ /dev/null @@ -1,44 +0,0 @@ -#[allow(unused_imports)] -pub use avr_hal_generic::wdt::{Timeout, WdtOps}; - -pub type Wdt = avr_hal_generic::wdt::Wdt; - -#[cfg(any(feature = "attiny85", feature = "attiny167", feature = "attiny2313"))] -avr_hal_generic::impl_wdt! { - hal: crate::Attiny, - peripheral: crate::pac::WDT, - mcusr: crate::pac::cpu::MCUSR, - wdtcsr_name: wdtcr, - timeout: |to, w| match to { - Timeout::Ms16 => w.wdpl().cycles_2k_512k(), - Timeout::Ms32 => w.wdpl().cycles_4k_1024k(), - Timeout::Ms64 => w.wdpl().cycles_8k(), - Timeout::Ms125 => w.wdpl().cycles_16k(), - Timeout::Ms250 => w.wdpl().cycles_32k(), - Timeout::Ms500 => w.wdpl().cycles_64k(), - Timeout::Ms1000 => w.wdpl().cycles_128k(), - Timeout::Ms2000 => w.wdpl().cycles_256k(), - Timeout::Ms4000 => w.wdph().set_bit().wdpl().cycles_2k_512k(), - Timeout::Ms8000 => w.wdph().set_bit().wdpl().cycles_4k_1024k(), - }, -} - -#[cfg(any(feature = "attiny84", feature = "attiny88"))] -avr_hal_generic::impl_wdt! { - hal: crate::Attiny, - peripheral: crate::pac::WDT, - mcusr: crate::pac::cpu::MCUSR, - wdtcsr_name: wdtcsr, - timeout: |to, w| match to { - Timeout::Ms16 => w.wdpl().cycles_2k_512k(), - Timeout::Ms32 => w.wdpl().cycles_4k_1024k(), - Timeout::Ms64 => w.wdpl().cycles_8k(), - Timeout::Ms125 => w.wdpl().cycles_16k(), - Timeout::Ms250 => w.wdpl().cycles_32k(), - Timeout::Ms500 => w.wdpl().cycles_64k(), - Timeout::Ms1000 => w.wdpl().cycles_128k(), - Timeout::Ms2000 => w.wdpl().cycles_256k(), - Timeout::Ms4000 => w.wdph().set_bit().wdpl().cycles_2k_512k(), - Timeout::Ms8000 => w.wdph().set_bit().wdpl().cycles_4k_1024k(), - }, -}