#![no_std]
extern crate atsamd_hal as hal;
#[cfg(feature = "rt")]
extern crate cortex_m_rt;
#[cfg(feature = "rt")]
pub use cortex_m_rt::entry;
use hal::prelude::*;
use hal::*;
pub use hal::common::*;
pub use hal::samd21::*;
pub use hal::target_device as pac;
use gpio::{self, *};
use hal::clock::GenericClockController;
use hal::define_pins;
use hal::sercom::{I2CMaster2, PadPin, UART0};
use hal::time::Hertz;
#[cfg(feature = "unproven")]
use apa102_spi::Apa102;
#[cfg(feature = "unproven")]
use embedded_hal::timer::{CountDown, Periodic};
#[cfg(feature = "usb")]
use hal::usb::usb_device::bus::UsbBusAllocator;
#[cfg(feature = "usb")]
pub use hal::usb::UsbBus;
define_pins!(
struct Pins,
target_device: target_device,
pin d0 = a8,
pin d1 = a2,
pin d2 = a9,
pin d3 = a7,
pin d4 = a6,
pin d13 = a10,
pin dotstar_ci = a1,
pin dotstar_di = a0,
pin dotstar_nc = a14,
pin swdio = a31,
pin swdclk = a30,
pin usb_host_enable = a28,
pin usb_sof = a23,
pin usb_dm = a24,
pin usb_dp = a25,
);
impl Pins {
pub fn split(self) -> Sets {
let dotstar = Dotstar {
ci: self.dotstar_ci,
di: self.dotstar_di,
nc: self.dotstar_nc,
};
let i2c = I2C {
sda: self.d0,
scl: self.d2,
};
let usb = USB {
dm: self.usb_dm,
dp: self.usb_dp,
};
let uart = UART {
rx: self.d3,
tx: self.d4,
};
Sets {
dotstar,
i2c,
usb,
uart,
port: self.port,
}
}
}
pub struct Sets {
pub dotstar: Dotstar,
pub i2c: I2C,
pub usb: USB,
pub uart: UART,
pub port: Port,
}
pub struct Dotstar {
pub ci: gpio::Pa1<Input<Floating>>,
pub di: gpio::Pa0<Input<Floating>>,
pub nc: gpio::Pa14<Input<Floating>>,
}
impl Dotstar {
#[cfg(feature = "unproven")]
pub fn init<T: CountDown + Periodic>(
self,
timer: T,
port: &mut Port,
) -> apa102_spi::Apa102<
bitbang_hal::spi::SPI<
gpio::Pa14<Input<PullUp>>,
gpio::Pa0<Output<PushPull>>,
gpio::Pa1<Output<PushPull>>,
T,
>,
> {
let di = self.di.into_push_pull_output(port);
let ci = self.ci.into_push_pull_output(port);
let nc = self.nc.into_pull_up_input(port);
let spi = bitbang_hal::spi::SPI::new(apa102_spi::MODE, nc, di, ci, timer);
Apa102::new_with_custom_postamble(spi, 4, false)
}
}
pub struct I2C {
pub sda: gpio::Pa8<Input<Floating>>,
pub scl: gpio::Pa9<Input<Floating>>,
}
impl I2C {
pub fn init<F: Into<Hertz>>(
self,
clocks: &mut GenericClockController,
bus_speed: F,
sercom2: pac::SERCOM2,
pm: &mut pac::PM,
port: &mut Port,
) -> I2CMaster2<
hal::sercom::Sercom2Pad0<gpio::Pa8<PfD>>,
hal::sercom::Sercom2Pad1<gpio::Pa9<PfD>>,
> {
let gclk0 = clocks.gclk0();
I2CMaster2::new(
&clocks.sercom2_core(&gclk0).unwrap(),
bus_speed.into(),
sercom2,
pm,
self.sda.into_pad(port),
self.scl.into_pad(port),
)
}
}
pub fn i2c_master<F: Into<Hertz>>(
clocks: &mut GenericClockController,
bus_speed: F,
sercom2: pac::SERCOM2,
pm: &mut pac::PM,
sda: gpio::Pa8<Input<Floating>>,
scl: gpio::Pa9<Input<Floating>>,
port: &mut Port,
) -> I2CMaster2<hal::sercom::Sercom2Pad0<gpio::Pa8<PfD>>, hal::sercom::Sercom2Pad1<gpio::Pa9<PfD>>>
{
let gclk0 = clocks.gclk0();
I2CMaster2::new(
&clocks.sercom2_core(&gclk0).unwrap(),
bus_speed.into(),
sercom2,
pm,
sda.into_pad(port),
scl.into_pad(port),
)
}
pub struct UART {
pub rx: gpio::Pa7<Input<Floating>>,
pub tx: gpio::Pa6<Input<Floating>>,
}
impl UART {
pub fn init<F: Into<Hertz>>(
self,
clocks: &mut GenericClockController,
baud: F,
sercom0: pac::SERCOM0,
pm: &mut pac::PM,
port: &mut Port,
) -> UART0<
hal::sercom::Sercom0Pad3<gpio::Pa7<PfD>>,
hal::sercom::Sercom0Pad2<gpio::Pa6<PfD>>,
(),
(),
> {
let gclk0 = clocks.gclk0();
UART0::new(
&clocks.sercom0_core(&gclk0).unwrap(),
baud.into(),
sercom0,
pm,
(self.rx.into_pad(port), self.tx.into_pad(port)),
)
}
}
pub fn uart<F: Into<Hertz>>(
clocks: &mut GenericClockController,
baud: F,
sercom0: pac::SERCOM0,
pm: &mut pac::PM,
d3: gpio::Pa7<Input<Floating>>,
d4: gpio::Pa6<Input<Floating>>,
port: &mut Port,
) -> UART0<hal::sercom::Sercom0Pad3<gpio::Pa7<PfD>>, hal::sercom::Sercom0Pad2<gpio::Pa6<PfD>>, (), ()>
{
let gclk0 = clocks.gclk0();
UART0::new(
&clocks.sercom0_core(&gclk0).unwrap(),
baud.into(),
sercom0,
pm,
(d3.into_pad(port), d4.into_pad(port)),
)
}
pub struct USB {
pub dm: gpio::Pa24<Input<Floating>>,
pub dp: gpio::Pa25<Input<Floating>>,
}
impl USB {
#[cfg(feature = "usb")]
pub fn init(
self,
usb: pac::USB,
clocks: &mut GenericClockController,
pm: &mut pac::PM,
port: &mut Port,
) -> UsbBusAllocator<UsbBus> {
let gclk0 = clocks.gclk0();
let usb_clock = &clocks.usb(&gclk0).unwrap();
UsbBusAllocator::new(UsbBus::new(
usb_clock,
pm,
self.dm.into_function(port),
self.dp.into_function(port),
usb,
))
}
}
#[cfg(feature = "usb")]
pub fn usb_allocator(
usb: pac::USB,
clocks: &mut GenericClockController,
pm: &mut pac::PM,
dm: gpio::Pa24<Input<Floating>>,
dp: gpio::Pa25<Input<Floating>>,
port: &mut Port,
) -> UsbBusAllocator<UsbBus> {
let gclk0 = clocks.gclk0();
let usb_clock = &clocks.usb(&gclk0).unwrap();
UsbBusAllocator::new(UsbBus::new(
usb_clock,
pm,
dm.into_function(port),
dp.into_function(port),
usb,
))
}