From 9466961bd7d4c2a62634823bd0fcad2178746bc7 Mon Sep 17 00:00:00 2001 From: Astro Date: Tue, 12 May 2020 23:16:57 +0200 Subject: [PATCH] main: refactor into Channel/Channels --- src/channel.rs | 34 +++++++++++++++++++++ src/channels.rs | 30 ++++++++++++++++++ src/main.rs | 81 ++++++++++++++++++++----------------------------- src/pins.rs | 72 +++++++++++++++++++++++++++++++++---------- 4 files changed, 153 insertions(+), 64 deletions(-) create mode 100644 src/channel.rs create mode 100644 src/channels.rs diff --git a/src/channel.rs b/src/channel.rs new file mode 100644 index 0000000..624e2f2 --- /dev/null +++ b/src/channel.rs @@ -0,0 +1,34 @@ +use crate::pins::{ChannelPins, ChannelPinSet}; +use crate::channel_state::ChannelState; +use crate::ad5680; + +/// Marker type for the first channel +pub struct Channel0; + +/// Marker type for the second channel +pub struct Channel1; + + +pub struct Channel { + pub state: ChannelState, + pub dac: ad5680::Dac, + pub shdn: C::Shdn, + pub ref_adc: C::RefAdc, + pub ref_pin: C::RefPin, +} + +impl Channel { + pub fn new(pins: ChannelPinSet) -> Self { + let state = ChannelState::default(); + let mut dac = ad5680::Dac::new(pins.dac_spi, pins.dac_sync); + let _ = dac.set(0); + + Channel { + state, + dac, + shdn: pins.shdn, + ref_adc: pins.ref_adc, + ref_pin: pins.ref_pin, + } + } +} diff --git a/src/channels.rs b/src/channels.rs new file mode 100644 index 0000000..5fa918c --- /dev/null +++ b/src/channels.rs @@ -0,0 +1,30 @@ +use crate::{ + ad7172, + channel::{Channel, Channel0, Channel1}, + pins, +}; + +pub struct Channels { + pub channel0: Channel, + pub channel1: Channel, + pub adc: ad7172::Adc, + pub pwm: pins::PwmPins, +} + +impl Channels { + pub fn new(pins: pins::Pins) -> Self { + let channel0 = Channel::new(pins.channel0); + let channel1 = Channel::new(pins.channel1); + let pwm = pins.pwm; + + let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap(); + // Feature not used + adc.set_sync_enable(false).unwrap(); + // Setup channels + adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap(); + adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap(); + adc.calibrate_offset().unwrap(); + + Channels { channel0, channel1, adc, pwm } + } +} diff --git a/src/main.rs b/src/main.rs index d5fc4df..1f5226b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,6 +45,9 @@ use command_parser::{Command, ShowCommand, PwmPin}; mod timer; mod pid; mod steinhart_hart; +mod channels; +use channels::Channels; +mod channel; mod channel_state; use channel_state::ChannelState; @@ -92,24 +95,10 @@ fn main() -> ! { dp.SPI2, dp.SPI4, dp.SPI5, dp.ADC1, dp.ADC2, ); - - let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap(); - // Feature not used - adc.set_sync_enable(false).unwrap(); - // Setup channels - adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap(); - adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap(); - adc.calibrate_offset().unwrap(); - - let mut dac0 = ad5680::Dac::new(pins.dac0_spi, pins.dac0_sync); - dac0.set(0).unwrap(); - let mut dac1 = ad5680::Dac::new(pins.dac1_spi, pins.dac1_sync); - dac1.set(0).unwrap(); - - let mut pwm = pins.pwm; - let mut shdn0 = pins.shdn0; - let mut shdn1 = pins.shdn1; - + let mut channels = Channels::new(pins); + let mut channel_states: [ChannelState; CHANNELS] = [ + ChannelState::default(), ChannelState::default() + ]; timer::setup(cp.SYST, clocks); #[cfg(not(feature = "generate-hwaddr"))] @@ -121,17 +110,13 @@ fn main() -> ! { }; info!("Net hwaddr: {}", hwaddr); - let mut channel_states: [ChannelState; CHANNELS] = [ - ChannelState::default(), ChannelState::default() - ]; - net::run(dp.ETHERNET_MAC, dp.ETHERNET_DMA, hwaddr, |iface| { Server::::run(iface, |server| { loop { let instant = Instant::from_millis(i64::from(timer::now())); // ADC input - adc.data_ready().unwrap().map(|channel| { - let data = adc.read_data().unwrap(); + channels.adc.data_ready().unwrap().map(|channel| { + let data = channels.adc.read_data().unwrap(); let state = &mut channel_states[usize::from(channel)]; state.update_adc(instant, data); @@ -140,12 +125,12 @@ fn main() -> ! { // Forward PID output to i_set DAC match channel { 0 => { - dac0.set(state.dac_value).unwrap(); - shdn0.set_high().unwrap(); + channels.channel0.dac.set(state.dac_value).unwrap(); + channels.channel0.shdn.set_high().unwrap(); } 1 => { - dac1.set(state.dac_value).unwrap(); - shdn1.set_high().unwrap(); + channels.channel1.dac.set(state.dac_value).unwrap(); + channels.channel1.shdn.set_high().unwrap(); } _ => unreachable!(), @@ -189,8 +174,8 @@ fn main() -> ! { } } - let ref0 = pins.ref0_adc.convert( - &pins.ref0_pin, stm32f4xx_hal::adc::config::SampleTime::Cycles_480 + let ref0 = channels.channel0.ref_adc.convert( + &channels.channel0.ref_pin, stm32f4xx_hal::adc::config::SampleTime::Cycles_480 ); let _ = writeln!(socket, "ref0={}", ref0); } @@ -241,14 +226,14 @@ fn main() -> ! { } match channel { 0 => { - show_pwm_channel(socket.deref_mut(), "max_v", &pwm.max_v0); - show_pwm_channel(socket.deref_mut(), "max_i_pos", &pwm.max_i_pos0); - show_pwm_channel(socket.deref_mut(), "max_i_neg", &pwm.max_i_neg0); + show_pwm_channel(socket.deref_mut(), "max_v", &channels.pwm.max_v0); + show_pwm_channel(socket.deref_mut(), "max_i_pos", &channels.pwm.max_i_pos0); + show_pwm_channel(socket.deref_mut(), "max_i_neg", &channels.pwm.max_i_neg0); } 1 => { - show_pwm_channel(socket.deref_mut(), "max_v", &pwm.max_v1); - show_pwm_channel(socket.deref_mut(), "max_i_pos", &pwm.max_i_pos1); - show_pwm_channel(socket.deref_mut(), "max_i_neg", &pwm.max_i_neg1); + show_pwm_channel(socket.deref_mut(), "max_v", &channels.pwm.max_v1); + show_pwm_channel(socket.deref_mut(), "max_i_pos", &channels.pwm.max_i_pos1); + show_pwm_channel(socket.deref_mut(), "max_i_neg", &channels.pwm.max_i_neg1); } _ => unreachable!(), } @@ -269,7 +254,7 @@ fn main() -> ! { } Command::Show(ShowCommand::PostFilter) => { for (channel, _) in channel_states.iter().enumerate() { - match adc.get_postfilter(channel as u8).unwrap() { + match channels.adc.get_postfilter(channel as u8).unwrap() { Some(filter) => { let _ = writeln!( socket, "channel {}: postfilter={:.2} SPS", @@ -294,12 +279,12 @@ fn main() -> ! { channel_states[channel].pid_enabled = false; match channel { 0 => { - dac0.set(duty).unwrap(); - shdn0.set_high().unwrap(); + channels.channel0.dac.set(duty).unwrap(); + channels.channel0.shdn.set_high().unwrap(); } 1 => { - dac1.set(duty).unwrap(); - shdn1.set_high().unwrap(); + channels.channel1.dac.set(duty).unwrap(); + channels.channel1.shdn.set_high().unwrap(); } _ => unreachable!(), } @@ -327,17 +312,17 @@ fn main() -> ! { // Handled above unreachable!(), (0, PwmPin::MaxIPos) => - set_pwm_channel(&mut pwm.max_i_pos0, duty), + set_pwm_channel(&mut channels.pwm.max_i_pos0, duty), (0, PwmPin::MaxINeg) => - set_pwm_channel(&mut pwm.max_i_neg0, duty), + set_pwm_channel(&mut channels.pwm.max_i_neg0, duty), (0, PwmPin::MaxV) => - set_pwm_channel(&mut pwm.max_v0, duty), + set_pwm_channel(&mut channels.pwm.max_v0, duty), (1, PwmPin::MaxIPos) => - set_pwm_channel(&mut pwm.max_i_pos1, duty), + set_pwm_channel(&mut channels.pwm.max_i_pos1, duty), (1, PwmPin::MaxINeg) => - set_pwm_channel(&mut pwm.max_i_neg1, duty), + set_pwm_channel(&mut channels.pwm.max_i_neg1, duty), (1, PwmPin::MaxV) => - set_pwm_channel(&mut pwm.max_v1, duty), + set_pwm_channel(&mut channels.pwm.max_v1, duty), _ => unreachable!(), }; @@ -389,7 +374,7 @@ fn main() -> ! { let filter = ad7172::PostFilter::closest(rate); match filter { Some(filter) => { - adc.set_postfilter(channel as u8, Some(filter)).unwrap(); + channels.adc.set_postfilter(channel as u8, Some(filter)).unwrap(); let _ = writeln!( socket, "channel {}: postfilter set to {:.2} SPS", channel, filter.output_rate().unwrap() diff --git a/src/pins.rs b/src/pins.rs index 50326fe..ae3d6b9 100644 --- a/src/pins.rs +++ b/src/pins.rs @@ -1,6 +1,6 @@ use stm32f4xx_hal::{ adc::Adc, - hal::digital::v2::OutputPin, + hal::{blocking::spi::Transfer, digital::v2::OutputPin}, gpio::{ AF5, Alternate, Analog, gpioa::*, @@ -22,25 +22,51 @@ use stm32f4xx_hal::{ use crate::channel::{Channel0, Channel1}; +pub trait ChannelPins { + type DacSpi: Transfer; + type DacSync: OutputPin; + type Shdn: OutputPin; + type RefAdc; + type RefPin; +} + +impl ChannelPins for Channel0 { + type DacSpi = Dac0Spi; + type DacSync = PE4>; + type Shdn = PE10>; + type RefAdc = Adc; + type RefPin = PA0; +} + +impl ChannelPins for Channel1 { + type DacSpi = Dac1Spi; + type DacSync = PF6>; + type Shdn = PE15>; + type RefAdc = Adc; + type RefPin = PA3; +} + /// SPI peripheral used for communication with the ADC -type AdcSpi = Spi>, PB14>, PB15>)>; +pub type AdcSpi = Spi>, PB14>, PB15>)>; +pub type AdcNss = PB12>; type Dac0Spi = Spi>, NoMiso, PE6>)>; type Dac1Spi = Spi>, NoMiso, PF9>)>; + +pub struct ChannelPinSet { + pub dac_spi: C::DacSpi, + pub dac_sync: C::DacSync, + pub shdn: C::Shdn, + pub ref_adc: C::RefAdc, + pub ref_pin: C::RefPin, +} + pub struct Pins { pub adc_spi: AdcSpi, - pub adc_nss: PB12>, + pub adc_nss: AdcNss, pub pwm: PwmPins, - pub dac0_spi: Dac0Spi, - pub dac0_sync: PE4>, - pub shdn0: PE10>, - pub ref0_adc: Adc, - pub ref0_pin: PA0, - pub dac1_spi: Dac1Spi, - pub dac1_sync: PF6>, - pub shdn1: PE15>, - pub ref1_adc: Adc, - pub ref1_pin: PA3, + pub channel0: ChannelPinSet, + pub channel1: ChannelPinSet, } impl Pins { @@ -83,6 +109,13 @@ impl Pins { let mut ref0_adc = Adc::adc1(adc1, true, Default::default()); ref0_adc.enable(); let ref0_pin = gpioa.pa0.into_analog(); + let channel0 = ChannelPinSet { + dac_spi: dac0_spi, + dac_sync: dac0_sync, + shdn: shdn0, + ref_adc: ref0_adc, + ref_pin: ref0_pin, + }; let (dac1_spi, dac1_sync) = Self::setup_dac1( clocks, spi5, @@ -91,14 +124,21 @@ impl Pins { let mut shdn1 = gpioe.pe15.into_push_pull_output(); let _ = shdn1.set_low(); let mut ref1_adc = Adc::adc2(adc2, true, Default::default()); - let ref1_pin = gpioa.pa3.into_analog(); ref1_adc.enable(); + let ref1_pin = gpioa.pa3.into_analog(); + let channel1 = ChannelPinSet { + dac_spi: dac1_spi, + dac_sync: dac1_sync, + shdn: shdn1, + ref_adc: ref1_adc, + ref_pin: ref1_pin, + }; Pins { adc_spi, adc_nss, pwm, - dac0_spi, dac0_sync, shdn0, ref0_adc, ref0_pin, - dac1_spi, dac1_sync, shdn1, ref1_adc, ref1_pin, + channel0, + channel1, } }