Compare commits

...

4 Commits

Author SHA1 Message Date
Astro 53930497e4 ad5680: fix MAX_VALUE 2020-05-13 23:19:20 +02:00
Astro 9ecf705420 ad5680: fix SPI_MODE 2020-05-13 23:19:09 +02:00
Astro c0079007f2 do not overwrite dac value when pid is disengaged 2020-05-13 22:11:25 +02:00
Astro b9d05ff274 channels: add set_dac() 2020-05-13 21:05:07 +02:00
4 changed files with 27 additions and 32 deletions

View File

@ -7,14 +7,15 @@ use stm32f4xx_hal::{
spi,
};
/// SPI Mode 1
pub const SPI_MODE: spi::Mode = spi::Mode {
polarity: spi::Polarity::IdleHigh,
phase: spi::Phase::CaptureOnFirstTransition,
polarity: spi::Polarity::IdleLow,
phase: spi::Phase::CaptureOnSecondTransition,
};
/// 30 MHz
pub const SPI_CLOCK: MegaHertz = MegaHertz(30);
pub const MAX_VALUE: u32 = 0x20000;
pub const MAX_VALUE: u32 = 0x3FFFF;
/// [AD5680](https://www.analog.com/media/en/technical-documentation/data-sheets/AD5680.pdf) DAC
pub struct Dac<SPI: Transfer<u8>, S: OutputPin> {

View File

@ -26,7 +26,7 @@ impl Default for ChannelState {
impl ChannelState {
/// Update PID state on ADC input, calculate new DAC output
pub fn update_pid(&mut self, now: Instant, adc_data: u32) {
pub fn update_pid(&mut self, now: Instant, adc_data: u32) -> u32 {
self.adc_data = Some(adc_data);
self.adc_time = now;
@ -34,6 +34,6 @@ impl ChannelState {
let input = (adc_data as f64) / (ad7172::MAX_VALUE as f64);
let temperature = self.sh.get_temperature(input);
let output = self.pid.update(temperature);
self.dac_value = (output * (ad5680::MAX_VALUE as f64)) as u32;
(output * (ad5680::MAX_VALUE as f64)) as u32
}
}

View File

@ -48,34 +48,40 @@ impl Channels {
let dac_value = {
let state = self.channel_state(channel);
state.update_pid(instant, data);
let pid_output = state.update_pid(instant, data);
if state.pid_engaged {
Some(state.dac_value)
Some(pid_output)
} else {
None
}
};
if let Some(dac_value) = dac_value {
// Forward PID output to i_set DAC
match channel {
0 => {
self.channel0.dac.set(dac_value).unwrap();
self.channel0.shdn.set_high().unwrap();
}
1 => {
self.channel1.dac.set(dac_value).unwrap();
self.channel1.shdn.set_high().unwrap();
}
_ =>
unreachable!(),
}
self.set_dac(channel.into(), dac_value);
}
channel
})
}
/// i_set DAC
pub fn set_dac(&mut self, channel: usize, duty: u32) {
match channel {
0 => {
self.channel0.dac.set(duty).unwrap();
self.channel0.state.dac_value = duty;
self.channel0.shdn.set_high().unwrap();
}
1 => {
self.channel1.dac.set(duty).unwrap();
self.channel1.state.dac_value = duty;
self.channel1.shdn.set_high().unwrap();
}
_ => unreachable!(),
}
}
pub fn read_ref_adc(&mut self, channel: usize) -> u16 {
match channel {
0 => self.channel0.ref_adc.convert(

View File

@ -16,7 +16,6 @@ use cortex_m_rt::entry;
use stm32f4xx_hal::{
hal::{
self,
digital::v2::OutputPin,
watchdog::{WatchdogEnable, Watchdog},
},
rcc::RccExt,
@ -253,18 +252,7 @@ fn main() -> ! {
}
Command::Pwm { channel, pin: PwmPin::ISet, duty } if duty <= ad5680::MAX_VALUE => {
channels.channel_state(channel).pid_engaged = false;
match channel {
0 => {
channels.channel0.dac.set(duty).unwrap();
channels.channel0.shdn.set_high().unwrap();
}
1 => {
channels.channel1.dac.set(duty).unwrap();
channels.channel1.shdn.set_high().unwrap();
}
_ => unreachable!(),
}
channels.channel_state(channel).dac_value = duty;
channels.set_dac(channel, duty);
let _ = writeln!(
socket, "channel {}: PWM duty cycle manually set to {}/{}",
channel, duty, ad5680::MAX_VALUE