diff --git a/examples/adc.rs b/examples/adc.rs new file mode 100644 index 0000000..c08e0aa --- /dev/null +++ b/examples/adc.rs @@ -0,0 +1,68 @@ +#![no_main] +#![no_std] + +use embedded_hal::{adc::OneShot, digital::v2::*}; +use msp430_rt::entry; +use msp430fr2x5x_hal::{ + adc::{AdcConfig, ClockDivider, Predivider, Resolution, SampleTime, SamplingRate}, + gpio::Batch, + pmm::Pmm, + watchdog::Wdt, +}; +use nb::block; +use panic_msp430 as _; + +// If pin 1.1 is between 1V and 2V, the LED on pin 1.0 should light up. +#[entry] +fn main() -> ! { + // Take peripherals and disable watchdog + let periph = msp430fr2355::Peripherals::take().unwrap(); + let _wdt = Wdt::constrain(periph.WDT_A); + + // Configure GPIO + let pmm = Pmm::new(periph.PMM); + let port1 = Batch::new(periph.P1).split(&pmm); + let mut led = port1.pin0.to_output(); + let mut adc_pin = port1.pin1.to_alternate3(); + + // ADC setup + let mut adc = AdcConfig::new( + ClockDivider::_1, + Predivider::_1, + Resolution::_8BIT, + SamplingRate::_50KSPS, + SampleTime::_4, + ) + .use_modclk() + .configure(periph.ADC); + + adc.enable(); + + loop { + // Get ADC count + // .read() is infallible besides nb::WouldBlock, so it's safe to unwrap after block!() + let count = block!( adc.read(&mut adc_pin) ).unwrap(); + let reading_mv = count_to_mv_8bit(count); + + // Turn on LED if voltage between 1000 and 2000mV + if (1000..=2000).contains(&reading_mv) { + led.set_high().ok(); + } else { + led.set_low().ok(); + } + } +} + +fn count_to_mv_8bit(count: u16) -> u16 { + const REF_MV: u32 = 3300; + const RESOLUTION: u32 = 256; + ((count as u32 * REF_MV) / RESOLUTION) as u16 +} + +// 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!(); +} diff --git a/src/adc.rs b/src/adc.rs index 03d2f6b..4f6c928 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -374,9 +374,8 @@ fn disable_adc_reg(adc: &mut ADC) { } } -impl OneShot for Adc +impl OneShot for Adc where - WORD: From, PIN: Channel, { type Error = Infallible; // Only returns WouldBlock @@ -384,13 +383,13 @@ where /// Begins a single ADC conversion if one is not already underway. /// /// If the result is ready it is returned, otherwise returns `WouldBlock` - fn read(&mut self, pin: &mut PIN) -> nb::Result { + fn read(&mut self, pin: &mut PIN) -> nb::Result { if self.is_waiting { if self.adc_is_busy() { return Err(nb::Error::WouldBlock); } else { self.is_waiting = false; - return Ok(self.adc_get_result().into()); + return Ok(self.adc_get_result()); } } self.disable();