From fb580edcee74e7585f38c39d51d25a8e0b169e02 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 13:11:32 +0200 Subject: [PATCH 1/8] Updating Stabilizer to remove compile-time config parameters --- docs/pages/getting-started.md | 22 ++------------ src/bin/dual-iir.rs | 35 +++++++++++++++------- src/bin/lockin.rs | 46 +++++++++++++++------------- src/configuration.rs | 41 ------------------------- src/hardware/adc.rs | 18 ++++++----- src/hardware/dac.rs | 20 ++++++++----- src/hardware/design_parameters.rs | 13 ++++---- src/hardware/setup.rs | 20 +++++++++---- src/hardware/signal_generator.rs | 50 ++++++++++++++++++++----------- src/net/miniconf_client.rs | 13 +++++--- src/net/mod.rs | 5 ++++ src/net/telemetry.rs | 13 +++++--- 12 files changed, 150 insertions(+), 146 deletions(-) delete mode 100644 src/configuration.rs diff --git a/docs/pages/getting-started.md b/docs/pages/getting-started.md index 3fefa77..014c081 100644 --- a/docs/pages/getting-started.md +++ b/docs/pages/getting-started.md @@ -17,7 +17,6 @@ nav_order: 2 There are a number of steps that must be completed when first getting started with Stabilizer. 1. Update the Stabilizer Application - 1. Set parameters in the firmware source code, such as IP addresses and sampling rate. 1. Build the application by compiling the source code. 1. Upload the application and programming it onto the device. 1. Set up MQTT for telemetry and configuration. @@ -31,23 +30,6 @@ Firmware is compiled and loaded onto Stabilizer to program a specific applicatio After receiving the Stabilizer hardware, you will need to flash firmware onto the device to use your desired application. -## Configuring Firmware - -Stabilizer firmware contains compile-time parameters that may need to be changed based on -application requirements. Some examples of parameters that may require configuraton: -* Sampling interval. -* Batch size. -* MQTT Broker IP address - -Parameters are configured by editing the file `src/configuration.rs`. - -Refer to the [documentation]({{site.baseurl}}/firmware/stabilizer/configuration/index.html) for more -information on parameters. - -When these parameters are updated, firmware must be built and flashed onto Stabilizer before they -take effect. - - ## Building Firmware 1. Clone or download [stabilizer](https://github.com/quartiq/stabilizer) @@ -60,9 +42,9 @@ git clone https://github.com/quartiq/stabilizer ```bash rustup target add thumbv7em-none-eabihf ``` -1. Build Firmware +1. Build Firmware with an optionally-specified MQTT broker IP. ```bash -cargo build --release +BROKER="10.34.16.10" cargo build --release ``` ## Uploading Firmware diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index c14dbc1..9d4eab5 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -29,10 +29,7 @@ #![no_std] #![no_main] -use core::{ - convert::TryInto, - sync::atomic::{fence, Ordering}, -}; +use core::sync::atomic::{fence, Ordering}; use mutex_trait::prelude::*; @@ -43,7 +40,7 @@ use stabilizer::{ adc::{Adc0Input, Adc1Input, AdcCode}, afe::Gain, dac::{Dac0Output, Dac1Output, DacCode}, - design_parameters::SAMPLE_BUFFER_SIZE, + design_parameters::DEFAULT_MQTT_BROKER, embedded_hal::digital::v2::InputPin, hal, signal_generator::{self, SignalGenerator}, @@ -64,6 +61,13 @@ const SCALE: f32 = i16::MAX as _; // The number of cascaded IIR biquads per channel. Select 1 or 2! const IIR_CASCADE_LENGTH: usize = 1; +// The number of samples in each batch process +const SAMPLE_BUFFER_SIZE: usize = 8; + +// The logarithm of the number of 100MHz timer ticks between each sample. With a value of 2^7 = +// 128, there is 1.28uS per sample, corresponding to a sampling frequency of 781.25 KHz. +const SAMPLE_TICKS_LOG2: u8 = 7; + #[derive(Clone, Copy, Debug, Deserialize, Miniconf)] pub struct Settings { /// Configure the Analog Front End (AFE) gain. @@ -183,8 +187,12 @@ const APP: () = { #[init(spawn=[telemetry, settings_update, ethernet_link])] fn init(c: init::Context) -> init::LateResources { // Configure the microcontroller - let (mut stabilizer, _pounder) = - hardware::setup::setup(c.core, c.device); + let (mut stabilizer, _pounder) = hardware::setup::setup( + c.core, + c.device, + SAMPLE_BUFFER_SIZE, + 1 << SAMPLE_TICKS_LOG2, + ); let mut network = NetworkUsers::new( stabilizer.net.stack, @@ -192,6 +200,9 @@ const APP: () = { stabilizer.cycle_counter, env!("CARGO_BIN_NAME"), stabilizer.net.mac_address, + option_env!("BROKER") + .and_then(|data| data.parse().ok()) + .unwrap_or(DEFAULT_MQTT_BROKER.into()), ); let generator = network.configure_streaming( @@ -228,10 +239,14 @@ const APP: () = { settings, signal_generator: [ SignalGenerator::new( - settings.signal_generator[0].try_into().unwrap(), + settings.signal_generator[0] + .try_into_config(SAMPLE_TICKS_LOG2) + .unwrap(), ), SignalGenerator::new( - settings.signal_generator[1].try_into().unwrap(), + settings.signal_generator[1] + .try_into_config(SAMPLE_TICKS_LOG2) + .unwrap(), ), ], } @@ -366,7 +381,7 @@ const APP: () = { // Update the signal generators for (i, &config) in settings.signal_generator.iter().enumerate() { - match config.try_into() { + match config.try_into_config(SAMPLE_TICKS_LOG2) { Ok(config) => { c.resources .signal_generator diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 3cabc7a..548c42e 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -37,13 +37,12 @@ use mutex_trait::prelude::*; use dsp::{Accu, Complex, ComplexExt, Lockin, RPLL}; use stabilizer::{ - configuration, hardware::{ self, adc::{Adc0Input, Adc1Input, AdcCode}, afe::Gain, dac::{Dac0Output, Dac1Output, DacCode}, - design_parameters::SAMPLE_BUFFER_SIZE, + design_parameters::DEFAULT_MQTT_BROKER, embedded_hal::digital::v2::InputPin, hal, input_stamper::InputStamper, @@ -60,6 +59,15 @@ use stabilizer::{ }, }; +// The logarithm of the number of samples in each batch process. This corresponds with 2^3 samples +// per batch = 8 samples +const SAMPLE_BUFFER_SIZE_LOG2: u8 = 3; + +// The logarithm of the number of 100MHz timer ticks between each sample. This corresponds with a +// sampling period of 2^7 = 128 ticks. At 100MHz, 10ns per tick, this corresponds to a sampling +// period of 1.28 uS or 781.25 KHz. +const ADC_SAMPLE_TICKS_LOG2: u8 = 7; + #[derive(Copy, Clone, Debug, Deserialize, Miniconf)] enum Conf { /// Output the lockin magnitude. @@ -220,8 +228,12 @@ const APP: () = { #[init(spawn=[settings_update, telemetry, ethernet_link])] fn init(c: init::Context) -> init::LateResources { // Configure the microcontroller - let (mut stabilizer, _pounder) = - hardware::setup::setup(c.core, c.device); + let (mut stabilizer, _pounder) = hardware::setup::setup( + c.core, + c.device, + 1 << SAMPLE_BUFFER_SIZE_LOG2, + 1 << ADC_SAMPLE_TICKS_LOG2, + ); let mut network = NetworkUsers::new( stabilizer.net.stack, @@ -229,19 +241,19 @@ const APP: () = { stabilizer.cycle_counter, env!("CARGO_BIN_NAME"), stabilizer.net.mac_address, + option_env!("BROKER") + .and_then(|data| data.parse().ok()) + .unwrap_or(DEFAULT_MQTT_BROKER.into()), ); let generator = network.configure_streaming( StreamFormat::AdcDacData, - SAMPLE_BUFFER_SIZE as u8, + 1u8 << SAMPLE_BUFFER_SIZE_LOG2, ); let settings = Settings::default(); - let pll = RPLL::new( - configuration::ADC_SAMPLE_TICKS_LOG2 - + configuration::SAMPLE_BUFFER_SIZE_LOG2, - ); + let pll = RPLL::new(ADC_SAMPLE_TICKS_LOG2 + SAMPLE_BUFFER_SIZE_LOG2); // Spawn a settings and telemetry update for default settings. c.spawn.settings_update().unwrap(); @@ -267,7 +279,7 @@ const APP: () = { let signal_config = { let frequency_tuning_word = - (1u64 << (32 - configuration::SAMPLE_BUFFER_SIZE_LOG2)) as u32; + (1u64 << (32 - SAMPLE_BUFFER_SIZE_LOG2)) as u32; signal_generator::Config { // Same frequency as batch size. @@ -334,18 +346,11 @@ const APP: () = { settings.pll_tc[0], settings.pll_tc[1], ); - ( - pll_phase, - (pll_frequency >> configuration::SAMPLE_BUFFER_SIZE_LOG2) - as i32, - ) + (pll_phase, (pll_frequency >> SAMPLE_BUFFER_SIZE_LOG2) as i32) } LockinMode::Internal => { // Reference phase and frequency are known. - ( - 1i32 << 30, - 1i32 << (32 - configuration::SAMPLE_BUFFER_SIZE_LOG2), - ) + (1i32 << 30, 1i32 << (32 - SAMPLE_BUFFER_SIZE_LOG2)) } }; @@ -399,7 +404,8 @@ const APP: () = { } // Stream the data. - const N: usize = SAMPLE_BUFFER_SIZE * core::mem::size_of::(); + const N: usize = + (1 << SAMPLE_BUFFER_SIZE_LOG2) * core::mem::size_of::(); generator.add::<_, { N * 4 }>(|buf| { for (data, buf) in adc_samples .iter() diff --git a/src/configuration.rs b/src/configuration.rs deleted file mode 100644 index 01e410a..0000000 --- a/src/configuration.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! This module contains any compile-time configuration parameters for the Stabilizer firmware. - -/// MQTT broker IPv4 address -/// -/// In the default configuration, the IP address is defined as 10.34.16.10. -pub const MQTT_BROKER: [u8; 4] = [10, 34, 16, 10]; - -/// Sampling Frequency -/// -/// Define the frequency at which ADCs (and DACs) are sampled at. -/// -/// # Units -/// The units of this parameter are specified as a logarithmic number of ticks of the internal -/// timer, which runs at 100 MHz. -/// -/// ## Example -/// With a value of 7, this corresponds to 2^7 = 128 ticks. Each tick of the 100 MHz timer requires -/// 10ns. -/// -/// Sampling Period = 10ns * 128 = 1.28 us -/// Sampling Frequency = 781.25 KHz -/// -/// Or more succinctly: -/// `F_s = 100 MHz / (2 ^ ADC_SAMPLE_TICKS_LOG2)` -pub const ADC_SAMPLE_TICKS_LOG2: u8 = 7; - -/// Sample Batch Sizing -/// -/// The sample batch size defines how many samples are collected before the DSP routines are -/// executed. -/// -/// # Note -/// Smaller batch sizes result in less input -> output latency, but come at the cost of reduced -/// maximum sampling frequency. -/// -/// # Units -/// The units of the batch size are specified logarithmically. -/// -/// ## Example -/// With a value of 3, the number of samples per batch is 2^3 = 8. -pub const SAMPLE_BUFFER_SIZE_LOG2: u8 = 3; diff --git a/src/hardware/adc.rs b/src/hardware/adc.rs index fd131ee..4814ab6 100644 --- a/src/hardware/adc.rs +++ b/src/hardware/adc.rs @@ -69,7 +69,7 @@ use stm32h7xx_hal as hal; use mutex_trait::Mutex; -use super::design_parameters::{SampleBuffer, SAMPLE_BUFFER_SIZE}; +use super::design_parameters::{SampleBuffer, MAX_SAMPLE_BUFFER_SIZE}; use super::timers; use hal::dma::{ @@ -142,7 +142,8 @@ static mut SPI_EOT_CLEAR: [u32; 1] = [0x00]; // processed). Note that the contents of AXI SRAM is uninitialized, so the buffer contents on // startup are undefined. The dimensions are `ADC_BUF[adc_index][ping_pong_index][sample_index]`. #[link_section = ".axisram.buffers"] -static mut ADC_BUF: [[SampleBuffer; 2]; 2] = [[[0; SAMPLE_BUFFER_SIZE]; 2]; 2]; +static mut ADC_BUF: [[SampleBuffer; 2]; 2] = + [[[0; MAX_SAMPLE_BUFFER_SIZE]; 2]; 2]; macro_rules! adc_input { ($name:ident, $index:literal, $trigger_stream:ident, $data_stream:ident, $clear_stream:ident, @@ -218,7 +219,7 @@ macro_rules! adc_input { hal::dma::dma::$data_stream, hal::spi::Spi, PeripheralToMemory, - &'static mut SampleBuffer, + &'static mut [u16], hal::dma::DBTransfer, >, trigger_transfer: Transfer< @@ -258,6 +259,7 @@ macro_rules! adc_input { clear_stream: hal::dma::dma::$clear_stream, trigger_channel: timers::tim2::$trigger_channel, clear_channel: timers::tim3::$clear_channel, + sample_buffer_size: usize, ) -> Self { // The flag clear DMA transfer always clears the EOT flag in the SPI // peripheral. It has the highest priority to ensure it is completed before the @@ -357,8 +359,8 @@ macro_rules! adc_input { spi, // Note(unsafe): The ADC_BUF[$index] is "owned" by this peripheral. // It shall not be used anywhere else in the module. - unsafe { &mut ADC_BUF[$index][0] }, - unsafe { Some(&mut ADC_BUF[$index][1]) }, + unsafe { &mut ADC_BUF[$index][0][..sample_buffer_size] }, + unsafe { Some(&mut ADC_BUF[$index][1][..sample_buffer_size]) }, data_config, ); @@ -390,8 +392,8 @@ macro_rules! adc_input { /// NOTE(unsafe): Memory safety and access ordering is not guaranteed /// (see the HAL DMA docs). pub fn with_buffer(&mut self, f: F) -> Result - where - F: FnOnce(&mut SampleBuffer) -> R, + where + F: FnOnce(&mut &'static mut [u16]) -> R, { unsafe { self.transfer.next_dbm_transfer_with(|buf, _current| f(buf)) } } @@ -400,7 +402,7 @@ macro_rules! adc_input { // This is not actually a Mutex. It only re-uses the semantics and macros of mutex-trait // to reduce rightward drift when jointly calling `with_buffer(f)` on multiple DAC/ADCs. impl Mutex for $name { - type Data = SampleBuffer; + type Data = &'static mut [u16]; fn lock(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R { self.with_buffer(f).unwrap() } diff --git a/src/hardware/dac.rs b/src/hardware/dac.rs index b5391c6..4339a52 100644 --- a/src/hardware/dac.rs +++ b/src/hardware/dac.rs @@ -54,7 +54,7 @@ use stm32h7xx_hal as hal; use mutex_trait::Mutex; -use super::design_parameters::{SampleBuffer, SAMPLE_BUFFER_SIZE}; +use super::design_parameters::{SampleBuffer, MAX_SAMPLE_BUFFER_SIZE}; use super::timers; use core::convert::TryFrom; @@ -70,7 +70,8 @@ use hal::dma::{ // processed). Note that the contents of AXI SRAM is uninitialized, so the buffer contents on // startup are undefined. The dimensions are `ADC_BUF[adc_index][ping_pong_index][sample_index]`. #[link_section = ".axisram.buffers"] -static mut DAC_BUF: [[SampleBuffer; 2]; 2] = [[[0; SAMPLE_BUFFER_SIZE]; 2]; 2]; +static mut DAC_BUF: [[SampleBuffer; 2]; 2] = + [[[0; MAX_SAMPLE_BUFFER_SIZE]; 2]; 2]; /// Custom type for referencing DAC output codes. /// The internal integer is the raw code written to the DAC output register. @@ -176,7 +177,7 @@ macro_rules! dac_output { hal::dma::dma::$data_stream, $spi, MemoryToPeripheral, - &'static mut SampleBuffer, + &'static mut [u16], hal::dma::DBTransfer, >, } @@ -192,6 +193,7 @@ macro_rules! dac_output { spi: hal::spi::Spi, stream: hal::dma::dma::$data_stream, trigger_channel: timers::tim2::$trigger_channel, + sample_buffer_size: usize, ) -> Self { // Generate DMA events when an output compare of the timer hitting zero (timer roll over) // occurs. @@ -225,9 +227,13 @@ macro_rules! dac_output { stream, $spi::new(trigger_channel, spi), // Note(unsafe): This buffer is only used once and provided for the DMA transfer. - unsafe { &mut DAC_BUF[$index][0] }, + unsafe { + &mut DAC_BUF[$index][0][..sample_buffer_size] + }, // Note(unsafe): This buffer is only used once and provided for the DMA transfer. - unsafe { Some(&mut DAC_BUF[$index][1]) }, + unsafe { + Some(&mut DAC_BUF[$index][1][..sample_buffer_size]) + }, trigger_config, ); @@ -246,7 +252,7 @@ macro_rules! dac_output { /// (see the HAL DMA docs). pub fn with_buffer(&mut self, f: F) -> Result where - F: FnOnce(&mut SampleBuffer) -> R, + F: FnOnce(&mut &'static mut [u16]) -> R, { unsafe { self.transfer.next_dbm_transfer_with(|buf, _current| f(buf)) @@ -257,7 +263,7 @@ macro_rules! dac_output { // This is not actually a Mutex. It only re-uses the semantics and macros of mutex-trait // to reduce rightward drift when jointly calling `with_buffer(f)` on multiple DAC/ADCs. impl Mutex for $name { - type Data = SampleBuffer; + type Data = &'static mut [u16]; fn lock(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R { self.with_buffer(f).unwrap() } diff --git a/src/hardware/design_parameters.rs b/src/hardware/design_parameters.rs index 4ac28e3..2597d87 100644 --- a/src/hardware/design_parameters.rs +++ b/src/hardware/design_parameters.rs @@ -40,13 +40,10 @@ pub const DDS_SYSTEM_CLK: MegaHertz = #[allow(dead_code)] pub const DDS_SYNC_CLK_DIV: u8 = 4; -// The number of ticks in the ADC sampling timer. The timer runs at 100MHz, so the step size is -// equal to 10ns per tick. -pub const ADC_SAMPLE_TICKS: u16 = - 1 << crate::configuration::ADC_SAMPLE_TICKS_LOG2; +/// The maximum ADC/DAC sample processing buffer size. +pub const MAX_SAMPLE_BUFFER_SIZE: usize = 32; -// The desired ADC sample processing buffer size. -pub const SAMPLE_BUFFER_SIZE: usize = - 1 << crate::configuration::SAMPLE_BUFFER_SIZE_LOG2; +pub type SampleBuffer = [u16; MAX_SAMPLE_BUFFER_SIZE]; -pub type SampleBuffer = [u16; SAMPLE_BUFFER_SIZE]; +/// The default MQTT broker IP address if unspecified. +pub const DEFAULT_MQTT_BROKER: [u8; 4] = [10, 34, 16, 10]; diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 61b9a2d..2239223 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -172,9 +172,14 @@ fn load_itcm() { /// Configure the stabilizer hardware for operation. /// +/// # Note +/// Refer to [design_parameters::TIMER_FREQUENCY] to determine the frequency of the sampling timer. +/// /// # Args /// * `core` - The RTIC core for configuring the cortex-M core of the device. /// * `device` - The microcontroller peripherals to be configured. +/// * `sample_buffer_size` - The size of the ADC/DAC sample buffer. +/// * `sample_ticks` - The number of timer ticks between each sample. /// /// # Returns /// (stabilizer, pounder) where `stabilizer` is a `StabilizerDevices` structure containing all @@ -184,6 +189,8 @@ fn load_itcm() { pub fn setup( mut core: rtic::Peripherals, device: stm32h7xx_hal::stm32::Peripherals, + sample_buffer_size: usize, + sample_ticks: u32, ) -> (StabilizerDevices, Option) { let pwr = device.PWR.constrain(); let vos = pwr.freeze(); @@ -295,8 +302,7 @@ pub fn setup( timer2.set_tick_freq(design_parameters::TIMER_FREQUENCY); let mut sampling_timer = timers::SamplingTimer::new(timer2); - sampling_timer - .set_period_ticks((design_parameters::ADC_SAMPLE_TICKS - 1) as u32); + sampling_timer.set_period_ticks(sample_ticks - 1); // The sampling timer is used as the master timer for the shadow-sampling timer. Thus, // it generates a trigger whenever it is enabled. @@ -320,8 +326,7 @@ pub fn setup( let mut shadow_sampling_timer = timers::ShadowSamplingTimer::new(timer3); - shadow_sampling_timer - .set_period_ticks(design_parameters::ADC_SAMPLE_TICKS - 1); + shadow_sampling_timer.set_period_ticks(sample_ticks as u16 - 1); // The shadow sampling timer is a slave-mode timer to the sampling timer. It should // always be in-sync - thus, we configure it to operate in slave mode using "Trigger @@ -409,6 +414,7 @@ pub fn setup( dma_streams.2, sampling_timer_channels.ch1, shadow_sampling_timer_channels.ch1, + sample_buffer_size, ) }; @@ -452,6 +458,7 @@ pub fn setup( dma_streams.5, sampling_timer_channels.ch2, shadow_sampling_timer_channels.ch2, + sample_buffer_size, ) }; @@ -539,11 +546,13 @@ pub fn setup( dac0_spi, dma_streams.6, sampling_timer_channels.ch3, + sample_buffer_size, ); let dac1 = dac::Dac1Output::new( dac1_spi, dma_streams.7, sampling_timer_channels.ch4, + sample_buffer_size, ); (dac0, dac1) }; @@ -940,8 +949,7 @@ pub fn setup( let sample_frequency = { let timer_frequency: hal::time::Hertz = design_parameters::TIMER_FREQUENCY.into(); - timer_frequency.0 as f32 - / design_parameters::ADC_SAMPLE_TICKS as f32 + timer_frequency.0 as f32 / sample_ticks as f32 }; let sample_period = 1.0 / sample_frequency; diff --git a/src/hardware/signal_generator.rs b/src/hardware/signal_generator.rs index 986941a..5bcea8f 100644 --- a/src/hardware/signal_generator.rs +++ b/src/hardware/signal_generator.rs @@ -1,8 +1,7 @@ use crate::{ - configuration::ADC_SAMPLE_TICKS_LOG2, hardware::dac::DacCode, - hardware::design_parameters::TIMER_FREQUENCY, + hardware::dac::DacCode, hardware::design_parameters::TIMER_FREQUENCY, }; -use core::convert::{TryFrom, TryInto}; +use core::convert::TryFrom; use miniconf::Miniconf; use serde::Deserialize; @@ -32,7 +31,7 @@ pub struct BasicConfig { /// The normalized symmetry of the signal. At 0% symmetry, the duration of the first half oscillation is minimal. /// At 25% symmetry, the first half oscillation lasts for 25% of the signal period. For square wave output this - //// symmetry is the duty cycle. + /// symmetry is the duty cycle. pub symmetry: f32, /// The amplitude of the output signal in volts. @@ -61,20 +60,25 @@ pub enum Error { InvalidFrequency, } -impl TryFrom for Config { - type Error = Error; - - fn try_from(config: BasicConfig) -> Result { - let symmetry_complement = 1.0 - config.symmetry; +impl BasicConfig { + /// Convert configuration into signal generator values. + /// + /// # Args + /// * `sample_ticks_log2` - The logarithm of the number of timer sample ticks between each + /// sample. + pub fn try_into_config( + self, + sample_ticks_log2: u8, + ) -> Result { + let symmetry_complement = 1.0 - self.symmetry; // Validate symmetry - if config.symmetry < 0.0 || symmetry_complement < 0.0 { + if self.symmetry < 0.0 || symmetry_complement < 0.0 { return Err(Error::InvalidSymmetry); } - const LSB_PER_HERTZ: f32 = (1u64 << (31 + ADC_SAMPLE_TICKS_LOG2)) - as f32 + let lsb_per_hertz: f32 = (1u64 << (31 + sample_ticks_log2)) as f32 / (TIMER_FREQUENCY.0 * 1_000_000) as f32; - let ftw = config.frequency * LSB_PER_HERTZ; + let ftw = self.frequency * lsb_per_hertz; // Validate base frequency tuning word to be below Nyquist. const NYQUIST: f32 = (1u32 << 31) as _; @@ -85,8 +89,8 @@ impl TryFrom for Config { // Calculate the frequency tuning words. // Clip both frequency tuning words to within Nyquist before rounding. let frequency_tuning_word = [ - if config.symmetry * NYQUIST > ftw { - ftw / config.symmetry + if self.symmetry * NYQUIST > ftw { + ftw / self.symmetry } else { NYQUIST } as u32, @@ -98,10 +102,10 @@ impl TryFrom for Config { ]; Ok(Config { - amplitude: DacCode::try_from(config.amplitude) + amplitude: DacCode::try_from(self.amplitude) .or(Err(Error::InvalidAmplitude))? .into(), - signal: config.signal, + signal: self.signal, frequency_tuning_word, }) } @@ -119,6 +123,16 @@ pub struct Config { pub frequency_tuning_word: [u32; 2], } +impl Default for Config { + fn default() -> Self { + Self { + signal: Signal::Cosine, + amplitude: 0, + frequency_tuning_word: [0, 0], + } + } +} + #[derive(Debug)] pub struct SignalGenerator { phase_accumulator: u32, @@ -128,7 +142,7 @@ pub struct SignalGenerator { impl Default for SignalGenerator { fn default() -> Self { Self { - config: BasicConfig::default().try_into().unwrap(), + config: Config::default(), phase_accumulator: 0, } } diff --git a/src/net/miniconf_client.rs b/src/net/miniconf_client.rs index 0caf8d0..79750a8 100644 --- a/src/net/miniconf_client.rs +++ b/src/net/miniconf_client.rs @@ -14,7 +14,7 @@ use heapless::String; use log::info; use super::{MqttMessage, NetworkReference, SettingsResponse, UpdateState}; -use crate::configuration::MQTT_BROKER; +use minimq::embedded_nal::IpAddr; /// MQTT settings interface. pub struct MiniconfClient @@ -38,9 +38,14 @@ where /// * `stack` - The network stack to use for communication. /// * `client_id` - The ID of the MQTT client. May be an empty string for auto-assigning. /// * `prefix` - The MQTT device prefix to use for this device. - pub fn new(stack: NetworkReference, client_id: &str, prefix: &str) -> Self { - let mqtt = - minimq::Minimq::new(MQTT_BROKER.into(), client_id, stack).unwrap(); + /// * `broker` - The IP address of the MQTT broker to use. + pub fn new( + stack: NetworkReference, + client_id: &str, + prefix: &str, + broker: IpAddr, + ) -> Self { + let mqtt = minimq::Minimq::new(broker, client_id, stack).unwrap(); let mut response_topic: String<128> = String::from(prefix); response_topic.push_str("/log").unwrap(); diff --git a/src/net/mod.rs b/src/net/mod.rs index da82999..2ca3b10 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -20,6 +20,7 @@ use crate::hardware::{cycle_counter::CycleCounter, EthernetPhy, NetworkStack}; use data_stream::{DataStream, FrameGenerator}; use messages::{MqttMessage, SettingsResponse}; use miniconf_client::MiniconfClient; +use minimq::embedded_nal::IpAddr; use network_processor::NetworkProcessor; use shared::NetworkManager; use telemetry::TelemetryClient; @@ -66,6 +67,7 @@ where /// * `cycle_counter` - The clock used for measuring time in the network. /// * `app` - The name of the application. /// * `mac` - The MAC address of the network. + /// * `broker` - The IP address of the MQTT broker to use. /// /// # Returns /// A new struct of network users. @@ -75,6 +77,7 @@ where cycle_counter: CycleCounter, app: &str, mac: smoltcp_nal::smoltcp::wire::EthernetAddress, + broker: IpAddr, ) -> Self { let stack_manager = cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)) @@ -92,12 +95,14 @@ where stack_manager.acquire_stack(), &get_client_id(app, "settings", mac), &prefix, + broker, ); let telemetry = TelemetryClient::new( stack_manager.acquire_stack(), &get_client_id(app, "tlm", mac), &prefix, + broker, ); let (generator, stream) = diff --git a/src/net/telemetry.rs b/src/net/telemetry.rs index ffb0d58..2fcf22a 100644 --- a/src/net/telemetry.rs +++ b/src/net/telemetry.rs @@ -15,8 +15,8 @@ use minimq::QoS; use serde::Serialize; use super::NetworkReference; -use crate::configuration::MQTT_BROKER; use crate::hardware::{adc::AdcCode, afe::Gain, dac::DacCode}; +use minimq::embedded_nal::IpAddr; /// The telemetry client for reporting telemetry data over MQTT. pub struct TelemetryClient { @@ -96,12 +96,17 @@ impl TelemetryClient { /// * `stack` - A reference to the (shared) underlying network stack. /// * `client_id` - The MQTT client ID of the telemetry client. /// * `prefix` - The device prefix to use for MQTT telemetry reporting. + /// * `broker` - The IP address of the MQTT broker to use. /// /// # Returns /// A new telemetry client. - pub fn new(stack: NetworkReference, client_id: &str, prefix: &str) -> Self { - let mqtt = - minimq::Minimq::new(MQTT_BROKER.into(), client_id, stack).unwrap(); + pub fn new( + stack: NetworkReference, + client_id: &str, + prefix: &str, + broker: IpAddr, + ) -> Self { + let mqtt = minimq::Minimq::new(broker, client_id, stack).unwrap(); let mut telemetry_topic: String<128> = String::from(prefix); telemetry_topic.push_str("/telemetry").unwrap(); From 2f2e38f31cf5b40f138ebc064e995a6b4afd4523 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 13:17:03 +0200 Subject: [PATCH 2/8] Fixing build --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 58c85af..85964a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![no_std] #![cfg_attr(feature = "nightly", feature(core_intrinsics))] -pub mod configuration; pub mod hardware; pub mod net; From 78bad36526f49edf97af2cec4eb5e79c6a293a26 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 14:40:02 +0200 Subject: [PATCH 3/8] Removing asserts --- src/bin/dual-iir.rs | 1 - src/bin/lockin.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 9d4eab5..0d924c3 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -333,7 +333,6 @@ const APP: () = { .chain(dac_samples.iter()) .zip(buf.chunks_exact_mut(N)) { - assert_eq!(core::mem::size_of_val(*data), N); let data = unsafe { core::slice::from_raw_parts( data.as_ptr() as *const u8, diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 548c42e..ee85dd9 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -412,7 +412,6 @@ const APP: () = { .chain(dac_samples.iter()) .zip(buf.chunks_exact_mut(N)) { - assert_eq!(core::mem::size_of_val(*data), N); let data = unsafe { core::slice::from_raw_parts( data.as_ptr() as *const u8, From d2b184e8e9b1066ad488d613d11a4a08aaf471f3 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 14:52:31 +0200 Subject: [PATCH 4/8] Adding logging if provided IP parsing fails --- src/bin/dual-iir.rs | 14 +++++++++++++- src/bin/lockin.rs | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 0d924c3..3b2b702 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -201,7 +201,19 @@ const APP: () = { env!("CARGO_BIN_NAME"), stabilizer.net.mac_address, option_env!("BROKER") - .and_then(|data| data.parse().ok()) + .and_then(|data| { + data.parse::().map_or_else( + |err| { + log::error!( + "{:?}: Failed to parse broker IP ({:?}) - Falling back to default", + err, + data + ); + None + }, + |ip| Some(ip), + ) + }) .unwrap_or(DEFAULT_MQTT_BROKER.into()), ); diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index ee85dd9..334aeab 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -242,7 +242,19 @@ const APP: () = { env!("CARGO_BIN_NAME"), stabilizer.net.mac_address, option_env!("BROKER") - .and_then(|data| data.parse().ok()) + .and_then(|data| { + data.parse::().map_or_else( + |err| { + log::error!( + "{:?}: Failed to parse broker IP ({:?}) - Falling back to default", + err, + data + ); + None + }, + |ip| Some(ip), + ) + }) .unwrap_or(DEFAULT_MQTT_BROKER.into()), ); From c4c3593bae39ec30e155ca39365c7a6ec1f929cd Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 16:13:01 +0200 Subject: [PATCH 5/8] Renaming variables, moving broker parsing --- src/bin/dual-iir.rs | 30 +++++++-------------------- src/bin/lockin.rs | 34 +++++++++---------------------- src/hardware/design_parameters.rs | 3 --- src/net/mod.rs | 30 +++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 50 deletions(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 3b2b702..84ce8e2 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -40,7 +40,6 @@ use stabilizer::{ adc::{Adc0Input, Adc1Input, AdcCode}, afe::Gain, dac::{Dac0Output, Dac1Output, DacCode}, - design_parameters::DEFAULT_MQTT_BROKER, embedded_hal::digital::v2::InputPin, hal, signal_generator::{self, SignalGenerator}, @@ -48,6 +47,7 @@ use stabilizer::{ DigitalInput0, DigitalInput1, AFE0, AFE1, }, net::{ + self, data_stream::{FrameGenerator, StreamFormat, StreamTarget}, miniconf::Miniconf, serde::Deserialize, @@ -62,7 +62,7 @@ const SCALE: f32 = i16::MAX as _; const IIR_CASCADE_LENGTH: usize = 1; // The number of samples in each batch process -const SAMPLE_BUFFER_SIZE: usize = 8; +const BATCH_SIZE: usize = 8; // The logarithm of the number of 100MHz timer ticks between each sample. With a value of 2^7 = // 128, there is 1.28uS per sample, corresponding to a sampling frequency of 781.25 KHz. @@ -190,7 +190,7 @@ const APP: () = { let (mut stabilizer, _pounder) = hardware::setup::setup( c.core, c.device, - SAMPLE_BUFFER_SIZE, + BATCH_SIZE, 1 << SAMPLE_TICKS_LOG2, ); @@ -200,27 +200,11 @@ const APP: () = { stabilizer.cycle_counter, env!("CARGO_BIN_NAME"), stabilizer.net.mac_address, - option_env!("BROKER") - .and_then(|data| { - data.parse::().map_or_else( - |err| { - log::error!( - "{:?}: Failed to parse broker IP ({:?}) - Falling back to default", - err, - data - ); - None - }, - |ip| Some(ip), - ) - }) - .unwrap_or(DEFAULT_MQTT_BROKER.into()), + net::parse_or_default_broker(option_env!("BROKER")), ); - let generator = network.configure_streaming( - StreamFormat::AdcDacData, - SAMPLE_BUFFER_SIZE as u8, - ); + let generator = network + .configure_streaming(StreamFormat::AdcDacData, BATCH_SIZE as u8); // Spawn a settings update for default settings. c.spawn.settings_update().unwrap(); @@ -338,7 +322,7 @@ const APP: () = { } // Stream the data. - const N: usize = SAMPLE_BUFFER_SIZE * core::mem::size_of::(); + const N: usize = BATCH_SIZE * core::mem::size_of::(); generator.add::<_, { N * 4 }>(|buf| { for (data, buf) in adc_samples .iter() diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 334aeab..5fd66b1 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -42,7 +42,6 @@ use stabilizer::{ adc::{Adc0Input, Adc1Input, AdcCode}, afe::Gain, dac::{Dac0Output, Dac1Output, DacCode}, - design_parameters::DEFAULT_MQTT_BROKER, embedded_hal::digital::v2::InputPin, hal, input_stamper::InputStamper, @@ -51,6 +50,7 @@ use stabilizer::{ DigitalInput0, DigitalInput1, AFE0, AFE1, }, net::{ + self, data_stream::{FrameGenerator, StreamFormat, StreamTarget}, miniconf::Miniconf, serde::Deserialize, @@ -61,7 +61,7 @@ use stabilizer::{ // The logarithm of the number of samples in each batch process. This corresponds with 2^3 samples // per batch = 8 samples -const SAMPLE_BUFFER_SIZE_LOG2: u8 = 3; +const BATCH_SIZE_SIZE_LOG2: u8 = 3; // The logarithm of the number of 100MHz timer ticks between each sample. This corresponds with a // sampling period of 2^7 = 128 ticks. At 100MHz, 10ns per tick, this corresponds to a sampling @@ -231,7 +231,7 @@ const APP: () = { let (mut stabilizer, _pounder) = hardware::setup::setup( c.core, c.device, - 1 << SAMPLE_BUFFER_SIZE_LOG2, + 1 << BATCH_SIZE_SIZE_LOG2, 1 << ADC_SAMPLE_TICKS_LOG2, ); @@ -241,31 +241,17 @@ const APP: () = { stabilizer.cycle_counter, env!("CARGO_BIN_NAME"), stabilizer.net.mac_address, - option_env!("BROKER") - .and_then(|data| { - data.parse::().map_or_else( - |err| { - log::error!( - "{:?}: Failed to parse broker IP ({:?}) - Falling back to default", - err, - data - ); - None - }, - |ip| Some(ip), - ) - }) - .unwrap_or(DEFAULT_MQTT_BROKER.into()), + net::parse_or_default_broker(option_env!("BROKER")), ); let generator = network.configure_streaming( StreamFormat::AdcDacData, - 1u8 << SAMPLE_BUFFER_SIZE_LOG2, + 1u8 << BATCH_SIZE_SIZE_LOG2, ); let settings = Settings::default(); - let pll = RPLL::new(ADC_SAMPLE_TICKS_LOG2 + SAMPLE_BUFFER_SIZE_LOG2); + let pll = RPLL::new(ADC_SAMPLE_TICKS_LOG2 + BATCH_SIZE_SIZE_LOG2); // Spawn a settings and telemetry update for default settings. c.spawn.settings_update().unwrap(); @@ -291,7 +277,7 @@ const APP: () = { let signal_config = { let frequency_tuning_word = - (1u64 << (32 - SAMPLE_BUFFER_SIZE_LOG2)) as u32; + (1u64 << (32 - BATCH_SIZE_SIZE_LOG2)) as u32; signal_generator::Config { // Same frequency as batch size. @@ -358,11 +344,11 @@ const APP: () = { settings.pll_tc[0], settings.pll_tc[1], ); - (pll_phase, (pll_frequency >> SAMPLE_BUFFER_SIZE_LOG2) as i32) + (pll_phase, (pll_frequency >> BATCH_SIZE_SIZE_LOG2) as i32) } LockinMode::Internal => { // Reference phase and frequency are known. - (1i32 << 30, 1i32 << (32 - SAMPLE_BUFFER_SIZE_LOG2)) + (1i32 << 30, 1i32 << (32 - BATCH_SIZE_SIZE_LOG2)) } }; @@ -417,7 +403,7 @@ const APP: () = { // Stream the data. const N: usize = - (1 << SAMPLE_BUFFER_SIZE_LOG2) * core::mem::size_of::(); + (1 << BATCH_SIZE_SIZE_LOG2) * core::mem::size_of::(); generator.add::<_, { N * 4 }>(|buf| { for (data, buf) in adc_samples .iter() diff --git a/src/hardware/design_parameters.rs b/src/hardware/design_parameters.rs index 2597d87..4884ed5 100644 --- a/src/hardware/design_parameters.rs +++ b/src/hardware/design_parameters.rs @@ -44,6 +44,3 @@ pub const DDS_SYNC_CLK_DIV: u8 = 4; pub const MAX_SAMPLE_BUFFER_SIZE: usize = 32; pub type SampleBuffer = [u16; MAX_SAMPLE_BUFFER_SIZE]; - -/// The default MQTT broker IP address if unspecified. -pub const DEFAULT_MQTT_BROKER: [u8; 4] = [10, 34, 16, 10]; diff --git a/src/net/mod.rs b/src/net/mod.rs index 2ca3b10..2e41695 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -33,6 +33,9 @@ use smoltcp_nal::embedded_nal::SocketAddr; pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>; +/// The default MQTT broker IP address if unspecified. +pub const DEFAULT_MQTT_BROKER: [u8; 4] = [10, 34, 16, 10]; + #[derive(Copy, Clone, PartialEq)] pub enum UpdateState { NoChange, @@ -205,3 +208,30 @@ pub fn get_device_prefix( prefix } + +/// Determine the broker IP address +/// +/// # Note +/// If the broker IP is unspecified or unparseable, the default IP is returned. +/// +/// # Args +/// * `input` - The optionally-specified command-line broker IP address as a string. +/// +/// # Returns +/// The broker IP address. +pub fn parse_or_default_broker(input: Option<&str>) -> IpAddr { + input.and_then(|data| { + data.parse::().map_or_else( + |err| { + log::error!( + "{:?}: Failed to parse broker IP ({:?}) - Falling back to default", + err, + data + ); + None + }, + Some, + ) + }) + .unwrap_or_else(|| DEFAULT_MQTT_BROKER.into()) +} From 9d3513d4d152698bbf27a8b70fea4931fc360241 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 16:29:21 +0200 Subject: [PATCH 6/8] Renaming variables, fixing pounder builds --- src/hardware/adc.rs | 6 +++--- src/hardware/dac.rs | 10 +++------- src/hardware/pounder/timestamp.rs | 18 ++++++++++++------ src/hardware/setup.rs | 13 +++++++------ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/hardware/adc.rs b/src/hardware/adc.rs index 4814ab6..4da4100 100644 --- a/src/hardware/adc.rs +++ b/src/hardware/adc.rs @@ -259,7 +259,7 @@ macro_rules! adc_input { clear_stream: hal::dma::dma::$clear_stream, trigger_channel: timers::tim2::$trigger_channel, clear_channel: timers::tim3::$clear_channel, - sample_buffer_size: usize, + batch_size: usize, ) -> Self { // The flag clear DMA transfer always clears the EOT flag in the SPI // peripheral. It has the highest priority to ensure it is completed before the @@ -359,8 +359,8 @@ macro_rules! adc_input { spi, // Note(unsafe): The ADC_BUF[$index] is "owned" by this peripheral. // It shall not be used anywhere else in the module. - unsafe { &mut ADC_BUF[$index][0][..sample_buffer_size] }, - unsafe { Some(&mut ADC_BUF[$index][1][..sample_buffer_size]) }, + unsafe { &mut ADC_BUF[$index][0][..batch_size] }, + unsafe { Some(&mut ADC_BUF[$index][1][..batch_size]) }, data_config, ); diff --git a/src/hardware/dac.rs b/src/hardware/dac.rs index 4339a52..2699ce5 100644 --- a/src/hardware/dac.rs +++ b/src/hardware/dac.rs @@ -193,7 +193,7 @@ macro_rules! dac_output { spi: hal::spi::Spi, stream: hal::dma::dma::$data_stream, trigger_channel: timers::tim2::$trigger_channel, - sample_buffer_size: usize, + batch_size: usize, ) -> Self { // Generate DMA events when an output compare of the timer hitting zero (timer roll over) // occurs. @@ -227,13 +227,9 @@ macro_rules! dac_output { stream, $spi::new(trigger_channel, spi), // Note(unsafe): This buffer is only used once and provided for the DMA transfer. - unsafe { - &mut DAC_BUF[$index][0][..sample_buffer_size] - }, + unsafe { &mut DAC_BUF[$index][0][..batch_size] }, // Note(unsafe): This buffer is only used once and provided for the DMA transfer. - unsafe { - Some(&mut DAC_BUF[$index][1][..sample_buffer_size]) - }, + unsafe { Some(&mut DAC_BUF[$index][1][..batch_size]) }, trigger_config, ); diff --git a/src/hardware/pounder/timestamp.rs b/src/hardware/pounder/timestamp.rs index 262af9b..571820e 100644 --- a/src/hardware/pounder/timestamp.rs +++ b/src/hardware/pounder/timestamp.rs @@ -16,8 +16,7 @@ ///! capture is simultaneously triggered. That trigger is prescaled (its rate is divided) by the ///! batch size. This results in the input capture triggering identically to when the ADC samples ///! the last sample of the batch. That sample is then available for processing by the user. -use crate::{configuration, hardware::timers}; -use core::convert::TryFrom; +use crate::hardware::timers; use stm32h7xx_hal as hal; /// Software unit to timestamp stabilizer ADC samples using an external pounder reference clock. @@ -34,6 +33,7 @@ impl Timestamper { /// * `capture_channel` - The input capture channel for collecting timestamps. /// * `sampling_timer` - The stabilizer ADC sampling timer. /// * `_clock_input` - The input pin for the external clock from Pounder. + /// * `batch_size` - The number of seamples in each batch. /// /// # Returns /// The new pounder timestamper in an operational state. @@ -44,6 +44,7 @@ impl Timestamper { _clock_input: hal::gpio::gpioa::PA0< hal::gpio::Alternate, >, + batch_size: usize, ) -> Self { // The sampling timer should generate a trigger output when CH1 comparison occurs. sampling_timer.generate_trigger(timers::TriggerGenerator::ComparePulse); @@ -56,11 +57,16 @@ impl Timestamper { let mut input_capture = capture_channel .into_input_capture(timers::tim8::CaptureSource1::TRC); + let prescaler = match batch_size { + 1 => timers::Prescaler::Div1, + 2 => timers::Prescaler::Div2, + 4 => timers::Prescaler::Div4, + 8 => timers::Prescaler::Div8, + _ => panic!("Batch size does not support DDS timestamping"), + }; + // Capture at the batch period. - input_capture.configure_prescaler( - timers::Prescaler::try_from(configuration::SAMPLE_BUFFER_SIZE_LOG2) - .unwrap(), - ); + input_capture.configure_prescaler(prescaler); Self { timer: timestamp_timer, diff --git a/src/hardware/setup.rs b/src/hardware/setup.rs index 2239223..fe69da2 100644 --- a/src/hardware/setup.rs +++ b/src/hardware/setup.rs @@ -178,7 +178,7 @@ fn load_itcm() { /// # Args /// * `core` - The RTIC core for configuring the cortex-M core of the device. /// * `device` - The microcontroller peripherals to be configured. -/// * `sample_buffer_size` - The size of the ADC/DAC sample buffer. +/// * `batch_size` - The size of each ADC/DAC batch. /// * `sample_ticks` - The number of timer ticks between each sample. /// /// # Returns @@ -189,7 +189,7 @@ fn load_itcm() { pub fn setup( mut core: rtic::Peripherals, device: stm32h7xx_hal::stm32::Peripherals, - sample_buffer_size: usize, + batch_size: usize, sample_ticks: u32, ) -> (StabilizerDevices, Option) { let pwr = device.PWR.constrain(); @@ -414,7 +414,7 @@ pub fn setup( dma_streams.2, sampling_timer_channels.ch1, shadow_sampling_timer_channels.ch1, - sample_buffer_size, + batch_size, ) }; @@ -458,7 +458,7 @@ pub fn setup( dma_streams.5, sampling_timer_channels.ch2, shadow_sampling_timer_channels.ch2, - sample_buffer_size, + batch_size, ) }; @@ -546,13 +546,13 @@ pub fn setup( dac0_spi, dma_streams.6, sampling_timer_channels.ch3, - sample_buffer_size, + batch_size, ); let dac1 = dac::Dac1Output::new( dac1_spi, dma_streams.7, sampling_timer_channels.ch4, - sample_buffer_size, + batch_size, ); (dac0, dac1) }; @@ -994,6 +994,7 @@ pub fn setup( tim8_channels.ch1, &mut sampling_timer, etr_pin, + batch_size, ) }; From 6e8320dc03dd47eb5a5680e87bceeb153191bb4c Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 16:31:53 +0200 Subject: [PATCH 7/8] Fixing spelling --- src/hardware/pounder/timestamp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/pounder/timestamp.rs b/src/hardware/pounder/timestamp.rs index 571820e..7c10d9e 100644 --- a/src/hardware/pounder/timestamp.rs +++ b/src/hardware/pounder/timestamp.rs @@ -33,7 +33,7 @@ impl Timestamper { /// * `capture_channel` - The input capture channel for collecting timestamps. /// * `sampling_timer` - The stabilizer ADC sampling timer. /// * `_clock_input` - The input pin for the external clock from Pounder. - /// * `batch_size` - The number of seamples in each batch. + /// * `batch_size` - The number of samples in each batch. /// /// # Returns /// The new pounder timestamper in an operational state. From 9b6e2f1a7d25496326e879225d97f270a7643dcd Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Mon, 2 Aug 2021 16:37:18 +0200 Subject: [PATCH 8/8] Fixing broken link --- docs/pages/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/getting-started.md b/docs/pages/getting-started.md index 014c081..c81480e 100644 --- a/docs/pages/getting-started.md +++ b/docs/pages/getting-started.md @@ -115,7 +115,7 @@ been used during development, but any MQTTv5 broker is supported. > later is used. Stabilizer utilizes a static IP address for broker configuration. Ensure the IP address was -[configured](#configuring-firmware) properly to point to your broker before continuing. +[configured](#building-firmware) properly to point to your broker before continuing. ## Test the Connection Once your broker is running, test that Stabilizer is properly connected to it.