#![no_std]
#![deny(nonstandard_style)]
#![deny(rust_2018_idioms)]
pub use atsamd_hal as hal;
pub use hal::pac;
use hal::bsp_pins;
use hal::clock::GenericClockController;
use hal::sercom::v2::spi;
use hal::sercom::v2::uart::{self, BaudMode, Oversampling};
use hal::sercom::v2::{Sercom0, Sercom2};
use hal::sercom::I2CMaster1;
use hal::time::Hertz;
#[cfg(feature = "rt")]
pub use cortex_m_rt::entry;
#[cfg(feature = "usb")]
use hal::usb::UsbBus;
#[cfg(feature = "usb")]
use usb_device::bus::UsbBusAllocator;
bsp_pins! {
PA02 {
name: a0
aliases: {
Reset: A0Reset
}
}
PA03 {
name: a1
aliases: {
Reset: A1Reset
}
}
PA04 {
name: a2
aliases: {
Reset: A2Reset
}
}
PA05 {
name: a3
aliases: {
Reset: A3Reset
}
}
PA06 {
name: tx
aliases: {
AlternateD: UartTx,
Reset: UartTxReset
}
},
PA07 {
name: rx
aliases: {
AlternateD: UartRx,
Reset: UartRxReset
}
}
PA09 {
name: miso
aliases: {
AlternateD: SpiMiso,
Reset: MisoReset
}
}
PA10 {
name: mosi
aliases: {
AlternateD: SpiMosi,
Reset: MosiReset
}
}
PA11 {
name: sclk
aliases: {
AlternateD: SpiSck,
Reset: SckReset
}
}
PA16 {
name: sda
aliases: {
AlternateC: I2cSda,
Reset: I2cSdaReset
}
}
PA17 {
name: scl
aliases: {
AlternateC: I2cScl,
Reset: I2cSclReset
}
}
PA15 {
name: neopixel_power
aliases: {
PushPullOutput: NeopixelPower,
Reset: NeopixelPowerReset
}
}
PA18 {
name: neopixel_data
aliases: {
PushPullOutput: NeopixelData,
Reset: NeopixelDataReset
}
}
PA24 {
name: usb_dm,
aliases: {
AlternateG: UsbDm,
Reset: UsbDmReset
}
}
PA25 {
name: usb_dp,
aliases: {
AlternateG: UsbDp,
Reset: UsbDpReset
}
}
PA08 {
name: flash_cs
aliases: {
PushPullOutput: FlashCs,
Reset: FlashCsReset
}
}
PA19 {
name: flash_miso
aliases: {
AlternateD: FlashMiso,
Reset: FlashMisoReset
}
}
PA22 {
name: flash_mosi
aliases: {
AlternateC: FlashMosi,
Reset: FlashMosiReset
}
}
PA23 {
name: flash_sclk
aliases: {
AlternateC: FlashSck,
Reset: FlashSckReset
}
}
}
impl Pins {
pub fn split(self) -> Sets {
let analog = Analog {
a0: self.a0,
a1: self.a1,
a2: self.a2,
a3: self.a3,
};
let uart = Uart {
tx: self.tx,
rx: self.rx,
};
let spi = Spi {
miso: self.miso,
mosi: self.mosi,
sclk: self.sclk,
};
let i2c = I2c {
sda: self.sda,
scl: self.scl,
};
let neopixel = Neopixel {
power: self.neopixel_power,
data: self.neopixel_data,
};
let usb = Usb {
dm: self.usb_dm,
dp: self.usb_dp,
};
Sets {
analog,
uart,
spi,
i2c,
neopixel,
usb,
}
}
}
pub struct Sets {
pub analog: Analog,
pub uart: Uart,
pub spi: Spi,
pub i2c: I2c,
pub neopixel: Neopixel,
pub usb: Usb,
}
pub struct Analog {
pub a0: A0Reset,
pub a1: A1Reset,
pub a2: A2Reset,
pub a3: A3Reset,
}
pub struct Uart {
pub tx: UartTxReset,
pub rx: UartRxReset,
}
pub type UartPads = uart::Pads<Sercom0, UartRx, UartTx>;
pub type UartConfig = uart::Uart<uart::Config<UartPads>, uart::Duplex>;
impl Uart {
pub fn init(
self,
clocks: &mut GenericClockController,
freq: impl Into<Hertz>,
sercom0: pac::SERCOM0,
pm: &mut pac::PM,
) -> UartConfig {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom0_core(&gclk0).unwrap();
let rx: UartRx = self.rx.into();
let tx: UartTx = self.tx.into();
let pads = uart::Pads::default().rx(rx).tx(tx);
uart::Config::new(pm, sercom0, pads, clock.freq())
.baud(freq.into(), BaudMode::Fractional(Oversampling::Bits16))
.enable()
}
}
pub struct Spi {
pub miso: MisoReset,
pub mosi: MosiReset,
pub sclk: SckReset,
}
type SpiPads = spi::Pads<Sercom2, SpiMiso, SpiMosi, SpiSck>;
pub type SpiConfig = spi::Spi<spi::Config<SpiPads>, spi::Duplex>;
impl Spi {
pub fn init(
self,
clocks: &mut GenericClockController,
baud: impl Into<Hertz>,
sercom2: pac::SERCOM2,
pm: &mut pac::PM,
) -> SpiConfig {
let gclk0 = clocks.gclk0();
let clock = clocks.sercom2_core(&gclk0).unwrap();
let pads = spi::Pads::default()
.data_in(self.miso)
.data_out(self.mosi)
.sclk(self.sclk);
spi::Config::new(pm, sercom2, pads, clock.freq())
.spi_mode(spi::MODE_0)
.baud(baud)
.enable()
}
}
pub struct I2c {
pub sda: I2cSdaReset,
pub scl: I2cSclReset,
}
impl I2c {
pub fn init(
self,
clocks: &mut GenericClockController,
freq: impl Into<Hertz>,
sercom1: pac::SERCOM1,
pm: &mut pac::PM,
) -> I2CMaster1<I2cSda, I2cScl> {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom1_core(&gclk0).unwrap();
I2CMaster1::new(
clock,
freq.into(),
sercom1,
pm,
self.sda.into(),
self.scl.into(),
)
}
}
pub struct Neopixel {
pub power: NeopixelPowerReset,
pub data: NeopixelDataReset,
}
pub struct Usb {
pub dm: UsbDmReset,
pub dp: UsbDpReset,
}
impl Usb {
#[cfg(feature = "usb")]
pub fn init(
self,
usb: pac::USB,
clocks: &mut GenericClockController,
pm: &mut pac::PM,
) -> UsbBusAllocator<UsbBus> {
let gclk0 = clocks.gclk0();
let usb_clock = &clocks.usb(&gclk0).unwrap();
let (dm, dp): (UsbDm, UsbDp) = (self.dm.into(), self.dp.into());
UsbBusAllocator::new(UsbBus::new(usb_clock, pm, dm, dp, usb))
}
}