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