diff --git a/mcu-contrib/default.nix b/mcu-contrib/default.nix index cac0e9e..728fa24 100644 --- a/mcu-contrib/default.nix +++ b/mcu-contrib/default.nix @@ -65,9 +65,6 @@ in src = ; patchPhase = '' patch -p1 < ${./pounder-725.diff} - substituteInPlace src/net/mod.rs \ - --replace "[10, 34, 16, 10];" \ - "[192, 168, 1, 10];" # or other default MQTT broker address ''; doCheck = false; } // value))) { diff --git a/mcu-contrib/pounder-725.diff b/mcu-contrib/pounder-725.diff index e5779cc..ea91140 100644 --- a/mcu-contrib/pounder-725.diff +++ b/mcu-contrib/pounder-725.diff @@ -1,5 +1,33 @@ +diff --git a/Cargo.lock b/Cargo.lock +index 7c796acf..cee5ba60 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -983,9 +983,9 @@ dependencies = [ + + [[package]] + name = "serde" +-version = "1.0.203" ++version = "1.0.202" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" ++checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" + dependencies = [ + "serde_derive", + ] +@@ -1003,9 +1003,9 @@ dependencies = [ + + [[package]] + name = "serde_derive" +-version = "1.0.203" ++version = "1.0.202" + source = "registry+https://github.com/rust-lang/crates.io-index" +-checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" ++checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" + dependencies = [ + "proc-macro2", + "quote", diff --git a/ad9959/src/lib.rs b/ad9959/src/lib.rs -index b15f2a5bd..4e83bcb2f 100644 +index 025f7d4f..59578cce 100644 --- a/ad9959/src/lib.rs +++ b/ad9959/src/lib.rs @@ -2,8 +2,24 @@ @@ -27,7 +55,7 @@ index b15f2a5bd..4e83bcb2f 100644 /// A device driver for the AD9959 direct digital synthesis (DDS) chip. /// /// This chip provides four independently controllable digital-to-analog output sinusoids with -@@ -216,23 +232,17 @@ impl Ad9959 { +@@ -218,23 +234,17 @@ impl Ad9959 { reference_clock_frequency: f32, multiplier: u8, ) -> Result { @@ -55,7 +83,7 @@ index b15f2a5bd..4e83bcb2f 100644 fr1[0].set_bit(7, vco_range); self.write(Register::FR1, &fr1)?; -@@ -363,9 +373,7 @@ impl Ad9959 { +@@ -365,9 +375,7 @@ impl Ad9959 { channel: Channel, phase_turns: f32, ) -> Result { @@ -66,7 +94,7 @@ index b15f2a5bd..4e83bcb2f 100644 self.modify_channel( channel, Register::CPOW0, -@@ -511,6 +519,108 @@ impl Ad9959 { +@@ -513,6 +521,108 @@ impl Ad9959 { } } @@ -175,7 +203,7 @@ index b15f2a5bd..4e83bcb2f 100644 /// Represents a means of serializing a DDS profile for writing to a stream. pub struct ProfileSerializer { // heapless::Vec, especially its extend_from_slice() is slow -@@ -566,6 +676,39 @@ impl ProfileSerializer { +@@ -568,6 +678,39 @@ impl ProfileSerializer { } } @@ -216,22 +244,22 @@ index b15f2a5bd..4e83bcb2f 100644 fn add_write(&mut self, register: Register, value: &[u8]) { let data = &mut self.data[self.index..]; diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs -index c7df3f603..dadd0523c 100644 +index a4a04be8..83dcdefb 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs -@@ -44,6 +44,8 @@ use stabilizer::{ - afe::Gain, +@@ -47,6 +47,8 @@ use stabilizer::{ dac::{Dac0Output, Dac1Output, DacCode}, hal, + signal_generator::{self, SignalGenerator}, + pounder::{ClockConfig, PounderConfig}, + setup::PounderDevices as Pounder, - signal_generator::{self, SignalGenerator}, timers::SamplingTimer, - DigitalInput0, DigitalInput1, SystemTimer, Systick, AFE0, AFE1, -@@ -145,6 +147,16 @@ pub struct Settings { + DigitalInput0, DigitalInput1, SerialTerminal, SystemTimer, Systick, + UsbDevice, AFE0, AFE1, +@@ -179,6 +181,16 @@ pub struct DualIir { /// See [signal_generator::BasicConfig#miniconf] - #[miniconf(defer)] - signal_generator: miniconf::Array, + #[tree(depth = 2)] + signal_generator: [signal_generator::BasicConfig; 2], + + /// Specifies the config for pounder DDS clock configuration, DDS channels & attenuations + /// @@ -240,13 +268,13 @@ index c7df3f603..dadd0523c 100644 + /// + /// # Value + /// See [PounderConfig#miniconf] -+ #[miniconf(defer)] -+ pounder: miniconf::Option, ++ #[tree] ++ pounder: Option, } - impl Default for Settings { -@@ -171,6 +183,8 @@ impl Default for Settings { - .into(), + impl Default for DualIir { +@@ -206,6 +218,8 @@ impl Default for DualIir { + signal_generator: [signal_generator::BasicConfig::default(); 2], stream_target: StreamTarget::default(), + @@ -254,166 +282,128 @@ index c7df3f603..dadd0523c 100644 } } } -@@ -189,6 +203,7 @@ mod app { - settings: Settings, +@@ -222,6 +236,7 @@ mod app { + active_settings: DualIir, telemetry: TelemetryBuffer, signal_generator: [SignalGenerator; 2], + pounder: Option, } #[local] -@@ -199,6 +214,7 @@ mod app { +@@ -233,6 +248,7 @@ mod app { adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2], + iir_state: [[[f32; 4]; IIR_CASCADE_LENGTH]; 2], + dds_clock_state: Option, generator: FrameGenerator, cpu_temp_sensor: stabilizer::hardware::cpu_temp_sensor::CpuTempSensor, } -@@ -208,7 +224,7 @@ mod app { - let clock = SystemTimer::new(|| monotonics::now().ticks() as u32); +@@ -242,7 +258,7 @@ mod app { + let clock = SystemTimer::new(|| Systick::now().ticks()); // Configure the microcontroller -- let (stabilizer, _pounder) = hardware::setup::setup( -+ let (stabilizer, pounder) = hardware::setup::setup( +- let (stabilizer, _pounder) = hardware::setup::setup::( ++ let (mut stabilizer, pounder) = hardware::setup::setup::( c.core, c.device, clock, -@@ -216,6 +232,13 @@ mod app { - SAMPLE_TICKS, - ); +@@ -261,6 +277,13 @@ mod app { + + let generator = network.configure_streaming(StreamFormat::AdcDacData); + let dds_clock_state = pounder.as_ref().map(|_| ClockConfig::default()); -+ -+ let mut settings = Settings::default(); + if pounder.is_some() { -+ settings.pounder.replace(PounderConfig::default()); ++ stabilizer.settings.dual_iir ++ .pounder ++ .replace(PounderConfig::default()); + } + - let mut network = NetworkUsers::new( - stabilizer.net.stack, - stabilizer.net.phy, -@@ -226,13 +249,12 @@ mod app { - .unwrap_or("10.34.16.1") - .parse() - .unwrap(), -+ settings, - ); - - let generator = network - .configure_streaming(StreamFormat::AdcDacData, BATCH_SIZE as _); - -- let settings = Settings::default(); -- let shared = Shared { + usb: stabilizer.usb, network, - settings, -@@ -249,6 +271,7 @@ mod app { - .unwrap(), +@@ -279,6 +302,7 @@ mod app { ), ], -+ pounder, + settings: stabilizer.settings, ++ pounder }; let mut local = Local { -@@ -258,6 +281,7 @@ mod app { +@@ -289,6 +313,7 @@ mod app { adcs: stabilizer.adcs, dacs: stabilizer.dacs, - iir_state: [[[0.; 5]; IIR_CASCADE_LENGTH]; 2], + iir_state: [[[0.; 4]; IIR_CASCADE_LENGTH]; 2], + dds_clock_state, generator, cpu_temp_sensor: stabilizer.temperature_sensor, }; -@@ -407,7 +431,7 @@ mod app { +@@ -458,7 +483,7 @@ mod app { } } -- #[task(priority = 1, local=[afes], shared=[network, settings, signal_generator])] -+ #[task(priority = 1, local=[afes, dds_clock_state], shared=[network, settings, signal_generator, pounder])] - fn settings_update(mut c: settings_update::Context) { - let settings = c.shared.network.lock(|net| *net.miniconf.settings()); - c.shared.settings.lock(|current| *current = settings); -@@ -431,15 +455,28 @@ mod app { +- #[task(priority = 1, local=[afes], shared=[network, settings, active_settings, signal_generator])] ++ #[task(priority = 1, local=[afes, dds_clock_state], shared=[network, settings, active_settings, signal_generator, pounder])] + async fn settings_update(mut c: settings_update::Context) { + c.shared.settings.lock(|settings| { + c.local.afes.0.set_gain(settings.dual_iir.afe[0]); +@@ -482,6 +507,17 @@ mod app { + ), + } } - } - + // Update Pounder configurations + c.shared.pounder.lock(|pounder| { + if let Some(pounder) = pounder { -+ let pounder_settings = settings.pounder.as_ref().unwrap(); -+ let mut clocking = c.local.dds_clock_state.unwrap(); -+ pounder.update_dds(*pounder_settings, &mut clocking); ++ let pounder_settings = settings.dual_iir.pounder.as_ref().unwrap(); ++ // let mut clocking = c.local.dds_clock_state; ++ pounder.update_dds( ++ *pounder_settings, ++ c.local.dds_clock_state.as_mut().unwrap(), ++ ); + } + }); -+ - let target = settings.stream_target.into(); - c.shared.network.lock(|net| net.direct_stream(target)); + + let target = settings.dual_iir.stream_target.into(); + c.shared.network.lock(|net| net.direct_stream(target)); +@@ -492,22 +528,31 @@ mod app { + }); } - #[task(priority = 1, shared=[network, settings, telemetry], local=[cpu_temp_sensor])] + #[task(priority = 1, shared=[network, settings, telemetry, pounder], local=[cpu_temp_sensor])] - fn telemetry(mut c: telemetry::Context) { - let telemetry: TelemetryBuffer = - c.shared.telemetry.lock(|telemetry| *telemetry); + async fn telemetry(mut c: telemetry::Context) { + loop { + let telemetry: TelemetryBuffer = + c.shared.telemetry.lock(|telemetry| *telemetry); -+ let pounder_telemetry = c.shared.pounder.lock(|pounder| { -+ pounder.as_mut().map(|pounder| pounder.get_telemetry()) -+ }); +- let (gains, telemetry_period) = ++ let (gains, telemetry_period, pounder_config) = + c.shared.settings.lock(|settings| { +- (settings.dual_iir.afe, settings.dual_iir.telemetry_period) ++ ( ++ settings.dual_iir.afe, ++ settings.dual_iir.telemetry_period, ++ settings.dual_iir.pounder ++ ) + }); + ++ let pounder_telemetry = c.shared.pounder.lock(|pounder| { ++ pounder.as_mut().map(|pdr| pdr.get_telemetry(pounder_config.unwrap())) ++ }); + - let (gains, telemetry_period) = c - .shared - .settings -@@ -450,6 +487,7 @@ mod app { - gains[0], - gains[1], - c.local.cpu_temp_sensor.get_temperature().unwrap(), -+ pounder_telemetry, - )) - }); - -diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs -index 6896df7ff..1e92a0f75 100644 ---- a/src/bin/lockin.rs -+++ b/src/bin/lockin.rs -@@ -254,6 +254,8 @@ mod app { - SAMPLE_TICKS, - ); - -+ let settings = Settings::default(); -+ - let mut network = NetworkUsers::new( - stabilizer.net.stack, - stabilizer.net.phy, -@@ -264,6 +266,7 @@ mod app { - .unwrap_or("10.34.16.1") - .parse() - .unwrap(), -+ settings, - ); - - let generator = network -@@ -272,7 +275,7 @@ mod app { - let shared = Shared { - network, - telemetry: TelemetryBuffer::default(), -- settings: Settings::default(), -+ settings, - }; - - let signal_config = signal_generator::Config { -@@ -499,6 +502,7 @@ mod app { - gains[0], - gains[1], - c.local.cpu_temp_sensor.get_temperature().unwrap(), -+ None, - )) - }); + c.shared.network.lock(|net| { + net.telemetry.publish(&telemetry.finalize( + gains[0], + gains[1], + c.local.cpu_temp_sensor.get_temperature().unwrap(), ++ pounder_telemetry, + )) + }); diff --git a/src/hardware/pounder/attenuators.rs b/src/hardware/pounder/attenuators.rs -index ef22814d4..a5d220dfb 100644 +index cfd08b7f..2570f506 100644 --- a/src/hardware/pounder/attenuators.rs +++ b/src/hardware/pounder/attenuators.rs -@@ -54,10 +54,9 @@ pub trait AttenuatorInterface { +@@ -52,10 +52,9 @@ pub trait AttenuatorInterface { fn get_attenuation(&mut self, channel: Channel) -> Result { let mut channels = [0_u8; 4]; @@ -427,7 +417,7 @@ index ef22814d4..a5d220dfb 100644 self.transfer_attenuators(&mut channels)?; // The attenuation code is stored in the upper 6 bits of the register, where each LSB -@@ -68,6 +67,9 @@ pub trait AttenuatorInterface { +@@ -66,6 +65,9 @@ pub trait AttenuatorInterface { // care) would contain erroneous data. let attenuation_code = (!channels[channel as usize]) >> 2; @@ -438,7 +428,7 @@ index ef22814d4..a5d220dfb 100644 Ok(attenuation_code as f32 / 2.0) } diff --git a/src/hardware/pounder/dds_output.rs b/src/hardware/pounder/dds_output.rs -index 9af23a9aa..559855fcc 100644 +index 3ae1ce90..cd978b01 100644 --- a/src/hardware/pounder/dds_output.rs +++ b/src/hardware/pounder/dds_output.rs @@ -55,7 +55,7 @@ @@ -498,7 +488,7 @@ index 9af23a9aa..559855fcc 100644 #[allow(dead_code)] #[inline] diff --git a/src/hardware/pounder/mod.rs b/src/hardware/pounder/mod.rs -index d6dd654fc..1e436f785 100644 +index 5bc7e9ff..5b8d5d30 100644 --- a/src/hardware/pounder/mod.rs +++ b/src/hardware/pounder/mod.rs @@ -1,10 +1,17 @@ @@ -513,21 +503,21 @@ index d6dd654fc..1e436f785 100644 +}; use embedded_hal::blocking::spi::Transfer; use enum_iterator::Sequence; -+use miniconf::Miniconf; ++use miniconf::Tree; +use rf_power::PowerMeasurementInterface; use serde::{Deserialize, Serialize}; +use stm32h7xx_hal::time::MegaHertz; pub mod attenuators; pub mod dds_output; -@@ -91,40 +98,98 @@ impl From for GpioPin { +@@ -120,40 +127,99 @@ impl From for GpioPin { } } -#[derive(Serialize, Deserialize, Copy, Clone, Debug)] -pub struct DdsChannelState { - pub phase_offset: f32, -+#[derive(Serialize, Deserialize, Copy, Clone, Debug, Miniconf)] ++#[derive(Serialize, Deserialize, Copy, Clone, Debug, Tree)] +pub struct DdsChannelConfig { pub frequency: f32, + pub phase_offset: f32, @@ -589,9 +579,9 @@ index d6dd654fc..1e436f785 100644 -#[derive(Serialize, Deserialize, Copy, Clone, Debug)] -pub struct OutputChannelState { -+#[derive(Serialize, Deserialize, Copy, Clone, Debug, Miniconf)] ++#[derive(Serialize, Deserialize, Copy, Clone, Debug, Tree)] +pub struct ChannelConfig { -+ #[miniconf(defer)] ++ #[tree] + pub dds: DdsChannelConfig, pub attenuation: f32, - pub channel: DdsChannelState, @@ -608,7 +598,7 @@ index d6dd654fc..1e436f785 100644 + } +} + -+#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Miniconf)] ++#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Tree)] +pub struct ClockConfig { pub multiplier: u8, pub reference_clock: f32, @@ -625,19 +615,20 @@ index d6dd654fc..1e436f785 100644 + } +} + -+#[derive(Copy, Clone, Debug, Default, Miniconf)] ++#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, Tree)] +pub struct PounderConfig { ++ #[tree] + pub clock: ClockConfig, -+ #[miniconf(defer)] -+ pub in_channel: miniconf::Array, -+ #[miniconf(defer)] -+ pub out_channel: miniconf::Array, ++ #[tree(depth = 2)] ++ pub in_channel: [ChannelConfig; 2], ++ #[tree(depth = 2)] ++ pub out_channel: [ChannelConfig; 2], +} + impl From for ad9959::Channel { /// Translate pounder channels to DDS output channels. fn from(other: Channel) -> Self { -@@ -489,3 +554,77 @@ impl rf_power::PowerMeasurementInterface for PounderDevices { +@@ -585,3 +651,78 @@ impl rf_power::PowerMeasurementInterface for PounderDevices { Ok(adc_scale * 2.048) } } @@ -705,68 +696,52 @@ index d6dd654fc..1e436f785 100644 + } + } + -+ pub fn get_telemetry(&mut self) -> PounderTelemetry { ++ pub fn get_telemetry(&mut self, config: PounderConfig) -> PounderTelemetry { + PounderTelemetry { + temperature: self.pounder.lm75.read_temperature().unwrap(), + input_power: [ + self.pounder.measure_power(Channel::In0).unwrap(), + self.pounder.measure_power(Channel::In1).unwrap(), + ], ++ config, + } + } +} diff --git a/src/net/mod.rs b/src/net/mod.rs -index f6372381b..9a88008f7 100644 +index a10b7cdb..efa2b8c8 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs -@@ -43,7 +43,7 @@ pub enum NetworkState { +@@ -33,14 +33,14 @@ pub type NetworkReference = + + pub struct MqttStorage { + telemetry: [u8; 2048], +- settings: [u8; 1024], ++ settings: [u8; 1536], } - /// A structure of Stabilizer's default network users. --pub struct NetworkUsers { -+pub struct NetworkUsers { - pub miniconf: miniconf::MqttClient, - pub processor: NetworkProcessor, - stream: DataStream, -@@ -53,7 +53,7 @@ pub struct NetworkUsers { - - impl NetworkUsers - where -- S: Default + Miniconf + Clone, -+ S: Miniconf + Clone, - T: Serialize, - { - /// Construct Stabilizer's default network users. -@@ -65,6 +65,7 @@ where - /// * `app` - The name of the application. - /// * `mac` - The MAC address of the network. - /// * `broker` - The IP address of the MQTT broker to use. -+ /// * `settings` - The initial settings value - /// - /// # Returns - /// A new struct of network users. -@@ -75,6 +76,7 @@ where - app: &str, - mac: smoltcp_nal::smoltcp::wire::EthernetAddress, - broker: IpAddr, -+ settings: S, - ) -> Self { - let stack_manager = - cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)) -@@ -91,7 +93,7 @@ where - &prefix, - broker, - clock, -- S::default(), -+ settings, - ) - .unwrap(); - + impl Default for MqttStorage { + fn default() -> Self { + Self { + telemetry: [0u8; 2048], +- settings: [0u8; 1024], ++ settings: [0u8; 1536], + } + } + } diff --git a/src/net/telemetry.rs b/src/net/telemetry.rs -index c6e071f17..e35347037 100644 +index 4aa82601..3dc3086c 100644 --- a/src/net/telemetry.rs +++ b/src/net/telemetry.rs -@@ -58,6 +58,23 @@ pub struct Telemetry { +@@ -16,7 +16,7 @@ use minimq::{DeferredPublication, Publication}; + use serde::Serialize; + + use super::NetworkReference; +-use crate::hardware::{adc::AdcCode, afe::Gain, dac::DacCode, SystemTimer}; ++use crate::hardware::{adc::AdcCode, afe::Gain, dac::DacCode, SystemTimer, pounder::PounderConfig}; + + /// Default metadata message if formatting errors occur. + const DEFAULT_METADATA: &str = "{\"message\":\"Truncated: See USB terminal\"}"; +@@ -68,6 +68,26 @@ pub struct Telemetry { /// The CPU temperature in degrees Celsius. pub cpu_temp: f32, @@ -787,10 +762,13 @@ index c6e071f17..e35347037 100644 + + /// The detected RF power into IN channels + pub input_power: [f32; 2], ++ ++ /// The configuration of the clock and DDS channels ++ pub config: PounderConfig, } impl Default for TelemetryBuffer { -@@ -77,10 +94,17 @@ impl TelemetryBuffer { +@@ -87,10 +107,17 @@ impl TelemetryBuffer { /// * `afe0` - The current AFE configuration for channel 0. /// * `afe1` - The current AFE configuration for channel 1. /// * `cpu_temp` - The current CPU temperature. @@ -809,7 +787,7 @@ index c6e071f17..e35347037 100644 let in0_volts = Into::::into(self.adcs[0]) / afe0.as_multiplier(); let in1_volts = Into::::into(self.adcs[1]) / afe1.as_multiplier(); -@@ -89,6 +113,7 @@ impl TelemetryBuffer { +@@ -99,6 +126,7 @@ impl TelemetryBuffer { adcs: [in0_volts, in1_volts], dacs: [self.dacs[0].into(), self.dacs[1].into()], digital_inputs: self.digital_inputs,