From 03af97ef5ef77e3f62bf5e088580ec093819b82b Mon Sep 17 00:00:00 2001 From: Astro Date: Mon, 11 Mar 2019 18:23:52 +0100 Subject: [PATCH] Add adc_input --- Cargo.toml | 11 ++++---- src/adc_input/input.rs | 37 +++++++++++++++++++++++++ src/adc_input/mod.rs | 39 +++++++++++++++++++++++++++ src/main.rs | 61 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 135 insertions(+), 13 deletions(-) create mode 100644 src/adc_input/input.rs create mode 100644 src/adc_input/mod.rs diff --git a/Cargo.toml b/Cargo.toml index ae0597b..8c669f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,16 +19,17 @@ features = [] default-target = "thumbv7em-none-eabihf" [dependencies] -volatile-register = "0.2" -aligned = "0.3" -panic-itm = "0.4" +panic-abort = "0.3.1" cortex-m = "0.5" cortex-m-rt = { version = "0.6", features = ["device"] } cortex-m-semihosting = "0.3" -stm32f429 = { version = "0.6.1", features = ["rt"] } -stm32-eth = { version = "0.0.1", features = ["target-stm32f429", "smoltcp-phy"] } +stm32f4 = { version = "0.6", features = ["rt", "stm32f429"] } +embedded-hal = "0.2" +stm32f4xx-hal = { git = "https://github.com/stm32-rs/stm32f4xx-hal.git", features = ["rt", "stm32f429"] } +#stm32f4xx-hal = { version = "0.3.0", features = ["rt", "stm32f429"] } +stm32-eth = { version = "0.1.0", features = ["smoltcp-phy", "nucleo-f429zi"] } smoltcp = { version = "0.5.0", default-features = false, features = ["proto-ipv4", "proto-ipv6", "socket-icmp", "socket-udp", "socket-tcp", "log", "verbose"] } diff --git a/src/adc_input/input.rs b/src/adc_input/input.rs new file mode 100644 index 0000000..a386c73 --- /dev/null +++ b/src/adc_input/input.rs @@ -0,0 +1,37 @@ +use stm32f4xx_hal::{ + adc::{ + Adc, + config::*, + }, + gpio::{Analog, gpioa::PA3 as Pin}, + stm32::ADC1 as ADC, +}; + +pub struct AdcInput { + /// unused but consumed + _pin: Pin, + pub adc: Adc, +} + +impl AdcInput { + pub fn new(adc: ADC, pin: Pin) -> 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); + 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 } + } + + pub fn read(&mut self) -> u16 { + let sample = self.adc.current_sample(); + self.adc.start_conversion(); + self.adc.sample_to_millivolts(sample) + } +} diff --git a/src/adc_input/mod.rs b/src/adc_input/mod.rs new file mode 100644 index 0000000..443df1e --- /dev/null +++ b/src/adc_input/mod.rs @@ -0,0 +1,39 @@ +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>> = Mutex::new(RefCell::new(None)); +static ADC_VALUE: Mutex>> = Mutex::new(RefCell::new(None)); + +pub fn setup(nvic: &mut NVIC, adc: ADC, pin: Pin) { + 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 { + 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; + }); +} diff --git a/src/main.rs b/src/main.rs index 69f0d32..d05fd0d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,63 @@ #![no_std] #![no_main] -// extern crate cortex_m; -// extern crate cortex_m_rt; -// extern crate cortex_m_semihosting; -extern crate stm32f429 as board; -// extern crate stm32_eth as eth; -// extern crate smoltcp; #[allow(unused_extern_crates)] -extern crate panic_itm; +extern crate panic_abort; +use cortex_m::asm::wfi; use cortex_m_rt::entry; +use embedded_hal::watchdog::{WatchdogEnable, Watchdog}; +use stm32f4xx_hal::{ + rcc::RccExt, + gpio::GpioExt, + watchdog::IndependentWatchdog, + time::U32Ext, + stm32::{CorePeripherals, Peripherals}, +}; + +use core::fmt::Write; +use cortex_m_semihosting::hio; + +mod adc_input; #[entry] fn main() -> ! { - loop {} + let mut stdout = hio::hstdout().unwrap(); + writeln!(stdout, "Hello").unwrap(); + + let mut cp = CorePeripherals::take().unwrap(); + let dp = Peripherals::take().unwrap(); + stm32_eth::setup(&dp.RCC, &dp.SYSCFG); + let _clocks = dp.RCC.constrain() + .cfgr + .sysclk(168.mhz()) + .hclk(84.mhz()) + .pclk1(32.mhz()) + .pclk2(64.mhz()) + .freeze(); + + let mut wd = IndependentWatchdog::new(dp.IWDG); + wd.start(8000u32.ms()); + wd.feed(); + + let gpioa = dp.GPIOA.split(); + let gpiob = dp.GPIOB.split(); + let gpioc = dp.GPIOC.split(); + let gpiog = dp.GPIOG.split(); + + stm32_eth::setup_pins( + gpioa.pa1, gpioa.pa2, gpioa.pa7, gpiob.pb13, gpioc.pc1, + gpioc.pc4, gpioc.pc5, gpiog.pg11, gpiog.pg13 + ); + + adc_input::setup(&mut cp.NVIC, dp.ADC1, gpioa.pa3); + + loop { + let adc_value = adc_input::read(); + adc_value.map(|adc_value| { + writeln!(stdout, "pa3: {}mV", adc_value).unwrap(); + }); + wd.feed(); + wfi(); + } }