From 13e02710cda7bd5bac30b15fdb3b432b2f399aa5 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 12:08:03 +0100 Subject: [PATCH] Adding simplified clocking semantics --- src/bin/dual-iir.rs | 54 +++++++++++++--------------------- src/bin/lockin-external.rs | 55 +++++++++++++++-------------------- src/hardware/configuration.rs | 10 +++---- src/hardware/cycle_counter.rs | 36 +++++++++++++++++++++++ src/hardware/mod.rs | 2 ++ 5 files changed, 87 insertions(+), 70 deletions(-) create mode 100644 src/hardware/cycle_counter.rs diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 841c62d..911b63d 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -4,20 +4,18 @@ use stm32h7xx_hal as hal; -use rtic::cyccnt::{Instant, U32Ext}; - use stabilizer::hardware; use miniconf::{ embedded_nal::{IpAddr, Ipv4Addr}, - minimq, - MqttInterface, StringSet, + minimq, MqttInterface, StringSet, }; use serde::Deserialize; use dsp::iir; use hardware::{ - Adc0Input, Adc1Input, Dac0Output, Dac1Output, NetworkStack, AFE0, AFE1, + Adc0Input, Adc1Input, CycleCounter, Dac0Output, Dac1Output, NetworkStack, + AFE0, AFE1, }; const SCALE: f32 = i16::MAX as _; @@ -32,9 +30,7 @@ pub struct Settings { impl Settings { pub fn new() -> Self { - Self { - test: 0, - } + Self { test: 0 } } } @@ -44,7 +40,9 @@ const APP: () = { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - mqtt_interface: MqttInterface, + mqtt_interface: + MqttInterface, + clock: CycleCounter, // Format: iir_state[ch][cascade-no][coeff] #[init([[iir::Vec5([0.; 5]); IIR_CASCADE_LENGTH]; 2])] @@ -61,15 +59,16 @@ const APP: () = { let mqtt_interface = { let mqtt_client = { let broker = IpAddr::V4(Ipv4Addr::new(10, 34, 16, 1)); - minimq::MqttClient::new(broker, "stabilizer", stabilizer.net.stack).unwrap() + minimq::MqttClient::new( + broker, + "stabilizer", + stabilizer.net.stack, + ) + .unwrap() }; - MqttInterface::new( - mqtt_client, - "stabilizer", - Settings::new(), - ) - .unwrap() + MqttInterface::new(mqtt_client, "stabilizer", Settings::new()) + .unwrap() }; // Enable ADC/DAC events @@ -86,6 +85,7 @@ const APP: () = { afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, + clock: stabilizer.cycle_counter, } } @@ -134,26 +134,14 @@ const APP: () = { } } - #[idle(resources=[mqtt_interface], spawn=[settings_update])] + #[idle(resources=[mqtt_interface, clock], spawn=[settings_update])] fn idle(mut c: idle::Context) -> ! { - let mut time = 0u32; - let mut next_ms = Instant::now(); - - // TODO: Replace with reference to CPU clock from CCDR. - next_ms += 400_000.cycles(); + let clock = c.resources.clock; loop { - let tick = Instant::now() > next_ms; - - if tick { - next_ms += 400_000.cycles(); - time += 1; - } - - let sleep = c - .resources - .mqtt_interface - .lock(|interface| !interface.network_stack().poll(time)); + let sleep = c.resources.mqtt_interface.lock(|interface| { + !interface.network_stack().poll(clock.current_ms()) + }); match c .resources diff --git a/src/bin/lockin-external.rs b/src/bin/lockin-external.rs index 3eafcd8..451765d 100644 --- a/src/bin/lockin-external.rs +++ b/src/bin/lockin-external.rs @@ -4,12 +4,9 @@ use stm32h7xx_hal as hal; -use rtic::cyccnt::{Instant, U32Ext}; - use miniconf::{ embedded_nal::{IpAddr, Ipv4Addr}, - minimq, - MqttInterface, StringSet, + minimq, MqttInterface, StringSet, }; use serde::Deserialize; @@ -23,12 +20,12 @@ use hardware::{ #[derive(Deserialize, StringSet)] pub struct Settings { + data: u32, } impl Settings { pub fn new() -> Self { - Self { - } + Self { data: 5 } } } @@ -38,7 +35,12 @@ const APP: () = { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - mqtt_interface: MqttInterface, + clock: hardware::CycleCounter, + mqtt_interface: MqttInterface< + Settings, + hardware::NetworkStack, + minimq::consts::U256, + >, timestamper: InputStamper, pll: RPLL, @@ -53,15 +55,16 @@ const APP: () = { let mqtt_interface = { let mqtt_client = { let broker = IpAddr::V4(Ipv4Addr::new(10, 34, 16, 1)); - minimq::MqttClient::new(broker, "stabilizer", stabilizer.net.stack).unwrap() + minimq::MqttClient::new( + broker, + "stabilizer", + stabilizer.net.stack, + ) + .unwrap() }; - MqttInterface::new( - mqtt_client, - "stabilizer", - Settings::new(), - ) - .unwrap() + MqttInterface::new(mqtt_client, "stabilizer", Settings::new()) + .unwrap() }; let pll = RPLL::new( @@ -90,6 +93,7 @@ const APP: () = { adcs: stabilizer.adcs, dacs: stabilizer.dacs, timestamper: stabilizer.timestamper, + clock: stabilizer.cycle_counter, pll, lockin: Lockin::default(), @@ -172,26 +176,13 @@ const APP: () = { } } - #[idle(resources=[mqtt_interface], spawn=[settings_update])] + #[idle(resources=[mqtt_interface, clock], spawn=[settings_update])] fn idle(mut c: idle::Context) -> ! { - let mut time = 0u32; - let mut next_ms = Instant::now(); - - // TODO: Replace with reference to CPU clock from CCDR. - next_ms += 400_000.cycles(); - + let clock = c.resources.clock; loop { - let tick = Instant::now() > next_ms; - - if tick { - next_ms += 400_000.cycles(); - time += 1; - } - - let sleep = c - .resources - .mqtt_interface - .lock(|interface| !interface.network_stack().poll(time)); + let sleep = c.resources.mqtt_interface.lock(|interface| { + !interface.network_stack().poll(clock.current_ms()) + }); match c .resources diff --git a/src/hardware/configuration.rs b/src/hardware/configuration.rs index fac712a..d3d10fe 100644 --- a/src/hardware/configuration.rs +++ b/src/hardware/configuration.rs @@ -12,8 +12,9 @@ use smoltcp_nal::smoltcp; use embedded_hal::digital::v2::{InputPin, OutputPin}; use super::{ - adc, afe, dac, design_parameters, digital_input_stamper, eeprom, pounder, - timers, DdsOutput, NetworkStack, AFE0, AFE1, + adc, afe, cycle_counter::CycleCounter, dac, design_parameters, + digital_input_stamper, eeprom, pounder, timers, DdsOutput, NetworkStack, + AFE0, AFE1, }; pub struct NetStorage { @@ -42,6 +43,7 @@ pub struct StabilizerDevices { pub adc_dac_timer: timers::SamplingTimer, pub timestamp_timer: timers::TimestampTimer, pub net: NetworkDevices, + pub cycle_counter: CycleCounter, } /// The available Pounder-specific hardware interfaces. @@ -831,6 +833,7 @@ pub fn setup( net: network_devices, adc_dac_timer: sampling_timer, timestamp_timer, + cycle_counter: CycleCounter::new(core.DWT, ccdr.clocks.c_ck()), }; // info!("Version {} {}", build_info::PKG_VERSION, build_info::GIT_VERSION.unwrap()); @@ -840,8 +843,5 @@ pub fn setup( // Enable the instruction cache. core.SCB.enable_icache(); - // Utilize the cycle counter for RTIC scheduling. - core.DWT.enable_cycle_counter(); - (stabilizer, pounder) } diff --git a/src/hardware/cycle_counter.rs b/src/hardware/cycle_counter.rs new file mode 100644 index 0000000..38db550 --- /dev/null +++ b/src/hardware/cycle_counter.rs @@ -0,0 +1,36 @@ +use rtic::cyccnt::{Duration, Instant, U32Ext}; + +use stm32h7xx_hal::time::Hertz; + +pub struct CycleCounter { + next_tick: Instant, + ticks: u32, + increment: Duration, +} + +impl CycleCounter { + pub fn new( + mut dwt: cortex_m::peripheral::DWT, + cpu_frequency: impl Into, + ) -> Self { + dwt.enable_cycle_counter(); + let increment = + ((cpu_frequency.into().0 as f32 / 1000.0) as u32).cycles(); + + Self { + increment, + ticks: 0, + next_tick: Instant::now() + increment, + } + } + + pub fn current_ms(&mut self) -> u32 { + let now = Instant::now(); + while now > self.next_tick { + self.next_tick += self.increment; + self.ticks += 1; + } + + self.ticks + } +} diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index b224541..0fa6d65 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -10,6 +10,7 @@ use panic_halt as _; mod adc; mod afe; mod configuration; +mod cycle_counter; mod dac; pub mod design_parameters; mod digital_input_stamper; @@ -19,6 +20,7 @@ mod timers; pub use adc::{Adc0Input, Adc1Input}; pub use afe::Gain as AfeGain; +pub use cycle_counter::CycleCounter; pub use dac::{Dac0Output, Dac1Output}; pub use digital_input_stamper::InputStamper; pub use pounder::DdsOutput;