adc_input: make synchronous and simplify

This commit is contained in:
Astro 2019-03-18 20:56:29 +01:00
parent 1832bd5884
commit 38b7e1b871
3 changed files with 20 additions and 51 deletions

View File

@ -7,31 +7,40 @@ use stm32f4xx_hal::{
stm32::ADC1 as ADC,
};
/// ADC Input
pub struct AdcInput {
/// unused but consumed
_pin: Pin<Analog>,
pub adc: Adc<ADC>,
adc: Adc<ADC>,
}
impl AdcInput {
/// Configure pin into analog mode
pub fn new<MODE>(adc: ADC, pin: Pin<MODE>) -> Self {
let pin = pin.into_analog();
let adc_config = AdcConfig::default()
.scan(Scan::Enabled)
.continuous(Continuous::Single)
.end_of_conversion_interrupt(Eoc::Conversion)
.clock(Clock::Pclk2_div_8);
.clock(Clock::Pclk2_div_2);
let mut adc = Adc::adc1(adc, true, adc_config);
adc.configure_channel(&pin, Sequence::One, SampleTime::Cycles_480);
adc.start_conversion();
AdcInput { _pin: pin, adc }
}
/// Enable the ADC,
/// run a conversion
/// disable the ADC
pub fn read(&mut self) -> u16 {
let sample = self.adc.current_sample();
self.adc.start_conversion();
self.adc.sample_to_millivolts(sample)
let adc = &mut self.adc;
adc.enable();
adc.clear_end_of_conversion_flag();
adc.start_conversion();
let sample = adc.current_sample();
let result = adc.sample_to_millivolts(sample);
adc.wait_for_conversion_sequence();
adc.disable();
result
}
}

View File

@ -1,39 +0,0 @@
use core::cell::RefCell;
use cortex_m::interrupt::Mutex;
use stm32f4xx_hal::{
gpio::{gpioa::PA3 as Pin},
stm32::{NVIC, ADC1 as ADC, interrupt, Interrupt},
};
mod input;
use input::AdcInput;
static ADC_INPUT: Mutex<RefCell<Option<AdcInput>>> = Mutex::new(RefCell::new(None));
static ADC_VALUE: Mutex<RefCell<Option<u16>>> = Mutex::new(RefCell::new(None));
pub fn setup<MODE>(nvic: &mut NVIC, adc: ADC, pin: Pin<MODE>) {
let adc_input = AdcInput::new(adc, pin);
cortex_m::interrupt::free(|cs| {
ADC_INPUT.borrow(cs)
.replace(Some(adc_input))
});
nvic.enable(Interrupt::ADC);
}
pub fn read() -> Option<u16> {
cortex_m::interrupt::free(|cs| {
ADC_VALUE.borrow(cs).borrow_mut().take()
})
}
#[interrupt]
fn ADC() {
cortex_m::interrupt::free(|cs| {
let mut adc_input = ADC_INPUT.borrow(cs)
.borrow_mut();
let value = adc_input.as_mut()
.map(|adc_input| adc_input.read());
*ADC_VALUE.borrow(cs)
.borrow_mut() = value;
});
}

View File

@ -26,6 +26,7 @@ use stm32f4xx_hal::{
use smoltcp::time::Instant;
mod adc_input;
use adc_input::AdcInput;
mod net;
mod server;
use server::Server;
@ -88,7 +89,7 @@ fn main() -> ! {
let mut led_red = Led::red(gpiob.pb14.into_push_pull_output());
info!("ADC init");
adc_input::setup(&mut cp.NVIC, dp.ADC1, gpioa.pa3);
let mut adc_input = AdcInput::new(dp.ADC1, gpioa.pa3);
info!("Eth setup");
stm32_eth::setup_pins(
@ -113,10 +114,8 @@ fn main() -> ! {
led_blue.on();
let now = timer::now().0;
if now - last_output >= OUTPUT_INTERVAL {
let adc_value = adc_input::read();
adc_value.map(|adc_value| {
write!(server, "t={},pa3={}\r\n", now, adc_value).unwrap();
});
let adc_value = adc_input.read();
write!(server, "t={},pa3={}\r\n", now, adc_value).unwrap();
last_output = now;
}
led_blue.off();