Updating config to reject out-of-bounds amplitudes
This commit is contained in:
parent
2f6e2a5ef5
commit
e1cfeff65f
@ -29,7 +29,10 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::{
|
||||||
|
convert::TryInto,
|
||||||
|
sync::atomic::{fence, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use mutex_trait::prelude::*;
|
use mutex_trait::prelude::*;
|
||||||
|
|
||||||
@ -220,8 +223,12 @@ const APP: () = {
|
|||||||
telemetry: TelemetryBuffer::default(),
|
telemetry: TelemetryBuffer::default(),
|
||||||
settings,
|
settings,
|
||||||
signal_generator: [
|
signal_generator: [
|
||||||
SignalGenerator::new(settings.signal_generator[0]),
|
SignalGenerator::new(
|
||||||
SignalGenerator::new(settings.signal_generator[1]),
|
settings.signal_generator[0].try_into().unwrap(),
|
||||||
|
),
|
||||||
|
SignalGenerator::new(
|
||||||
|
settings.signal_generator[1].try_into().unwrap(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,8 +346,11 @@ const APP: () = {
|
|||||||
|
|
||||||
// Update the signal generators
|
// Update the signal generators
|
||||||
c.resources.signal_generator.lock(|generator| {
|
c.resources.signal_generator.lock(|generator| {
|
||||||
generator[0].update_waveform(settings.signal_generator[0]);
|
for i in 0..2 {
|
||||||
generator[1].update_waveform(settings.signal_generator[1]);
|
if let Ok(config) = settings.signal_generator[i].try_into() {
|
||||||
|
generator[i].update_waveform(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let target = settings.stream_target.into();
|
let target = settings.stream_target.into();
|
||||||
|
@ -28,7 +28,10 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::{
|
||||||
|
convert::TryFrom,
|
||||||
|
sync::atomic::{fence, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use mutex_trait::prelude::*;
|
use mutex_trait::prelude::*;
|
||||||
|
|
||||||
@ -269,7 +272,7 @@ const APP: () = {
|
|||||||
frequency_tuning_word,
|
frequency_tuning_word,
|
||||||
],
|
],
|
||||||
// 1V Amplitude
|
// 1V Amplitude
|
||||||
amplitude: DacCode::from(1.0).into(),
|
amplitude: DacCode::try_from(1.0).unwrap().into(),
|
||||||
|
|
||||||
signal: signal_generator::Signal::Cosine,
|
signal: signal_generator::Signal::Cosine,
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,8 @@ use mutex_trait::Mutex;
|
|||||||
use super::design_parameters::{SampleBuffer, SAMPLE_BUFFER_SIZE};
|
use super::design_parameters::{SampleBuffer, SAMPLE_BUFFER_SIZE};
|
||||||
use super::timers;
|
use super::timers;
|
||||||
|
|
||||||
|
use core::convert::TryFrom;
|
||||||
|
|
||||||
use hal::dma::{
|
use hal::dma::{
|
||||||
dma::{DMAReq, DmaConfig},
|
dma::{DMAReq, DmaConfig},
|
||||||
traits::TargetAddress,
|
traits::TargetAddress,
|
||||||
@ -75,21 +77,23 @@ static mut DAC_BUF: [[SampleBuffer; 2]; 2] = [[[0; SAMPLE_BUFFER_SIZE]; 2]; 2];
|
|||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct DacCode(pub u16);
|
pub struct DacCode(pub u16);
|
||||||
|
|
||||||
impl From<f32> for DacCode {
|
impl TryFrom<f32> for DacCode {
|
||||||
fn from(voltage: f32) -> DacCode {
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(voltage: f32) -> Result<DacCode, ()> {
|
||||||
// The DAC output range in bipolar mode (including the external output op-amp) is +/- 4.096
|
// The DAC output range in bipolar mode (including the external output op-amp) is +/- 4.096
|
||||||
// V with 16-bit resolution. The anti-aliasing filter has an additional gain of 2.5.
|
// V with 16-bit resolution. The anti-aliasing filter has an additional gain of 2.5.
|
||||||
let dac_range = 4.096 * 2.5;
|
let dac_range = 4.096 * 2.5;
|
||||||
|
|
||||||
let voltage = if voltage > dac_range {
|
if voltage > dac_range {
|
||||||
dac_range
|
Err(())
|
||||||
} else if voltage < -1. * dac_range {
|
} else if voltage < -1. * dac_range {
|
||||||
-1. * dac_range
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
voltage
|
Ok(DacCode::from(
|
||||||
};
|
(voltage / dac_range * i16::MAX as f32) as i16,
|
||||||
|
))
|
||||||
DacCode::from((voltage / dac_range * i16::MAX as f32) as i16)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::hardware::{dac::DacCode, design_parameters::ADC_SAMPLE_TICKS};
|
use crate::hardware::{dac::DacCode, design_parameters::ADC_SAMPLE_TICKS};
|
||||||
|
use core::convert::{TryFrom, TryInto};
|
||||||
use miniconf::Miniconf;
|
use miniconf::Miniconf;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@ -45,8 +46,17 @@ impl Default for BasicConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BasicConfig> for Config {
|
/// Represents the errors that can occur when attempting to configure the signal generator.
|
||||||
fn from(config: BasicConfig) -> Config {
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// The provided amplitude is out-of-range.
|
||||||
|
InvalidAmplitude,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<BasicConfig> for Config {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(config: BasicConfig) -> Result<Config, Error> {
|
||||||
// Calculate the frequency tuning words
|
// Calculate the frequency tuning words
|
||||||
let frequency_tuning_word: [u32; 2] = {
|
let frequency_tuning_word: [u32; 2] = {
|
||||||
let conversion_factor =
|
let conversion_factor =
|
||||||
@ -72,20 +82,13 @@ impl From<BasicConfig> for Config {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clamp amplitude and symmetry.
|
Ok(Config {
|
||||||
let amplitude = if config.amplitude > 10.24 {
|
amplitude: DacCode::try_from(config.amplitude)
|
||||||
10.24
|
.or(Err(Error::InvalidAmplitude))?
|
||||||
} else if config.amplitude < 0.0 {
|
.into(),
|
||||||
0.0
|
|
||||||
} else {
|
|
||||||
config.amplitude
|
|
||||||
};
|
|
||||||
|
|
||||||
Config {
|
|
||||||
amplitude: DacCode::from(amplitude).into(),
|
|
||||||
signal: config.signal,
|
signal: config.signal,
|
||||||
frequency_tuning_word,
|
frequency_tuning_word,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +113,7 @@ pub struct SignalGenerator {
|
|||||||
impl Default for SignalGenerator {
|
impl Default for SignalGenerator {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
config: BasicConfig::default().into(),
|
config: BasicConfig::default().try_into().unwrap(),
|
||||||
phase_accumulator: 0,
|
phase_accumulator: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,16 +127,16 @@ impl SignalGenerator {
|
|||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
/// The generator
|
/// The generator
|
||||||
pub fn new(config: impl Into<Config>) -> Self {
|
pub fn new(config: Config) -> Self {
|
||||||
Self {
|
Self {
|
||||||
config: config.into(),
|
config,
|
||||||
phase_accumulator: 0,
|
phase_accumulator: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update waveform generation settings.
|
/// Update waveform generation settings.
|
||||||
pub fn update_waveform(&mut self, new_config: impl Into<Config>) {
|
pub fn update_waveform(&mut self, new_config: Config) {
|
||||||
self.config = new_config.into();
|
self.config = new_config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user