//! BLE interface. #![no_std] #![no_main] mod i2c; mod logger; mod macros; mod rtc; use clint::HandlerArray; use core::fmt::Write; use core::mem; use cortex_m::asm::wfi; use cortex_m_rt::{entry, exception, ExceptionFrame}; use log::{info, trace, LevelFilter}; #[allow(unused_imports)] extern crate panic_semihosting; use nrf52840_mdk_bsp::{ hal::{ gpio::{Floating, Input, Level, Output, Pin, PushPull}, target::{interrupt, Interrupt, UARTE0}, twis::{self, Twis}, uarte::{self, Baudrate as UartBaudrate, Parity as UartParity, Uarte}, Clocks, Rtc, }, Board, }; const I2C_ADDR: u8 = 4; // TODO: // * set up serial reader for trinket // * set up i²c interface for keyboard reports // * and, finally, bluetooth // Interrupt handler table. static HANDLERS: HandlerArray = HandlerArray::new(); #[entry] fn main() -> ! { let nrf52 = Board::take().unwrap(); let uart_wrapped = logger::WriteWrapper::new(nrf52.cdc); let logger = logger::SerialLogger::new(uart_wrapped); let logger_ref: &'static logger::SerialLogger = unsafe { mem::transmute(&logger) }; log::set_logger(logger_ref).expect("setting logger"); log::set_max_level(LevelFilter::Trace); nrf52.RTC0.intenset.write(|w| w.tick().set()); let mut nvic = nrf52.NVIC; let mut rtc_handler = rtc::setup(Rtc::new(nrf52.RTC0), Clocks::new(nrf52.CLOCK)); let mut twis_handler = i2c::setup(Twis::new( I2C_ADDR, nrf52.TWIS0, twis::Pins { scl: nrf52.pins.P0_06.into_floating_input().degrade(), sda: nrf52.pins.P0_07.into_floating_input().degrade(), }, )); let txp = nrf52 .pins .P0_26 .into_push_pull_output(Level::High) .degrade(); let rxp = nrf52.pins.P0_25.into_floating_input().degrade(); let mut uarte1 = uarte1(nrf52.UARTE1, txp, rxp); HANDLERS.with_overrides(|hs| { hs.register(0, &mut rtc_handler); nvic.enable(Interrupt::RTC0); hs.register(1, &mut twis_handler); nvic.enable(Interrupt::SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); info!("Bootstrap complete."); let mut last_tick = rtc::millis(); last_tick -= last_tick % 1024; loop { let tick = rtc::millis(); if tick >= last_tick + 1024 { last_tick = tick; last_tick -= last_tick % 1024; trace!("."); write!(uarte1, "!").expect("uarte1 write"); } wfi(); } }); unreachable!(); } fn uarte1(uarte: U, tx: Pin>, rx: Pin>) -> Uarte where U: uarte::Instance, { Uarte::new( uarte, uarte::Pins { txd: tx, rxd: rx, cts: None, rts: None, }, UartParity::EXCLUDED, UartBaudrate::BAUD115200, ) } #[exception] fn HardFault(ef: &ExceptionFrame) -> ! { log::logger().flush(); logln_now!("!!! Hard Fault - ef: {:?} !!!", ef); logln_now!("flushing log"); loop { log::logger().flush(); wfi() } } #[interrupt] fn RTC0() { HANDLERS.call(0); } #[interrupt] fn SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0() { HANDLERS.call(1); }