From 4cca1215d158c742e23e6538a4d1a6a82b2cf30c Mon Sep 17 00:00:00 2001 From: Bradley Harden Date: Sun, 20 Jun 2021 09:38:07 -0400 Subject: [PATCH] Port pygamer to the v2 APIs Port the pygamer BSP to the `gpio::v2` and `sercom::v2::spi` APIs. While implementing this, I discovered that the pygamer uses an undocumented combination of pins for `Sercom1`. It uses PA17, PB22 & PB23. The datasheet indicates that PA17 is in `IoSet1`, while the other two pins are in `IoSet3`. It shouldn't be possible to use these together, but it appears there is an undocumented `IoSet`. Add this as `IoSet5` for `Sercom1`. Also fix a warning from a trinket_m0 example. --- boards/pygamer/examples/blinky_basic.rs | 7 +- boards/pygamer/examples/button_rtic.rs | 12 +- boards/pygamer/examples/clock_out.rs | 8 +- boards/pygamer/examples/ferris_img.rs | 6 +- .../pygamer/examples/neopixel_adc_battery.rs | 9 +- boards/pygamer/examples/neopixel_adc_light.rs | 10 +- boards/pygamer/examples/neopixel_button.rs | 13 +- boards/pygamer/examples/neopixel_easing.rs | 7 +- .../pygamer/examples/neopixel_rainbow_spi.rs | 41 +- .../examples/neopixel_rainbow_timer.rs | 7 +- boards/pygamer/examples/neopixel_tilt.rs | 8 +- boards/pygamer/examples/pwm_tc4.rs | 8 +- boards/pygamer/examples/pwm_tcc0.rs | 8 +- boards/pygamer/examples/qspi.rs | 7 +- boards/pygamer/examples/sd_card.rs | 11 +- boards/pygamer/examples/timer.rs | 7 +- boards/pygamer/examples/usb_poll.rs | 7 +- boards/pygamer/examples/usb_serial.rs | 7 +- boards/pygamer/src/buttons.rs | 10 +- boards/pygamer/src/lib.rs | 18 +- boards/pygamer/src/pins.rs | 674 ++++++++++-------- boards/trinket_m0/examples/eic.rs | 1 - crates.json | 2 +- hal/src/thumbv7em/sercom/v2/impl_pad.rs | 7 + 24 files changed, 493 insertions(+), 402 deletions(-) diff --git a/boards/pygamer/examples/blinky_basic.rs b/boards/pygamer/examples/blinky_basic.rs index a353629af817..0b5535ee979c 100644 --- a/boards/pygamer/examples/blinky_basic.rs +++ b/boards/pygamer/examples/blinky_basic.rs @@ -5,7 +5,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins, RedLed}; use hal::clock::GenericClockController; use hal::delay::Delay; @@ -27,8 +28,8 @@ fn main() -> ! { let mut delay = Delay::new(core.SYST, &mut clocks); delay.delay_ms(400u16); - let mut pins = Pins::new(peripherals.PORT); - let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + let pins = Pins::new(peripherals.PORT); + let mut red_led: RedLed = pins.d13.into(); let mut wdt = Watchdog::new(peripherals.WDT); wdt.start(WatchdogTimeout::Cycles256 as u8); diff --git a/boards/pygamer/examples/button_rtic.rs b/boards/pygamer/examples/button_rtic.rs index b75bef51385d..3265571db22e 100644 --- a/boards/pygamer/examples/button_rtic.rs +++ b/boards/pygamer/examples/button_rtic.rs @@ -3,17 +3,17 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, pins::ButtonReader, pins::Keys, Pins}; +use pygamer as bsp; +use bsp::{hal, Pins, RedLed, ButtonReader, Keys}; use hal::clock::GenericClockController; -use hal::gpio::{OpenDrain, Output, Pa23}; use hal::prelude::*; use rtic::app; #[app(device = crate::hal::pac, peripherals = true)] const APP: () = { struct Resources { - red_led: Pa23>, + red_led: RedLed, timer: hal::timer::TimerCounter3, buttons: ButtonReader, } @@ -50,7 +50,7 @@ const APP: () = { &mut device.NVMCTRL, ); - let mut pins = Pins::new(device.PORT).split(); + let pins = Pins::new(device.PORT).split(); let gclk0 = clocks.gclk0(); let timer_clock = clocks.tc2_tc3(&gclk0).unwrap(); @@ -61,8 +61,8 @@ const APP: () = { tc3.enable_interrupt(); init::LateResources { - buttons: pins.buttons.init(&mut pins.port), - red_led: pins.led_pin.into_open_drain_output(&mut pins.port), + buttons: pins.buttons.init(), + red_led: pins.led_pin, timer: tc3, } } diff --git a/boards/pygamer/examples/clock_out.rs b/boards/pygamer/examples/clock_out.rs index 10dc0e313e48..b72734a096a7 100644 --- a/boards/pygamer/examples/clock_out.rs +++ b/boards/pygamer/examples/clock_out.rs @@ -5,11 +5,13 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::clock::GenericClockController; use pac::gclk::genctrl::SRC_A::DPLL0; use pac::gclk::pchctrl::GEN_A::GCLK2; +use hal::gpio::v2::AlternateM; use pac::Peripherals; #[entry] @@ -22,12 +24,12 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT); + let pins = Pins::new(peripherals.PORT); //3mhz let _gclk2 = clocks .configure_gclk_divider_and_source(GCLK2, 40, DPLL0, false) .unwrap(); - pins.d5.into_function_m(&mut pins.port); + pins.d5.into_mode::(); loop {} } diff --git a/boards/pygamer/examples/ferris_img.rs b/boards/pygamer/examples/ferris_img.rs index 450f4a1a35ad..a241ae797493 100644 --- a/boards/pygamer/examples/ferris_img.rs +++ b/boards/pygamer/examples/ferris_img.rs @@ -12,7 +12,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use embedded_graphics::pixelcolor::{Rgb565, RgbColor}; use embedded_graphics::prelude::*; @@ -32,7 +33,7 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); let mut delay = hal::delay::Delay::new(core.SYST, &mut clocks); let (mut display, _backlight) = pins @@ -43,7 +44,6 @@ fn main() -> ! { &mut peripherals.MCLK, peripherals.TC2, &mut delay, - &mut pins.port, ) .unwrap(); diff --git a/boards/pygamer/examples/neopixel_adc_battery.rs b/boards/pygamer/examples/neopixel_adc_battery.rs index a46d5653be33..3e9447f867c4 100644 --- a/boards/pygamer/examples/neopixel_adc_battery.rs +++ b/boards/pygamer/examples/neopixel_adc_battery.rs @@ -8,7 +8,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::adc::Adc; use hal::pac::gclk::pchctrl::GEN_A::GCLK11; @@ -29,14 +30,14 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); let mut adc0 = Adc::adc0(peripherals.ADC0, &mut peripherals.MCLK, &mut clocks, GCLK11); - let mut battery = pins.battery.init(&mut pins.port); + let mut battery = pins.battery.init(); // neopixels let timer = SpinTimer::new(4); - let mut neopixel = pins.neopixel.init(timer, &mut pins.port); + let mut neopixel = pins.neopixel.init(timer); let mut delay = Delay::new(core.SYST, &mut clocks); diff --git a/boards/pygamer/examples/neopixel_adc_light.rs b/boards/pygamer/examples/neopixel_adc_light.rs index ef3aaa9b66cf..3d66b3b886d1 100644 --- a/boards/pygamer/examples/neopixel_adc_light.rs +++ b/boards/pygamer/examples/neopixel_adc_light.rs @@ -8,10 +8,12 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use embedded_hal::digital::v1_compat::OldOutputPin; use hal::adc::Adc; +use hal::gpio::v2::AlternateB; use hal::prelude::*; use hal::timer::SpinTimer; use hal::{clock::GenericClockController, delay::Delay}; @@ -32,13 +34,13 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT); + let pins = Pins::new(peripherals.PORT); let mut adc1 = Adc::adc1(peripherals.ADC1, &mut peripherals.MCLK, &mut clocks, GCLK11); - let mut light = pins.light.into_function_b(&mut pins.port); + let mut light = pins.light.into_mode::(); let timer = SpinTimer::new(4); - let neopixel_pin: OldOutputPin<_> = pins.neopixel.into_push_pull_output(&mut pins.port).into(); + let neopixel_pin: OldOutputPin<_> = pins.neopixel.into_push_pull_output().into(); let mut neopixel = ws2812::Ws2812::new(timer, neopixel_pin); let mut delay = Delay::new(core.SYST, &mut clocks); diff --git a/boards/pygamer/examples/neopixel_button.rs b/boards/pygamer/examples/neopixel_button.rs index 52b08cc8b89f..f42a94db3b43 100644 --- a/boards/pygamer/examples/neopixel_button.rs +++ b/boards/pygamer/examples/neopixel_button.rs @@ -12,12 +12,13 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, pins::Keys, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins, Keys}; +use bsp::util::map_from; use hal::adc::Adc; use hal::prelude::*; use hal::timer::SpinTimer; -use hal::util::map_from; use hal::{clock::GenericClockController, delay::Delay}; use pac::gclk::pchctrl::GEN_A::GCLK11; use pac::{CorePeripherals, Peripherals}; @@ -38,17 +39,17 @@ fn main() -> ! { ); let mut delay = Delay::new(core_peripherals.SYST, &mut clocks); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); - let mut buttons = pins.buttons.init(&mut pins.port); + let mut buttons = pins.buttons.init(); let mut adc1 = Adc::adc1(peripherals.ADC1, &mut peripherals.MCLK, &mut clocks, GCLK11); - let mut joystick = pins.joystick.init(&mut pins.port); + let mut joystick = pins.joystick.init(); // neopixels let timer = SpinTimer::new(4); - let mut neopixel = pins.neopixel.init(timer, &mut pins.port); + let mut neopixel = pins.neopixel.init(timer); const NUM_LEDS: usize = 5; let mut pos_button: usize = 2; diff --git a/boards/pygamer/examples/neopixel_easing.rs b/boards/pygamer/examples/neopixel_easing.rs index 3a100f068000..788b23f6dfd7 100644 --- a/boards/pygamer/examples/neopixel_easing.rs +++ b/boards/pygamer/examples/neopixel_easing.rs @@ -8,7 +8,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use core::f32::consts::FRAC_PI_2; use hal::clock::GenericClockController; @@ -33,10 +34,10 @@ fn main() -> ! { &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); let timer = SpinTimer::new(4); - let mut neopixel = pins.neopixel.init(timer, &mut pins.port); + let mut neopixel = pins.neopixel.init(timer); let mut delay = Delay::new(core.SYST, &mut clocks); let trng = Trng::new(&mut peripherals.MCLK, peripherals.TRNG); diff --git a/boards/pygamer/examples/neopixel_rainbow_spi.rs b/boards/pygamer/examples/neopixel_rainbow_spi.rs index 4390ec1fad4e..1829aa842b51 100644 --- a/boards/pygamer/examples/neopixel_rainbow_spi.rs +++ b/boards/pygamer/examples/neopixel_rainbow_spi.rs @@ -9,11 +9,11 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::prelude::*; -use hal::sercom::PadPin; -use hal::time::MegaHertz; +use hal::sercom::v2::spi; use hal::{clock::GenericClockController, delay::Delay}; use pac::{CorePeripherals, Peripherals}; use smart_leds::hsv::{hsv2rgb, Hsv}; @@ -31,32 +31,20 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT); + let pins = Pins::new(peripherals.PORT); + let mclk = &mut peripherals.MCLK; let gclk = clocks.gclk0(); - - let spi: hal::sercom::SPIMaster2< - hal::sercom::Sercom2Pad0>, - hal::sercom::Sercom2Pad3>, - hal::sercom::Sercom2Pad1>, - > = hal::sercom::SPIMaster2::new( - &clocks.sercom2_core(&gclk).unwrap(), - MegaHertz(3), - embedded_hal::spi::Mode { - phase: embedded_hal::spi::Phase::CaptureOnFirstTransition, - polarity: embedded_hal::spi::Polarity::IdleLow, - }, - peripherals.SERCOM2, - &mut peripherals.MCLK, - ( - pins.sda.into_pad(&mut pins.port), - pins.neopixel.into_pad(&mut pins.port), - pins.scl.into_pad(&mut pins.port), - ), - ); - + let clock = &clocks.sercom2_core(&gclk).unwrap(); + let sercom2 = peripherals.SERCOM2; + let pads = spi::Pads::default() + .data_in(pins.sda) + .data_out(pins.neopixel) + .sclk(pins.scl); + let spi = spi::Config::new(mclk, sercom2, pads, clock.freq()) + .baud(3.mhz()) + .enable(); let mut neopixel = ws2812::Ws2812::new(spi); let mut delay = Delay::new(core.SYST, &mut clocks); - loop { for j in 0..255u8 { let colors = [ @@ -88,7 +76,6 @@ fn main() -> ! { val: 32, }), ]; - neopixel.write(colors.iter().cloned()).unwrap(); delay.delay_ms(5u8); } diff --git a/boards/pygamer/examples/neopixel_rainbow_timer.rs b/boards/pygamer/examples/neopixel_rainbow_timer.rs index d1ae56fa291a..d7e60aab1cd4 100644 --- a/boards/pygamer/examples/neopixel_rainbow_timer.rs +++ b/boards/pygamer/examples/neopixel_rainbow_timer.rs @@ -11,7 +11,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, Pins}; use hal::pac::{CorePeripherals, Peripherals}; use hal::prelude::*; @@ -30,14 +31,14 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); let gclk0 = clocks.gclk0(); let timer_clock = clocks.tc2_tc3(&gclk0).unwrap(); let mut timer = TimerCounter::tc3_(&timer_clock, peripherals.TC3, &mut peripherals.MCLK); timer.start(3.mhz()); - let mut neopixel = pins.neopixel.init(timer, &mut pins.port); + let mut neopixel = pins.neopixel.init(timer); let mut delay = Delay::new(core.SYST, &mut clocks); loop { diff --git a/boards/pygamer/examples/neopixel_tilt.rs b/boards/pygamer/examples/neopixel_tilt.rs index 229b334023aa..b5f0e8034930 100644 --- a/boards/pygamer/examples/neopixel_tilt.rs +++ b/boards/pygamer/examples/neopixel_tilt.rs @@ -9,7 +9,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::prelude::*; use hal::time::KiloHertz; @@ -34,11 +35,11 @@ fn main() -> ! { ); let mut delay = Delay::new(core_peripherals.SYST, &mut clocks); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); // neopixels let timer = SpinTimer::new(4); - let mut neopixel = pins.neopixel.init(timer, &mut pins.port); + let mut neopixel = pins.neopixel.init(timer); // i2c let i2c = pins.i2c.init( @@ -46,7 +47,6 @@ fn main() -> ! { KiloHertz(400), peripherals.SERCOM2, &mut peripherals.MCLK, - &mut pins.port, ); let mut lis3dh = Lis3dh::new(i2c, 0x19).unwrap(); diff --git a/boards/pygamer/examples/pwm_tc4.rs b/boards/pygamer/examples/pwm_tc4.rs index dc704761eaf7..291ba84b91c9 100644 --- a/boards/pygamer/examples/pwm_tc4.rs +++ b/boards/pygamer/examples/pwm_tc4.rs @@ -5,11 +5,13 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use core::f32::consts::FRAC_PI_2; use hal::clock::GenericClockController; use hal::delay::Delay; +use hal::gpio::v2::AlternateE; use hal::prelude::*; use hal::pwm::{Pwm4, TC4Pinout}; use micromath::F32Ext; @@ -30,7 +32,7 @@ fn main() -> ! { let mut delay = Delay::new(core.SYST, &mut clocks); delay.delay_ms(400u16); - let mut pins = Pins::new(peripherals.PORT); + let pins = Pins::new(peripherals.PORT); let gclk = clocks.gclk0(); @@ -38,7 +40,7 @@ fn main() -> ! { &clocks.tc4_tc5(&gclk).unwrap(), 1.khz(), peripherals.TC4, - TC4Pinout::Pa23(pins.d13.into_function_e(&mut pins.port)), + TC4Pinout::Pa23(pins.d13.into_mode::()), &mut peripherals.MCLK, ); let max_duty = pwm0.get_max_duty(); diff --git a/boards/pygamer/examples/pwm_tcc0.rs b/boards/pygamer/examples/pwm_tcc0.rs index 74eda7b86673..09e1acfb47a5 100644 --- a/boards/pygamer/examples/pwm_tcc0.rs +++ b/boards/pygamer/examples/pwm_tcc0.rs @@ -5,11 +5,13 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use core::f32::consts::FRAC_PI_2; use hal::clock::GenericClockController; use hal::delay::Delay; +use hal::gpio::v2::AlternateG; use hal::prelude::*; use hal::pwm::{Channel, TCC0Pinout, Tcc0Pwm}; use micromath::F32Ext; @@ -30,7 +32,7 @@ fn main() -> ! { let mut delay = Delay::new(core.SYST, &mut clocks); delay.delay_ms(400u16); - let mut pins = Pins::new(peripherals.PORT); + let pins = Pins::new(peripherals.PORT); let gclk = clocks.gclk0(); @@ -38,7 +40,7 @@ fn main() -> ! { &clocks.tcc0_tcc1(&gclk).unwrap(), 1.khz(), peripherals.TCC0, - TCC0Pinout::Pa23(pins.d13.into_function_g(&mut pins.port)), + TCC0Pinout::Pa23(pins.d13.into_mode::()), &mut peripherals.MCLK, ); let max_duty = pwm0.get_max_duty(); diff --git a/boards/pygamer/examples/qspi.rs b/boards/pygamer/examples/qspi.rs index 20e6eb929234..df192fcb9241 100644 --- a/boards/pygamer/examples/qspi.rs +++ b/boards/pygamer/examples/qspi.rs @@ -24,7 +24,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::clock::GenericClockController; use hal::delay::Delay; @@ -45,11 +46,11 @@ fn main() -> ! { ); let mut delay = Delay::new(core.SYST, &mut clocks); - let mut sets = Pins::new(peripherals.PORT).split(); + let sets = Pins::new(peripherals.PORT).split(); let mut flash = sets .flash - .init(&mut peripherals.MCLK, &mut sets.port, peripherals.QSPI); + .init(&mut peripherals.MCLK, peripherals.QSPI); // Startup delay. Can't find documented but Adafruit use 5ms delay.delay_ms(5u8); diff --git a/boards/pygamer/examples/sd_card.rs b/boards/pygamer/examples/sd_card.rs index 1b9af7bbe206..e08532bb533b 100644 --- a/boards/pygamer/examples/sd_card.rs +++ b/boards/pygamer/examples/sd_card.rs @@ -16,7 +16,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use embedded_graphics::pixelcolor::{Rgb565, RgbColor}; use embedded_graphics::prelude::*; @@ -43,17 +44,16 @@ fn main() -> ! { ); let mut delay = Delay::new(core.SYST, &mut clocks); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); - let mut red_led = pins.led_pin.into_open_drain_output(&mut pins.port); + let mut red_led = pins.led_pin; - let sdmmc_cs: OldOutputPin<_> = pins.sd_cs_pin.into_push_pull_output(&mut pins.port).into(); + let sdmmc_cs: OldOutputPin<_> = pins.sd_cs_pin.into_push_pull_output().into(); let sdmmc_spi = pins.spi.init( &mut clocks, MegaHertz(3), peripherals.SERCOM1, &mut peripherals.MCLK, - &mut pins.port, ); let mut cont = embedded_sdmmc::Controller::new(embedded_sdmmc::SdMmcSpi::new(sdmmc_spi, sdmmc_cs), Clock); @@ -66,7 +66,6 @@ fn main() -> ! { &mut peripherals.MCLK, peripherals.TC2, &mut delay, - &mut pins.port, ) .unwrap(); diff --git a/boards/pygamer/examples/timer.rs b/boards/pygamer/examples/timer.rs index 4ba12d28f0b9..d622102cd2cc 100644 --- a/boards/pygamer/examples/timer.rs +++ b/boards/pygamer/examples/timer.rs @@ -6,7 +6,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::clock::GenericClockController; use hal::prelude::*; @@ -24,13 +25,13 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT); + let pins = Pins::new(peripherals.PORT); let gclk0 = clocks.gclk0(); let timer_clock = clocks.tc2_tc3(&gclk0).unwrap(); let mut timer = TimerCounter::tc3_(&timer_clock, peripherals.TC3, &mut peripherals.MCLK); timer.start(250.khz()); - let mut d5 = pins.d5.into_push_pull_output(&mut pins.port); + let mut d5 = pins.d5.into_push_pull_output(); //50% duty cycle, so 500khz period loop { diff --git a/boards/pygamer/examples/usb_poll.rs b/boards/pygamer/examples/usb_poll.rs index 74a43c8f085e..08af3c25694b 100644 --- a/boards/pygamer/examples/usb_poll.rs +++ b/boards/pygamer/examples/usb_poll.rs @@ -6,7 +6,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use hal::clock::GenericClockController; use hal::prelude::*; @@ -26,14 +27,14 @@ fn main() -> ! { &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); let usb_bus = pins .usb .init(peripherals.USB, &mut clocks, &mut peripherals.MCLK); let mut serial = SerialPort::new(&usb_bus); - let mut led = pins.led_pin.into_open_drain_output(&mut pins.port); + let mut led = pins.led_pin; let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) .manufacturer("Fake company") diff --git a/boards/pygamer/examples/usb_serial.rs b/boards/pygamer/examples/usb_serial.rs index 30fc1a7a57e9..8990a3684137 100644 --- a/boards/pygamer/examples/usb_serial.rs +++ b/boards/pygamer/examples/usb_serial.rs @@ -16,7 +16,8 @@ #[cfg(not(feature = "panic_led"))] use panic_halt as _; -use pygamer::{self as hal, entry, pac, Pins}; +use pygamer as bsp; +use bsp::{hal, entry, pac, Pins}; use cortex_m::interrupt::free as disable_interrupts; use cortex_m::peripheral::NVIC; @@ -40,10 +41,10 @@ fn main() -> ! { &mut peripherals.OSCCTRL, &mut peripherals.NVMCTRL, ); - let mut pins = Pins::new(peripherals.PORT).split(); + let pins = Pins::new(peripherals.PORT).split(); let timer = SpinTimer::new(4); - let mut neopixel = pins.neopixel.init(timer, &mut pins.port); + let mut neopixel = pins.neopixel.init(timer); let _ = neopixel.write((0..5).map(|_| RGB8::default())); diff --git a/boards/pygamer/src/buttons.rs b/boards/pygamer/src/buttons.rs index 39672f809c94..c2c61ee080a0 100644 --- a/boards/pygamer/src/buttons.rs +++ b/boards/pygamer/src/buttons.rs @@ -1,10 +1,10 @@ use super::hal; use cortex_m::asm::delay as cycle_delay; -use gpio::{Floating, Input, Output, PushPull}; -use hal::gpio::{self, *}; use hal::prelude::*; +use super::pins::{ButtonLatch, ButtonOut, ButtonClock}; + #[derive(Debug, PartialEq)] pub enum Keys { SelectDown, @@ -100,11 +100,11 @@ impl Iterator for ButtonIter { pub struct ButtonReader { /// Button Latch - pub latch: Pb0>, + pub latch: ButtonLatch, /// Button Out - pub data_in: Pb30>, + pub data_in: ButtonOut, /// Button Clock - pub clock: Pb31>, + pub clock: ButtonClock, pub last: u8, } diff --git a/boards/pygamer/src/lib.rs b/boards/pygamer/src/lib.rs index 2b52ebf66132..64ddea5371d1 100644 --- a/boards/pygamer/src/lib.rs +++ b/boards/pygamer/src/lib.rs @@ -1,22 +1,18 @@ #![no_std] #![recursion_limit = "1024"] -#[cfg(feature = "unproven")] -pub mod buttons; - -pub mod pins; -use atsamd_hal as hal; - #[cfg(feature = "rt")] pub use cortex_m_rt::entry; -pub use pins::Pins; +pub use atsamd_hal as hal; +pub use hal::pac; -use hal::*; +#[cfg(feature = "unproven")] +pub mod buttons; +pub mod pins; -pub use hal::common::*; -pub use hal::samd51::*; -pub use hal::target_device as pac; +pub use buttons::*; +pub use pins::*; pub mod util { /// Analogous to Arduinos map function diff --git a/boards/pygamer/src/pins.rs b/boards/pygamer/src/pins.rs index e5720ebc9936..9b5f6d36848f 100644 --- a/boards/pygamer/src/pins.rs +++ b/boards/pygamer/src/pins.rs @@ -1,17 +1,23 @@ //! PyGamer pins -use super::{hal, pac, target_device}; - use embedded_hal::{digital::v1_compat::OldOutputPin, timer::CountDown, timer::Periodic}; -use gpio::{Floating, Input, Output, Port, PushPull}; -use hal::clock::GenericClockController; -use hal::define_pins; -use hal::gpio::{self, *}; -use hal::hal::spi; -use hal::prelude::*; -use hal::sercom::{I2CMaster2, PadPin, SPIMaster1, SPIMaster4, UART5}; -use hal::{qspi, time::Hertz}; + +use super::{hal, pac}; + use pac::{MCLK, QSPI}; + +use hal::prelude::*; + +use hal::bsp_pins; +use hal::clock::GenericClockController; +use hal::gpio::v2::{self as gpio, Pin}; +use hal::pwm; +use hal::qspi; +use hal::sercom::{I2CMaster2, UART5}; +use hal::sercom::v2::{Sercom1, Sercom4, IoSet1, IoSet5, spi}; +use hal::time::Hertz; +use hal::typelevel::NoneT; + use st7735_lcd::{Orientation, ST7735}; use ws2812_timer_delay as ws2812; @@ -31,117 +37,258 @@ use hal::pwm::Pwm2; #[cfg(feature = "unproven")] use pac::{ADC0, ADC1}; -define_pins!( - /// Maps the pins to their arduino names and - /// the numbers printed on the board. - struct Pins, - target_device: target_device, +bsp_pins!( - /// Analog pin 0. Can act as a true analog output + /// Analog pin 0. Can act as a true analog output /// as it has a DAC (which is not currently supported /// by this hal) as well as input. - pin speaker = a2, + PA02 { name: speaker }, /// enable speaker amplifier - pin speaker_enable = a27, + PA27 { name: speaker_enable }, /// Analog pin 1 - pin a1 = a5, + PA05 { name: a1 }, /// Analog pin 2 - pin a2 = b8, + PB08 { name: a2 }, /// Analog pin 3 - pin a3 = b9, + PB09 { name: a3 }, /// Analog pin 4 - pin a4 = a4, + PA04 { name: a4 }, /// Analog pin 5 - pin a5 = a6, + PA06 { name: a5 }, /// Battery Measure (also Analog pin 6) - pin battery = b1, + PB01 { + name: battery + aliases: { + AlternateB: BatteryPin + } + }, /// Light sensor (also Analog pin 7) - pin light = b4, + PB04 { name: light }, /// Digital pin 2 (also Analog pin 8) - pin d2 = b3, + PB03 { name: d2 }, /// Digital pin 3 (also Analog pin 9) - pin d3 = b2, + PB02 { name: d3 }, /// Digital pin 5 - pin d5 = a16, + PA16 { name: d5 }, /// Digital pin 6 - pin d6 = a18, + PA18 { name: d6 }, /// Accelerometer interrupt pin (also d7) - pin accel_irq = b14, - /// Neopixel data line (controls all 5 neopixels, also d8) - pin neopixel = a15, + PB14 { name: accel_irq }, + PA15 { + /// Neopixel data line (controls all 5 neopixels, also d8) + name: neopixel + aliases: { + PushPullOutput: NeopixelPin + } + }, /// Digital pin 9 - pin d9 = a19, + PA19 { name: d9 }, /// Digital pin 10 - pin d10 = a20, + PA20 { name: d10 }, /// Digital pin 11 - pin d11 = a21, + PA21 { name: d11 }, /// Digital pin 12 - pin d12 = a22, + PA22 { name: d12 }, /// D13 LED/JACDAC - pin d13 = a23, + PA23 { + name: d13 + aliases: { + PushPullOutput: RedLed + } + }, // TFT(Thin-film-transistor liquid-crystal display) control pins - /// TFT MOSI - pin tft_mosi = b15, - /// TFT SCK - pin tft_sck = b13, - /// TFT Reset - pin tft_reset = a0, - /// TFT DC - pin tft_dc = b5, - /// TFT CS - pin tft_cs = b12, - /// TFT Backlight (also Analog pin 7) - pin tft_backlight = a1, + PB15 { + /// TFT MOSI + name: tft_mosi, + aliases: { + AlternateC: TftMosi + } + }, + PB13 { + /// TFT SCLK + name: tft_sclk + aliases: { + AlternateC: TftSclk + } + }, + PA00 { + /// TFT Reset + name: tft_reset + aliases: { + PushPullOutput: TftReset + } + }, + PB05 { + /// TFT DC + name: tft_dc + aliases: { + PushPullOutput: TftDc + } + }, + PB12 { + /// TFT CS + name: tft_cs + aliases: { + PushPullOutput: TftCs + } + }, + PA01 { + /// TFT Backlight (also Analog pin 7) + name: tft_backlight + aliases: { + AlternateE: TftBacklight + } + }, // UART - Universal Asynchronous Receiver/Transmitter - /// Pin TX (d1) - pin tx = b16, - /// Pin RX (d0) - pin rx = b17, + PB16 { + /// Pin TX (d1) + name: tx + aliases: { + AlternateC: UartTx + } + }, + PB17 { + /// Pin RX (d0) + name: rx + aliases: { + AlternateC: UartRx + } + }, // SPI - Serial Peripheral Interface (connected to sd card slot) - /// Pin MISO - pin miso = b22, - /// Pin MOSI - pin mosi = b23, - /// Pin SCK - pin sck = a17, + PB22 { + /// Pin MISO + name: miso + aliases: { + AlternateC: SpiMiso + } + }, + PB23 { + /// Pin MOSI + name: mosi + aliases: { + AlternateC: SpiMosi + } + }, + PA17 { + /// Pin SCK + name: sclk + aliases: { + AlternateC: SpiSclk + } + }, // I2C (connected to LIS3DH accelerometer) - /// STEMMA SDA - pin sda = a12, - /// STEMMA SCL - pin scl = a13, + PA12 { + /// STEMMA SDA + name: sda + aliases: { + AlternateC: Sda + } + }, + PA13 { + /// STEMMA SCL + name: scl + aliases: { + AlternateC: Scl + } + }, - /// USB D- pin - pin usb_dm = a24, - /// USB D+ pin - pin usb_dp = a25, + PA24 { + /// USB D- pin + name: usb_dm + aliases: { + AlternateH: UsbDm + } + }, + PA25 { + /// USB D+ pin + name: usb_dp + aliases: { + AlternateH: UsbDp + } + }, /// SD card chip select (also d4) - pin sd_cs = a14, + PA14 { name: sd_cs }, - /// Joystick X - pin joy_x = b7, - /// Joystick Y - pin joy_y = b6, + PB07 { + /// Joystick X + name: joy_x + aliases: { + AlternateB: JoyX + } + }, + PB06 { + /// Joystick Y + name: joy_y + aliases: { + AlternateB: JoyY + } + }, - /// Button Latch - pin button_latch = b0, - /// Button Out - pin button_out = b30, - /// Button Clock - pin button_clock = b31, - - /// qspi flash - pin flash_sck = b10, - pin flash_cs = b11, - pin flash_d0 = a8, - pin flash_d1 = a9, - pin flash_d2 = a10, - pin flash_d3 = a11, + PB00 { + /// Button Latch + name: button_latch + aliases: { + PushPullOutput: ButtonLatch + } + }, + PB30 { + /// Button Out + name: button_out + aliases: { + FloatingInput: ButtonOut + } + }, + PB31 { + /// Button Clock + name: button_clock + aliases: { + PushPullOutput: ButtonClock + } + }, + + // qspi flash + PB10 { + name: flash_sclk + aliases: { + AlternateH: QspiSclk + } + }, + PB11 { + name: flash_cs + aliases: { + AlternateH: QspiCs + } + }, + PA08 { + name: flash_d0 + aliases: { + AlternateH: QspiD0 + } + }, + PA09 { + name: flash_d1 + aliases: { + AlternateH: QspiD1 + } + }, + PA10 { + name: flash_d2 + aliases: { + AlternateH: QspiD2 + } + }, + PA11 { + name: flash_d3 + aliases: { + AlternateH: QspiD3 + } + }, ); impl Pins { @@ -153,13 +300,12 @@ impl Pins { }; let display = Display { - accel_irq: self.accel_irq, - tft_mosi: self.tft_mosi, - tft_sck: self.tft_sck, - tft_reset: self.tft_reset, - tft_cs: self.tft_cs, - tft_dc: self.tft_dc, - tft_backlight: self.tft_backlight, + tft_mosi: self.tft_mosi.into(), + tft_sclk: self.tft_sclk.into(), + tft_reset: self.tft_reset.into(), + tft_cs: self.tft_cs.into(), + tft_dc: self.tft_dc.into(), + tft_backlight: self.tft_backlight.into(), }; let analog = Analog { @@ -182,58 +328,57 @@ impl Pins { }; let flash = QSPIFlash { - sck: self.flash_sck, - cs: self.flash_cs, - data0: self.flash_d0, - data1: self.flash_d1, - data2: self.flash_d2, - data3: self.flash_d3, + sclk: self.flash_sclk.into(), + cs: self.flash_cs.into(), + data0: self.flash_d0.into(), + data1: self.flash_d1.into(), + data2: self.flash_d2.into(), + data3: self.flash_d3.into(), }; let spi = SPI { - sck: self.sck, - mosi: self.mosi, - miso: self.miso, + sclk: self.sclk.into(), + mosi: self.mosi.into(), + miso: self.miso.into(), }; let i2c = I2C { - sda: self.sda, - scl: self.scl, + sda: self.sda.into(), + scl: self.scl.into(), }; let neopixel = Neopixel { - neopixel: self.neopixel, + neopixel: self.neopixel.into(), }; let battery = Battery { - battery: self.battery, + battery: self.battery.into(), }; let usb = USB { - dm: self.usb_dm, - dp: self.usb_dp, + dm: self.usb_dm.into(), + dp: self.usb_dp.into(), }; let uart = UART { - rx: self.rx, - tx: self.tx, + rx: self.rx.into(), + tx: self.tx.into(), }; let buttons = Buttons { - latch: self.button_latch, - data_in: self.button_out, - clock: self.button_clock, + latch: self.button_latch.into(), + data_in: self.button_out.into(), + clock: self.button_clock.into(), }; let joystick = Joystick { - joy_x: self.joy_x, - joy_y: self.joy_y, + joy_x: self.joy_x.into(), + joy_y: self.joy_y.into(), }; Sets { - port: self.port, display, - led_pin: self.d13, + led_pin: self.d13.into(), neopixel, battery, light_pin: self.light, @@ -254,26 +399,24 @@ impl Pins { /// Sets of pins split apart by category pub struct Sets { - /// Port - pub port: Port, /// LCD Display pub display: Display, /// Red Led - pub led_pin: Pa23>, + pub led_pin: Pin, /// Neopixel (RGB LED) pins pub neopixel: Neopixel, /// Analog Light Sensor - pub light_pin: Pb4>, + pub light_pin: Pin, /// I2C (connected to LIS3DH accelerometer and "Stemma" port) pub i2c: I2C, /// SD Card CS pin - pub sd_cs_pin: Pa14>, + pub sd_cs_pin: Pin, /// Battery Voltage pub battery: Battery, @@ -306,183 +449,139 @@ pub struct Sets { /// Display pins pub struct Display { - pub accel_irq: Pb14>, // TODO remove once we make miso optional - pub tft_mosi: Pb15>, - pub tft_sck: Pb13>, - pub tft_reset: Pa0>, - pub tft_cs: Pb12>, - pub tft_dc: Pb5>, - pub tft_backlight: Pa1>, + pub tft_mosi: TftMosi, + pub tft_sclk: TftSclk, + pub tft_reset: TftReset, + pub tft_cs: TftCs, + pub tft_dc: TftDc, + pub tft_backlight: TftBacklight, } +pub type TftPads = spi::Pads; +pub type TftSpi = spi::Spi>; + #[cfg(feature = "unproven")] impl Display { /// Convenience for setting up the on board display. pub fn init( - self, + mut self, clocks: &mut GenericClockController, sercom4: pac::SERCOM4, mclk: &mut pac::MCLK, timer2: pac::TC2, delay: &mut hal::delay::Delay, - port: &mut Port, - ) -> Result< - ( - ST7735< - SPIMaster4< - hal::sercom::Sercom4Pad2>, - hal::sercom::Sercom4Pad3>, - hal::sercom::Sercom4Pad1>, - >, - Pb5>, - Pa0>, - >, - Pwm2, - ), - (), - > { + ) -> Result<( ST7735, Pwm2 ), ()> + { let gclk0 = clocks.gclk0(); - let tft_spi = SPIMaster4::new( - &clocks.sercom4_core(&gclk0).ok_or(())?, - 16.mhz(), - spi::Mode { - phase: spi::Phase::CaptureOnFirstTransition, - polarity: spi::Polarity::IdleLow, - }, - sercom4, - mclk, - ( - self.accel_irq.into_pad(port), - self.tft_mosi.into_pad(port), - self.tft_sck.into_pad(port), - ), - ); - - let mut tft_cs = self.tft_cs.into_push_pull_output(port); - tft_cs.set_low()?; - - let tft_dc = self.tft_dc.into_push_pull_output(port); - let tft_reset = self.tft_reset.into_push_pull_output(port); - + let clock = &clocks.sercom4_core(&gclk0).ok_or(())?; + let pads = spi::Pads::default().sclk(self.tft_sclk).data_out(self.tft_mosi); + let tft_spi = spi::Config::new(mclk, sercom4, pads, clock.freq()) + .spi_mode(spi::MODE_0) + .baud(16.mhz()) + .enable(); + self.tft_cs.set_low().ok(); let mut display = - st7735_lcd::ST7735::new(tft_spi, tft_dc, tft_reset, true, false, 160, 128); + st7735_lcd::ST7735::new(tft_spi, self.tft_dc, self.tft_reset, true, false, 160, 128); display.init(delay)?; display.set_orientation(&Orientation::LandscapeSwapped)?; - - let tft_backlight = self.tft_backlight.into_function_e(port); - let mut pwm2 = Pwm2::new( - &clocks.tc2_tc3(&gclk0).ok_or(())?, - 1.khz(), - timer2, - hal::pwm::TC2Pinout::Pa1(tft_backlight), - mclk, - ); - + let pwm_clock = &clocks.tc2_tc3(&gclk0).ok_or(())?; + let pwm_pinout = pwm::TC2Pinout::Pa1(self.tft_backlight); + let mut pwm2 = Pwm2::new(pwm_clock, 1.khz(), timer2, pwm_pinout, mclk); pwm2.set_duty(pwm2.get_max_duty()); - Ok((display, pwm2)) } } /// Neopixel pins pub struct Neopixel { - pub neopixel: Pa15>, + pub neopixel: NeopixelPin, } impl Neopixel { /// Convenience for setting up the onboard neopixels using the provided /// Timer preconfigured to 3mhz. - pub fn init( - self, - timer: T, - port: &mut Port, - ) -> ws2812::Ws2812>>> { - let neopixel_pin: OldOutputPin<_> = self.neopixel.into_push_pull_output(port).into(); - + pub fn init(self, timer: T) -> ws2812::Ws2812> + where + T: CountDown + Periodic + { + let neopixel_pin: OldOutputPin<_> = self.neopixel.into(); ws2812::Ws2812::new(timer, neopixel_pin) } } /// SPI pins pub struct SPI { - pub mosi: Pb23>, - pub miso: Pb22>, - pub sck: Pa17>, + pub mosi: SpiMosi, + pub miso: SpiMiso, + pub sclk: SpiSclk, } +/// Pads for the labelled SPI pins +/// +/// According to the datasheet, the combination of PA17, PB22 & PB23 shouldn't +/// work, even though it does. We have added an undocumented `IoSet5` to +/// `Sercom1` for this combination. +pub type SpiPads = spi::Pads; + +/// SPI master for the labelled pins +pub type Spi = spi::Spi>; + impl SPI { /// Convenience for setting up the labelled pins to operate /// as an SPI master, running at the specified frequency. - pub fn init>( + pub fn init( self, clocks: &mut GenericClockController, - bus_speed: F, + baud: impl Into, sercom1: pac::SERCOM1, mclk: &mut MCLK, - port: &mut Port, - ) -> SPIMaster1< - hal::sercom::Sercom1Pad2>, - hal::sercom::Sercom1Pad3>, - hal::sercom::Sercom1Pad1>, - > { + ) -> Spi { let gclk0 = clocks.gclk0(); - SPIMaster1::new( - &clocks.sercom1_core(&gclk0).unwrap(), - bus_speed.into(), - spi::Mode { - phase: spi::Phase::CaptureOnFirstTransition, - polarity: spi::Polarity::IdleLow, - }, - sercom1, - mclk, - ( - self.miso.into_pad(port), - self.mosi.into_pad(port), - self.sck.into_pad(port), - ), - ) + let clock = &clocks.sercom1_core(&gclk0).unwrap(); + let pads = spi::Pads::default() + .data_in(self.miso) + .data_out(self.mosi) + .sclk(self.sclk); + spi::Config::new(mclk, sercom1, pads, clock.freq()) + .spi_mode(spi::MODE_0) + .baud(baud) + .enable() } } /// I2C pins pub struct I2C { - pub sda: Pa12>, - pub scl: Pa13>, + pub sda: Sda, + pub scl: Scl, } impl I2C { /// Convenience for setting up the labelled SDA, SCL pins to /// operate as an I2C master running at the specified frequency. - pub fn init>( + pub fn init( self, clocks: &mut GenericClockController, - bus_speed: F, + baud: impl Into, sercom2: pac::SERCOM2, mclk: &mut MCLK, - port: &mut Port, - ) -> I2CMaster2>, hal::sercom::Sercom2Pad1>> { + ) -> I2CMaster2 { let gclk0 = clocks.gclk0(); - I2CMaster2::new( - &clocks.sercom2_core(&gclk0).unwrap(), - bus_speed.into(), - sercom2, - mclk, - self.sda.into_pad(port), - self.scl.into_pad(port), - ) + let clock = &clocks.sercom2_core(&gclk0).unwrap(); + let baud = baud.into(); + I2CMaster2::new(clock, baud, sercom2, mclk, self.sda, self.scl) } } /// Speaker pins pub struct Speaker { - pub speaker: Pa2>, - pub enable: Pa27>, + pub speaker: Pin, + pub enable: Pin, } /// USB pins pub struct USB { - pub dm: Pa24>, - pub dp: Pa25>, + pub dm: UsbDm, + pub dp: UsbDp, } impl USB { @@ -498,78 +597,71 @@ impl USB { clocks.configure_gclk_divider_and_source(GEN_A::GCLK2, 1, SRC_A::DFLL, false); let usb_gclk = clocks.get_gclk(GEN_A::GCLK2).unwrap(); let usb_clock = &clocks.usb(&usb_gclk).unwrap(); - UsbBusAllocator::new(UsbBus::new(usb_clock, mclk, self.dm, self.dp, usb)) } } /// UART pins pub struct UART { - pub tx: Pb16>, - pub rx: Pb17>, + pub tx: UartTx, + pub rx: UartRx, } impl UART { /// Convenience for setting up the labelled TX, RX pins /// to operate as a UART device at the specified baud rate. - pub fn init>( + pub fn init( self, clocks: &mut GenericClockController, - baud: F, + baud: impl Into, sercom5: pac::SERCOM5, mclk: &mut MCLK, - port: &mut Port, - ) -> UART5>, hal::sercom::Sercom5Pad0>, (), ()> + ) -> UART5 { let gclk0 = clocks.gclk0(); - - UART5::new( - &clocks.sercom5_core(&gclk0).unwrap(), - baud.into(), - sercom5, - mclk, - (self.rx.into_pad(port), self.tx.into_pad(port)), - ) + let clock = &clocks.sercom5_core(&gclk0).unwrap(); + let baud = baud.into(); + UART5::new(clock, baud, sercom5, mclk, (self.rx, self.tx)) } } /// Analog pins pub struct Analog { - pub a1: Pa5>, - pub a2: Pb8>, - pub a3: Pb9>, - pub a4: Pa4>, - pub a5: Pa6>, + pub a1: Pin, + pub a2: Pin, + pub a3: Pin, + pub a4: Pin, + pub a5: Pin, } /// Digital pins pub struct Digital { /// also usabe as A8 - pub d2: Pb3>, + pub d2: Pin, /// also usabe as A9 - pub d3: Pb2>, - pub d5: Pa16>, - pub d6: Pa18>, - pub d9: Pa19>, - pub d10: Pa20>, - pub d11: Pa21>, - pub d12: Pa22>, + pub d3: Pin, + pub d5: Pin, + pub d6: Pin, + pub d9: Pin, + pub d10: Pin, + pub d11: Pin, + pub d12: Pin, } /// QSPI flash pins pub struct QSPIFlash { - pub sck: Pb10>, - pub cs: Pb11>, - pub data0: Pa8>, - pub data1: Pa9>, - pub data2: Pa10>, - pub data3: Pa11>, + pub sclk: QspiSclk, + pub cs: QspiCs, + pub data0: QspiD0, + pub data1: QspiD1, + pub data2: QspiD2, + pub data3: QspiD3, } impl QSPIFlash { - pub fn init(self, mclk: &mut MCLK, _port: &mut Port, qspi: QSPI) -> qspi::Qspi { + pub fn init(self, mclk: &mut MCLK, qspi: QSPI) -> qspi::Qspi { qspi::Qspi::new( - mclk, qspi, self.sck, self.cs, self.data0, self.data1, self.data2, self.data3, + mclk, qspi, self.sclk, self.cs, self.data0, self.data1, self.data2, self.data3, ) } } @@ -577,30 +669,24 @@ impl QSPIFlash { /// Button pins pub struct Buttons { /// Button Latch - pub latch: Pb0>, + pub latch: ButtonLatch, /// Button Out - pub data_in: Pb30>, + pub data_in: ButtonOut, /// Button Clock - pub clock: Pb31>, + pub clock: ButtonClock, } #[cfg(feature = "unproven")] impl Buttons { /// Convenience for setting up the button latch pins /// Returns ButtonReader iterator which can be polled for Key events - pub fn init(self, port: &mut Port) -> ButtonReader { - let mut latch = self.latch.into_push_pull_output(port); - latch.set_high().ok(); - - let data_in = self.data_in.into_floating_input(port); - - let mut clock = self.clock.into_push_pull_output(port); - clock.set_high().ok(); - + pub fn init(mut self) -> ButtonReader { + self.latch.set_high().ok(); + self.clock.set_high().ok(); ButtonReader { - latch, - data_in, - clock, + latch: self.latch, + data_in: self.data_in, + clock: self.clock, last: 0, } } @@ -609,9 +695,9 @@ impl Buttons { /// Joystick pins pub struct JoystickReader { /// Joystick X - pub joy_x: Pb7, + pub joy_x: JoyX, /// Joystick Y - pub joy_y: Pb6, + pub joy_y: JoyY, } #[cfg(feature = "unproven")] @@ -633,19 +719,19 @@ impl JoystickReader { /// Joystick pins pub struct Joystick { /// Joystick X - pub joy_x: Pb7>, + pub joy_x: JoyX, /// Joystick Y - pub joy_y: Pb6>, + pub joy_y: JoyY, } #[cfg(feature = "unproven")] impl Joystick { /// Convenience for setting up the joystick. Returns JoystickReader instance /// which can be polled for joystick (x,y) tuple - pub fn init(self, port: &mut Port) -> JoystickReader { + pub fn init(self) -> JoystickReader { JoystickReader { - joy_x: self.joy_x.into_function_b(port), - joy_y: self.joy_y.into_function_b(port), + joy_x: self.joy_x, + joy_y: self.joy_y, } } } @@ -654,7 +740,7 @@ impl Joystick { #[cfg(feature = "unproven")] pub struct BatteryReader { /// Battery pin - pub battery: Pb1, + pub battery: BatteryPin, } #[cfg(feature = "unproven")] @@ -669,16 +755,16 @@ impl BatteryReader { /// Battery pin pub struct Battery { - pub battery: Pb1>, + pub battery: BatteryPin, } #[cfg(feature = "unproven")] impl Battery { /// Convenience for reading Battery Volage. Returns BatteryReader instance /// which can be polled for battery voltage - pub fn init(self, port: &mut Port) -> BatteryReader { + pub fn init(self) -> BatteryReader { BatteryReader { - battery: self.battery.into_function_b(port), + battery: self.battery, } } } diff --git a/boards/trinket_m0/examples/eic.rs b/boards/trinket_m0/examples/eic.rs index 4c0ff5a9fc1b..8ec64e2023e4 100644 --- a/boards/trinket_m0/examples/eic.rs +++ b/boards/trinket_m0/examples/eic.rs @@ -7,7 +7,6 @@ use panic_halt as _; use trinket_m0 as hal; -use cortex_m::asm::delay as cycle_delay; use hal::clock::GenericClockController; use hal::eic::{pin::Sense, EIC}; use hal::entry; diff --git a/crates.json b/crates.json index 1d57c16ce399..a9fd1690466e 100644 --- a/crates.json +++ b/crates.json @@ -52,7 +52,7 @@ "build": "cargo build --examples --features=unproven" }, "pygamer": { - "build": "cargo build --examples --features=unproven,usb,math" + "build": "cargo build --examples --features=unproven,usb,math,sd-card" }, "pyportal": { "build": "cargo build --examples --features=unproven" diff --git a/hal/src/thumbv7em/sercom/v2/impl_pad.rs b/hal/src/thumbv7em/sercom/v2/impl_pad.rs index 9d98ebe17308..69600fd55fac 100644 --- a/hal/src/thumbv7em/sercom/v2/impl_pad.rs +++ b/hal/src/thumbv7em/sercom/v2/impl_pad.rs @@ -427,3 +427,10 @@ pad_table!( D: (Sercom3, Pad3, IoSet4), } ); + +// Implement an undocumented `IoSet` for PA17, PB22 & PB23 configured for +// `Sercom1`. The pygamer uses this combination, but it is not listed as valid +// in the datasheet. +impl InIoSet for Pin> {} +impl InIoSet for Pin> {} +impl InIoSet for Pin> {} \ No newline at end of file