diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 58b91d583..2b270d57f 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -82,8 +82,8 @@ impl TcpSocketStorage { } } -impl NetStorage { - pub fn new() -> Self { +impl Default for NetStorage { + fn default() -> Self { NetStorage { // Placeholder for the real IP address, which is initialized at runtime. ip_addrs: [smoltcp::wire::IpCidr::Ipv6( @@ -671,7 +671,7 @@ pub fn setup( // Note(unwrap): The hardware configuration function is only allowed to be called once. // Unwrapping is intended to panic if called again to prevent re-use of global memory. let store = - cortex_m::singleton!(: NetStorage = NetStorage::new()).unwrap(); + cortex_m::singleton!(: NetStorage = NetStorage::default()).unwrap(); store.ip_addrs[0] = smoltcp::wire::IpCidr::new( smoltcp::wire::IpAddress::Ipv4( diff --git a/src/hardware/signal_generator.rs b/src/hardware/signal_generator.rs index 2eade0924..cc0547521 100644 --- a/src/hardware/signal_generator.rs +++ b/src/hardware/signal_generator.rs @@ -1,4 +1,7 @@ -use crate::{configuration::ADC_SAMPLE_TICKS_LOG2, hardware::dac::DacCode}; +use crate::{ + configuration::ADC_SAMPLE_TICKS_LOG2, hardware::dac::DacCode, + hardware::design_parameters::TIMER_FREQUENCY, +}; use core::convert::{TryFrom, TryInto}; use miniconf::Miniconf; use serde::Deserialize; @@ -52,27 +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 for Config { type Error = Error; fn try_from(config: BasicConfig) -> Result { - // Calculate the frequency tuning words - let frequency_tuning_word: [u32; 2] = { - const LSB_PER_HERTZ: f32 = - (1u64 << (31 + ADC_SAMPLE_TICKS_LOG2)) as f32 / 100.0e6; - let ftw = config.frequency * LSB_PER_HERTZ; - - if config.symmetry <= 0.0 { - [1u32 << 31, ftw as u32] - } else if config.symmetry >= 1.0 { - [ftw as u32, 1u32 << 31] + // Validate symmetry + if config.symmetry < 0.0 || config.symmetry > 1.0 { + return Err(Error::InvalidSymmetry); + } + + 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 ftw < 0.0 || 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] } }; diff --git a/src/net/network_processor.rs b/src/net/network_processor.rs index eeb4f0656..8d7de25cc 100644 --- a/src/net/network_processor.rs +++ b/src/net/network_processor.rs @@ -74,12 +74,10 @@ impl NetworkProcessor { // Service the network stack to process any inbound and outbound traffic. let now = self.clock.current_ms(); - let result = match self.stack.lock(|stack| stack.poll(now)) { + match self.stack.lock(|stack| stack.poll(now)) { Ok(true) => UpdateState::Updated, Ok(false) => UpdateState::NoChange, Err(_) => UpdateState::Updated, - }; - - result + } } }