#![no_std]
#[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::prelude::*;
use hal::sercom::v2::spi;
use hal::sercom::v2::uart::{self, BaudMode, Oversampling};
use hal::sercom::v2::{Sercom0, Sercom3, Sercom4};
use hal::sercom::I2CMaster5;
use hal::time::{Hertz, MegaHertz};
#[cfg(feature = "usb")]
use hal::usb::{usb_device::bus::UsbBusAllocator, UsbBus};
pub mod pins {
use super::hal;
hal::bsp_pins!(
PB09 {
name: a6,
aliases: {
AlternateD: UartRx
}
},
PB08 {
name: a7,
aliases: {
AlternateD: UartTx
}
},
PA28 {
name: d4,
},
PA14 {
name: d5,
},
PA15 {
name: d7,
},
PA30 {
name: d11,
},
PA17 {
name: d13,
aliases: {
PushPullOutput: RedLed
}
},
PB02 {
name: a5,
aliases: {
AlternateD: Sda
}
},
PB03 {
name: a4,
aliases: {
AlternateD: Scl
}
},
PB23 {
name: d8,
aliases: {
PushPullOutput: NeoPixel
}
},
PA02 {
name: a0,
aliases: {
PushPullOutput: Speaker
}
},
PA05 {
name: a1,
aliases: {
AlternateD: Sck
}
},
PA07 {
name: a3,
aliases: {
AlternateD: Mosi
}
},
PA06 {
name: a2,
aliases: {
AlternateD: Miso
}
},
PA21 {
name: flash_sck,
aliases: {
AlternateD: FlashSck
}
},
PA20 {
name: flash_mosi,
aliases: {
AlternateD: FlashMosi
}
},
PA16 {
name: flash_miso,
aliases: {
AlternateD: FlashMiso
}
},
PB22 {
name: flash_cs,
aliases: {
PushPullOutput: FlashCs
}
},
PA00 {
name: accel_sda,
},
PA01 {
name: accel_scl,
},
PA24 {
name: usb_dm
aliases: {
AlternateG: UsbDm
}
}
PA25 {
name: usb_dp
aliases: {
AlternateG: UsbDp
}
}
);
}
pub use pins::*;
pub type SpiPads = spi::Pads<Sercom0, Miso, Mosi, Sck>;
pub type Spi = spi::Spi<spi::Config<SpiPads>, spi::Duplex>;
pub fn spi_master(
clocks: &mut GenericClockController,
baud: impl Into<Hertz>,
sercom0: pac::SERCOM0,
pm: &mut pac::PM,
sck: impl Into<Sck>,
mosi: impl Into<Mosi>,
miso: impl Into<Miso>,
) -> Spi {
let gclk0 = clocks.gclk0();
let clock = clocks.sercom0_core(&gclk0).unwrap();
let freq = clock.freq();
let (miso, mosi, sck) = (miso.into(), mosi.into(), sck.into());
let pads = spi::Pads::default().data_in(miso).data_out(mosi).sclk(sck);
spi::Config::new(pm, sercom0, pads, freq)
.baud(baud)
.spi_mode(spi::MODE_0)
.enable()
}
pub type FlashPads = spi::Pads<Sercom3, FlashMiso, FlashMosi, FlashSck>;
pub type FlashSpi = spi::Spi<spi::Config<FlashPads>, spi::Duplex>;
pub fn flash_spi_master(
clocks: &mut GenericClockController,
sercom3: pac::SERCOM3,
pm: &mut pac::PM,
sck: impl Into<FlashSck>,
mosi: impl Into<FlashMosi>,
miso: impl Into<FlashMiso>,
cs: impl Into<FlashCs>,
) -> (FlashSpi, FlashCs) {
let gclk0 = clocks.gclk0();
let clock = clocks.sercom3_core(&gclk0).unwrap();
let freq = clock.freq();
let (sck, mosi, miso, mut cs) = (sck.into(), mosi.into(), miso.into(), cs.into());
let pads = spi::Pads::default().data_in(miso).data_out(mosi).sclk(sck);
let spi = spi::Config::new(pm, sercom3, pads, freq)
.baud(MegaHertz(48))
.spi_mode(spi::MODE_0)
.enable();
cs.set_high().unwrap();
(spi, cs)
}
pub type I2C = I2CMaster5<Sda, Scl>;
pub fn i2c_master(
clocks: &mut GenericClockController,
baud: impl Into<Hertz>,
sercom5: pac::SERCOM5,
pm: &mut pac::PM,
sda: impl Into<Sda>,
scl: impl Into<Scl>,
) -> I2C {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom5_core(&gclk0).unwrap();
let baud = baud.into();
let sda = sda.into();
let scl = scl.into();
I2CMaster5::new(clock, baud, sercom5, pm, sda, scl)
}
pub type UartPads = uart::Pads<Sercom4, UartRx, UartTx>;
pub type Uart = uart::Uart<uart::Config<UartPads>, uart::Duplex>;
pub fn uart(
clocks: &mut GenericClockController,
baud: impl Into<Hertz>,
sercom4: pac::SERCOM4,
pm: &mut pac::PM,
uart_rx: impl Into<UartRx>,
uart_tx: impl Into<UartTx>,
) -> Uart {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom4_core(&gclk0).unwrap();
let baud = baud.into();
let pads = uart::Pads::default().rx(uart_rx.into()).tx(uart_tx.into());
uart::Config::new(pm, sercom4, pads, clock.freq())
.baud(baud, BaudMode::Fractional(Oversampling::Bits16))
.enable()
}
#[cfg(feature = "usb")]
pub fn usb_allocator(
usb: pac::USB,
clocks: &mut GenericClockController,
pm: &mut pac::PM,
dm: impl Into<UsbDm>,
dp: impl Into<UsbDp>,
) -> UsbBusAllocator<UsbBus> {
let gclk0 = clocks.gclk0();
let clock = &clocks.usb(&gclk0).unwrap();
let (dm, dp) = (dm.into(), dp.into());
UsbBusAllocator::new(UsbBus::new(clock, pm, dm, dp, usb))
}