diff options
Diffstat (limited to 'app/src/main.rs')
-rwxr-xr-x | app/src/main.rs | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/app/src/main.rs b/app/src/main.rs new file mode 100755 index 0000000..1025fae --- /dev/null +++ b/app/src/main.rs @@ -0,0 +1,202 @@ +#![no_std] +#![no_main] +#![feature(const_fn)] +#![feature(const_transmute)] +#![allow(dead_code)] + +mod dotstar; +mod log; +mod macros; +mod rtc; +mod usb; + +//#[allow(unused)] +//use panic_halt; + +use clint::HandlerArray; +use cortex_m::asm::wfi; +use cortex_m_rt::{entry, exception, ExceptionFrame}; +use embedded_hal::digital::v2::OutputPin; +use smart_leds::colors; +use smart_leds_trait::SmartLedsWrite; +use trinket_m0::{ + self as hal, + clock::GenericClockController, + gpio::{OpenDrain, Output, Pa10}, + target_device::{interrupt, Interrupt}, + time::*, + CorePeripherals, Peripherals, +}; + +static HANDLERS: HandlerArray = HandlerArray::new(); + +static mut LED: usize = 0; + +#[entry] +fn main() -> ! { + let mut peripherals = Peripherals::take().expect("taking peripherals"); + let mut core = CorePeripherals::take().expect("taking core peripherals"); + + let mut clocks = GenericClockController::with_internal_32kosc( + peripherals.GCLK, + &mut peripherals.PM, + &mut peripherals.SYSCTRL, + &mut peripherals.NVMCTRL, + ); + + let mut pins = hal::Pins::new(peripherals.PORT); + + let uart = hal::uart( + &mut clocks, + 115_200.hz(), + peripherals.SERCOM0, + &mut core.NVIC, + &mut peripherals.PM, + pins.d3, + pins.d4, + &mut pins.port, + ); + + let mut red_led = pins.d13.into_open_drain_output(&mut pins.port); + red_led.set_low().expect("turning off red LED"); + unsafe { LED = core::mem::transmute(&red_led) } + + let mut processor = log::Processor::new(uart, red_led); + logln_now!("setting up dotstar"); + + let mut dotstar = dotstar::new( + peripherals.SERCOM1, + pins.swdio, + pins.dotstar_di, + pins.dotstar_ci, + &mut pins.port, + &mut peripherals.PM, + &mut clocks, + ); + + let black = [colors::BLACK]; + let blue = [colors::DARK_MAGENTA]; + + logln_now!("setting up timer"); + let mut rtc_handler = rtc::setup(peripherals.RTC, &mut clocks); + + logln_now!("setting up usb host"); + let (mut usb_host, mut usb_handler) = usb::USBHost::new( + peripherals.USB, + pins.usb_sof, + pins.usb_dm, + pins.usb_dp, + Some(pins.usb_host_enable), + &mut pins.port, + &mut clocks, + &mut peripherals.PM, + ); + + logln!("setting up handlers"); + HANDLERS.with_overrides(|hs| { + hs.register(0, &mut rtc_handler); + core.NVIC.enable(Interrupt::RTC); + + hs.register(1, &mut usb_handler); + unsafe { core.NVIC.set_priority(Interrupt::USB, 0) }; + core.NVIC.enable(Interrupt::USB); + + logln!("Boot up complete."); + + let mut last_tick = 0; + loop { + dotstar + .write(black.iter().cloned()) + .expect("turning off dotstar"); + + let tick = rtc::millis(); + if tick >= last_tick + 1_024 { + last_tick = tick; + //logln!("{}: tick", rtc::millis()); + } + + usb_host.task(); + + processor.task(); + + dotstar + .write(blue.iter().cloned()) + .expect("turning on dotstar"); + wfi(); + } + }); + unreachable!(); +} + +#[panic_handler] +fn panic_handler(pi: &core::panic::PanicInfo) -> ! { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("~~~ PANIC ~~~"); + logln_now!("{}", pi); + loop { + wfi() + } +} + +#[exception] +fn HardFault(ef: &ExceptionFrame) -> ! { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("!!! Hard Fault - ef: {:?} !!!", ef); + loop { + wfi() + } +} + +#[exception] +fn DefaultHandler(interrupt: i16) { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("*** Default Handler: {} ***", interrupt); +} + +#[exception] +fn NonMaskableInt() { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("+++ NonMaskableInt +++"); +} + +#[exception] +fn SVCall() { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("+++ SVCall +++"); +} + +#[exception] +fn PendSV() { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("+++ PendSV +++"); +} + +#[exception] +fn SysTick() { + let red_led: &mut Pa10<Output<OpenDrain>> = unsafe { core::mem::transmute(LED) }; + red_led.set_high().ok(); + + logln_now!("+++ SysTick +++"); +} + +#[interrupt] +fn RTC() { + HANDLERS.call(0); +} + +#[interrupt] +fn USB() { + HANDLERS.call(1); +} |