#![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::sercom::{
i2c, spi,
uart::{self, BaudMode, Oversampling},
};
use hal::time::Hertz;
#[cfg(feature = "usb")]
use hal::usb::{usb_device::bus::UsbBusAllocator, UsbBus};
hal::bsp_peripherals!(
Sercom0 { UartSercom }
Sercom3 { I2cSercom }
Sercom4 { SpiSercom }
);
pub mod pins {
use super::hal;
hal::bsp_pins!(
PA03 {
name: aref
}
PA02 {
name: a0,
aliases: {
AlternateB: A0
}
}
PB08 {
name: a1
}
PB09 {
name: a2
}
PA04 {
name: a3
}
PA05 {
name: a4
}
PB02 {
name: a5
}
PA11 {
name: d0
aliases: {
AlternateC: UartRx
}
}
PA10 {
name: d1
aliases: {
AlternateC: UartTx
}
}
PA15 {
name: d5
aliases: {
AlternateE: D5Pwm
}
}
PA20 {
name: d6
aliases: {
PushPullOutput: Ssd1306Dc
}
}
PA07 {
name: d9
aliases: {
PushPullOutput: Ssd1306Rst
}
}
PA18 {
name: d10
}
PA16 {
name: d11
}
PA19 {
name: d12
}
PA17 {
name: d13
aliases: {
PushPullOutput: RedLed
}
}
PA22 {
name: sda
aliases: {
AlternateC: Sda
}
}
PA23 {
name: scl
aliases: {
AlternateC: Scl
}
}
PB11 {
name: sclk
aliases: {
AlternateD: Sclk
}
}
PB10 {
name: mosi
aliases: {
AlternateD: Mosi
}
}
PA12 {
name: miso
aliases: {
AlternateD: Miso
}
}
PA24 {
name: usb_dm
aliases: {
AlternateG: UsbDm
}
}
PA25 {
name: usb_dp
aliases: {
AlternateG: UsbDp
}
}
#[cfg(all(feature = "rfm", not(feature = "express"), not(feature = "winc")))]
PA06 {
name: rfm_cs
}
#[cfg(all(feature = "rfm", not(feature = "express"), not(feature = "adalogger"), not(feature = "winc")))]
PA08 {
name: rfm_reset
}
#[cfg(all(feature = "rfm", not(feature = "express")))]
PA09 {
name: rfm_irq
}
#[cfg(all(feature = "express", not(feature = "rfm"), not(feature = "winc")))]
PA06 {
name: neopixel
}
#[cfg(all(feature = "express", not(feature = "rfm")))]
PA09 {
name: flash_sclk
}
#[cfg(all(feature = "express", not(feature = "rfm"), not(feature = "adalogger"), not(feature = "winc")))]
PA08 {
name: flash_mosi
}
#[cfg(all(feature = "express", not(feature= "winc")))]
PA14 {
name: flash_miso
}
#[cfg(feature = "express")]
PA13 {
name: flash_cs
}
#[cfg(all(feature = "adalogger", not(feature = "rfm"), not(feature = "express"), not(feature = "winc")))]
PA08 {
name: sd_cs
aliases: {
PushPullOutput: SdCs
}
},
#[cfg(all(feature = "adalogger", not(feature = "rfm"), not(feature = "express") , not(feature = "winc")))]
PA21 {
name: sd_cd
aliases: {
PullUpInput: SdCd
}
},
#[cfg(all(feature = "winc", not(feature = "rfm"), not(feature = "express"), not(feature = "adalogger")))]
PA08 {
name: winc_rst
aliases: {
PushPullOutput: WincRst
}
},
#[cfg(all(feature = "winc", not(feature= "express")))]
PA14 {
name: winc_ena
aliases: {
PushPullOutput: WincEna
}
}
#[cfg(all(feature = "winc", not(feature = "adalogger")))]
PA21 {
name: winc_irq
aliases: {
PullUpInterrupt: WincIrq
}
},
#[cfg(all(feature = "winc", not(feature = "rfm"), not(feature = "express")))]
PA06 {
name: winc_cs
aliases: {
PushPullOutput: WincCs
}
},
);
}
pub use pins::*;
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,
pm: &mut pac::Pm,
sclk: impl Into<Sclk>,
mosi: impl Into<Mosi>,
miso: impl Into<Miso>,
) -> Spi {
let gclk0 = clocks.gclk0();
let clock = clocks.sercom4_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(pm, 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,
pm: &mut pac::Pm,
sda: impl Into<Sda>,
scl: impl Into<Scl>,
) -> I2c {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom3_core(&gclk0).unwrap();
let freq = clock.freq();
let baud = baud.into();
let pads = i2c::Pads::new(sda.into(), scl.into());
i2c::Config::new(pm, 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,
pm: &mut pac::Pm,
uart_rx: impl Into<UartRx>,
uart_tx: impl Into<UartTx>,
) -> Uart {
let gclk0 = clocks.gclk0();
let clock = &clocks.sercom0_core(&gclk0).unwrap();
let baud = baud.into();
let pads = uart::Pads::default().rx(uart_rx.into()).tx(uart_tx.into());
uart::Config::new(pm, sercom, 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))
}