forked from M-Labs/thermostat
main: refactor into Channel/Channels
This commit is contained in:
parent
6dd6bb2e1e
commit
9466961bd7
|
@ -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<C: ChannelPins> {
|
||||
pub state: ChannelState,
|
||||
pub dac: ad5680::Dac<C::DacSpi, C::DacSync>,
|
||||
pub shdn: C::Shdn,
|
||||
pub ref_adc: C::RefAdc,
|
||||
pub ref_pin: C::RefPin,
|
||||
}
|
||||
|
||||
impl<C: ChannelPins> Channel<C> {
|
||||
pub fn new(pins: ChannelPinSet<C>) -> 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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
use crate::{
|
||||
ad7172,
|
||||
channel::{Channel, Channel0, Channel1},
|
||||
pins,
|
||||
};
|
||||
|
||||
pub struct Channels {
|
||||
pub channel0: Channel<Channel0>,
|
||||
pub channel1: Channel<Channel1>,
|
||||
pub adc: ad7172::Adc<pins::AdcSpi, pins::AdcNss>,
|
||||
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 }
|
||||
}
|
||||
}
|
81
src/main.rs
81
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::<Session>::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()
|
||||
|
|
72
src/pins.rs
72
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<u8>;
|
||||
type DacSync: OutputPin;
|
||||
type Shdn: OutputPin;
|
||||
type RefAdc;
|
||||
type RefPin;
|
||||
}
|
||||
|
||||
impl ChannelPins for Channel0 {
|
||||
type DacSpi = Dac0Spi;
|
||||
type DacSync = PE4<Output<PushPull>>;
|
||||
type Shdn = PE10<Output<PushPull>>;
|
||||
type RefAdc = Adc<ADC1>;
|
||||
type RefPin = PA0<Analog>;
|
||||
}
|
||||
|
||||
impl ChannelPins for Channel1 {
|
||||
type DacSpi = Dac1Spi;
|
||||
type DacSync = PF6<Output<PushPull>>;
|
||||
type Shdn = PE15<Output<PushPull>>;
|
||||
type RefAdc = Adc<ADC2>;
|
||||
type RefPin = PA3<Analog>;
|
||||
}
|
||||
|
||||
/// SPI peripheral used for communication with the ADC
|
||||
type AdcSpi = Spi<SPI2, (PB10<Alternate<AF5>>, PB14<Alternate<AF5>>, PB15<Alternate<AF5>>)>;
|
||||
pub type AdcSpi = Spi<SPI2, (PB10<Alternate<AF5>>, PB14<Alternate<AF5>>, PB15<Alternate<AF5>>)>;
|
||||
pub type AdcNss = PB12<Output<PushPull>>;
|
||||
type Dac0Spi = Spi<SPI4, (PE2<Alternate<AF5>>, NoMiso, PE6<Alternate<AF5>>)>;
|
||||
type Dac1Spi = Spi<SPI5, (PF7<Alternate<AF5>>, NoMiso, PF9<Alternate<AF5>>)>;
|
||||
|
||||
|
||||
pub struct ChannelPinSet<C: ChannelPins> {
|
||||
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<Output<PushPull>>,
|
||||
pub adc_nss: AdcNss,
|
||||
pub pwm: PwmPins,
|
||||
pub dac0_spi: Dac0Spi,
|
||||
pub dac0_sync: PE4<Output<PushPull>>,
|
||||
pub shdn0: PE10<Output<PushPull>>,
|
||||
pub ref0_adc: Adc<ADC1>,
|
||||
pub ref0_pin: PA0<Analog>,
|
||||
pub dac1_spi: Dac1Spi,
|
||||
pub dac1_sync: PF6<Output<PushPull>>,
|
||||
pub shdn1: PE15<Output<PushPull>>,
|
||||
pub ref1_adc: Adc<ADC2>,
|
||||
pub ref1_pin: PA3<Analog>,
|
||||
pub channel0: ChannelPinSet<Channel0>,
|
||||
pub channel1: ChannelPinSet<Channel1>,
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue