#![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> = 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> = 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> = unsafe { core::mem::transmute(LED) }; red_led.set_high().ok(); logln_now!("*** Default Handler: {} ***", interrupt); } #[exception] fn NonMaskableInt() { let red_led: &mut Pa10> = unsafe { core::mem::transmute(LED) }; red_led.set_high().ok(); logln_now!("+++ NonMaskableInt +++"); } #[exception] fn SVCall() { let red_led: &mut Pa10> = unsafe { core::mem::transmute(LED) }; red_led.set_high().ok(); logln_now!("+++ SVCall +++"); } #[exception] fn PendSV() { let red_led: &mut Pa10> = unsafe { core::mem::transmute(LED) }; red_led.set_high().ok(); logln_now!("+++ PendSV +++"); } #[exception] fn SysTick() { let red_led: &mut Pa10> = 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); }