forked from M-Labs/thermostat
adc_input: make synchronous and simplify
This commit is contained in:
parent
1832bd5884
commit
38b7e1b871
|
@ -7,31 +7,40 @@ use stm32f4xx_hal::{
|
||||||
stm32::ADC1 as ADC,
|
stm32::ADC1 as ADC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// ADC Input
|
||||||
pub struct AdcInput {
|
pub struct AdcInput {
|
||||||
/// unused but consumed
|
/// unused but consumed
|
||||||
_pin: Pin<Analog>,
|
_pin: Pin<Analog>,
|
||||||
pub adc: Adc<ADC>,
|
adc: Adc<ADC>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AdcInput {
|
impl AdcInput {
|
||||||
|
/// Configure pin into analog mode
|
||||||
pub fn new<MODE>(adc: ADC, pin: Pin<MODE>) -> Self {
|
pub fn new<MODE>(adc: ADC, pin: Pin<MODE>) -> Self {
|
||||||
let pin = pin.into_analog();
|
let pin = pin.into_analog();
|
||||||
let adc_config = AdcConfig::default()
|
let adc_config = AdcConfig::default()
|
||||||
.scan(Scan::Enabled)
|
.scan(Scan::Enabled)
|
||||||
.continuous(Continuous::Single)
|
.continuous(Continuous::Single)
|
||||||
.end_of_conversion_interrupt(Eoc::Conversion)
|
.clock(Clock::Pclk2_div_2);
|
||||||
.clock(Clock::Pclk2_div_8);
|
|
||||||
let mut adc = Adc::adc1(adc, true, adc_config);
|
let mut adc = Adc::adc1(adc, true, adc_config);
|
||||||
|
|
||||||
adc.configure_channel(&pin, Sequence::One, SampleTime::Cycles_480);
|
adc.configure_channel(&pin, Sequence::One, SampleTime::Cycles_480);
|
||||||
adc.start_conversion();
|
|
||||||
|
|
||||||
AdcInput { _pin: pin, adc }
|
AdcInput { _pin: pin, adc }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enable the ADC,
|
||||||
|
/// run a conversion
|
||||||
|
/// disable the ADC
|
||||||
pub fn read(&mut self) -> u16 {
|
pub fn read(&mut self) -> u16 {
|
||||||
let sample = self.adc.current_sample();
|
let adc = &mut self.adc;
|
||||||
self.adc.start_conversion();
|
adc.enable();
|
||||||
self.adc.sample_to_millivolts(sample)
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -26,6 +26,7 @@ use stm32f4xx_hal::{
|
||||||
use smoltcp::time::Instant;
|
use smoltcp::time::Instant;
|
||||||
|
|
||||||
mod adc_input;
|
mod adc_input;
|
||||||
|
use adc_input::AdcInput;
|
||||||
mod net;
|
mod net;
|
||||||
mod server;
|
mod server;
|
||||||
use server::Server;
|
use server::Server;
|
||||||
|
@ -88,7 +89,7 @@ fn main() -> ! {
|
||||||
let mut led_red = Led::red(gpiob.pb14.into_push_pull_output());
|
let mut led_red = Led::red(gpiob.pb14.into_push_pull_output());
|
||||||
|
|
||||||
info!("ADC init");
|
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");
|
info!("Eth setup");
|
||||||
stm32_eth::setup_pins(
|
stm32_eth::setup_pins(
|
||||||
|
@ -113,10 +114,8 @@ fn main() -> ! {
|
||||||
led_blue.on();
|
led_blue.on();
|
||||||
let now = timer::now().0;
|
let now = timer::now().0;
|
||||||
if now - last_output >= OUTPUT_INTERVAL {
|
if now - last_output >= OUTPUT_INTERVAL {
|
||||||
let adc_value = adc_input::read();
|
let adc_value = adc_input.read();
|
||||||
adc_value.map(|adc_value| {
|
|
||||||
write!(server, "t={},pa3={}\r\n", now, adc_value).unwrap();
|
write!(server, "t={},pa3={}\r\n", now, adc_value).unwrap();
|
||||||
});
|
|
||||||
last_output = now;
|
last_output = now;
|
||||||
}
|
}
|
||||||
led_blue.off();
|
led_blue.off();
|
||||||
|
|
Loading…
Reference in New Issue