#![no_main] #![no_std] use embedded_hal::digital::v2::*; use embedded_hal::prelude::*; use msp430_rt::entry; use msp430fr2x5x_hal::{ capture::{CapTrigger, CaptureParts3, OverCapture, TimerConfig}, clock::{ClockConfig, DcoclkFreqSel, MclkDiv, SmclkDiv}, fram::Fram, gpio::Batch, pmm::Pmm, prelude::*, serial::*, watchdog::Wdt, }; use nb::block; use panic_msp430 as _; use void::ResultVoidExt; // Connect push button input to P1.6. When button is pressed, putty should print the # of cycles // since the last press. Sometimes we get 2 consecutive readings due to lack of debouncing. #[entry] fn main() -> ! { let periph = msp430fr2355::Peripherals::take().unwrap(); let mut fram = Fram::new(periph.FRCTL); Wdt::constrain(periph.WDT_A); let pmm = Pmm::new(periph.PMM); let p4 = Batch::new(periph.P4).split(&pmm); let mut p1 = Batch::new(periph.P1) .config_pin0(|p| p.to_output()) .split(&pmm); let (smclk, aclk) = ClockConfig::new(periph.CS) .mclk_dcoclk(DcoclkFreqSel::_1MHz, MclkDiv::_1) .smclk_on(SmclkDiv::_1) .aclk_vloclk() .freeze(&mut fram); let mut tx = SerialConfig::new( periph.E_USCI_A1, BitOrder::LsbFirst, BitCount::EightBits, StopBits::OneStopBit, Parity::NoParity, Loopback::NoLoop, 9600, ) .use_smclk(&smclk) .tx_only(p4.pin3.to_alternate1()); let captures = CaptureParts3::config(periph.TB0, TimerConfig::aclk(&aclk)) .config_cap1_input_A(p1.pin6.to_alternate2()) .config_cap1_trigger(CapTrigger::FallingEdge) .commit(); let mut capture = captures.cap1; let mut last_cap = 0; loop { match block!(capture.capture()) { Ok(cap) => { let diff = cap.wrapping_sub(last_cap); last_cap = cap; p1.pin0.set_high().void_unwrap(); print_num(&mut tx, diff); } Err(OverCapture(_)) => { p1.pin0.set_high().void_unwrap(); write(&mut tx, '!'); write(&mut tx, '\n'); } } } } fn print_num(tx: &mut Tx, num: u16) { write(tx, '0'); write(tx, 'x'); print_hex(tx, num >> 12); print_hex(tx, (num >> 8) & 0xF); print_hex(tx, (num >> 4) & 0xF); print_hex(tx, num & 0xF); write(tx, '\n'); } fn print_hex(tx: &mut Tx, h: u16) { let c = match h { 0 => '0', 1 => '1', 2 => '2', 3 => '3', 4 => '4', 5 => '5', 6 => '6', 7 => '7', 8 => '8', 9 => '9', 10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f', _ => '?', }; write(tx, c); } fn write(tx: &mut Tx, ch: char) { block!(tx.write(ch as u8)).void_unwrap(); } // The compiler will emit calls to the abort() compiler intrinsic if debug assertions are // enabled (default for dev profile). MSP430 does not actually have meaningful abort() support // so for now, we create our own in each application where debug assertions are present. #[no_mangle] extern "C" fn abort() -> ! { panic!(); }