#![no_main]
#![no_std]
use panic_halt as _;
use atsamd_hal::{
clock::v2::{
self as clock,
dpll::Dpll,
gclk::{Gclk, GclkDiv16, GclkDiv8},
osculp32k::OscUlp32k,
pclk::Pclk,
rtcosc::RtcOsc,
xosc32k::{ControlGainMode, Xosc1k, Xosc32k, Xosc32kBase},
},
embedded_io::{Read, Write},
fugit::RateExtU32,
gpio::{Pins, PA04, PA05},
rtc::{ClockMode, Rtc},
sercom::{
uart::{self, BaudMode, Flags, Oversampling},
Sercom0,
},
};
use rtic::app;
type Pads = uart::PadsFromIds<Sercom0, PA05, PA04>;
type Uart = uart::Uart<uart::Config<Pads>, uart::Duplex>;
#[app(device = atsamd_hal::pac)]
mod app {
use super::*;
#[shared]
struct SharedResources {
uart: Uart,
rtc: Rtc<ClockMode>,
}
#[local]
struct LocalResources {}
#[init]
fn init(cx: init::Context) -> (SharedResources, LocalResources) {
let mut device = cx.device;
let (_buses, clocks, tokens) = clock::clock_system_at_reset(
device.oscctrl,
device.osc32kctrl,
device.gclk,
device.mclk,
&mut device.nvmctrl,
);
let (_, _, _, mut mclk) = unsafe { clocks.pac.steal() };
let pins = Pins::new(device.port);
let (gclk1, dfll) = Gclk::from_source(tokens.gclks.gclk1, clocks.dfll);
let gclk1 = gclk1.div(GclkDiv16::Div(24)).enable();
let (gclk1, _gclk1_out) = gclk1.enable_gclk_out(pins.pb15);
let (pclk_dpll0, gclk1) = Pclk::enable(tokens.pclks.dpll0, gclk1);
let dpll0 = Dpll::from_pclk(tokens.dpll0, pclk_dpll0)
.loop_div(60, 0)
.enable();
let (gclk0, _dfll, _dpll0) = clocks.gclk0.swap_sources(dfll, dpll0);
let (gclk0, _gclk0_out) = gclk0.enable_gclk_out(pins.pb14);
let (pclk_dpll1, _gclk1) = Pclk::enable(tokens.pclks.dpll1, gclk1);
let dpll1 = Dpll::from_pclk(tokens.dpll1, pclk_dpll1)
.loop_div(50, 0)
.enable();
let (gclk6, _dpll1) = Gclk::from_source(tokens.gclks.gclk6, dpll1);
let gclk6 = gclk6.div(GclkDiv8::Div(200)).enable();
let (_gclk6, _gclk6_out) = gclk6.enable_gclk_out(pins.pb12);
let xosc32k_base = Xosc32kBase::from_crystal(tokens.xosc32k.base, pins.pa00, pins.pa01)
.control_gain_mode(ControlGainMode::HighSpeed)
.on_demand(false)
.run_standby(true)
.enable();
let (xosc1k, xosc32k_base) = Xosc1k::enable(tokens.xosc32k.xosc1k, xosc32k_base);
let (xosc32k, _xosc32k_base) = Xosc32k::enable(tokens.xosc32k.xosc32k, xosc32k_base);
let (gclk2, _xosc32k) = Gclk::from_source(tokens.gclks.gclk2, xosc32k);
let gclk2 = gclk2.div(GclkDiv8::Div(2)).enable();
let (_gclk2, _gclk2_out) = gclk2.enable_gclk_out(pins.pb16);
let (osculp32k, _osculp_base) =
OscUlp32k::enable(tokens.osculp32k.osculp32k, clocks.osculp32k_base);
let (gclk5, _osculp32k) = Gclk::from_source(tokens.gclks.gclk5, osculp32k);
let gclk5 = gclk5.enable();
let (_gclk5, _gclk5_out) = gclk5.enable_gclk_out(pins.pb11);
let (pclk_sercom0, _gclk0) = Pclk::enable(tokens.pclks.sercom0, gclk0);
use atsamd_hal::sercom::uart;
let pads = uart::Pads::default().rx(pins.pa05).tx(pins.pa04);
let mut uart = uart::Config::new(&mclk, device.sercom0, pads, pclk_sercom0.freq())
.baud(115_200.Hz(), BaudMode::Arithmetic(Oversampling::Bits16))
.enable();
uart.enable_interrupts(Flags::RXC);
let (rtc_osc, _xosc1k) = RtcOsc::enable(tokens.rtcosc, xosc1k);
let rtc = Rtc::clock_mode(device.rtc, rtc_osc.freq(), &mut mclk);
writeln!(&mut uart as &mut dyn Write<Error = _>, "RTIC booted!").unwrap();
(SharedResources { uart, rtc }, LocalResources {})
}
#[task(binds = SERCOM0_2, shared = [uart, rtc])]
fn uart(cx: uart::Context) {
let mut uart = cx.shared.uart;
let mut rtc = cx.shared.rtc;
let mut buf = [0];
let _ = uart.lock(|u| u.read(&mut buf).unwrap());
uart.lock(|u| {
writeln!(
u as &mut dyn Write<Error = _>,
"{:#?}",
rtc.lock(|r| r.current_time())
)
.unwrap()
});
}
}