Compare commits
4 Commits
0bc0af7487
...
e6e150dac3
Author | SHA1 | Date |
---|---|---|
Astro | e6e150dac3 | |
Astro | 70127491f6 | |
Astro | 3d6e1f18a6 | |
Astro | 28a71d34d7 |
|
@ -6,7 +6,6 @@ use stm32f4xx_hal::{
|
||||||
time::MegaHertz,
|
time::MegaHertz,
|
||||||
spi,
|
spi,
|
||||||
};
|
};
|
||||||
use crate::units::Volts;
|
|
||||||
|
|
||||||
/// SPI Mode 1
|
/// SPI Mode 1
|
||||||
pub const SPI_MODE: spi::Mode = spi::Mode {
|
pub const SPI_MODE: spi::Mode = spi::Mode {
|
||||||
|
@ -45,9 +44,7 @@ impl<SPI: Transfer<u8>, S: OutputPin> Dac<SPI, S> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, voltage: Volts) -> Result<(), SPI::Error> {
|
pub fn set(&mut self, value: u32) -> Result<(), SPI::Error> {
|
||||||
let value = ((voltage.0 * (MAX_VALUE as f64) / 5.0) as u32)
|
|
||||||
.min(MAX_VALUE);
|
|
||||||
let buf = [
|
let buf = [
|
||||||
(value >> 14) as u8,
|
(value >> 14) as u8,
|
||||||
(value >> 6) as u8,
|
(value >> 6) as u8,
|
||||||
|
|
|
@ -2,7 +2,6 @@ use crate::{
|
||||||
ad5680,
|
ad5680,
|
||||||
channel_state::ChannelState,
|
channel_state::ChannelState,
|
||||||
pins::{ChannelPins, ChannelPinSet},
|
pins::{ChannelPins, ChannelPinSet},
|
||||||
units::Volts,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Marker type for the first channel
|
/// Marker type for the first channel
|
||||||
|
@ -16,27 +15,35 @@ pub struct Channel<C: ChannelPins> {
|
||||||
pub state: ChannelState,
|
pub state: ChannelState,
|
||||||
/// for `i_set`
|
/// for `i_set`
|
||||||
pub dac: ad5680::Dac<C::DacSpi, C::DacSync>,
|
pub dac: ad5680::Dac<C::DacSpi, C::DacSync>,
|
||||||
|
/// 1 / Volts
|
||||||
|
pub dac_factor: f64,
|
||||||
pub shdn: C::Shdn,
|
pub shdn: C::Shdn,
|
||||||
/// stm32f4 integrated adc
|
/// stm32f4 integrated adc
|
||||||
pub adc: C::Adc,
|
pub adc: C::Adc,
|
||||||
|
pub vref_pin: C::VRefPin,
|
||||||
pub itec_pin: C::ItecPin,
|
pub itec_pin: C::ItecPin,
|
||||||
/// feedback from `dac` output
|
/// feedback from `dac` output
|
||||||
pub dac_feedback_pin: C::DacFeedbackPin,
|
pub dac_feedback_pin: C::DacFeedbackPin,
|
||||||
|
pub tec_u_meas_pin: C::TecUMeasPin,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: ChannelPins> Channel<C> {
|
impl<C: ChannelPins> Channel<C> {
|
||||||
pub fn new(pins: ChannelPinSet<C>) -> Self {
|
pub fn new(pins: ChannelPinSet<C>) -> Self {
|
||||||
let state = ChannelState::default();
|
let state = ChannelState::default();
|
||||||
let mut dac = ad5680::Dac::new(pins.dac_spi, pins.dac_sync);
|
let mut dac = ad5680::Dac::new(pins.dac_spi, pins.dac_sync);
|
||||||
let _ = dac.set(Volts(0.0));
|
let _ = dac.set(0);
|
||||||
|
// sensible dummy preset. calibrate_i_set() must be used.
|
||||||
|
let dac_factor = ad5680::MAX_VALUE as f64 / 5.0;
|
||||||
|
|
||||||
Channel {
|
Channel {
|
||||||
state,
|
state,
|
||||||
dac,
|
dac, dac_factor,
|
||||||
shdn: pins.shdn,
|
shdn: pins.shdn,
|
||||||
adc: pins.adc,
|
adc: pins.adc,
|
||||||
|
vref_pin: pins.vref_pin,
|
||||||
itec_pin: pins.itec_pin,
|
itec_pin: pins.itec_pin,
|
||||||
dac_feedback_pin: pins.dac_feedback_pin,
|
dac_feedback_pin: pins.dac_feedback_pin,
|
||||||
|
tec_u_meas_pin: pins.tec_u_meas_pin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
103
src/channels.rs
103
src/channels.rs
|
@ -1,6 +1,8 @@
|
||||||
use stm32f4xx_hal::hal::digital::v2::OutputPin;
|
use stm32f4xx_hal::hal::digital::v2::OutputPin;
|
||||||
use smoltcp::time::Instant;
|
use smoltcp::time::Instant;
|
||||||
|
use log::info;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
ad5680,
|
||||||
ad7172,
|
ad7172,
|
||||||
channel::{Channel, Channel0, Channel1},
|
channel::{Channel, Channel0, Channel1},
|
||||||
channel_state::ChannelState,
|
channel_state::ChannelState,
|
||||||
|
@ -10,10 +12,12 @@ use crate::{
|
||||||
|
|
||||||
pub const CHANNELS: usize = 2;
|
pub const CHANNELS: usize = 2;
|
||||||
|
|
||||||
|
// TODO: -pub
|
||||||
pub struct Channels {
|
pub struct Channels {
|
||||||
pub channel0: Channel<Channel0>,
|
pub channel0: Channel<Channel0>,
|
||||||
pub channel1: Channel<Channel1>,
|
pub channel1: Channel<Channel1>,
|
||||||
pub adc: ad7172::Adc<pins::AdcSpi, pins::AdcNss>,
|
pub adc: ad7172::Adc<pins::AdcSpi, pins::AdcNss>,
|
||||||
|
pub tec_u_meas_adc: pins::TecUMeasAdc,
|
||||||
pub pwm: pins::PwmPins,
|
pub pwm: pins::PwmPins,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +25,7 @@ impl Channels {
|
||||||
pub fn new(pins: pins::Pins) -> Self {
|
pub fn new(pins: pins::Pins) -> Self {
|
||||||
let channel0 = Channel::new(pins.channel0);
|
let channel0 = Channel::new(pins.channel0);
|
||||||
let channel1 = Channel::new(pins.channel1);
|
let channel1 = Channel::new(pins.channel1);
|
||||||
|
let tec_u_meas_adc = pins.tec_u_meas_adc;
|
||||||
let pwm = pins.pwm;
|
let pwm = pins.pwm;
|
||||||
|
|
||||||
let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap();
|
let mut adc = ad7172::Adc::new(pins.adc_spi, pins.adc_nss).unwrap();
|
||||||
|
@ -43,7 +48,7 @@ impl Channels {
|
||||||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
||||||
adc.start_continuous_conversion().unwrap();
|
adc.start_continuous_conversion().unwrap();
|
||||||
|
|
||||||
Channels { channel0, channel1, adc, pwm }
|
Channels { channel0, channel1, adc, tec_u_meas_adc, pwm }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn channel_state<I: Into<usize>>(&mut self, channel: I) -> &mut ChannelState {
|
pub fn channel_state<I: Into<usize>>(&mut self, channel: I) -> &mut ChannelState {
|
||||||
|
@ -80,14 +85,21 @@ impl Channels {
|
||||||
|
|
||||||
/// i_set DAC
|
/// i_set DAC
|
||||||
pub fn set_dac(&mut self, channel: usize, voltage: Volts) {
|
pub fn set_dac(&mut self, channel: usize, voltage: Volts) {
|
||||||
|
let dac_factor = match channel.into() {
|
||||||
|
0 => self.channel0.dac_factor,
|
||||||
|
1 => self.channel1.dac_factor,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let value = (voltage.0 * dac_factor) as u32;
|
||||||
|
info!("set_dac {} {}", voltage, value);
|
||||||
match channel {
|
match channel {
|
||||||
0 => {
|
0 => {
|
||||||
self.channel0.dac.set(voltage).unwrap();
|
self.channel0.dac.set(value).unwrap();
|
||||||
self.channel0.state.dac_value = voltage;
|
self.channel0.state.dac_value = voltage;
|
||||||
self.channel0.shdn.set_high().unwrap();
|
self.channel0.shdn.set_high().unwrap();
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
self.channel1.dac.set(voltage).unwrap();
|
self.channel1.dac.set(value).unwrap();
|
||||||
self.channel1.state.dac_value = voltage;
|
self.channel1.state.dac_value = voltage;
|
||||||
self.channel1.shdn.set_high().unwrap();
|
self.channel1.shdn.set_high().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -138,4 +150,89 @@ impl Channels {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// should be 1.5V
|
||||||
|
pub fn read_vref(&mut self, channel: usize) -> Volts {
|
||||||
|
match channel {
|
||||||
|
0 => {
|
||||||
|
let sample = self.channel0.adc.convert(
|
||||||
|
&self.channel0.vref_pin,
|
||||||
|
stm32f4xx_hal::adc::config::SampleTime::Cycles_480
|
||||||
|
);
|
||||||
|
let mv = self.channel0.adc.sample_to_millivolts(sample);
|
||||||
|
Volts(mv as f64 / 1000.0)
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
let sample = self.channel1.adc.convert(
|
||||||
|
&self.channel1.vref_pin,
|
||||||
|
stm32f4xx_hal::adc::config::SampleTime::Cycles_480
|
||||||
|
);
|
||||||
|
let mv = self.channel1.adc.sample_to_millivolts(sample);
|
||||||
|
Volts(mv as f64 / 1000.0)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_tec_u_meas(&mut self, channel: usize) -> Volts {
|
||||||
|
match channel {
|
||||||
|
0 => {
|
||||||
|
let sample = self.tec_u_meas_adc.convert(
|
||||||
|
&self.channel0.tec_u_meas_pin,
|
||||||
|
stm32f4xx_hal::adc::config::SampleTime::Cycles_480
|
||||||
|
);
|
||||||
|
let mv = self.tec_u_meas_adc.sample_to_millivolts(sample);
|
||||||
|
Volts(mv as f64 / 1000.0)
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
let sample = self.tec_u_meas_adc.convert(
|
||||||
|
&self.channel1.tec_u_meas_pin,
|
||||||
|
stm32f4xx_hal::adc::config::SampleTime::Cycles_480
|
||||||
|
);
|
||||||
|
let mv = self.tec_u_meas_adc.sample_to_millivolts(sample);
|
||||||
|
Volts(mv as f64 / 1000.0)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// for i_set
|
||||||
|
pub fn calibrate_dac_value(&mut self, channel: usize) {
|
||||||
|
let vref = self.read_vref(channel);
|
||||||
|
let mut best_value = 0;
|
||||||
|
let mut best_error = Volts(100.0);
|
||||||
|
for value in 1..=ad5680::MAX_VALUE {
|
||||||
|
match channel {
|
||||||
|
0 => {
|
||||||
|
self.channel0.dac.set(value).unwrap();
|
||||||
|
self.channel0.shdn.set_high().unwrap();
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
self.channel1.dac.set(value).unwrap();
|
||||||
|
self.channel1.shdn.set_high().unwrap();
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
let dac_feedback = self.read_dac_feedback(channel);
|
||||||
|
let error = vref - dac_feedback;
|
||||||
|
if error < Volts(0.0) {
|
||||||
|
info!("calibration done at {} > {}", dac_feedback, vref);
|
||||||
|
break;
|
||||||
|
} else if error < best_error {
|
||||||
|
best_value = value;
|
||||||
|
best_error = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_dac(channel, Volts(0.0));
|
||||||
|
info!("best dac value for {}: {}, itec={}", vref, best_value, self.read_itec(channel));
|
||||||
|
|
||||||
|
let dac_factor = best_value as f64 / vref.0;
|
||||||
|
match channel {
|
||||||
|
0 => self.channel0.dac_factor = dac_factor,
|
||||||
|
1 => self.channel1.dac_factor = dac_factor,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -43,7 +43,7 @@ mod command_parser;
|
||||||
use command_parser::{Command, ShowCommand, PwmPin};
|
use command_parser::{Command, ShowCommand, PwmPin};
|
||||||
mod timer;
|
mod timer;
|
||||||
mod units;
|
mod units;
|
||||||
use units::{Amps, Ohms, Volts};
|
use units::{Ohms, Volts};
|
||||||
mod pid;
|
mod pid;
|
||||||
mod steinhart_hart;
|
mod steinhart_hart;
|
||||||
mod channels;
|
mod channels;
|
||||||
|
@ -93,9 +93,11 @@ fn main() -> ! {
|
||||||
clocks, dp.TIM1, dp.TIM3,
|
clocks, dp.TIM1, dp.TIM3,
|
||||||
dp.GPIOA, dp.GPIOB, dp.GPIOC, dp.GPIOE, dp.GPIOF, dp.GPIOG,
|
dp.GPIOA, dp.GPIOB, dp.GPIOC, dp.GPIOE, dp.GPIOF, dp.GPIOG,
|
||||||
dp.SPI2, dp.SPI4, dp.SPI5,
|
dp.SPI2, dp.SPI4, dp.SPI5,
|
||||||
dp.ADC1, dp.ADC2,
|
dp.ADC1, dp.ADC2, dp.ADC3,
|
||||||
);
|
);
|
||||||
let mut channels = Channels::new(pins);
|
let mut channels = Channels::new(pins);
|
||||||
|
channels.calibrate_dac_value(0);
|
||||||
|
|
||||||
timer::setup(cp.SYST, clocks);
|
timer::setup(cp.SYST, clocks);
|
||||||
|
|
||||||
#[cfg(not(feature = "generate-hwaddr"))]
|
#[cfg(not(feature = "generate-hwaddr"))]
|
||||||
|
@ -143,18 +145,21 @@ fn main() -> ! {
|
||||||
Command::Show(ShowCommand::Input) => {
|
Command::Show(ShowCommand::Input) => {
|
||||||
for channel in 0..CHANNELS {
|
for channel in 0..CHANNELS {
|
||||||
if let Some(adc_data) = channels.channel_state(channel).adc_data {
|
if let Some(adc_data) = channels.channel_state(channel).adc_data {
|
||||||
|
let vref = channels.read_vref(channel);
|
||||||
let dac_feedback = channels.read_dac_feedback(channel);
|
let dac_feedback = channels.read_dac_feedback(channel);
|
||||||
let dac_i = dac_feedback / Ohms(5.0);
|
|
||||||
|
|
||||||
let itec = channels.read_itec(channel);
|
let itec = channels.read_itec(channel);
|
||||||
let tec_i = Amps((itec.0 - 1.5) / 8.0);
|
let tec_i = -(itec - Volts(1.5)) / Ohms(0.4);
|
||||||
|
|
||||||
|
let tec_u_meas = channels.read_tec_u_meas(channel);
|
||||||
|
|
||||||
let state = channels.channel_state(channel);
|
let state = channels.channel_state(channel);
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
socket, "t={} raw{}=0x{:06X} dac_feedback={}/{} itec={} tec={}",
|
socket, "t={} adc_raw{}=0x{:06X} vref={} dac_feedback={} itec={} tec={} tec_u_meas={}",
|
||||||
state.adc_time, channel, adc_data,
|
state.adc_time, channel, adc_data,
|
||||||
dac_feedback, dac_i,
|
vref, dac_feedback,
|
||||||
itec, tec_i,
|
itec, tec_i,
|
||||||
|
tec_u_meas,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
src/pins.rs
25
src/pins.rs
|
@ -16,7 +16,7 @@ use stm32f4xx_hal::{
|
||||||
rcc::Clocks,
|
rcc::Clocks,
|
||||||
pwm::{self, PwmChannels},
|
pwm::{self, PwmChannels},
|
||||||
spi::{Spi, NoMiso},
|
spi::{Spi, NoMiso},
|
||||||
stm32::{ADC1, ADC2, GPIOA, GPIOB, GPIOC, GPIOE, GPIOF, GPIOG, SPI2, SPI4, SPI5, TIM1, TIM3},
|
stm32::{ADC1, ADC2, ADC3, GPIOA, GPIOB, GPIOC, GPIOE, GPIOF, GPIOG, SPI2, SPI4, SPI5, TIM1, TIM3},
|
||||||
time::U32Ext,
|
time::U32Ext,
|
||||||
};
|
};
|
||||||
use crate::channel::{Channel0, Channel1};
|
use crate::channel::{Channel0, Channel1};
|
||||||
|
@ -27,8 +27,10 @@ pub trait ChannelPins {
|
||||||
type DacSync: OutputPin;
|
type DacSync: OutputPin;
|
||||||
type Shdn: OutputPin;
|
type Shdn: OutputPin;
|
||||||
type Adc;
|
type Adc;
|
||||||
|
type VRefPin;
|
||||||
type ItecPin;
|
type ItecPin;
|
||||||
type DacFeedbackPin;
|
type DacFeedbackPin;
|
||||||
|
type TecUMeasPin;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelPins for Channel0 {
|
impl ChannelPins for Channel0 {
|
||||||
|
@ -36,8 +38,10 @@ impl ChannelPins for Channel0 {
|
||||||
type DacSync = PE4<Output<PushPull>>;
|
type DacSync = PE4<Output<PushPull>>;
|
||||||
type Shdn = PE10<Output<PushPull>>;
|
type Shdn = PE10<Output<PushPull>>;
|
||||||
type Adc = Adc<ADC1>;
|
type Adc = Adc<ADC1>;
|
||||||
|
type VRefPin = PA0<Analog>;
|
||||||
type ItecPin = PA6<Analog>;
|
type ItecPin = PA6<Analog>;
|
||||||
type DacFeedbackPin = PA4<Analog>;
|
type DacFeedbackPin = PA4<Analog>;
|
||||||
|
type TecUMeasPin = PC2<Analog>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelPins for Channel1 {
|
impl ChannelPins for Channel1 {
|
||||||
|
@ -45,8 +49,10 @@ impl ChannelPins for Channel1 {
|
||||||
type DacSync = PF6<Output<PushPull>>;
|
type DacSync = PF6<Output<PushPull>>;
|
||||||
type Shdn = PE15<Output<PushPull>>;
|
type Shdn = PE15<Output<PushPull>>;
|
||||||
type Adc = Adc<ADC2>;
|
type Adc = Adc<ADC2>;
|
||||||
|
type VRefPin = PA3<Analog>;
|
||||||
type ItecPin = PB0<Analog>;
|
type ItecPin = PB0<Analog>;
|
||||||
type DacFeedbackPin = PA5<Analog>;
|
type DacFeedbackPin = PA5<Analog>;
|
||||||
|
type TecUMeasPin = PC3<Analog>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SPI peripheral used for communication with the ADC
|
/// SPI peripheral used for communication with the ADC
|
||||||
|
@ -55,19 +61,23 @@ pub type AdcNss = PB12<Output<PushPull>>;
|
||||||
type Dac0Spi = Spi<SPI4, (PE2<Alternate<AF5>>, NoMiso, PE6<Alternate<AF5>>)>;
|
type Dac0Spi = Spi<SPI4, (PE2<Alternate<AF5>>, NoMiso, PE6<Alternate<AF5>>)>;
|
||||||
type Dac1Spi = Spi<SPI5, (PF7<Alternate<AF5>>, NoMiso, PF9<Alternate<AF5>>)>;
|
type Dac1Spi = Spi<SPI5, (PF7<Alternate<AF5>>, NoMiso, PF9<Alternate<AF5>>)>;
|
||||||
|
|
||||||
|
pub type TecUMeasAdc = Adc<ADC3>;
|
||||||
|
|
||||||
pub struct ChannelPinSet<C: ChannelPins> {
|
pub struct ChannelPinSet<C: ChannelPins> {
|
||||||
pub dac_spi: C::DacSpi,
|
pub dac_spi: C::DacSpi,
|
||||||
pub dac_sync: C::DacSync,
|
pub dac_sync: C::DacSync,
|
||||||
pub shdn: C::Shdn,
|
pub shdn: C::Shdn,
|
||||||
pub adc: C::Adc,
|
pub adc: C::Adc,
|
||||||
|
pub vref_pin: C::VRefPin,
|
||||||
pub itec_pin: C::ItecPin,
|
pub itec_pin: C::ItecPin,
|
||||||
pub dac_feedback_pin: C::DacFeedbackPin,
|
pub dac_feedback_pin: C::DacFeedbackPin,
|
||||||
|
pub tec_u_meas_pin: C::TecUMeasPin,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pins {
|
pub struct Pins {
|
||||||
pub adc_spi: AdcSpi,
|
pub adc_spi: AdcSpi,
|
||||||
pub adc_nss: AdcNss,
|
pub adc_nss: AdcNss,
|
||||||
|
pub tec_u_meas_adc: TecUMeasAdc,
|
||||||
pub pwm: PwmPins,
|
pub pwm: PwmPins,
|
||||||
pub channel0: ChannelPinSet<Channel0>,
|
pub channel0: ChannelPinSet<Channel0>,
|
||||||
pub channel1: ChannelPinSet<Channel1>,
|
pub channel1: ChannelPinSet<Channel1>,
|
||||||
|
@ -80,7 +90,7 @@ impl Pins {
|
||||||
tim1: TIM1, tim3: TIM3,
|
tim1: TIM1, tim3: TIM3,
|
||||||
gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpioe: GPIOE, gpiof: GPIOF, gpiog: GPIOG,
|
gpioa: GPIOA, gpiob: GPIOB, gpioc: GPIOC, gpioe: GPIOE, gpiof: GPIOF, gpiog: GPIOG,
|
||||||
spi2: SPI2, spi4: SPI4, spi5: SPI5,
|
spi2: SPI2, spi4: SPI4, spi5: SPI5,
|
||||||
adc1: ADC1, adc2: ADC2,
|
adc1: ADC1, adc2: ADC2, adc3: ADC3,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let gpioa = gpioa.split();
|
let gpioa = gpioa.split();
|
||||||
let gpiob = gpiob.split();
|
let gpiob = gpiob.split();
|
||||||
|
@ -97,6 +107,8 @@ impl Pins {
|
||||||
let adc_spi = Self::setup_spi_adc(clocks, spi2, gpiob.pb10, gpiob.pb14, gpiob.pb15);
|
let adc_spi = Self::setup_spi_adc(clocks, spi2, gpiob.pb10, gpiob.pb14, gpiob.pb15);
|
||||||
let adc_nss = gpiob.pb12.into_push_pull_output();
|
let adc_nss = gpiob.pb12.into_push_pull_output();
|
||||||
|
|
||||||
|
let tec_u_meas_adc = Adc::adc3(adc3, true, Default::default());
|
||||||
|
|
||||||
let pwm = PwmPins::setup(
|
let pwm = PwmPins::setup(
|
||||||
clocks, tim1, tim3,
|
clocks, tim1, tim3,
|
||||||
gpioc.pc6, gpioc.pc7,
|
gpioc.pc6, gpioc.pc7,
|
||||||
|
@ -112,15 +124,19 @@ impl Pins {
|
||||||
let _ = shdn0.set_low();
|
let _ = shdn0.set_low();
|
||||||
let mut adc0 = Adc::adc1(adc1, true, Default::default());
|
let mut adc0 = Adc::adc1(adc1, true, Default::default());
|
||||||
adc0.enable();
|
adc0.enable();
|
||||||
|
let vref0_pin = gpioa.pa0.into_analog();
|
||||||
let itec0_pin = gpioa.pa6.into_analog();
|
let itec0_pin = gpioa.pa6.into_analog();
|
||||||
let dac_feedback0_pin = gpioa.pa4.into_analog();
|
let dac_feedback0_pin = gpioa.pa4.into_analog();
|
||||||
|
let tec_u_meas0_pin = gpioc.pc2.into_analog();
|
||||||
let channel0 = ChannelPinSet {
|
let channel0 = ChannelPinSet {
|
||||||
dac_spi: dac0_spi,
|
dac_spi: dac0_spi,
|
||||||
dac_sync: dac0_sync,
|
dac_sync: dac0_sync,
|
||||||
shdn: shdn0,
|
shdn: shdn0,
|
||||||
adc: adc0,
|
adc: adc0,
|
||||||
|
vref_pin: vref0_pin,
|
||||||
itec_pin: itec0_pin,
|
itec_pin: itec0_pin,
|
||||||
dac_feedback_pin: dac_feedback0_pin,
|
dac_feedback_pin: dac_feedback0_pin,
|
||||||
|
tec_u_meas_pin: tec_u_meas0_pin,
|
||||||
};
|
};
|
||||||
|
|
||||||
let (dac1_spi, dac1_sync) = Self::setup_dac1(
|
let (dac1_spi, dac1_sync) = Self::setup_dac1(
|
||||||
|
@ -131,19 +147,24 @@ impl Pins {
|
||||||
let _ = shdn1.set_low();
|
let _ = shdn1.set_low();
|
||||||
let mut adc1 = Adc::adc2(adc2, true, Default::default());
|
let mut adc1 = Adc::adc2(adc2, true, Default::default());
|
||||||
adc1.enable();
|
adc1.enable();
|
||||||
|
let vref1_pin = gpioa.pa3.into_analog();
|
||||||
let itec1_pin = gpiob.pb0.into_analog();
|
let itec1_pin = gpiob.pb0.into_analog();
|
||||||
let dac_feedback1_pin = gpioa.pa5.into_analog();
|
let dac_feedback1_pin = gpioa.pa5.into_analog();
|
||||||
|
let tec_u_meas1_pin = gpioc.pc3.into_analog();
|
||||||
let channel1 = ChannelPinSet {
|
let channel1 = ChannelPinSet {
|
||||||
dac_spi: dac1_spi,
|
dac_spi: dac1_spi,
|
||||||
dac_sync: dac1_sync,
|
dac_sync: dac1_sync,
|
||||||
shdn: shdn1,
|
shdn: shdn1,
|
||||||
adc: adc1,
|
adc: adc1,
|
||||||
|
vref_pin: vref1_pin,
|
||||||
itec_pin: itec1_pin,
|
itec_pin: itec1_pin,
|
||||||
dac_feedback_pin: dac_feedback1_pin,
|
dac_feedback_pin: dac_feedback1_pin,
|
||||||
|
tec_u_meas_pin: tec_u_meas1_pin,
|
||||||
};
|
};
|
||||||
|
|
||||||
Pins {
|
Pins {
|
||||||
adc_spi, adc_nss,
|
adc_spi, adc_nss,
|
||||||
|
tec_u_meas_adc,
|
||||||
pwm,
|
pwm,
|
||||||
channel0,
|
channel0,
|
||||||
channel1,
|
channel1,
|
||||||
|
|
30
src/units.rs
30
src/units.rs
|
@ -1,10 +1,36 @@
|
||||||
use core::{
|
use core::{
|
||||||
fmt,
|
fmt,
|
||||||
ops::Div,
|
ops::{Add, Div, Neg, Sub},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
macro_rules! impl_add_sub {
|
||||||
|
($Type: ident) => {
|
||||||
|
impl Add<$Type> for $Type {
|
||||||
|
type Output = $Type;
|
||||||
|
fn add(self, rhs: $Type) -> $Type {
|
||||||
|
$Type(self.0 + rhs.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<$Type> for $Type {
|
||||||
|
type Output = $Type;
|
||||||
|
fn sub(self, rhs: $Type) -> $Type {
|
||||||
|
$Type(self.0 - rhs.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Neg for $Type {
|
||||||
|
type Output = $Type;
|
||||||
|
fn neg(self) -> $Type {
|
||||||
|
$Type(-self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||||
pub struct Volts(pub f64);
|
pub struct Volts(pub f64);
|
||||||
|
impl_add_sub!(Volts);
|
||||||
|
|
||||||
impl fmt::Display for Volts {
|
impl fmt::Display for Volts {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -21,6 +47,7 @@ impl Div<Ohms> for Volts {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||||
pub struct Amps(pub f64);
|
pub struct Amps(pub f64);
|
||||||
|
impl_add_sub!(Amps);
|
||||||
|
|
||||||
impl fmt::Display for Amps {
|
impl fmt::Display for Amps {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -29,6 +56,7 @@ impl fmt::Display for Amps {
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||||
pub struct Ohms(pub f64);
|
pub struct Ohms(pub f64);
|
||||||
|
impl_add_sub!(Ohms);
|
||||||
|
|
||||||
impl fmt::Display for Ohms {
|
impl fmt::Display for Ohms {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|
Loading…
Reference in New Issue