signal_generator: fix config conversion, clarify

master
Robert Jördens 2021-07-21 13:11:39 +02:00
parent 0d6402e81a
commit f4fd752d54
1 changed files with 29 additions and 14 deletions

View File

@ -55,28 +55,43 @@ impl Default for BasicConfig {
pub enum Error {
/// The provided amplitude is out-of-range.
InvalidAmplitude,
/// The provided symmetry is out of range.
InvalidSymmetry,
/// The provided frequency is out of range.
InvalidFrequency,
}
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] = {
const LSB_PER_HERTZ: f32 = (1u64 << (31 + ADC_SAMPLE_TICKS_LOG2))
as f32
/ (TIMER_FREQUENCY.0 * 1_000_000) as f32;
let ftw = config.frequency * LSB_PER_HERTZ;
// Validate symmetry
if config.symmetry < 0.0 || config.symmetry > 1.0 {
return Err(Error::InvalidSymmetry);
}
if config.symmetry <= ftw / u32::MAX as f32 {
[1u32 << 31, ftw as u32]
} else if 1. - config.symmetry <= ftw / u32::MAX as f32 {
[ftw as u32, 1u32 << 31]
const LSB_PER_HERTZ: f32 = (1u64 << (31 + ADC_SAMPLE_TICKS_LOG2))
as f32
/ (TIMER_FREQUENCY.0 * 1_000_000) as f32;
let ftw = config.frequency * LSB_PER_HERTZ;
// Validate base frequency tuning word to be below Nyquist.
const NYQUIST: f32 = (1u32 << 31) as _;
if 2.0 * ftw > NYQUIST {
return Err(Error::InvalidFrequency);
}
// Calculate the frequency tuning words.
let frequency_tuning_word = {
let ftws = [ftw / config.symmetry, ftw / (1.0 - config.symmetry)];
// Clip both frequency tuning words to within Nyquist before rounding.
if ftws[0] > NYQUIST {
[1u32 << 31, ftws[1] as u32]
} else if ftws[1] > NYQUIST {
[ftws[0] as u32, 1u32 << 31]
} else {
[
(ftw / config.symmetry) as u32,
(ftw / (1.0 - config.symmetry)) as u32,
]
[ftws[0] as u32, ftws[1] as u32]
}
};