#![no_std]
#![deny(missing_docs)]
#[cfg(feature = "rt")]
pub use cortex_m_rt::entry;
pub use atsamd_hal as hal;
pub use hal::ehal;
pub use hal::pac;
use hal::clock::GenericClockController;
use hal::sercom::{
i2c, spi,
uart::{self, BaudMode, Oversampling},
};
use hal::time::Hertz;
#[cfg(feature = "usb")]
use hal::usb::usb_device::bus::UsbBusAllocator;
#[cfg(feature = "usb")]
pub use hal::usb::UsbBus;
hal::bsp_peripherals!(
Sercom1 { SpiSercom }
Sercom2 { I2cSercom }
Sercom5 { UartSercom }
);
hal::bsp_pins!(
PA02 {
name: a0,
}
PA05 {
name: a1,
}
PB08 {
name: a2,
}
PB09 {
name: a3,
}
PA04 {
name: a4,
}
PA06 {
name: a5,
}
PB01 {
name: battery,
}
PB17 {
name: d0,
aliases: {
AlternateC: UartRx
}
}
PB16 {
name: d1,
aliases: {
AlternateC: UartTx
}
}
PA14 {
name: d4,
}
PA16 {
name: d5,
}
PA18 {
name: d6,
}
PB03 {
name: neopixel,
}
PA19 {
name: d9,
}
PA20 {
name: d10,
}
PA21 {
name: d11,
}
PA22 {
name: d12,
}
PA23 {
name: d13,
aliases: {
PushPullOutput: RedLed,
AlternateE: RedLedPwm
}
}
PA12 {
name: sda,
aliases: {
AlternateC: Sda
}
}
PA13 {
name: scl,
aliases: {
AlternateC: Scl
}
}
PA17 {
name: sck,
aliases: {
AlternateC: Sclk
}
}
PB23 {
name: mosi,
aliases: {
AlternateC: Mosi
}
}
PB22 {
name: miso,
aliases: {
AlternateC: Miso
}
}
PA24 {
name: usb_dm,
aliases: {
AlternateH: UsbDm
}
}
PA25 {
name: usb_dp,
aliases: {
AlternateH: UsbDp
}
}
);
pub type SpiPads = spi::Pads<SpiSercom, Miso, Mosi, Sclk>;
pub type Spi = spi::Spi<spi::Config<SpiPads>, spi::Duplex>;
pub fn spi_master(
clocks: &mut GenericClockController,
baud: Hertz,
sercom: SpiSercom,
mclk: &mut pac::Mclk,
sclk: impl Into<Sclk>,
mosi: impl Into<Mosi>,
miso: impl Into<Miso>,
) -> Spi {
let gclk0 = clocks.gclk0();
let clock = clocks.sercom1_core(&gclk0).unwrap();
let freq = clock.freq();
let (miso, mosi, sclk) = (miso.into(), mosi.into(), sclk.into());
let pads = spi::Pads::default().data_in(miso).data_out(mosi).sclk(sclk);
spi::Config::new(mclk, sercom, pads, freq)
.baud(baud)
.spi_mode(spi::MODE_0)
.enable()
}
pub type I2cPads = i2c::Pads<I2cSercom, Sda, Scl>;
pub type I2c = i2c::I2c<i2c::Config<I2cPads>>;
pub fn i2c_master(
clocks: &mut GenericClockController,
baud: impl Into<Hertz>,
sercom: I2cSercom,
mclk: &mut pac::Mclk,
sda: impl Into<Sda>,
scl: impl Into<Scl>,
) -> I2c {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom2_core(&gclk0).unwrap();
let freq = clock.freq();
let baud = baud.into();
let pads = i2c::Pads::new(sda.into(), scl.into());
i2c::Config::new(mclk, sercom, pads, freq)
.baud(baud)
.enable()
}
pub type UartPads = uart::Pads<UartSercom, UartRx, UartTx>;
pub type Uart = uart::Uart<uart::Config<UartPads>, uart::Duplex>;
pub fn uart(
clocks: &mut GenericClockController,
baud: impl Into<Hertz>,
sercom: UartSercom,
mclk: &mut pac::Mclk,
rx: impl Into<UartRx>,
tx: impl Into<UartTx>,
) -> Uart {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom5_core(&gclk0).unwrap();
let baud = baud.into();
let pads = uart::Pads::default().rx(rx.into()).tx(tx.into());
uart::Config::new(mclk, sercom, pads, clock.freq())
.baud(baud, BaudMode::Fractional(Oversampling::Bits16))
.enable()
}
#[cfg(feature = "usb")]
pub fn usb_allocator(
dm: impl Into<UsbDm>,
dp: impl Into<UsbDp>,
usb: pac::Usb,
clocks: &mut GenericClockController,
mclk: &mut pac::Mclk,
) -> UsbBusAllocator<UsbBus> {
use pac::gclk::{genctrl::Srcselect, pchctrl::Genselect};
clocks.configure_gclk_divider_and_source(Genselect::Gclk2, 1, Srcselect::Dfll, false);
let usb_gclk = clocks.get_gclk(Genselect::Gclk2).unwrap();
let usb_clock = &clocks.usb(&usb_gclk).unwrap();
let (dm, dp) = (dm.into(), dp.into());
UsbBusAllocator::new(UsbBus::new(usb_clock, mclk, dm, dp, usb))
}