//! BLE interface. #![no_std] #![no_main] mod i2c; mod logger; mod macros; mod rtc; mod uarte1; use clint::HandlerArray; use core::mem; use cortex_m::asm::wfi; use cortex_m_rt::{entry, exception, ExceptionFrame}; use log::{info, 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 // * 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_reader, 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 uarte1 = uarte1(nrf52.UARTE1, txp, rxp); let (mut uarte1_reader, mut uarte1_handler) = uarte1::setup(uarte1); 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); hs.register(2, &mut uarte1_handler); nvic.enable(Interrupt::UARTE1); info!("Bootstrap complete."); let mut last_tick = rtc::millis(); last_tick -= last_tick % 1024; let mut buf: [u8; 256] = [0; 256]; loop { let tick = rtc::millis(); if tick >= last_tick + 1024 { last_tick = tick; last_tick -= last_tick % 1024; } if !twis_reader.is_empty() { let mut i = 0; for b in &mut twis_reader { if i == buf.len() { info!("i²c data: {:?}", &buf[0..i]); i = 0; } buf[i] = b; i += 1; } info!("i²c data: {:?}", &buf[0..i]); } if !uarte1_reader.is_empty() { let mut i = 0; for b in &mut uarte1_reader { if i == buf.len() { info!( "serial - {}: {}", i, core::str::from_utf8(&buf[0..i]).expect("utf8conv") ); i = 0; } buf[i] = b; i += 1; } info!( "serial - {}: {}", i, core::str::from_utf8(&buf[0..i]).expect("utf8conv") ); } 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); } #[interrupt] fn UARTE1() { HANDLERS.call(2); }