From f0e7c153ba852a05a652b6e81aed71e7f211e82e Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Tue, 26 Jan 2021 14:28:06 +0100 Subject: [PATCH 01/27] Adding WIP refactor for MQTT + settings --- Cargo.toml | 1 + src/bin/dual-iir.rs | 154 ++++------------------------ src/hardware/configuration.rs | 40 +++++--- src/hardware/mod.rs | 5 +- src/hardware/mqtt_interface.rs | 102 +++++++++++++++++++ src/hardware/smoltcp_nal.rs | 181 +++++++++++++++++++++++++++++++++ 6 files changed, 337 insertions(+), 146 deletions(-) create mode 100644 src/hardware/mqtt_interface.rs create mode 100644 src/hardware/smoltcp_nal.rs diff --git a/Cargo.toml b/Cargo.toml index f4f90fa..2789de0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ enum-iterator = "0.6.0" paste = "1" dsp = { path = "dsp" } ad9959 = { path = "ad9959" } +minimq = "0.1.0" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index fd8f5e4..53d1924 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -25,6 +25,12 @@ const TCP_TX_BUFFER_SIZE: usize = 8192; // The number of cascaded IIR biquads per channel. Select 1 or 2! const IIR_CASCADE_LENGTH: usize = 1; +#[derive(miniconf::StringSet)] +struct Settings { + afe_gain: [hardware::AfeGain; 2], + iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], +} + #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { struct Resources { @@ -32,6 +38,7 @@ const APP: () = { adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), net_interface: hardware::Ethernet, + mqtt_interface: hardware::MqttInterface, // Format: iir_state[ch][cascade-no][coeff] #[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])] @@ -107,26 +114,8 @@ const APP: () = { } } - #[idle(resources=[net_interface, iir_state, iir_ch, afes])] + #[idle(resources=[mqtt_interface], spawn=[settings_update])] fn idle(mut c: idle::Context) -> ! { - let mut socket_set_entries: [_; 8] = Default::default(); - let mut sockets = - smoltcp::socket::SocketSet::new(&mut socket_set_entries[..]); - - let mut rx_storage = [0; TCP_RX_BUFFER_SIZE]; - let mut tx_storage = [0; TCP_TX_BUFFER_SIZE]; - let tcp_handle = { - let tcp_rx_buffer = - smoltcp::socket::TcpSocketBuffer::new(&mut rx_storage[..]); - let tcp_tx_buffer = - smoltcp::socket::TcpSocketBuffer::new(&mut tx_storage[..]); - let tcp_socket = - smoltcp::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); - sockets.add(tcp_socket) - }; - - let mut server = server::Server::new(); - let mut time = 0u32; let mut next_ms = Instant::now(); @@ -141,125 +130,26 @@ const APP: () = { time += 1; } - { - let socket = - &mut *sockets.get::(tcp_handle); - if socket.state() == smoltcp::socket::TcpState::CloseWait { - socket.close(); - } else if !(socket.is_open() || socket.is_listening()) { - socket - .listen(1235) - .unwrap_or_else(|e| warn!("TCP listen error: {:?}", e)); - } else { - server.poll(socket, |req| { - info!("Got request: {:?}", req); - stabilizer::route_request!(req, - readable_attributes: [ - "stabilizer/iir/state": (|| { - let state = c.resources.iir_state.lock(|iir_state| - server::Status { - t: time, - x0: iir_state[0][0][0], - y0: iir_state[0][0][2], - x1: iir_state[1][0][0], - y1: iir_state[1][0][2], - }); - - Ok::(state) - }), - // "_b" means cascades 2nd IIR - "stabilizer/iir_b/state": (|| { let state = c.resources.iir_state.lock(|iir_state| - server::Status { - t: time, - x0: iir_state[0][IIR_CASCADE_LENGTH-1][0], - y0: iir_state[0][IIR_CASCADE_LENGTH-1][2], - x1: iir_state[1][IIR_CASCADE_LENGTH-1][0], - y1: iir_state[1][IIR_CASCADE_LENGTH-1][2], - }); - - Ok::(state) - }), - "stabilizer/afe0/gain": (|| c.resources.afes.0.get_gain()), - "stabilizer/afe1/gain": (|| c.resources.afes.1.get_gain()) - ], - - modifiable_attributes: [ - "stabilizer/iir0/state": server::IirRequest, (|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][0] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/iir1/state": server::IirRequest, (|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][0] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/iir_b0/state": server::IirRequest, (|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][IIR_CASCADE_LENGTH-1] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/iir_b1/state": server::IirRequest,(|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][IIR_CASCADE_LENGTH-1] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/afe0/gain": hardware::AfeGain, (|gain| { - c.resources.afes.0.set_gain(gain); - Ok::<(), ()>(()) - }), - "stabilizer/afe1/gain": hardware::AfeGain, (|gain| { - c.resources.afes.1.set_gain(gain); - Ok::<(), ()>(()) - }) - ] - ) - }); - } - } - - let sleep = match c.resources.net_interface.poll( - &mut sockets, + let sleep = c.resources.network_stack.update( smoltcp::time::Instant::from_millis(time as i64), - ) { - Ok(changed) => !changed, - Err(smoltcp::Error::Unrecognized) => true, - Err(e) => { - info!("iface poll error: {:?}", e); - true - } - }; + ); - if sleep { - cortex_m::asm::wfi(); + match c.resources.mqtt_interface.lock(|interface| interface.update(time).unwrap()) { + Action::Sleep => cortex_m::asm::wfi(), + Action::Continue => {}, + Action::CommitSettings => c.spawn.settings_update().unwrap(); } } } + #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] + fn settings_update(c: settings_update::Context) { + let settings = c.resources.mqtt_interface.current_settings(); + c.resources.iir_ch.lock(|iir_ch| *iir_ch = settings.iir); + c.resources.afes.0.set_gain(settings.afe_gain[0]); + c.resources.afes.1.set_gain(settings.afe_gain[1]); + } + #[task(binds = ETH, priority = 1)] fn eth(_: eth::Context) { unsafe { hal::ethernet::interrupt_handler() } diff --git a/src/hardware/configuration.rs b/src/hardware/configuration.rs index 18ca67f..925d684 100644 --- a/src/hardware/configuration.rs +++ b/src/hardware/configuration.rs @@ -21,20 +21,12 @@ use embedded_hal::digital::v2::{InputPin, OutputPin}; use super::{ adc, afe, dac, design_parameters, digital_input_stamper, eeprom, pounder, - timers, DdsOutput, Ethernet, AFE0, AFE1, + smoltcp_nal::NetStorage, timers, DdsOutput, NetworkStack, AFE0, AFE1, }; -// Network storage definition for the ethernet interface. -struct NetStorage { - ip_addrs: [smoltcp::wire::IpCidr; 1], - neighbor_cache: - [Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8], - routes_storage: [Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 1], -} - /// The available networking devices on Stabilizer. pub struct NetworkDevices { - pub interface: Ethernet, + pub stack: NetworkStack, pub phy: ethernet::phy::LAN8742A, } @@ -71,7 +63,11 @@ static mut NET_STORE: NetStorage = NetStorage { smoltcp::wire::Ipv6Cidr::SOLICITED_NODE_PREFIX, )], neighbor_cache: [None; 8], - routes_storage: [None; 1], + routes_cache: [None; 8], + sockets: [None; 1], + + tx_storage: [0; 4096], + rx_storage: [0; 4096], }; /// Configure the stabilizer hardware for operation. @@ -515,7 +511,7 @@ pub fn setup( ); let default_v4_gw = Ipv4Address::new(10, 0, 16, 1); - let mut routes = Routes::new(&mut store.routes_storage[..]); + let mut routes = Routes::new(&mut store.routes_cache[..]); routes.add_default_ipv4_route(default_v4_gw).unwrap(); let neighbor_cache = @@ -528,8 +524,26 @@ pub fn setup( .routes(routes) .finalize(); + let sockets = { + // Note(unsafe): Configuration is only called once, so we only access the global + // storage a single time. + let socket_storage = unsafe { &mut NET_STORE.sockets }; + let mut sockets = smoltcp::socket::SocketSet::new(socket_storage); + + let tcp_socket = { + // Note(unsafe): Configuration is only called once, so we only access the global + // storage a single time. + let rx_storage = unsafe { &mut NET_STORE.rx_storage[..] }; + let tx_storage = unsafe { &mut NET_STORE.tx_storage[..] }; + smoltcp::socket::TcpSocket::new(rx_storage, tx_storage) + }; + + sockets.add(tcp_socket); + sockets + }; + NetworkDevices { - interface, + stack: NetworkStack::new(interface, sockets), phy: lan8742a, } }; diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index dc3aa25..2d638c4 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -15,6 +15,7 @@ mod design_parameters; mod digital_input_stamper; mod eeprom; mod pounder; +mod smoltcp_nal; mod timers; pub use adc::{Adc0Input, Adc1Input}; @@ -36,13 +37,15 @@ pub type AFE1 = afe::ProgrammableGainAmplifier< >; // Type alias for the ethernet interface on Stabilizer. -pub type Ethernet = smoltcp::iface::EthernetInterface< +type Ethernet = smoltcp::iface::EthernetInterface< 'static, 'static, 'static, hal::ethernet::EthernetDMA<'static>, >; +pub type NetworkStack = smoltcp_nal::NetworkStack<'static, 'static, 'static>; + pub use configuration::{setup, PounderDevices, StabilizerDevices}; #[inline(never)] diff --git a/src/hardware/mqtt_interface.rs b/src/hardware/mqtt_interface.rs new file mode 100644 index 0000000..7ce6544 --- /dev/null +++ b/src/hardware/mqtt_interface.rs @@ -0,0 +1,102 @@ +use super::NetworkStack; + +use minimq::{QoS, Error, Property, MqttClient}; + +pub enum Action { + Continue, + Sleep, + CommitSettings, +} + +struct MqttInterface { + client: MqttClient, + subscribed: bool, + settings: T, +} + +impl MqttInterface +where + T: miniconf::StringSet +{ + pub fn new(stack: NetworkStack, settings: T) -> Self { + let client: MqttClient = MqttClient::new( + IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), + "stabilizer", + stack).unwrap(); + + Self { + client, + subscribed: false, + settings, + } + } + + pub fn current_settings(&self) -> &T { + &self.settings + } + + pub fn update(&mut self, time: u32) -> Result { + + let sleep = self.client.network_stack.update(smoltcp::time::Instant::from_millis(time as i64)); + + if !self.subscribed && self.client.is_connected().unwrap() { + self.client.subscribe("stabilizer/settings/#", &[]); + self.client.subscribe("stabilizer/commit", &[]); + } + + let mut commit = false; + + match self.client.poll(|client, topic, message, properties| { + let split = topic.split('/').iter(); + // TODO: Verify topic ID against our ID. + let id = split.next().unwrap(); + + // Process the command + let command = split.next().unwrap(); + let response: String = match command { + "settings" => { + // Handle settings failures + let mut response: String = String::new(); + match self.settings.string_set(split.peekable(), message) { + Ok(_) => write!(&mut response, "{} written", topic).unwrap(), + Err(error) => { + write!(&mut response, "Settings failure: {}", error).unwrap(); + } + }; + + response + }, + "commit" => { + commit = true; + String::from("Committing pending settings"); + } + }; + + // Publish the response to the request over MQTT using the ResponseTopic property if + // possible. Otherwise, default to a logging topic. + if let Property::ResponseTopic(topic) = properties.iter().find(|&prop| { + if let Property::ResponseTopic(_) = *prop { + true + } else { + false + } + }).or(Some(&Property::ResponseTopic("stabilizer/log"))).unwrap() { + self.client.publish(topic, &response.into_bytes(), QoS::AtMostOnce, &[]).unwrap(); + } + }) { + Ok(_) => {}, + Err(Error::Disconnected) => self.subscribed = false, + Err(err) => error!("Unexpected error: {:?}", err) + }; + + let action = if commit { + Action::Commit + } else if sleep { + Action::Sleep + } else { + Action::Continue + }; + + Ok(action) + } +} diff --git a/src/hardware/smoltcp_nal.rs b/src/hardware/smoltcp_nal.rs new file mode 100644 index 0000000..8cd7f46 --- /dev/null +++ b/src/hardware/smoltcp_nal.rs @@ -0,0 +1,181 @@ +use core::cell::RefCell; +///! Network abstraction layer for smoltcp. +use heapless::{consts, Vec}; +use minimq::embedded_nal::{self as nal, nb}; + +use super::Ethernet; + +pub struct NetStorage { + pub ip_addrs: [smoltcp::wire::IpCidr; 1], + pub sockets: [Option>; 1], + pub neighbor_cache: + [Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8], + pub routes_cache: + [Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 8], + pub tx_storage: [u8; 4096], + pub rx_storage: [u8; 4096], +} + +#[derive(Debug)] +pub enum NetworkError { + NoSocket, + ConnectionFailure, + ReadFailure, + WriteFailure, + Unsupported, +} + +pub struct NetworkStack<'a, 'b, 'c> { + network_interface: RefCell, + sockets: RefCell>, + next_port: RefCell, + unused_handles: RefCell>, +} + +impl<'a, 'b, 'c> NetworkStack<'a, 'b, 'c> { + pub fn new( + interface: Ethernet, + sockets: smoltcp::socket::SocketSet<'a, 'b, 'c>, + ) -> Self { + let mut unused_handles: Vec< + smoltcp::socket::SocketHandle, + consts::U16, + > = Vec::new(); + for socket in sockets.iter() { + unused_handles.push(socket.handle()).unwrap(); + } + + NetworkStack { + network_interface: RefCell::new(interface), + sockets: RefCell::new(sockets), + next_port: RefCell::new(49152), + unused_handles: RefCell::new(unused_handles), + } + } + + pub fn update(&self, time: u32) -> bool { + match self.network_interface.borrow_mut().poll( + &mut self.sockets.borrow_mut(), + smoltcp::time::Instant::from_millis(time as i64), + ) { + Ok(changed) => changed == false, + Err(e) => { + info!("{:?}", e); + true + } + } + } + + fn get_ephemeral_port(&self) -> u16 { + // Get the next ephemeral port + let current_port = self.next_port.borrow().clone(); + + let (next, wrap) = self.next_port.borrow().overflowing_add(1); + *self.next_port.borrow_mut() = if wrap { 49152 } else { next }; + + return current_port; + } +} + +impl<'a, 'b, 'c> NetworkStack<'a, 'b, 'c> { + fn open( + &self, + _mode: nal::Mode, + ) -> Result { + match self.unused_handles.borrow_mut().pop() { + Some(handle) => { + // Abort any active connections on the handle. + let mut sockets = self.sockets.borrow_mut(); + let internal_socket: &mut smoltcp::socket::TcpSocket = + &mut *sockets.get(handle); + internal_socket.abort(); + + Ok(handle) + } + None => Err(NetworkError::NoSocket), + } + } + + fn connect( + &self, + socket: smoltcp::socket::SocketHandle, + remote: nal::SocketAddr, + ) -> Result { + let mut sockets = self.sockets.borrow_mut(); + let internal_socket: &mut smoltcp::socket::TcpSocket = + &mut *sockets.get(socket); + + // If we're already in the process of connecting, ignore the request silently. + if internal_socket.is_open() { + return Ok(socket); + } + + match remote.ip() { + nal::IpAddr::V4(addr) => { + let octets = addr.octets(); + let address = smoltcp::wire::Ipv4Address::new( + octets[0], octets[1], octets[2], octets[3], + ); + internal_socket + .connect( + (address, remote.port()), + self.get_ephemeral_port(), + ) + .map_err(|_| NetworkError::ConnectionFailure)?; + Ok(socket) + } + + // We only support IPv4. + _ => Err(NetworkError::Unsupported), + } + } + + fn is_connected( + &self, + socket: &smoltcp::socket::SocketHandle, + ) -> Result { + let mut sockets = self.sockets.borrow_mut(); + let socket: &mut smoltcp::socket::TcpSocket = + &mut *sockets.get(*socket); + Ok(socket.may_send() && socket.may_recv()) + } + + fn write( + &self, + socket: &mut smoltcp::socket::SocketHandle, + buffer: &[u8], + ) -> nb::Result { + let mut sockets = self.sockets.borrow_mut(); + let socket: &mut smoltcp::socket::TcpSocket = + &mut *sockets.get(*socket); + socket + .send_slice(buffer) + .map_err(|_| nb::Error::Other(NetworkError::WriteFailure)) + } + + fn read( + &self, + socket: &mut smoltcp::socket::SocketHandle, + buffer: &mut [u8], + ) -> nb::Result { + let mut sockets = self.sockets.borrow_mut(); + let socket: &mut smoltcp::socket::TcpSocket = + &mut *sockets.get(*socket); + socket + .recv_slice(buffer) + .map_err(|_| nb::Error::Other(NetworkError::ReadFailure)) + } + + fn close( + &self, + socket: smoltcp::socket::SocketHandle, + ) -> Result<(), NetworkError> { + let mut sockets = self.sockets.borrow_mut(); + let internal_socket: &mut smoltcp::socket::TcpSocket = + &mut *sockets.get(socket); + internal_socket.close(); + + self.unused_handles.borrow_mut().push(socket).unwrap(); + Ok(()) + } +} From a772ccc38ac4ac66084c262388c5335933608862 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Tue, 26 Jan 2021 19:14:23 +0100 Subject: [PATCH 02/27] Adding WIP updates for StringSet --- Cargo.lock | 67 ++++++++++++++++++++++++++++++++-- Cargo.toml | 7 +++- dsp/Cargo.toml | 6 +++ src/bin/dual-iir.rs | 34 +++++++---------- src/hardware/configuration.rs | 22 ++++++++--- src/hardware/mod.rs | 4 +- src/hardware/mqtt_interface.rs | 48 ++++++++++++------------ src/hardware/smoltcp_nal.rs | 5 ++- 8 files changed, 137 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c6083ae..b1c6fbd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,13 +341,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "derive_stringset" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dsp" version = "0.1.0" dependencies = [ "criterion", "libm", + "miniconf", "serde", + "serde-json-core 0.1.0", ] [[package]] @@ -375,6 +386,17 @@ dependencies = [ "void", ] +[[package]] +name = "embedded-nal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae46eb1b02de5a76d9d0ea21d657ff5b0ad2cc47f3a7723608227b1dd1b3eb18" +dependencies = [ + "heapless", + "nb 1.0.0", + "no-std-net", +] + [[package]] name = "enum-iterator" version = "0.6.0" @@ -556,6 +578,27 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniconf" +version = "0.1.0" +dependencies = [ + "derive_stringset", + "serde", + "serde-json-core 0.2.0", +] + +[[package]] +name = "minimq" +version = "0.1.0" +source = "git+https://github.com/quartiq/minimq.git#dc459f5a3978fd90410adc916ce12b56ca449c47" +dependencies = [ + "bit_field", + "embedded-nal", + "enum-iterator", + "generic-array 0.14.4", + "heapless", +] + [[package]] name = "nb" version = "0.1.3" @@ -571,6 +614,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" +[[package]] +name = "no-std-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2178127478ae4ee9be7180bc9c3bffb6354dd7238400db567102f98c413a9f35" + [[package]] name = "num-traits" version = "0.2.14" @@ -641,9 +690,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" dependencies = [ "proc-macro2", ] @@ -784,6 +833,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde-json-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89fd6016a00149b485f66da701f76d909210d319040c97b6eff300f6e2ba2153" +dependencies = [ + "heapless", + "serde", +] + [[package]] name = "serde_cbor" version = "0.11.1" @@ -843,12 +902,14 @@ dependencies = [ "heapless", "log", "mcp23017", + "miniconf", + "minimq", "nb 1.0.0", "panic-halt", "panic-semihosting", "paste", "serde", - "serde-json-core", + "serde-json-core 0.1.0", "smoltcp", "stm32h7xx-hal", ] diff --git a/Cargo.toml b/Cargo.toml index 2789de0..bdc73e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,12 @@ enum-iterator = "0.6.0" paste = "1" dsp = { path = "dsp" } ad9959 = { path = "ad9959" } -minimq = "0.1.0" +minimq = { git = "https://github.com/quartiq/minimq.git" } + +[dependencies.miniconf] +# git = "https://github.com/vertigo-designs/miniconf.git" +# branch = "james/derive_stringset" +path = "../../vertigo-designs/miniconf" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 548e64f..661bf78 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -7,6 +7,12 @@ edition = "2018" [dependencies] libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } +serde-json-core = "0.1" + +[dependencies.miniconf] +# git = "https://github.com/vertigo-designs/miniconf.git" +# branch = "james/derive_stringset" +path = "../../../vertigo-designs/miniconf" [dev-dependencies] criterion = "0.3" diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 53d1924..f7bb97b 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -3,19 +3,16 @@ #![no_main] #![cfg_attr(feature = "nightly", feature(core_intrinsics))] -use stm32h7xx_hal as hal; +use miniconf::StringSet; -#[macro_use] -extern crate log; +use stm32h7xx_hal as hal; use rtic::cyccnt::{Instant, U32Ext}; -use heapless::{consts::*, String}; - -use stabilizer::{hardware, server}; +use stabilizer::hardware; use dsp::iir; -use hardware::{Adc0Input, Adc1Input, Dac0Output, Dac1Output, AFE0, AFE1}; +use hardware::{Adc0Input, Adc1Input, Dac0Output, Dac1Output, AFE0, AFE1, MqttAction}; const SCALE: f32 = ((1 << 15) - 1) as f32; @@ -25,10 +22,10 @@ const TCP_TX_BUFFER_SIZE: usize = 8192; // The number of cascaded IIR biquads per channel. Select 1 or 2! const IIR_CASCADE_LENGTH: usize = 1; -#[derive(miniconf::StringSet)] +#[derive(Default, StringSet)] struct Settings { - afe_gain: [hardware::AfeGain; 2], - iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], + pub afe_gain: [hardware::AfeGain; 2], + //iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] @@ -37,7 +34,6 @@ const APP: () = { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - net_interface: hardware::Ethernet, mqtt_interface: hardware::MqttInterface, // Format: iir_state[ch][cascade-no][coeff] @@ -62,10 +58,10 @@ const APP: () = { stabilizer.adc_dac_timer.start(); init::LateResources { + mqtt_interface: hardware::MqttInterface::new(stabilizer.net.stack, Settings::default()), afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, - net_interface: stabilizer.net.interface, } } @@ -130,22 +126,18 @@ const APP: () = { time += 1; } - let sleep = c.resources.network_stack.update( - smoltcp::time::Instant::from_millis(time as i64), - ); - match c.resources.mqtt_interface.lock(|interface| interface.update(time).unwrap()) { - Action::Sleep => cortex_m::asm::wfi(), - Action::Continue => {}, - Action::CommitSettings => c.spawn.settings_update().unwrap(); + MqttAction::Sleep => cortex_m::asm::wfi(), + MqttAction::Continue => {}, + MqttAction::CommitSettings => c.spawn.settings_update().unwrap(), } } } #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] fn settings_update(c: settings_update::Context) { - let settings = c.resources.mqtt_interface.current_settings(); - c.resources.iir_ch.lock(|iir_ch| *iir_ch = settings.iir); + let settings = c.resources.mqtt_interface.settings.borrow(); + //c.resources.iir_ch.lock(|iir_ch| *iir_ch = settings.iir); c.resources.afes.0.set_gain(settings.afe_gain[0]); c.resources.afes.1.set_gain(settings.afe_gain[1]); } diff --git a/src/hardware/configuration.rs b/src/hardware/configuration.rs index 925d684..721c523 100644 --- a/src/hardware/configuration.rs +++ b/src/hardware/configuration.rs @@ -527,15 +527,25 @@ pub fn setup( let sockets = { // Note(unsafe): Configuration is only called once, so we only access the global // storage a single time. - let socket_storage = unsafe { &mut NET_STORE.sockets }; + let socket_storage = unsafe { &mut NET_STORE.sockets[..] }; let mut sockets = smoltcp::socket::SocketSet::new(socket_storage); let tcp_socket = { - // Note(unsafe): Configuration is only called once, so we only access the global - // storage a single time. - let rx_storage = unsafe { &mut NET_STORE.rx_storage[..] }; - let tx_storage = unsafe { &mut NET_STORE.tx_storage[..] }; - smoltcp::socket::TcpSocket::new(rx_storage, tx_storage) + let rx_buffer = { + // Note(unsafe): Configuration is only called once, so we only access the global + // storage a single time. + let storage = unsafe { &mut NET_STORE.rx_storage[..] }; + smoltcp::socket::TcpSocketBuffer::new(storage) + }; + + let tx_buffer = { + // Note(unsafe): Configuration is only called once, so we only access the global + // storage a single time. + let storage = unsafe { &mut NET_STORE.tx_storage[..] }; + smoltcp::socket::TcpSocketBuffer::new(storage) + }; + + smoltcp::socket::TcpSocket::new(rx_buffer, tx_buffer) }; sockets.add(tcp_socket); diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index 2d638c4..47620cd 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -17,12 +17,14 @@ mod eeprom; mod pounder; mod smoltcp_nal; mod timers; +mod mqtt_interface; pub use adc::{Adc0Input, Adc1Input}; pub use afe::Gain as AfeGain; pub use dac::{Dac0Output, Dac1Output}; pub use digital_input_stamper::InputStamper; pub use pounder::DdsOutput; +pub use mqtt_interface::{MqttInterface, Action as MqttAction}; // Type alias for the analog front-end (AFE) for ADC0. pub type AFE0 = afe::ProgrammableGainAmplifier< @@ -37,7 +39,7 @@ pub type AFE1 = afe::ProgrammableGainAmplifier< >; // Type alias for the ethernet interface on Stabilizer. -type Ethernet = smoltcp::iface::EthernetInterface< +pub type Ethernet = smoltcp::iface::EthernetInterface< 'static, 'static, 'static, diff --git a/src/hardware/mqtt_interface.rs b/src/hardware/mqtt_interface.rs index 7ce6544..6ab5745 100644 --- a/src/hardware/mqtt_interface.rs +++ b/src/hardware/mqtt_interface.rs @@ -1,6 +1,11 @@ use super::NetworkStack; -use minimq::{QoS, Error, Property, MqttClient}; +use minimq::{ + embedded_nal::{IpAddr, Ipv4Addr}, + QoS, Error, Property, MqttClient +}; +use heapless::{String, consts}; +use core::fmt::Write; pub enum Action { Continue, @@ -8,10 +13,10 @@ pub enum Action { CommitSettings, } -struct MqttInterface { - client: MqttClient, +pub struct MqttInterface { + client: core::cell::RefCell>, subscribed: bool, - settings: T, + pub settings: core::cell::RefCell, } impl MqttInterface @@ -25,29 +30,25 @@ where stack).unwrap(); Self { - client, + client: core::cell::RefCell::new(client), subscribed: false, - settings, + settings: core::cell::RefCell::new(settings), } } - pub fn current_settings(&self) -> &T { - &self.settings - } + pub fn update(&mut self, time: u32) -> Result { - pub fn update(&mut self, time: u32) -> Result { + let sleep = self.client.borrow_mut().network_stack.update(time); - let sleep = self.client.network_stack.update(smoltcp::time::Instant::from_millis(time as i64)); - - if !self.subscribed && self.client.is_connected().unwrap() { - self.client.subscribe("stabilizer/settings/#", &[]); - self.client.subscribe("stabilizer/commit", &[]); + if !self.subscribed && self.client.borrow_mut().is_connected().unwrap() { + self.client.borrow_mut().subscribe("stabilizer/settings/#", &[]).unwrap(); + self.client.borrow_mut().subscribe("stabilizer/commit", &[]).unwrap(); } let mut commit = false; - match self.client.poll(|client, topic, message, properties| { - let split = topic.split('/').iter(); + match self.client.borrow_mut().poll(|client, topic, message, properties| { + let mut split = topic.split('/'); // TODO: Verify topic ID against our ID. let id = split.next().unwrap(); @@ -57,10 +58,10 @@ where "settings" => { // Handle settings failures let mut response: String = String::new(); - match self.settings.string_set(split.peekable(), message) { + match self.settings.borrow_mut().string_set(split.peekable(), message) { Ok(_) => write!(&mut response, "{} written", topic).unwrap(), Err(error) => { - write!(&mut response, "Settings failure: {}", error).unwrap(); + write!(&mut response, "Settings failure: {:?}", error).unwrap(); } }; @@ -68,8 +69,9 @@ where }, "commit" => { commit = true; - String::from("Committing pending settings"); - } + String::from("Committing pending settings") + }, + _ => String::from("Unknown topic"), }; // Publish the response to the request over MQTT using the ResponseTopic property if @@ -81,7 +83,7 @@ where false } }).or(Some(&Property::ResponseTopic("stabilizer/log"))).unwrap() { - self.client.publish(topic, &response.into_bytes(), QoS::AtMostOnce, &[]).unwrap(); + client.publish(topic, &response.into_bytes(), QoS::AtMostOnce, &[]).unwrap(); } }) { Ok(_) => {}, @@ -90,7 +92,7 @@ where }; let action = if commit { - Action::Commit + Action::CommitSettings } else if sleep { Action::Sleep } else { diff --git a/src/hardware/smoltcp_nal.rs b/src/hardware/smoltcp_nal.rs index 8cd7f46..ac0bf2e 100644 --- a/src/hardware/smoltcp_nal.rs +++ b/src/hardware/smoltcp_nal.rs @@ -77,7 +77,10 @@ impl<'a, 'b, 'c> NetworkStack<'a, 'b, 'c> { } } -impl<'a, 'b, 'c> NetworkStack<'a, 'b, 'c> { +impl<'a, 'b, 'c> nal::TcpStack for NetworkStack<'a, 'b, 'c> { + type Error = NetworkError; + type TcpSocket = smoltcp::socket::SocketHandle; + fn open( &self, _mode: nal::Mode, From 702ccc231dd32ee61496ca2caeeb209ba873357b Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 27 Jan 2021 18:15:35 +0100 Subject: [PATCH 03/27] Using custom branch of miniconf --- Cargo.lock | 3 +- Cargo.toml | 6 +- dsp/Cargo.toml | 5 +- dsp/src/iir.rs | 4 +- src/bin/dual-iir.rs | 33 ++-- src/bin/lockin.rs | 149 +----------------- src/hardware/mqtt_interface.rs | 2 +- src/lib.rs | 1 - src/server.rs | 278 --------------------------------- 9 files changed, 35 insertions(+), 446 deletions(-) delete mode 100644 src/server.rs diff --git a/Cargo.lock b/Cargo.lock index b1c6fbd..78621fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,6 +344,7 @@ dependencies = [ [[package]] name = "derive_stringset" version = "0.1.0" +source = "git+https://github.com/vertigo-designs/miniconf.git?branch=rs/cleanup#396a759356ae977d718ef6d30cfa6481f0d40b2f" dependencies = [ "proc-macro2", "quote", @@ -581,6 +582,7 @@ dependencies = [ [[package]] name = "miniconf" version = "0.1.0" +source = "git+https://github.com/vertigo-designs/miniconf.git?branch=rs/cleanup#396a759356ae977d718ef6d30cfa6481f0d40b2f" dependencies = [ "derive_stringset", "serde", @@ -909,7 +911,6 @@ dependencies = [ "panic-semihosting", "paste", "serde", - "serde-json-core 0.1.0", "smoltcp", "stm32h7xx-hal", ] diff --git a/Cargo.toml b/Cargo.toml index bdc73e4..41ca5db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,6 @@ panic-semihosting = { version = "0.5", optional = true } panic-halt = "0.2" serde = { version = "1.0", features = ["derive"], default-features = false } heapless = { version = "0.5", features = ["serde"] } -serde-json-core = "0.1" cortex-m-rtic = "0.5.5" embedded-hal = "0.2.4" nb = "1.0.0" @@ -48,9 +47,8 @@ ad9959 = { path = "ad9959" } minimq = { git = "https://github.com/quartiq/minimq.git" } [dependencies.miniconf] -# git = "https://github.com/vertigo-designs/miniconf.git" -# branch = "james/derive_stringset" -path = "../../vertigo-designs/miniconf" +git = "https://github.com/vertigo-designs/miniconf.git" +branch = "rs/cleanup" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 661bf78..55e150e 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -10,9 +10,8 @@ serde = { version = "1.0", features = ["derive"], default-features = false } serde-json-core = "0.1" [dependencies.miniconf] -# git = "https://github.com/vertigo-designs/miniconf.git" -# branch = "james/derive_stringset" -path = "../../../vertigo-designs/miniconf" +git = "https://github.com/vertigo-designs/miniconf.git" +branch = "rs/cleanup" [dev-dependencies] criterion = "0.3" diff --git a/dsp/src/iir.rs b/dsp/src/iir.rs index dbec8d8..398a900 100644 --- a/dsp/src/iir.rs +++ b/dsp/src/iir.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use super::{abs, copysign, macc, max, min}; use core::f32; +use miniconf::StringSet; + /// IIR state and coefficients type. /// /// To represent the IIR state (input and output memory) during the filter update @@ -38,7 +40,7 @@ pub type IIRState = [f32; 5]; /// Therefore it can trivially implement bump-less transfer. /// * Cascading multiple IIR filters allows stable and robust /// implementation of transfer functions beyond bequadratic terms. -#[derive(Copy, Clone, Deserialize, Serialize)] +#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, StringSet)] pub struct IIR { pub ba: IIRState, pub y_offset: f32, diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index f7bb97b..1ec7d85 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -3,29 +3,36 @@ #![no_main] #![cfg_attr(feature = "nightly", feature(core_intrinsics))] -use miniconf::StringSet; - use stm32h7xx_hal as hal; use rtic::cyccnt::{Instant, U32Ext}; use stabilizer::hardware; +use miniconf::StringSet; +use serde::Deserialize; + use dsp::iir; use hardware::{Adc0Input, Adc1Input, Dac0Output, Dac1Output, AFE0, AFE1, MqttAction}; const SCALE: f32 = ((1 << 15) - 1) as f32; -const TCP_RX_BUFFER_SIZE: usize = 8192; -const TCP_TX_BUFFER_SIZE: usize = 8192; - // The number of cascaded IIR biquads per channel. Select 1 or 2! const IIR_CASCADE_LENGTH: usize = 1; -#[derive(Default, StringSet)] -struct Settings { - pub afe_gain: [hardware::AfeGain; 2], - //iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], +#[derive(Debug, Deserialize, StringSet)] +pub struct Settings { + test: u32, + iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], +} + +impl Settings { + pub fn new() -> Self { + Self { + test: 5, + iir: [[iir::IIR::default(); IIR_CASCADE_LENGTH]; 2], + } + } } #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] @@ -58,7 +65,7 @@ const APP: () = { stabilizer.adc_dac_timer.start(); init::LateResources { - mqtt_interface: hardware::MqttInterface::new(stabilizer.net.stack, Settings::default()), + mqtt_interface: hardware::MqttInterface::new(stabilizer.net.stack, Settings::new()), afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, @@ -135,11 +142,9 @@ const APP: () = { } #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] - fn settings_update(c: settings_update::Context) { + fn settings_update(mut c: settings_update::Context) { let settings = c.resources.mqtt_interface.settings.borrow(); - //c.resources.iir_ch.lock(|iir_ch| *iir_ch = settings.iir); - c.resources.afes.0.set_gain(settings.afe_gain[0]); - c.resources.afes.1.set_gain(settings.afe_gain[1]); + c.resources.iir_ch.lock(|iir| *iir = settings.iir); } #[task(binds = ETH, priority = 1)] diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 304c35e..8793949 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -5,15 +5,10 @@ use stm32h7xx_hal as hal; -#[macro_use] -extern crate log; - use rtic::cyccnt::{Instant, U32Ext}; -use heapless::{consts::*, String}; - use stabilizer::{ - hardware, server, ADC_SAMPLE_TICKS_LOG2, SAMPLE_BUFFER_SIZE_LOG2, + hardware, ADC_SAMPLE_TICKS_LOG2, SAMPLE_BUFFER_SIZE_LOG2, }; use dsp::{iir, iir_int, lockin::Lockin, reciprocal_pll::TimestampHandler}; @@ -23,9 +18,6 @@ use hardware::{ const SCALE: f32 = ((1 << 15) - 1) as f32; -const TCP_RX_BUFFER_SIZE: usize = 8192; -const TCP_TX_BUFFER_SIZE: usize = 8192; - // The number of cascaded IIR biquads per channel. Select 1 or 2! const IIR_CASCADE_LENGTH: usize = 1; @@ -35,7 +27,7 @@ const APP: () = { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - net_interface: hardware::Ethernet, + stack: hardware::NetworkStack, // Format: iir_state[ch][cascade-no][coeff] #[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])] @@ -80,7 +72,7 @@ const APP: () = { afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, - net_interface: stabilizer.net.interface, + stack: stabilizer.net.stack, timestamper: stabilizer.timestamper, pll, @@ -165,26 +157,8 @@ const APP: () = { } } - #[idle(resources=[net_interface, iir_state, iir_ch, afes])] - fn idle(mut c: idle::Context) -> ! { - let mut socket_set_entries: [_; 8] = Default::default(); - let mut sockets = - smoltcp::socket::SocketSet::new(&mut socket_set_entries[..]); - - let mut rx_storage = [0; TCP_RX_BUFFER_SIZE]; - let mut tx_storage = [0; TCP_TX_BUFFER_SIZE]; - let tcp_handle = { - let tcp_rx_buffer = - smoltcp::socket::TcpSocketBuffer::new(&mut rx_storage[..]); - let tcp_tx_buffer = - smoltcp::socket::TcpSocketBuffer::new(&mut tx_storage[..]); - let tcp_socket = - smoltcp::socket::TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); - sockets.add(tcp_socket) - }; - - let mut server = server::Server::new(); - + #[idle(resources=[stack, iir_state, iir_ch, afes])] + fn idle(c: idle::Context) -> ! { let mut time = 0u32; let mut next_ms = Instant::now(); @@ -199,118 +173,7 @@ const APP: () = { time += 1; } - { - let socket = - &mut *sockets.get::(tcp_handle); - if socket.state() == smoltcp::socket::TcpState::CloseWait { - socket.close(); - } else if !(socket.is_open() || socket.is_listening()) { - socket - .listen(1235) - .unwrap_or_else(|e| warn!("TCP listen error: {:?}", e)); - } else { - server.poll(socket, |req| { - info!("Got request: {:?}", req); - stabilizer::route_request!(req, - readable_attributes: [ - "stabilizer/iir/state": (|| { - let state = c.resources.iir_state.lock(|iir_state| - server::Status { - t: time, - x0: iir_state[0][0][0], - y0: iir_state[0][0][2], - x1: iir_state[1][0][0], - y1: iir_state[1][0][2], - }); - - Ok::(state) - }), - // "_b" means cascades 2nd IIR - "stabilizer/iir_b/state": (|| { let state = c.resources.iir_state.lock(|iir_state| - server::Status { - t: time, - x0: iir_state[0][IIR_CASCADE_LENGTH-1][0], - y0: iir_state[0][IIR_CASCADE_LENGTH-1][2], - x1: iir_state[1][IIR_CASCADE_LENGTH-1][0], - y1: iir_state[1][IIR_CASCADE_LENGTH-1][2], - }); - - Ok::(state) - }), - "stabilizer/afe0/gain": (|| c.resources.afes.0.get_gain()), - "stabilizer/afe1/gain": (|| c.resources.afes.1.get_gain()) - ], - - modifiable_attributes: [ - "stabilizer/iir0/state": server::IirRequest, (|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][0] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/iir1/state": server::IirRequest, (|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][0] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/iir_b0/state": server::IirRequest, (|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][IIR_CASCADE_LENGTH-1] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/iir_b1/state": server::IirRequest,(|req: server::IirRequest| { - c.resources.iir_ch.lock(|iir_ch| { - if req.channel > 1 { - return Err(()); - } - - iir_ch[req.channel as usize][IIR_CASCADE_LENGTH-1] = req.iir; - - Ok::(req) - }) - }), - "stabilizer/afe0/gain": hardware::AfeGain, (|gain| { - c.resources.afes.0.set_gain(gain); - Ok::<(), ()>(()) - }), - "stabilizer/afe1/gain": hardware::AfeGain, (|gain| { - c.resources.afes.1.set_gain(gain); - Ok::<(), ()>(()) - }) - ] - ) - }); - } - } - - let sleep = match c.resources.net_interface.poll( - &mut sockets, - smoltcp::time::Instant::from_millis(time as i64), - ) { - Ok(changed) => !changed, - Err(smoltcp::Error::Unrecognized) => true, - Err(e) => { - info!("iface poll error: {:?}", e); - true - } - }; + let sleep = c.resources.stack.update(time); if sleep { cortex_m::asm::wfi(); diff --git a/src/hardware/mqtt_interface.rs b/src/hardware/mqtt_interface.rs index 6ab5745..3e0f44f 100644 --- a/src/hardware/mqtt_interface.rs +++ b/src/hardware/mqtt_interface.rs @@ -50,7 +50,7 @@ where match self.client.borrow_mut().poll(|client, topic, message, properties| { let mut split = topic.split('/'); // TODO: Verify topic ID against our ID. - let id = split.next().unwrap(); + let _id = split.next().unwrap(); // Process the command let command = split.next().unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 254e626..067c5c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ extern crate log; pub mod hardware; -pub mod server; // The number of ticks in the ADC sampling timer. The timer runs at 100MHz, so the step size is // equal to 10ns per tick. diff --git a/src/server.rs b/src/server.rs deleted file mode 100644 index 5e6950d..0000000 --- a/src/server.rs +++ /dev/null @@ -1,278 +0,0 @@ -use core::fmt::Write; -use heapless::{consts::*, String, Vec}; -use serde::{Deserialize, Serialize}; -use serde_json_core::{de::from_slice, ser::to_string}; -use smoltcp as net; - -use dsp::iir; - -#[macro_export] -macro_rules! route_request { - ($request:ident, - readable_attributes: [$($read_attribute:tt: $getter:tt),*], - modifiable_attributes: [$($write_attribute:tt: $TYPE:ty, $setter:tt),*]) => { - match $request.req { - server::AccessRequest::Read => { - match $request.attribute { - $( - $read_attribute => { - #[allow(clippy::redundant_closure_call)] - let value = match $getter() { - Ok(data) => data, - Err(_) => return server::Response::error($request.attribute, - "Failed to read attribute"), - }; - - let encoded_data: String = match serde_json_core::to_string(&value) { - Ok(data) => data, - Err(_) => return server::Response::error($request.attribute, - "Failed to encode attribute value"), - }; - - server::Response::success($request.attribute, &encoded_data) - }, - )* - _ => server::Response::error($request.attribute, "Unknown attribute") - } - }, - server::AccessRequest::Write => { - match $request.attribute { - $( - $write_attribute => { - let new_value = match serde_json_core::from_str::<$TYPE>(&$request.value) { - Ok(data) => data, - Err(_) => return server::Response::error($request.attribute, - "Failed to decode value"), - }; - - #[allow(clippy::redundant_closure_call)] - match $setter(new_value) { - Ok(_) => server::Response::success($request.attribute, &$request.value), - Err(_) => server::Response::error($request.attribute, - "Failed to set attribute"), - } - } - )* - _ => server::Response::error($request.attribute, "Unknown attribute") - } - } - } - } -} - -#[derive(Deserialize, Serialize, Debug)] -pub enum AccessRequest { - Read, - Write, -} - -#[derive(Deserialize, Serialize, Debug)] -pub struct Request<'a> { - pub req: AccessRequest, - pub attribute: &'a str, - pub value: String, -} - -#[derive(Serialize, Deserialize)] -pub struct IirRequest { - pub channel: u8, - pub iir: iir::IIR, -} - -#[derive(Serialize)] -pub struct Response { - code: i32, - attribute: String, - value: String, -} - -impl<'a> Request<'a> { - pub fn restore_value(&mut self) { - let mut new_value: String = String::new(); - for byte in self.value.as_str().chars() { - if byte == '\'' { - new_value.push('"').unwrap(); - } else { - new_value.push(byte).unwrap(); - } - } - - self.value = new_value; - } -} - -impl Response { - /// Remove all double quotation marks from the `value` field of a response. - fn sanitize_value(&mut self) { - let mut new_value: String = String::new(); - for byte in self.value.as_str().chars() { - if byte == '"' { - new_value.push('\'').unwrap(); - } else { - new_value.push(byte).unwrap(); - } - } - - self.value = new_value; - } - - /// Remove all double quotation marks from the `value` field of a response and wrap it in single - /// quotes. - fn wrap_and_sanitize_value(&mut self) { - let mut new_value: String = String::new(); - new_value.push('\'').unwrap(); - for byte in self.value.as_str().chars() { - if byte == '"' { - new_value.push('\'').unwrap(); - } else { - new_value.push(byte).unwrap(); - } - } - new_value.push('\'').unwrap(); - - self.value = new_value; - } - - /// Construct a successful reply. - /// - /// Note: `value` will be sanitized to convert all single quotes to double quotes. - /// - /// Args: - /// * `attrbute` - The attribute of the success. - /// * `value` - The value of the attribute. - pub fn success(attribute: &str, value: &str) -> Self { - let mut res = Self { - code: 200, - attribute: String::from(attribute), - value: String::from(value), - }; - res.sanitize_value(); - res - } - - /// Construct an error reply. - /// - /// Note: `message` will be sanitized to convert all single quotes to double quotes. - /// - /// Args: - /// * `attrbute` - The attribute of the success. - /// * `message` - The message denoting the error. - pub fn error(attribute: &str, message: &str) -> Self { - let mut res = Self { - code: 400, - attribute: String::from(attribute), - value: String::from(message), - }; - res.wrap_and_sanitize_value(); - res - } - - /// Construct a custom reply. - /// - /// Note: `message` will be sanitized to convert all single quotes to double quotes. - /// - /// Args: - /// * `attrbute` - The attribute of the success. - /// * `message` - The message denoting the status. - pub fn custom(code: i32, message: &str) -> Self { - let mut res = Self { - code, - attribute: String::from(""), - value: String::from(message), - }; - res.wrap_and_sanitize_value(); - res - } -} - -#[derive(Serialize)] -pub struct Status { - pub t: u32, - pub x0: f32, - pub y0: f32, - pub x1: f32, - pub y1: f32, -} - -pub fn json_reply(socket: &mut net::socket::TcpSocket, msg: &T) { - let mut u: String = to_string(msg).unwrap(); - u.push('\n').unwrap(); - socket.write_str(&u).unwrap(); -} - -pub struct Server { - data: Vec, - discard: bool, -} - -impl Server { - /// Construct a new server object for managing requests. - pub fn new() -> Self { - Self { - data: Vec::new(), - discard: false, - } - } - - /// Poll the server for potential data updates. - /// - /// Args: - /// * `socket` - The socket to check contents from. - /// * `f` - A closure that can be called if a request has been received on the server. - pub fn poll(&mut self, socket: &mut net::socket::TcpSocket, mut f: F) - where - F: FnMut(&Request) -> Response, - { - while socket.can_recv() { - let found = socket - .recv(|buf| { - let (len, found) = - match buf.iter().position(|&c| c as char == '\n') { - Some(end) => (end + 1, true), - None => (buf.len(), false), - }; - if self.data.len() + len >= self.data.capacity() { - self.discard = true; - self.data.clear(); - } else if !self.discard && len > 0 { - self.data.extend_from_slice(&buf[..len]).unwrap(); - } - (len, found) - }) - .unwrap(); - - if found { - if self.discard { - self.discard = false; - json_reply( - socket, - &Response::custom(520, "command buffer overflow"), - ); - } else { - let r = from_slice::( - &self.data[..self.data.len() - 1], - ); - match r { - Ok(mut res) => { - // Note that serde_json_core doesn't escape quotations within a string. - // To account for this, we manually translate all single quotes to - // double quotes. This occurs because we doubly-serialize this field in - // some cases. - res.restore_value(); - let response = f(&res); - json_reply(socket, &response); - } - Err(err) => { - warn!("parse error {:?}", err); - json_reply( - socket, - &Response::custom(550, "parse error"), - ); - } - } - } - self.data.clear(); - } - } - } -} From b73286c188213a1495bb63c57d99b50634db3fed Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Sat, 30 Jan 2021 15:00:58 +0100 Subject: [PATCH 04/27] Removing MQTT interface --- Cargo.lock | 7 ++- Cargo.toml | 3 +- dsp/Cargo.toml | 2 +- src/bin/dual-iir.rs | 46 ++++++++++++--- src/bin/lockin.rs | 4 +- src/hardware/mod.rs | 2 - src/hardware/mqtt_interface.rs | 104 --------------------------------- src/hardware/smoltcp_nal.rs | 2 +- 8 files changed, 45 insertions(+), 125 deletions(-) delete mode 100644 src/hardware/mqtt_interface.rs diff --git a/Cargo.lock b/Cargo.lock index 78621fc..28ab3dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,7 +344,7 @@ dependencies = [ [[package]] name = "derive_stringset" version = "0.1.0" -source = "git+https://github.com/vertigo-designs/miniconf.git?branch=rs/cleanup#396a759356ae977d718ef6d30cfa6481f0d40b2f" +source = "git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface#38379f7fa72e675c348a4f532811795cc95766df" dependencies = [ "proc-macro2", "quote", @@ -582,9 +582,11 @@ dependencies = [ [[package]] name = "miniconf" version = "0.1.0" -source = "git+https://github.com/vertigo-designs/miniconf.git?branch=rs/cleanup#396a759356ae977d718ef6d30cfa6481f0d40b2f" +source = "git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface#38379f7fa72e675c348a4f532811795cc95766df" dependencies = [ "derive_stringset", + "heapless", + "minimq", "serde", "serde-json-core 0.2.0", ] @@ -905,7 +907,6 @@ dependencies = [ "log", "mcp23017", "miniconf", - "minimq", "nb 1.0.0", "panic-halt", "panic-semihosting", diff --git a/Cargo.toml b/Cargo.toml index 41ca5db..438e185 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,11 +44,10 @@ enum-iterator = "0.6.0" paste = "1" dsp = { path = "dsp" } ad9959 = { path = "ad9959" } -minimq = { git = "https://github.com/quartiq/minimq.git" } [dependencies.miniconf] git = "https://github.com/vertigo-designs/miniconf.git" -branch = "rs/cleanup" +branch = "feature/mqtt-interface" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 55e150e..44cc6fb 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -11,7 +11,7 @@ serde-json-core = "0.1" [dependencies.miniconf] git = "https://github.com/vertigo-designs/miniconf.git" -branch = "rs/cleanup" +branch = "feature/mqtt-interface" [dev-dependencies] criterion = "0.3" diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 1ec7d85..e72067b 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -10,10 +10,16 @@ use rtic::cyccnt::{Instant, U32Ext}; use stabilizer::hardware; use miniconf::StringSet; +use miniconf::{ + embedded_nal::{IpAddr, Ipv4Addr}, + MqttInterface, +}; use serde::Deserialize; use dsp::iir; -use hardware::{Adc0Input, Adc1Input, Dac0Output, Dac1Output, AFE0, AFE1, MqttAction}; +use hardware::{ + Adc0Input, Adc1Input, Dac0Output, Dac1Output, NetworkStack, AFE0, AFE1, +}; const SCALE: f32 = ((1 << 15) - 1) as f32; @@ -22,7 +28,6 @@ const IIR_CASCADE_LENGTH: usize = 1; #[derive(Debug, Deserialize, StringSet)] pub struct Settings { - test: u32, iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } @@ -41,7 +46,7 @@ const APP: () = { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - mqtt_interface: hardware::MqttInterface, + mqtt_interface: MqttInterface, // Format: iir_state[ch][cascade-no][coeff] #[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])] @@ -64,8 +69,16 @@ const APP: () = { // Start sampling ADCs. stabilizer.adc_dac_timer.start(); + let broker = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)); + init::LateResources { - mqtt_interface: hardware::MqttInterface::new(stabilizer.net.stack, Settings::new()), + mqtt_interface: MqttInterface::new( + stabilizer.net.stack, + "stabilizer", + broker, + Settings::new(), + ) + .unwrap(), afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, @@ -133,18 +146,33 @@ const APP: () = { time += 1; } - match c.resources.mqtt_interface.lock(|interface| interface.update(time).unwrap()) { - MqttAction::Sleep => cortex_m::asm::wfi(), - MqttAction::Continue => {}, - MqttAction::CommitSettings => c.spawn.settings_update().unwrap(), + let sleep = c + .resources + .mqtt_interface + .lock(|interface| interface.network_stack().update(time)); + + match c + .resources + .mqtt_interface + .lock(|interface| interface.update().unwrap()) + { + miniconf::Action::Continue => { + if sleep { + cortex_m::asm::wfi(); + } + } + miniconf::Action::CommitSettings => { + c.spawn.settings_update().unwrap() + } } } } #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] fn settings_update(mut c: settings_update::Context) { - let settings = c.resources.mqtt_interface.settings.borrow(); + let settings = &c.resources.mqtt_interface.settings; c.resources.iir_ch.lock(|iir| *iir = settings.iir); + // TODO: Update AFEs } #[task(binds = ETH, priority = 1)] diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index d51f039..c226e3a 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -7,9 +7,7 @@ use stm32h7xx_hal as hal; use rtic::cyccnt::{Instant, U32Ext}; -use stabilizer::{ - hardware, ADC_SAMPLE_TICKS_LOG2, SAMPLE_BUFFER_SIZE_LOG2, -}; +use stabilizer::{hardware, ADC_SAMPLE_TICKS_LOG2, SAMPLE_BUFFER_SIZE_LOG2}; use dsp::{iir, iir_int, lockin::Lockin, rpll::RPLL}; use hardware::{ diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index 47620cd..97f8058 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -17,14 +17,12 @@ mod eeprom; mod pounder; mod smoltcp_nal; mod timers; -mod mqtt_interface; pub use adc::{Adc0Input, Adc1Input}; pub use afe::Gain as AfeGain; pub use dac::{Dac0Output, Dac1Output}; pub use digital_input_stamper::InputStamper; pub use pounder::DdsOutput; -pub use mqtt_interface::{MqttInterface, Action as MqttAction}; // Type alias for the analog front-end (AFE) for ADC0. pub type AFE0 = afe::ProgrammableGainAmplifier< diff --git a/src/hardware/mqtt_interface.rs b/src/hardware/mqtt_interface.rs deleted file mode 100644 index 3e0f44f..0000000 --- a/src/hardware/mqtt_interface.rs +++ /dev/null @@ -1,104 +0,0 @@ -use super::NetworkStack; - -use minimq::{ - embedded_nal::{IpAddr, Ipv4Addr}, - QoS, Error, Property, MqttClient -}; -use heapless::{String, consts}; -use core::fmt::Write; - -pub enum Action { - Continue, - Sleep, - CommitSettings, -} - -pub struct MqttInterface { - client: core::cell::RefCell>, - subscribed: bool, - pub settings: core::cell::RefCell, -} - -impl MqttInterface -where - T: miniconf::StringSet -{ - pub fn new(stack: NetworkStack, settings: T) -> Self { - let client: MqttClient = MqttClient::new( - IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), - "stabilizer", - stack).unwrap(); - - Self { - client: core::cell::RefCell::new(client), - subscribed: false, - settings: core::cell::RefCell::new(settings), - } - } - - pub fn update(&mut self, time: u32) -> Result { - - let sleep = self.client.borrow_mut().network_stack.update(time); - - if !self.subscribed && self.client.borrow_mut().is_connected().unwrap() { - self.client.borrow_mut().subscribe("stabilizer/settings/#", &[]).unwrap(); - self.client.borrow_mut().subscribe("stabilizer/commit", &[]).unwrap(); - } - - let mut commit = false; - - match self.client.borrow_mut().poll(|client, topic, message, properties| { - let mut split = topic.split('/'); - // TODO: Verify topic ID against our ID. - let _id = split.next().unwrap(); - - // Process the command - let command = split.next().unwrap(); - let response: String = match command { - "settings" => { - // Handle settings failures - let mut response: String = String::new(); - match self.settings.borrow_mut().string_set(split.peekable(), message) { - Ok(_) => write!(&mut response, "{} written", topic).unwrap(), - Err(error) => { - write!(&mut response, "Settings failure: {:?}", error).unwrap(); - } - }; - - response - }, - "commit" => { - commit = true; - String::from("Committing pending settings") - }, - _ => String::from("Unknown topic"), - }; - - // Publish the response to the request over MQTT using the ResponseTopic property if - // possible. Otherwise, default to a logging topic. - if let Property::ResponseTopic(topic) = properties.iter().find(|&prop| { - if let Property::ResponseTopic(_) = *prop { - true - } else { - false - } - }).or(Some(&Property::ResponseTopic("stabilizer/log"))).unwrap() { - client.publish(topic, &response.into_bytes(), QoS::AtMostOnce, &[]).unwrap(); - } - }) { - Ok(_) => {}, - Err(Error::Disconnected) => self.subscribed = false, - Err(err) => error!("Unexpected error: {:?}", err) - }; - - let action = if commit { - Action::CommitSettings - } else if sleep { - Action::Sleep - } else { - Action::Continue - }; - - Ok(action) - } -} diff --git a/src/hardware/smoltcp_nal.rs b/src/hardware/smoltcp_nal.rs index ac0bf2e..9fd5420 100644 --- a/src/hardware/smoltcp_nal.rs +++ b/src/hardware/smoltcp_nal.rs @@ -1,7 +1,7 @@ use core::cell::RefCell; ///! Network abstraction layer for smoltcp. use heapless::{consts, Vec}; -use minimq::embedded_nal::{self as nal, nb}; +use miniconf::embedded_nal::{self as nal, nb}; use super::Ethernet; From 9a1bb5da91595ccfde402d1b1714ed1b95b965b2 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Sat, 30 Jan 2021 15:07:26 +0100 Subject: [PATCH 05/27] Fixing build --- src/bin/dual-iir.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index e72067b..32a4b9e 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -34,7 +34,6 @@ pub struct Settings { impl Settings { pub fn new() -> Self { Self { - test: 5, iir: [[iir::IIR::default(); IIR_CASCADE_LENGTH]; 2], } } From 411a847a88d8f11c3940afb5aa0a83356582eecb Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Sat, 30 Jan 2021 18:48:27 +0100 Subject: [PATCH 06/27] Updating smoltcp-nal --- Cargo.lock | 18 +++- Cargo.toml | 11 +- src/bin/dual-iir.rs | 2 +- src/bin/lockin.rs | 2 +- src/hardware/configuration.rs | 24 +++-- src/hardware/mod.rs | 7 +- src/hardware/smoltcp_nal.rs | 184 ---------------------------------- 7 files changed, 40 insertions(+), 208 deletions(-) delete mode 100644 src/hardware/smoltcp_nal.rs diff --git a/Cargo.lock b/Cargo.lock index 28ab3dc..f4c420b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,15 +881,25 @@ dependencies = [ [[package]] name = "smoltcp" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe46639fd2ec79eadf8fe719f237a7a0bd4dac5d957f1ca5bbdbc1c3c39e53a" +checksum = "ab527c390c7e107f687bd92a886a083fde61b8cdc700b37f3d7e4346ffd8fae1" dependencies = [ "bitflags", "byteorder", "managed", ] +[[package]] +name = "smoltcp-nal" +version = "0.1.0" +source = "git+https://github.com/vertigo-designs/smoltcp-nal.git?branch=main#6a656dd78c5f7543475e95c0eaf81def95fc5a10" +dependencies = [ + "embedded-nal", + "heapless", + "smoltcp", +] + [[package]] name = "stabilizer" version = "0.4.1" @@ -912,7 +922,7 @@ dependencies = [ "panic-semihosting", "paste", "serde", - "smoltcp", + "smoltcp-nal", "stm32h7xx-hal", ] @@ -937,7 +947,7 @@ dependencies = [ [[package]] name = "stm32h7xx-hal" version = "0.8.0" -source = "git+https://github.com/stm32-rs/stm32h7xx-hal?branch=dma#3da22d4935c8f6e412b99e6662ec11da5265fb88" +source = "git+https://github.com/quartiq/stm32h7xx-hal?branch=rs/smoltcp-update#87a650664beab422b33f1e3d842f8d585ab5fdab" dependencies = [ "bare-metal 1.0.0", "cast", diff --git a/Cargo.toml b/Cargo.toml index 438e185..182d62b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,15 +52,14 @@ branch = "feature/mqtt-interface" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" -[dependencies.smoltcp] -version = "0.6" -features = ["ethernet", "proto-ipv4", "socket-tcp", "proto-ipv6"] -default-features = false +[dependencies.smoltcp-nal] +git = "https://github.com/vertigo-designs/smoltcp-nal.git" +branch = "main" [dependencies.stm32h7xx-hal] features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"] -git = "https://github.com/stm32-rs/stm32h7xx-hal" -branch = "dma" +git = "https://github.com/quartiq/stm32h7xx-hal" +branch = "rs/smoltcp-update" [features] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 32a4b9e..ce084df 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -148,7 +148,7 @@ const APP: () = { let sleep = c .resources .mqtt_interface - .lock(|interface| interface.network_stack().update(time)); + .lock(|interface| !interface.network_stack().poll(time)); match c .resources diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index c226e3a..9575442 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -168,7 +168,7 @@ const APP: () = { time += 1; } - let sleep = c.resources.stack.update(time); + let sleep = !c.resources.stack.poll(time); if sleep { cortex_m::asm::wfi(); diff --git a/src/hardware/configuration.rs b/src/hardware/configuration.rs index 721c523..c2c8333 100644 --- a/src/hardware/configuration.rs +++ b/src/hardware/configuration.rs @@ -9,21 +9,32 @@ use crate::SAMPLE_BUFFER_SIZE; #[cfg(feature = "pounder_v1_1")] use core::convert::TryInto; -use smoltcp::{iface::Routes, wire::Ipv4Address}; - use stm32h7xx_hal::{ self as hal, ethernet::{self, PHY}, prelude::*, }; +use smoltcp_nal::smoltcp; + use embedded_hal::digital::v2::{InputPin, OutputPin}; use super::{ adc, afe, dac, design_parameters, digital_input_stamper, eeprom, pounder, - smoltcp_nal::NetStorage, timers, DdsOutput, NetworkStack, AFE0, AFE1, + timers, DdsOutput, NetworkStack, AFE0, AFE1, }; +pub struct NetStorage { + pub ip_addrs: [smoltcp::wire::IpCidr; 1], + pub sockets: [Option>; 1], + pub neighbor_cache: + [Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8], + pub routes_cache: + [Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 8], + pub tx_storage: [u8; 4096], + pub rx_storage: [u8; 4096], +} + /// The available networking devices on Stabilizer. pub struct NetworkDevices { pub stack: NetworkStack, @@ -510,8 +521,9 @@ pub fn setup( 24, ); - let default_v4_gw = Ipv4Address::new(10, 0, 16, 1); - let mut routes = Routes::new(&mut store.routes_cache[..]); + let default_v4_gw = smoltcp::wire::Ipv4Address::new(10, 0, 16, 1); + let mut routes = + smoltcp::iface::Routes::new(&mut store.routes_cache[..]); routes.add_default_ipv4_route(default_v4_gw).unwrap(); let neighbor_cache = @@ -553,7 +565,7 @@ pub fn setup( }; NetworkDevices { - stack: NetworkStack::new(interface, sockets), + stack: smoltcp_nal::NetworkStack::new(interface, sockets), phy: lan8742a, } }; diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index 97f8058..e1e6731 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -15,7 +15,6 @@ mod design_parameters; mod digital_input_stamper; mod eeprom; mod pounder; -mod smoltcp_nal; mod timers; pub use adc::{Adc0Input, Adc1Input}; @@ -36,16 +35,12 @@ pub type AFE1 = afe::ProgrammableGainAmplifier< hal::gpio::gpiod::PD15>, >; -// Type alias for the ethernet interface on Stabilizer. -pub type Ethernet = smoltcp::iface::EthernetInterface< - 'static, +pub type NetworkStack = smoltcp_nal::NetworkStack< 'static, 'static, hal::ethernet::EthernetDMA<'static>, >; -pub type NetworkStack = smoltcp_nal::NetworkStack<'static, 'static, 'static>; - pub use configuration::{setup, PounderDevices, StabilizerDevices}; #[inline(never)] diff --git a/src/hardware/smoltcp_nal.rs b/src/hardware/smoltcp_nal.rs deleted file mode 100644 index 9fd5420..0000000 --- a/src/hardware/smoltcp_nal.rs +++ /dev/null @@ -1,184 +0,0 @@ -use core::cell::RefCell; -///! Network abstraction layer for smoltcp. -use heapless::{consts, Vec}; -use miniconf::embedded_nal::{self as nal, nb}; - -use super::Ethernet; - -pub struct NetStorage { - pub ip_addrs: [smoltcp::wire::IpCidr; 1], - pub sockets: [Option>; 1], - pub neighbor_cache: - [Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8], - pub routes_cache: - [Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 8], - pub tx_storage: [u8; 4096], - pub rx_storage: [u8; 4096], -} - -#[derive(Debug)] -pub enum NetworkError { - NoSocket, - ConnectionFailure, - ReadFailure, - WriteFailure, - Unsupported, -} - -pub struct NetworkStack<'a, 'b, 'c> { - network_interface: RefCell, - sockets: RefCell>, - next_port: RefCell, - unused_handles: RefCell>, -} - -impl<'a, 'b, 'c> NetworkStack<'a, 'b, 'c> { - pub fn new( - interface: Ethernet, - sockets: smoltcp::socket::SocketSet<'a, 'b, 'c>, - ) -> Self { - let mut unused_handles: Vec< - smoltcp::socket::SocketHandle, - consts::U16, - > = Vec::new(); - for socket in sockets.iter() { - unused_handles.push(socket.handle()).unwrap(); - } - - NetworkStack { - network_interface: RefCell::new(interface), - sockets: RefCell::new(sockets), - next_port: RefCell::new(49152), - unused_handles: RefCell::new(unused_handles), - } - } - - pub fn update(&self, time: u32) -> bool { - match self.network_interface.borrow_mut().poll( - &mut self.sockets.borrow_mut(), - smoltcp::time::Instant::from_millis(time as i64), - ) { - Ok(changed) => changed == false, - Err(e) => { - info!("{:?}", e); - true - } - } - } - - fn get_ephemeral_port(&self) -> u16 { - // Get the next ephemeral port - let current_port = self.next_port.borrow().clone(); - - let (next, wrap) = self.next_port.borrow().overflowing_add(1); - *self.next_port.borrow_mut() = if wrap { 49152 } else { next }; - - return current_port; - } -} - -impl<'a, 'b, 'c> nal::TcpStack for NetworkStack<'a, 'b, 'c> { - type Error = NetworkError; - type TcpSocket = smoltcp::socket::SocketHandle; - - fn open( - &self, - _mode: nal::Mode, - ) -> Result { - match self.unused_handles.borrow_mut().pop() { - Some(handle) => { - // Abort any active connections on the handle. - let mut sockets = self.sockets.borrow_mut(); - let internal_socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(handle); - internal_socket.abort(); - - Ok(handle) - } - None => Err(NetworkError::NoSocket), - } - } - - fn connect( - &self, - socket: smoltcp::socket::SocketHandle, - remote: nal::SocketAddr, - ) -> Result { - let mut sockets = self.sockets.borrow_mut(); - let internal_socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(socket); - - // If we're already in the process of connecting, ignore the request silently. - if internal_socket.is_open() { - return Ok(socket); - } - - match remote.ip() { - nal::IpAddr::V4(addr) => { - let octets = addr.octets(); - let address = smoltcp::wire::Ipv4Address::new( - octets[0], octets[1], octets[2], octets[3], - ); - internal_socket - .connect( - (address, remote.port()), - self.get_ephemeral_port(), - ) - .map_err(|_| NetworkError::ConnectionFailure)?; - Ok(socket) - } - - // We only support IPv4. - _ => Err(NetworkError::Unsupported), - } - } - - fn is_connected( - &self, - socket: &smoltcp::socket::SocketHandle, - ) -> Result { - let mut sockets = self.sockets.borrow_mut(); - let socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(*socket); - Ok(socket.may_send() && socket.may_recv()) - } - - fn write( - &self, - socket: &mut smoltcp::socket::SocketHandle, - buffer: &[u8], - ) -> nb::Result { - let mut sockets = self.sockets.borrow_mut(); - let socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(*socket); - socket - .send_slice(buffer) - .map_err(|_| nb::Error::Other(NetworkError::WriteFailure)) - } - - fn read( - &self, - socket: &mut smoltcp::socket::SocketHandle, - buffer: &mut [u8], - ) -> nb::Result { - let mut sockets = self.sockets.borrow_mut(); - let socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(*socket); - socket - .recv_slice(buffer) - .map_err(|_| nb::Error::Other(NetworkError::ReadFailure)) - } - - fn close( - &self, - socket: smoltcp::socket::SocketHandle, - ) -> Result<(), NetworkError> { - let mut sockets = self.sockets.borrow_mut(); - let internal_socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(socket); - internal_socket.close(); - - self.unused_handles.borrow_mut().push(socket).unwrap(); - Ok(()) - } -} From 096f786795543a64a05aa0c99cb7c8455c6828e1 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Sat, 30 Jan 2021 18:57:06 +0100 Subject: [PATCH 07/27] Expanding miniconf to lockin --- src/bin/dual-iir.rs | 22 ++++++++-------- src/bin/lockin.rs | 63 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index ce084df..940a02c 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -9,10 +9,9 @@ use rtic::cyccnt::{Instant, U32Ext}; use stabilizer::hardware; -use miniconf::StringSet; use miniconf::{ embedded_nal::{IpAddr, Ipv4Addr}, - MqttInterface, + MqttInterface, StringSet, }; use serde::Deserialize; @@ -59,6 +58,15 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); + let broker = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)); + let mqtt_interface = MqttInterface::new( + stabilizer.net.stack, + "stabilizer/iir/dual", + broker, + Settings::new(), + ) + .unwrap(); + // Enable ADC/DAC events stabilizer.adcs.0.start(); stabilizer.adcs.1.start(); @@ -68,16 +76,8 @@ const APP: () = { // Start sampling ADCs. stabilizer.adc_dac_timer.start(); - let broker = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)); - init::LateResources { - mqtt_interface: MqttInterface::new( - stabilizer.net.stack, - "stabilizer", - broker, - Settings::new(), - ) - .unwrap(), + mqtt_interface, afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index 9575442..1f0b6a1 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -9,6 +9,12 @@ use rtic::cyccnt::{Instant, U32Ext}; use stabilizer::{hardware, ADC_SAMPLE_TICKS_LOG2, SAMPLE_BUFFER_SIZE_LOG2}; +use miniconf::{ + embedded_nal::{IpAddr, Ipv4Addr}, + MqttInterface, StringSet, +}; +use serde::Deserialize; + use dsp::{iir, iir_int, lockin::Lockin, rpll::RPLL}; use hardware::{ Adc0Input, Adc1Input, Dac0Output, Dac1Output, InputStamper, AFE0, AFE1, @@ -19,13 +25,26 @@ const SCALE: f32 = ((1 << 15) - 1) as f32; // The number of cascaded IIR biquads per channel. Select 1 or 2! const IIR_CASCADE_LENGTH: usize = 1; +#[derive(Debug, Deserialize, StringSet)] +pub struct Settings { + iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], +} + +impl Settings { + pub fn new() -> Self { + Self { + iir: [[iir::IIR::default(); IIR_CASCADE_LENGTH]; 2], + } + } +} + #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { struct Resources { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - stack: hardware::NetworkStack, + mqtt_interface: MqttInterface, // Format: iir_state[ch][cascade-no][coeff] #[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])] @@ -43,6 +62,15 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); + let broker = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)); + let mqtt_interface = MqttInterface::new( + stabilizer.net.stack, + "stabilizer/lockin", + broker, + Settings::new(), + ) + .unwrap(); + let pll = RPLL::new(ADC_SAMPLE_TICKS_LOG2 + SAMPLE_BUFFER_SIZE_LOG2, 0); let lockin = Lockin::new( @@ -62,10 +90,10 @@ const APP: () = { stabilizer.adc_dac_timer.start(); init::LateResources { + mqtt_interface, afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, - stack: stabilizer.net.stack, timestamper: stabilizer.timestamper, pll, @@ -152,8 +180,8 @@ const APP: () = { } } - #[idle(resources=[stack, iir_state, iir_ch, afes])] - fn idle(c: idle::Context) -> ! { + #[idle(resources=[mqtt_interface], spawn=[settings_update])] + fn idle(mut c: idle::Context) -> ! { let mut time = 0u32; let mut next_ms = Instant::now(); @@ -168,14 +196,35 @@ const APP: () = { time += 1; } - let sleep = !c.resources.stack.poll(time); + let sleep = c + .resources + .mqtt_interface + .lock(|interface| !interface.network_stack().poll(time)); - if sleep { - cortex_m::asm::wfi(); + match c + .resources + .mqtt_interface + .lock(|interface| interface.update().unwrap()) + { + miniconf::Action::Continue => { + if sleep { + cortex_m::asm::wfi(); + } + } + miniconf::Action::CommitSettings => { + c.spawn.settings_update().unwrap() + } } } } + #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] + fn settings_update(mut c: settings_update::Context) { + let settings = &c.resources.mqtt_interface.settings; + c.resources.iir_ch.lock(|iir| *iir = settings.iir); + // TODO: Update AFEs + } + #[task(binds = ETH, priority = 1)] fn eth(_: eth::Context) { unsafe { hal::ethernet::interrupt_handler() } From 9e1a6ec4d534580e4e3c2c25b5344ee1a506bbf5 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 3 Feb 2021 14:06:09 +0100 Subject: [PATCH 08/27] Updating dependencies --- Cargo.lock | 14 ++++++++++++-- Cargo.toml | 11 +++++------ src/bin/dual-iir.rs | 8 +++----- src/bin/lockin-external.rs | 10 ++++------ 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7dc698b..77cf37a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1028,6 +1028,16 @@ dependencies = [ "managed", ] +[[package]] +name = "smoltcp-nal" +version = "0.1.0" +source = "git+https://github.com/vertigo-designs/smoltcp-nal.git?branch=main#6a656dd78c5f7543475e95c0eaf81def95fc5a10" +dependencies = [ + "embedded-nal", + "heapless", + "smoltcp", +] + [[package]] name = "stabilizer" version = "0.4.1" @@ -1050,7 +1060,7 @@ dependencies = [ "panic-semihosting", "paste", "serde", - "smoltcp", + "smoltcp-nal", "stm32h7xx-hal", ] @@ -1075,7 +1085,7 @@ dependencies = [ [[package]] name = "stm32h7xx-hal" version = "0.8.0" -source = "git+https://github.com/quartiq/stm32h7xx-hal?branch=rs/smoltcp-update#87a650664beab422b33f1e3d842f8d585ab5fdab" +source = "git+https://github.com/stm32-rs/stm32h7xx-hal?branch=dma#2b8a04caac566a8560f400ddd6503508f78bea77" dependencies = [ "bare-metal 1.0.0", "cast", diff --git a/Cargo.toml b/Cargo.toml index 26016e1..23aab3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,15 +52,14 @@ branch = "feature/mqtt-interface" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" -[dependencies.smoltcp] -version = "0.7" -features = ["ethernet", "proto-ipv4", "socket-tcp", "proto-ipv6"] -default-features = false +[dependencies.smoltcp-nal] +git = "https://github.com/vertigo-designs/smoltcp-nal.git" +branch = "main" [dependencies.stm32h7xx-hal] features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"] -git = "https://github.com/quartiq/stm32h7xx-hal" -branch = "rs/smoltcp-update" +git = "https://github.com/stm32-rs/stm32h7xx-hal" +branch = "dma" [features] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index e76020a..88dca46 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -27,13 +27,11 @@ const IIR_CASCADE_LENGTH: usize = 1; #[derive(Debug, Deserialize, StringSet)] pub struct Settings { - iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } impl Settings { pub fn new() -> Self { Self { - iir: [[iir::IIR::default(); IIR_CASCADE_LENGTH]; 2], } } } @@ -168,9 +166,9 @@ const APP: () = { } #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] - fn settings_update(mut c: settings_update::Context) { - let settings = &c.resources.mqtt_interface.settings; - c.resources.iir_ch.lock(|iir| *iir = settings.iir); + fn settings_update(c: settings_update::Context) { + let _settings = &c.resources.mqtt_interface.settings; + //c.resources.iir_ch.lock(|iir| *iir = settings.iir); // TODO: Update AFEs } diff --git a/src/bin/lockin-external.rs b/src/bin/lockin-external.rs index bbe09a3..ffeb849 100644 --- a/src/bin/lockin-external.rs +++ b/src/bin/lockin-external.rs @@ -25,15 +25,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; -#[derive(Debug, Deserialize, StringSet)] +#[derive(Deserialize, StringSet)] pub struct Settings { - iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } impl Settings { pub fn new() -> Self { Self { - iir: [[iir::IIR::default(); IIR_CASCADE_LENGTH]; 2], } } } @@ -228,9 +226,9 @@ const APP: () = { } #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] - fn settings_update(mut c: settings_update::Context) { - let settings = &c.resources.mqtt_interface.settings; - c.resources.iir_ch.lock(|iir| *iir = settings.iir); + fn settings_update(c: settings_update::Context) { + let _settings = &c.resources.mqtt_interface.settings; + //c.resources.iir_ch.lock(|iir| *iir = settings.iir); // TODO: Update AFEs } From 738516eedbd07230fe2e658bae21572740e113e3 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 3 Feb 2021 15:13:37 +0100 Subject: [PATCH 09/27] Adding broken example --- Cargo.lock | 26 +++++++++++++++++++++++--- Cargo.toml | 7 ++++--- src/bin/dual-iir.rs | 8 ++++++-- src/bin/lockin-external.rs | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77cf37a..e7f0729 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,6 +348,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "derive_stringset" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_stringset" version = "0.1.0" @@ -364,7 +373,7 @@ version = "0.1.0" dependencies = [ "criterion", "libm", - "miniconf", + "miniconf 0.1.0 (git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface)", "ndarray", "rand", "serde", @@ -617,12 +626,23 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniconf" +version = "0.1.0" +dependencies = [ + "derive_stringset 0.1.0", + "heapless", + "minimq", + "serde", + "serde-json-core 0.2.0", +] + [[package]] name = "miniconf" version = "0.1.0" source = "git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface#38379f7fa72e675c348a4f532811795cc95766df" dependencies = [ - "derive_stringset", + "derive_stringset 0.1.0 (git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface)", "heapless", "minimq", "serde", @@ -1054,7 +1074,7 @@ dependencies = [ "heapless", "log", "mcp23017", - "miniconf", + "miniconf 0.1.0", "nb 1.0.0", "panic-halt", "panic-semihosting", diff --git a/Cargo.toml b/Cargo.toml index 23aab3a..460a296 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,8 +46,9 @@ dsp = { path = "dsp" } ad9959 = { path = "ad9959" } [dependencies.miniconf] -git = "https://github.com/vertigo-designs/miniconf.git" -branch = "feature/mqtt-interface" +# git = "https://github.com/vertigo-designs/miniconf.git" +# branch = "feature/mqtt-interface" +path = "../../vertigo-designs/miniconf" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" @@ -70,7 +71,7 @@ pounder_v1_1 = [ ] [profile.dev] codegen-units = 1 incremental = false -opt-level = 3 +opt-level = 1 [profile.release] opt-level = 3 diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 88dca46..b115ec5 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -27,15 +27,19 @@ const IIR_CASCADE_LENGTH: usize = 1; #[derive(Debug, Deserialize, StringSet)] pub struct Settings { + test: u32, } impl Settings { pub fn new() -> Self { Self { + test: 0, } } } +const ID: &str = "test"; + #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { struct Resources { @@ -56,10 +60,10 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); - let broker = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)); + let broker = IpAddr::V4(Ipv4Addr::new(10, 34, 16, 1)); let mqtt_interface = MqttInterface::new( stabilizer.net.stack, - "stabilizer/iir/dual", + ID, broker, Settings::new(), ) diff --git a/src/bin/lockin-external.rs b/src/bin/lockin-external.rs index ffeb849..c32fa81 100644 --- a/src/bin/lockin-external.rs +++ b/src/bin/lockin-external.rs @@ -60,7 +60,7 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); - let broker = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)); + let broker = IpAddr::V4(Ipv4Addr::new(10, 34, 16, 1)); let mqtt_interface = MqttInterface::new( stabilizer.net.stack, "stabilizer/lockin", From 91f16c2961e243e28c34d6a647534674113e72e9 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 3 Feb 2021 19:55:58 +0100 Subject: [PATCH 10/27] Adding working example --- Cargo.lock | 27 ++------------------------- Cargo.toml | 7 +++---- dsp/Cargo.toml | 4 ---- src/bin/dual-iir.rs | 4 +--- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7f0729..7d0cb25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,23 +357,12 @@ dependencies = [ "syn", ] -[[package]] -name = "derive_stringset" -version = "0.1.0" -source = "git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface#38379f7fa72e675c348a4f532811795cc95766df" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "dsp" version = "0.1.0" dependencies = [ "criterion", "libm", - "miniconf 0.1.0 (git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface)", "ndarray", "rand", "serde", @@ -630,19 +619,7 @@ dependencies = [ name = "miniconf" version = "0.1.0" dependencies = [ - "derive_stringset 0.1.0", - "heapless", - "minimq", - "serde", - "serde-json-core 0.2.0", -] - -[[package]] -name = "miniconf" -version = "0.1.0" -source = "git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface#38379f7fa72e675c348a4f532811795cc95766df" -dependencies = [ - "derive_stringset 0.1.0 (git+https://github.com/vertigo-designs/miniconf.git?branch=feature/mqtt-interface)", + "derive_stringset", "heapless", "minimq", "serde", @@ -1074,7 +1051,7 @@ dependencies = [ "heapless", "log", "mcp23017", - "miniconf 0.1.0", + "miniconf", "nb 1.0.0", "panic-halt", "panic-semihosting", diff --git a/Cargo.toml b/Cargo.toml index 460a296..23aab3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,9 +46,8 @@ dsp = { path = "dsp" } ad9959 = { path = "ad9959" } [dependencies.miniconf] -# git = "https://github.com/vertigo-designs/miniconf.git" -# branch = "feature/mqtt-interface" -path = "../../vertigo-designs/miniconf" +git = "https://github.com/vertigo-designs/miniconf.git" +branch = "feature/mqtt-interface" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" @@ -71,7 +70,7 @@ pounder_v1_1 = [ ] [profile.dev] codegen-units = 1 incremental = false -opt-level = 1 +opt-level = 3 [profile.release] opt-level = 3 diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 25d395a..d0d46d8 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -9,10 +9,6 @@ libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } serde-json-core = "0.1" -[dependencies.miniconf] -git = "https://github.com/vertigo-designs/miniconf.git" -branch = "feature/mqtt-interface" - [dev-dependencies] criterion = "0.3" rand = "0.8" diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index b115ec5..a8dfa39 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -38,8 +38,6 @@ impl Settings { } } -const ID: &str = "test"; - #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { struct Resources { @@ -63,7 +61,7 @@ const APP: () = { let broker = IpAddr::V4(Ipv4Addr::new(10, 34, 16, 1)); let mqtt_interface = MqttInterface::new( stabilizer.net.stack, - ID, + "stabilizer", broker, Settings::new(), ) From 13e02710cda7bd5bac30b15fdb3b432b2f399aa5 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 12:08:03 +0100 Subject: [PATCH 11/27] 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; From cb16e9a85f35a20f6c67ac1feb1f97952992aa99 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 12:59:24 +0100 Subject: [PATCH 12/27] Updating settings update function --- Cargo.lock | 16 ++------------- dsp/src/iir.rs | 26 ++++++++++++------------ src/bin/dual-iir.rs | 38 ++++++++++++++++++++++++----------- src/hardware/afe.rs | 3 ++- src/hardware/cycle_counter.rs | 12 +++++++---- 5 files changed, 51 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34941fc..27dd8d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -351,7 +351,6 @@ dependencies = [ [[package]] name = "derive_stringset" version = "0.1.0" -source = "git+https://github.com/vertigo-designs/miniconf.git?branch=develop#256098cafc6db93b456b5014c8ef1b835b5e239d" dependencies = [ "proc-macro2", "quote", @@ -365,10 +364,10 @@ dependencies = [ "criterion", "generic-array 0.14.4", "libm", + "miniconf", "ndarray", "rand", "serde", - "serde-json-core 0.1.0", ] [[package]] @@ -620,13 +619,12 @@ dependencies = [ [[package]] name = "miniconf" version = "0.1.0" -source = "git+https://github.com/vertigo-designs/miniconf.git?branch=develop#256098cafc6db93b456b5014c8ef1b835b5e239d" dependencies = [ "derive_stringset", "heapless", "minimq", "serde", - "serde-json-core 0.2.0", + "serde-json-core", ] [[package]] @@ -966,16 +964,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-json-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf406405ada9ef326ca78677324ac66994ff348fc48a16030be08caeed29825" -dependencies = [ - "heapless", - "serde", -] - [[package]] name = "serde-json-core" version = "0.2.0" diff --git a/dsp/src/iir.rs b/dsp/src/iir.rs index 4206c2b..7c0efc3 100644 --- a/dsp/src/iir.rs +++ b/dsp/src/iir.rs @@ -1,4 +1,5 @@ -use serde::{Deserialize, Serialize}; +use serde::Deserialize; +use miniconf::StringSet; use super::{abs, copysign, macc, max, min}; use core::f32; @@ -11,8 +12,7 @@ use core::f32; /// To represent the IIR coefficients, this contains the feed-forward /// coefficients (b0, b1, b2) followd by the negated feed-back coefficients /// (-a1, -a2), all five normalized such that a0 = 1. -#[derive(Copy, Clone, Default, Deserialize, Serialize)] -pub struct Vec5(pub [f32; 5]); +pub type Vec5 = [f32; 5]; /// IIR configuration. /// @@ -39,7 +39,7 @@ pub struct Vec5(pub [f32; 5]); /// Therefore it can trivially implement bump-less transfer. /// * Cascading multiple IIR filters allows stable and robust /// implementation of transfer functions beyond bequadratic terms. -#[derive(Copy, Clone, Default, Deserialize, Serialize)] +#[derive(Copy, Clone, Debug, Default, Deserialize, StringSet)] pub struct IIR { pub ba: Vec5, pub y_offset: f32, @@ -50,7 +50,7 @@ pub struct IIR { impl IIR { pub const fn new(gain: f32, y_min: f32, y_max: f32) -> Self { Self { - ba: Vec5([gain, 0., 0., 0., 0.]), + ba: [gain, 0., 0., 0., 0.], y_offset: 0., y_min, y_max, @@ -84,13 +84,13 @@ impl IIR { } (a1, b0, b1) }; - self.ba.0.copy_from_slice(&[b0, b1, 0., a1, 0.]); + self.ba.copy_from_slice(&[b0, b1, 0., a1, 0.]); Ok(()) } /// Compute the overall (DC feed-forward) gain. pub fn get_k(&self) -> f32 { - self.ba.0[..3].iter().sum() + self.ba[..3].iter().sum() } /// Compute input-referred (`x`) offset from output (`y`) offset. @@ -118,21 +118,21 @@ impl IIR { /// * `xy` - Current filter state. /// * `x0` - New input. pub fn update(&self, xy: &mut Vec5, x0: f32) -> f32 { - let n = self.ba.0.len(); - debug_assert!(xy.0.len() == n); + let n = self.ba.len(); + debug_assert!(xy.len() == n); // `xy` contains x0 x1 y0 y1 y2 // Increment time x1 x2 y1 y2 y3 // Shift x1 x1 x2 y1 y2 // This unrolls better than xy.rotate_right(1) - xy.0.copy_within(0..n - 1, 1); + xy.copy_within(0..n - 1, 1); // Store x0 x0 x1 x2 y1 y2 - xy.0[0] = x0; + xy[0] = x0; // Compute y0 by multiply-accumulate - let y0 = macc(self.y_offset, &xy.0, &self.ba.0); + let y0 = macc(self.y_offset, xy, &self.ba); // Limit y0 let y0 = max(self.y_min, min(self.y_max, y0)); // Store y0 x0 x1 y0 y1 y2 - xy.0[n / 2] = y0; + xy[n / 2] = y0; y0 } } diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 911b63d..0470d83 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -15,7 +15,7 @@ use serde::Deserialize; use dsp::iir; use hardware::{ Adc0Input, Adc1Input, CycleCounter, Dac0Output, Dac1Output, NetworkStack, - AFE0, AFE1, + AFE0, AFE1, AfeGain, }; const SCALE: f32 = i16::MAX as _; @@ -25,12 +25,18 @@ const IIR_CASCADE_LENGTH: usize = 1; #[derive(Debug, Deserialize, StringSet)] pub struct Settings { - test: u32, + afe: [AfeGain; 2], + iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2], + iir_ch: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } -impl Settings { - pub fn new() -> Self { - Self { test: 0 } +impl Default for Settings { + fn default() -> Self { + Self { + afe: [AfeGain::G1, AfeGain::G1], + iir_state: [[[0.; 5]; IIR_CASCADE_LENGTH]; 2], + iir_ch: [[iir::IIR::new(1., -SCALE, SCALE); IIR_CASCADE_LENGTH]; 2], + } } } @@ -45,7 +51,7 @@ const APP: () = { clock: CycleCounter, // Format: iir_state[ch][cascade-no][coeff] - #[init([[iir::Vec5([0.; 5]); IIR_CASCADE_LENGTH]; 2])] + #[init([[[0.; 5]; IIR_CASCADE_LENGTH]; 2])] iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2], #[init([[iir::IIR::new(1., -SCALE, SCALE); IIR_CASCADE_LENGTH]; 2])] iir_ch: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], @@ -67,7 +73,7 @@ const APP: () = { .unwrap() }; - MqttInterface::new(mqtt_client, "stabilizer", Settings::new()) + MqttInterface::new(mqtt_client, "stabilizer", Settings::default()) .unwrap() }; @@ -160,11 +166,19 @@ const APP: () = { } } - #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] - fn settings_update(c: settings_update::Context) { - let _settings = &c.resources.mqtt_interface.settings; - //c.resources.iir_ch.lock(|iir| *iir = settings.iir); - // TODO: Update AFEs + #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch, iir_state])] + fn settings_update(mut c: settings_update::Context) { + let settings = &c.resources.mqtt_interface.settings; + + // Update the IIR channels. + c.resources.iir_ch.lock(|iir| *iir = settings.iir_ch); + + // Update the IIR states. + c.resources.iir_state.lock(|iir| *iir = settings.iir_state); + + // Update AFEs + c.resources.afes.0.set_gain(settings.afe[0]); + c.resources.afes.1.set_gain(settings.afe[1]); } #[task(binds = ETH, priority = 1)] diff --git a/src/hardware/afe.rs b/src/hardware/afe.rs index 5dd725a..451dfa7 100644 --- a/src/hardware/afe.rs +++ b/src/hardware/afe.rs @@ -1,9 +1,10 @@ use serde::{Deserialize, Serialize}; +use miniconf::StringSet; use core::convert::TryFrom; use enum_iterator::IntoEnumIterator; -#[derive(Copy, Clone, Debug, Serialize, Deserialize, IntoEnumIterator)] +#[derive(Copy, Clone, Debug, Serialize, Deserialize, IntoEnumIterator, StringSet)] pub enum Gain { G1 = 0b00, G2 = 0b01, diff --git a/src/hardware/cycle_counter.rs b/src/hardware/cycle_counter.rs index 38db550..53535ff 100644 --- a/src/hardware/cycle_counter.rs +++ b/src/hardware/cycle_counter.rs @@ -3,7 +3,7 @@ use rtic::cyccnt::{Duration, Instant, U32Ext}; use stm32h7xx_hal::time::Hertz; pub struct CycleCounter { - next_tick: Instant, + next_tick: Option, ticks: u32, increment: Duration, } @@ -20,14 +20,18 @@ impl CycleCounter { Self { increment, ticks: 0, - next_tick: Instant::now() + increment, + next_tick: None, } } pub fn current_ms(&mut self) -> u32 { + if self.next_tick.is_none() { + self.next_tick = Some(Instant::now() + self.increment); + } + let now = Instant::now(); - while now > self.next_tick { - self.next_tick += self.increment; + while now > self.next_tick.unwrap() { + *self.next_tick.as_mut().unwrap() += self.increment; self.ticks += 1; } From 6b0595b4ade805470faf2d277c9a481505abc4ac Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 14:50:49 +0100 Subject: [PATCH 13/27] Fixing dsp toml --- dsp/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 9c6b411..8e07060 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [dependencies] libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } -serde-json-core = "0.1" generic-array = "0.14" [dev-dependencies] From b66f80f78446fbeb80dbe739e93ec88c0e53c4c5 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 16:30:39 +0100 Subject: [PATCH 14/27] Fixing dependencies --- Cargo.lock | 5 ++++- Cargo.toml | 9 +++------ dsp/Cargo.toml | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27dd8d0..cc31add 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -351,6 +351,7 @@ dependencies = [ [[package]] name = "derive_stringset" version = "0.1.0" +source = "git+https://github.com/quartiq/miniconf.git?branch=rs/issue-21/terminal-array-elements#b93924e81ad860efd9dcda8df2ea901a579958e2" dependencies = [ "proc-macro2", "quote", @@ -619,6 +620,7 @@ dependencies = [ [[package]] name = "miniconf" version = "0.1.0" +source = "git+https://github.com/quartiq/miniconf.git?branch=rs/issue-21/terminal-array-elements#b93924e81ad860efd9dcda8df2ea901a579958e2" dependencies = [ "derive_stringset", "heapless", @@ -1020,7 +1022,8 @@ dependencies = [ [[package]] name = "smoltcp-nal" version = "0.1.0" -source = "git+https://github.com/vertigo-designs/smoltcp-nal.git?branch=main#6a656dd78c5f7543475e95c0eaf81def95fc5a10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e5aeb4818706fd74c35917692008d29a5314483c8180300a582253718ce57a" dependencies = [ "embedded-nal", "heapless", diff --git a/Cargo.toml b/Cargo.toml index 6942942..eeade26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,18 +44,15 @@ enum-iterator = "0.6.0" paste = "1" dsp = { path = "dsp" } ad9959 = { path = "ad9959" } +smoltcp-nal = "0.1.0" [dependencies.miniconf] -git = "https://github.com/vertigo-designs/miniconf.git" -branch = "develop" +git = "https://github.com/quartiq/miniconf.git" +branch = "rs/issue-21/terminal-array-elements" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" -[dependencies.smoltcp-nal] -git = "https://github.com/vertigo-designs/smoltcp-nal.git" -branch = "main" - [dependencies.stm32h7xx-hal] features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"] git = "https://github.com/stm32-rs/stm32h7xx-hal" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 8e07060..457e209 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -9,6 +9,10 @@ libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } generic-array = "0.14" +[dependencies.miniconf] +git = "https://github.com/quartiq/miniconf.git" +branch = "rs/issue-21/terminal-array-elements" + [dev-dependencies] criterion = "0.3" rand = "0.8" From 50476f68fd865d9b89170ff7ac7916bdf8313cd8 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 16:53:53 +0100 Subject: [PATCH 15/27] Adding settings support for lockin-external --- dsp/src/iir.rs | 2 +- src/bin/dual-iir.rs | 4 +- src/bin/lockin-external.rs | 96 ++++++++++++++++++++++++++------------ src/hardware/afe.rs | 6 ++- 4 files changed, 73 insertions(+), 35 deletions(-) diff --git a/dsp/src/iir.rs b/dsp/src/iir.rs index 7c0efc3..d323a6c 100644 --- a/dsp/src/iir.rs +++ b/dsp/src/iir.rs @@ -1,5 +1,5 @@ -use serde::Deserialize; use miniconf::StringSet; +use serde::Deserialize; use super::{abs, copysign, macc, max, min}; use core::f32; diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 0470d83..e536939 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -14,8 +14,8 @@ use serde::Deserialize; use dsp::iir; use hardware::{ - Adc0Input, Adc1Input, CycleCounter, Dac0Output, Dac1Output, NetworkStack, - AFE0, AFE1, AfeGain, + Adc0Input, Adc1Input, AfeGain, CycleCounter, Dac0Output, Dac1Output, + NetworkStack, AFE0, AFE1, }; const SCALE: f32 = i16::MAX as _; diff --git a/src/bin/lockin-external.rs b/src/bin/lockin-external.rs index 451765d..3ed6252 100644 --- a/src/bin/lockin-external.rs +++ b/src/bin/lockin-external.rs @@ -15,17 +15,52 @@ use stabilizer::{hardware, hardware::design_parameters}; use dsp::{lockin::Lockin, rpll::RPLL, Accu}; use hardware::{ - Adc0Input, Adc1Input, Dac0Output, Dac1Output, InputStamper, AFE0, AFE1, + Adc0Input, Adc1Input, AfeGain, Dac0Output, Dac1Output, InputStamper, AFE0, + AFE1, }; -#[derive(Deserialize, StringSet)] -pub struct Settings { - data: u32, +#[derive(Debug, Clone, Copy, Deserialize, StringSet)] +pub struct DspData { + // frequency settling time (log2 counter cycles) + frequency_settling_time: u8, + + // phase settling time + phase_settling_time: u8, + + // Harmonic index of the LO: -1 to _de_modulate the fundamental (complex conjugate) + harmonic: i32, + + // Demodulation LO phase offset + phase_offset: i32, + + // Log2 lowpass time constant + time_constant: u8, } -impl Settings { - pub fn new() -> Self { - Self { data: 5 } +impl Default for DspData { + fn default() -> Self { + Self { + frequency_settling_time: 21, + phase_settling_time: 21, + harmonic: -1, + phase_offset: 0, + time_constant: 6, + } + } +} + +#[derive(Debug, Deserialize, StringSet)] +pub struct Settings { + afe: [AfeGain; 2], + dsp: DspData, +} + +impl Default for Settings { + fn default() -> Self { + Self { + afe: [AfeGain::G1, AfeGain::G1], + dsp: DspData::default(), + } } } @@ -44,7 +79,9 @@ const APP: () = { timestamper: InputStamper, pll: RPLL, + lockin: Lockin, + parameters: DspData, } #[init] @@ -63,7 +100,7 @@ const APP: () = { .unwrap() }; - MqttInterface::new(mqtt_client, "stabilizer", Settings::new()) + MqttInterface::new(mqtt_client, "stabilizer", Settings::default()) .unwrap() }; @@ -94,9 +131,9 @@ const APP: () = { dacs: stabilizer.dacs, timestamper: stabilizer.timestamper, clock: stabilizer.cycle_counter, - pll, lockin: Lockin::default(), + parameters: DspData::default(), } } @@ -107,7 +144,7 @@ const APP: () = { /// This is an implementation of a externally (DI0) referenced PLL lockin on the ADC0 signal. /// It outputs either I/Q or power/phase on DAC0/DAC1. Data is normalized to full scale. /// PLL bandwidth, filter bandwidth, slope, and x/y or power/phase post-filters are available. - #[task(binds=DMA1_STR4, resources=[adcs, dacs, lockin, timestamper, pll], priority=2)] + #[task(binds=DMA1_STR4, resources=[adcs, dacs, lockin, timestamper, pll, parameters], priority=2)] fn process(c: process::Context) { let adc_samples = [ c.resources.adcs.0.acquire_buffer(), @@ -120,6 +157,7 @@ const APP: () = { ]; let lockin = c.resources.lockin; + let params = c.resources.parameters; let timestamp = c .resources @@ -129,34 +167,27 @@ const APP: () = { .map(|t| t as i32); let (pll_phase, pll_frequency) = c.resources.pll.update( timestamp, - 21, // frequency settling time (log2 counter cycles), TODO: expose - 21, // phase settling time, TODO: expose + params.frequency_settling_time, + params.phase_settling_time, ); - // Harmonic index of the LO: -1 to _de_modulate the fundamental (complex conjugate) - let harmonic: i32 = -1; // TODO: expose - - // Demodulation LO phase offset - let phase_offset: i32 = 0; // TODO: expose - - // Log2 lowpass time constant - let time_constant: u8 = 6; // TODO: expose - let sample_frequency = ((pll_frequency // half-up rounding bias // .wrapping_add(1 << design_parameters::SAMPLE_BUFFER_SIZE_LOG2 - 1) >> design_parameters::SAMPLE_BUFFER_SIZE_LOG2) as i32) - .wrapping_mul(harmonic); - let sample_phase = - phase_offset.wrapping_add(pll_phase.wrapping_mul(harmonic)); + // Harmonic index of the LO: -1 to _de_modulate the fundamental (complex conjugate) + .wrapping_mul(params.harmonic); + let sample_phase = params + .phase_offset + .wrapping_add(pll_phase.wrapping_mul(params.harmonic)); let output = adc_samples[0] .iter() .zip(Accu::new(sample_phase, sample_frequency)) // Convert to signed, MSB align the ADC sample. .map(|(&sample, phase)| { - lockin.update(sample as i16, phase, time_constant) + lockin.update(sample as i16, phase, params.time_constant) }) .last() .unwrap(); @@ -201,11 +232,16 @@ const APP: () = { } } - #[task(priority = 1, resources=[mqtt_interface, afes])] - fn settings_update(c: settings_update::Context) { - let _settings = &c.resources.mqtt_interface.settings; - //c.resources.iir_ch.lock(|iir| *iir = settings.iir); - // TODO: Update AFEs + #[task(priority = 1, resources=[mqtt_interface, afes, parameters])] + fn settings_update(mut c: settings_update::Context) { + let settings = &c.resources.mqtt_interface.settings; + + // Update AFEs + c.resources.afes.0.set_gain(settings.afe[0]); + c.resources.afes.1.set_gain(settings.afe[1]); + + // Update DSP parameters. + c.resources.parameters.lock(|params| *params = settings.dsp); } #[task(binds = ETH, priority = 1)] diff --git a/src/hardware/afe.rs b/src/hardware/afe.rs index 451dfa7..8ce1bd1 100644 --- a/src/hardware/afe.rs +++ b/src/hardware/afe.rs @@ -1,10 +1,12 @@ -use serde::{Deserialize, Serialize}; use miniconf::StringSet; +use serde::{Deserialize, Serialize}; use core::convert::TryFrom; use enum_iterator::IntoEnumIterator; -#[derive(Copy, Clone, Debug, Serialize, Deserialize, IntoEnumIterator, StringSet)] +#[derive( + Copy, Clone, Debug, Serialize, Deserialize, IntoEnumIterator, StringSet, +)] pub enum Gain { G1 = 0b00, G2 = 0b01, From 3c8cd58d6f3652b34b9893ee5802ed84dc3d0e5b Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 17:22:43 +0100 Subject: [PATCH 16/27] Removing lockin-external changes --- src/bin/lockin-external.rs | 145 ++++++------------------------------- 1 file changed, 22 insertions(+), 123 deletions(-) diff --git a/src/bin/lockin-external.rs b/src/bin/lockin-external.rs index 3ed6252..ae15111 100644 --- a/src/bin/lockin-external.rs +++ b/src/bin/lockin-external.rs @@ -4,84 +4,23 @@ use stm32h7xx_hal as hal; -use miniconf::{ - embedded_nal::{IpAddr, Ipv4Addr}, - minimq, MqttInterface, StringSet, -}; - -use serde::Deserialize; use stabilizer::{hardware, hardware::design_parameters}; use dsp::{lockin::Lockin, rpll::RPLL, Accu}; - use hardware::{ - Adc0Input, Adc1Input, AfeGain, Dac0Output, Dac1Output, InputStamper, AFE0, - AFE1, + Adc0Input, Adc1Input, Dac0Output, Dac1Output, InputStamper, AFE0, AFE1, }; -#[derive(Debug, Clone, Copy, Deserialize, StringSet)] -pub struct DspData { - // frequency settling time (log2 counter cycles) - frequency_settling_time: u8, - - // phase settling time - phase_settling_time: u8, - - // Harmonic index of the LO: -1 to _de_modulate the fundamental (complex conjugate) - harmonic: i32, - - // Demodulation LO phase offset - phase_offset: i32, - - // Log2 lowpass time constant - time_constant: u8, -} - -impl Default for DspData { - fn default() -> Self { - Self { - frequency_settling_time: 21, - phase_settling_time: 21, - harmonic: -1, - phase_offset: 0, - time_constant: 6, - } - } -} - -#[derive(Debug, Deserialize, StringSet)] -pub struct Settings { - afe: [AfeGain; 2], - dsp: DspData, -} - -impl Default for Settings { - fn default() -> Self { - Self { - afe: [AfeGain::G1, AfeGain::G1], - dsp: DspData::default(), - } - } -} - #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] const APP: () = { struct Resources { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - clock: hardware::CycleCounter, - mqtt_interface: MqttInterface< - Settings, - hardware::NetworkStack, - minimq::consts::U256, - >, timestamper: InputStamper, pll: RPLL, - lockin: Lockin, - parameters: DspData, } #[init] @@ -89,21 +28,6 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); - 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() - }; - - MqttInterface::new(mqtt_client, "stabilizer", Settings::default()) - .unwrap() - }; - let pll = RPLL::new( design_parameters::ADC_SAMPLE_TICKS_LOG2 + design_parameters::SAMPLE_BUFFER_SIZE_LOG2, @@ -125,15 +49,13 @@ const APP: () = { stabilizer.timestamper.start(); init::LateResources { - mqtt_interface, afes: stabilizer.afes, adcs: stabilizer.adcs, dacs: stabilizer.dacs, timestamper: stabilizer.timestamper, - clock: stabilizer.cycle_counter, + pll, lockin: Lockin::default(), - parameters: DspData::default(), } } @@ -144,7 +66,7 @@ const APP: () = { /// This is an implementation of a externally (DI0) referenced PLL lockin on the ADC0 signal. /// It outputs either I/Q or power/phase on DAC0/DAC1. Data is normalized to full scale. /// PLL bandwidth, filter bandwidth, slope, and x/y or power/phase post-filters are available. - #[task(binds=DMA1_STR4, resources=[adcs, dacs, lockin, timestamper, pll, parameters], priority=2)] + #[task(binds=DMA1_STR4, resources=[adcs, dacs, lockin, timestamper, pll], priority=2)] fn process(c: process::Context) { let adc_samples = [ c.resources.adcs.0.acquire_buffer(), @@ -157,7 +79,6 @@ const APP: () = { ]; let lockin = c.resources.lockin; - let params = c.resources.parameters; let timestamp = c .resources @@ -167,27 +88,34 @@ const APP: () = { .map(|t| t as i32); let (pll_phase, pll_frequency) = c.resources.pll.update( timestamp, - params.frequency_settling_time, - params.phase_settling_time, + 21, // frequency settling time (log2 counter cycles), TODO: expose + 21, // phase settling time, TODO: expose ); + // Harmonic index of the LO: -1 to _de_modulate the fundamental (complex conjugate) + let harmonic: i32 = -1; // TODO: expose + + // Demodulation LO phase offset + let phase_offset: i32 = 0; // TODO: expose + + // Log2 lowpass time constant + let time_constant: u8 = 6; // TODO: expose + let sample_frequency = ((pll_frequency // half-up rounding bias // .wrapping_add(1 << design_parameters::SAMPLE_BUFFER_SIZE_LOG2 - 1) >> design_parameters::SAMPLE_BUFFER_SIZE_LOG2) as i32) - // Harmonic index of the LO: -1 to _de_modulate the fundamental (complex conjugate) - .wrapping_mul(params.harmonic); - let sample_phase = params - .phase_offset - .wrapping_add(pll_phase.wrapping_mul(params.harmonic)); + .wrapping_mul(harmonic); + let sample_phase = + phase_offset.wrapping_add(pll_phase.wrapping_mul(harmonic)); let output = adc_samples[0] .iter() .zip(Accu::new(sample_phase, sample_frequency)) // Convert to signed, MSB align the ADC sample. .map(|(&sample, phase)| { - lockin.update(sample as i16, phase, params.time_constant) + lockin.update(sample as i16, phase, time_constant) }) .last() .unwrap(); @@ -207,43 +135,14 @@ const APP: () = { } } - #[idle(resources=[mqtt_interface, clock], spawn=[settings_update])] - fn idle(mut c: idle::Context) -> ! { - let clock = c.resources.clock; + #[idle(resources=[afes])] + fn idle(_: idle::Context) -> ! { loop { - let sleep = c.resources.mqtt_interface.lock(|interface| { - !interface.network_stack().poll(clock.current_ms()) - }); - - match c - .resources - .mqtt_interface - .lock(|interface| interface.update().unwrap()) - { - miniconf::Action::Continue => { - if sleep { - cortex_m::asm::wfi(); - } - } - miniconf::Action::CommitSettings => { - c.spawn.settings_update().unwrap() - } - } + // TODO: Implement network interface. + cortex_m::asm::wfi(); } } - #[task(priority = 1, resources=[mqtt_interface, afes, parameters])] - fn settings_update(mut c: settings_update::Context) { - let settings = &c.resources.mqtt_interface.settings; - - // Update AFEs - c.resources.afes.0.set_gain(settings.afe[0]); - c.resources.afes.1.set_gain(settings.afe[1]); - - // Update DSP parameters. - c.resources.parameters.lock(|params| *params = settings.dsp); - } - #[task(binds = ETH, priority = 1)] fn eth(_: eth::Context) { unsafe { hal::ethernet::interrupt_handler() } From e8c48297908835b6c2920709a7c87c40467e045c Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 17:26:54 +0100 Subject: [PATCH 17/27] Adding docs for the cycle counter --- src/hardware/cycle_counter.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/hardware/cycle_counter.rs b/src/hardware/cycle_counter.rs index 53535ff..fab196b 100644 --- a/src/hardware/cycle_counter.rs +++ b/src/hardware/cycle_counter.rs @@ -2,13 +2,29 @@ use rtic::cyccnt::{Duration, Instant, U32Ext}; use stm32h7xx_hal::time::Hertz; +/// A simple clock for counting elapsed milliseconds. pub struct CycleCounter { + + // The time of the next millisecond in the system. next_tick: Option, + + // The number of elapsed milliseconds recorded. ticks: u32, + + // The increment amount of clock cycles for each elapsed millisecond. increment: Duration, } impl CycleCounter { + + /// Construct the cycle counting clock. + /// + /// # Args + /// * `dwt` - The debug watch and trace unit of the CPU core. + /// * `cpu_frequency` - The frequency that the cycle counter counts at. + /// + /// # Returns + /// A clock that can be used for measuring elapsed milliseconds. pub fn new( mut dwt: cortex_m::peripheral::DWT, cpu_frequency: impl Into, @@ -24,6 +40,18 @@ impl CycleCounter { } } + /// Get the current number of milliseconds elapsed in the system. + /// + /// # Note + /// This function must be called more often than once per 10 seconds to prevent internal + /// wrapping of the cycle counter. + /// + /// The internal millisecond accumulator will overflow just shy of every 50 days. + /// + /// This function does not start counting milliseconds until the very first invocation. + /// + /// # Returns + /// The number of elapsed milliseconds since the system started. pub fn current_ms(&mut self) -> u32 { if self.next_tick.is_none() { self.next_tick = Some(Instant::now() + self.increment); From a55b30e6c4c059b72d42f6208cdd7ed3690dc2db Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 17:50:17 +0100 Subject: [PATCH 18/27] Working around dependency injection bug --- Cargo.lock | 492 -------------------------------------------- dsp/Cargo.toml | 7 +- src/bin/dual-iir.rs | 8 +- 3 files changed, 12 insertions(+), 495 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc31add..ab055f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,17 +40,6 @@ dependencies = [ "embedded-hal", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -96,24 +85,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c147d86912d04bef727828fda769a76ca81629a46d8ba311a8d58a26aa91473d" -[[package]] -name = "bstr" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9" - [[package]] name = "byteorder" version = "1.4.2" @@ -135,23 +106,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - -[[package]] -name = "const_fn" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" - [[package]] name = "cortex-m" version = "0.6.7" @@ -244,110 +198,6 @@ dependencies = [ "cortex-m 0.7.1", ] -[[package]] -name = "criterion" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools 0.10.0", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" -dependencies = [ - "cast", - "itertools 0.9.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" -dependencies = [ - "cfg-if", - "const_fn", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "csv" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97" -dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - [[package]] name = "derive_stringset" version = "0.1.0" @@ -362,7 +212,6 @@ dependencies = [ name = "dsp" version = "0.1.0" dependencies = [ - "criterion", "generic-array 0.14.4", "libm", "miniconf", @@ -371,12 +220,6 @@ dependencies = [ "serde", ] -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - [[package]] name = "embedded-dma" version = "0.1.2" @@ -466,12 +309,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "half" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" - [[package]] name = "hash32" version = "0.1.1" @@ -500,15 +337,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hermit-abi" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -dependencies = [ - "libc", -] - [[package]] name = "indexmap" version = "1.6.1" @@ -519,45 +347,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "js-sys" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.86" @@ -602,21 +391,6 @@ dependencies = [ "embedded-hal", ] -[[package]] -name = "memchr" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "memoffset" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" -dependencies = [ - "autocfg", -] - [[package]] name = "miniconf" version = "0.1.0" @@ -704,22 +478,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "panic-halt" version = "0.2.0" @@ -742,34 +500,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5d65c4d95931acda4498f675e332fcbdc9a06705cd07086c510e9b6009cd1c1" -[[package]] -name = "plotters" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" - -[[package]] -name = "plotters-svg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" -dependencies = [ - "plotters-backend", -] - [[package]] name = "ppv-lite86" version = "0.2.10" @@ -846,55 +576,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" -[[package]] -name = "rayon" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" -dependencies = [ - "byteorder", -] - -[[package]] -name = "regex-syntax" -version = "0.6.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" - [[package]] name = "rtic-core" version = "0.3.1" @@ -921,27 +602,6 @@ dependencies = [ "semver", ] -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "semver" version = "0.9.0" @@ -976,16 +636,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_cbor" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.123" @@ -997,17 +647,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.62" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "smoltcp" version = "0.7.0" @@ -1103,37 +742,12 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "tinytemplate" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - [[package]] name = "unicode-xid" version = "0.2.1" @@ -1167,114 +781,8 @@ dependencies = [ "vcell", ] -[[package]] -name = "walkdir" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasm-bindgen" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64" - -[[package]] -name = "web-sys" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 457e209..78f27c2 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -14,7 +14,7 @@ git = "https://github.com/quartiq/miniconf.git" branch = "rs/issue-21/terminal-array-elements" [dev-dependencies] -criterion = "0.3" +# criterion = "0.3" rand = "0.8" ndarray = "0.14" @@ -22,5 +22,10 @@ ndarray = "0.14" name = "micro" harness = false +# Note: Due to a dependency injection bug, criterion enables std-features for serde, which breaks +# testing. Patch serde to not use std dependencies. +[patch.crates-io] +serde = { version = "1.0", features = ["derive"], default-features = false } + [features] nightly = [] diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index e536939..b10f57d 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -26,6 +26,7 @@ const IIR_CASCADE_LENGTH: usize = 1; #[derive(Debug, Deserialize, StringSet)] pub struct Settings { afe: [AfeGain; 2], + update_state: bool, iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2], iir_ch: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } @@ -34,6 +35,7 @@ impl Default for Settings { fn default() -> Self { Self { afe: [AfeGain::G1, AfeGain::G1], + update_state: false, iir_state: [[[0.; 5]; IIR_CASCADE_LENGTH]; 2], iir_ch: [[iir::IIR::new(1., -SCALE, SCALE); IIR_CASCADE_LENGTH]; 2], } @@ -173,8 +175,10 @@ const APP: () = { // Update the IIR channels. c.resources.iir_ch.lock(|iir| *iir = settings.iir_ch); - // Update the IIR states. - c.resources.iir_state.lock(|iir| *iir = settings.iir_state); + // Update the IIR states only if explicitly requested. + if settings.update_state { + c.resources.iir_state.lock(|iir| *iir = settings.iir_state); + } // Update AFEs c.resources.afes.0.set_gain(settings.afe[0]); From 63a2220fa034157a6b4718861681b9c1873b40e1 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 17:56:18 +0100 Subject: [PATCH 19/27] Removing support for configuring IIR state --- src/bin/dual-iir.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index b10f57d..a2279d8 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -26,8 +26,6 @@ const IIR_CASCADE_LENGTH: usize = 1; #[derive(Debug, Deserialize, StringSet)] pub struct Settings { afe: [AfeGain; 2], - update_state: bool, - iir_state: [[iir::Vec5; IIR_CASCADE_LENGTH]; 2], iir_ch: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], } @@ -35,8 +33,6 @@ impl Default for Settings { fn default() -> Self { Self { afe: [AfeGain::G1, AfeGain::G1], - update_state: false, - iir_state: [[[0.; 5]; IIR_CASCADE_LENGTH]; 2], iir_ch: [[iir::IIR::new(1., -SCALE, SCALE); IIR_CASCADE_LENGTH]; 2], } } @@ -168,18 +164,13 @@ const APP: () = { } } - #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch, iir_state])] + #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] fn settings_update(mut c: settings_update::Context) { let settings = &c.resources.mqtt_interface.settings; // Update the IIR channels. c.resources.iir_ch.lock(|iir| *iir = settings.iir_ch); - // Update the IIR states only if explicitly requested. - if settings.update_state { - c.resources.iir_state.lock(|iir| *iir = settings.iir_state); - } - // Update AFEs c.resources.afes.0.set_gain(settings.afe[0]); c.resources.afes.1.set_gain(settings.afe[1]); From 90ef0836afddbe02fac6286a3981704011e9bb90 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 17 Feb 2021 17:56:49 +0100 Subject: [PATCH 20/27] Fixing style --- src/hardware/cycle_counter.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/cycle_counter.rs b/src/hardware/cycle_counter.rs index fab196b..da915c8 100644 --- a/src/hardware/cycle_counter.rs +++ b/src/hardware/cycle_counter.rs @@ -4,7 +4,6 @@ use stm32h7xx_hal::time::Hertz; /// A simple clock for counting elapsed milliseconds. pub struct CycleCounter { - // The time of the next millisecond in the system. next_tick: Option, @@ -16,7 +15,6 @@ pub struct CycleCounter { } impl CycleCounter { - /// Construct the cycle counting clock. /// /// # Args From 78e69b170709ab7b09f3996318ac939f24c31f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 17 Feb 2021 18:35:52 +0100 Subject: [PATCH 21/27] s/criterion/easybench/ for less weight --- Cargo.lock | 7 ++++ dsp/Cargo.toml | 7 +--- dsp/benches/micro.rs | 88 ++++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab055f2..cb3441b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,6 +212,7 @@ dependencies = [ name = "dsp" version = "0.1.0" dependencies = [ + "easybench", "generic-array 0.14.4", "libm", "miniconf", @@ -220,6 +221,12 @@ dependencies = [ "serde", ] +[[package]] +name = "easybench" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355215cf95ddc4db0459d5313c9b146bedd43453305e3f0f1c4e8fde7f8d3884" + [[package]] name = "embedded-dma" version = "0.1.2" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 78f27c2..875012d 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -14,7 +14,7 @@ git = "https://github.com/quartiq/miniconf.git" branch = "rs/issue-21/terminal-array-elements" [dev-dependencies] -# criterion = "0.3" +easybench = "1.0" rand = "0.8" ndarray = "0.14" @@ -22,10 +22,5 @@ ndarray = "0.14" name = "micro" harness = false -# Note: Due to a dependency injection bug, criterion enables std-features for serde, which breaks -# testing. Patch serde to not use std dependencies. -[patch.crates-io] -serde = { version = "1.0", features = ["derive"], default-features = false } - [features] nightly = [] diff --git a/dsp/benches/micro.rs b/dsp/benches/micro.rs index 56b9149..8c34256 100644 --- a/dsp/benches/micro.rs +++ b/dsp/benches/micro.rs @@ -1,70 +1,80 @@ use core::f32::consts::PI; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; use dsp::{atan2, cossin}; use dsp::{iir, iir_int}; use dsp::{pll::PLL, rpll::RPLL}; +use easybench::bench_env; -fn atan2_bench(c: &mut Criterion) { +fn atan2_bench() { let xi = (10 << 16) as i32; let xf = xi as f32 / i32::MAX as f32; let yi = (-26_328 << 16) as i32; let yf = yi as f32 / i32::MAX as f32; - c.bench_function("atan2(y, x)", |b| { - b.iter(|| atan2(black_box(yi), black_box(xi))) - }); - c.bench_function("y.atan2(x)", |b| { - b.iter(|| black_box(yf).atan2(black_box(xf))) - }); + println!( + "atan2(yi, xi): {}", + bench_env((yi, xi), |(yi, xi)| atan2(*yi, *xi)) + ); + println!( + "yf.atan2(xf): {}", + bench_env((yf, xf), |(yf, xf)| yf.atan2(*xf)) + ); } -fn cossin_bench(c: &mut Criterion) { +fn cossin_bench() { let zi = -0x7304_2531_i32; let zf = zi as f32 / i32::MAX as f32 * PI; - c.bench_function("cossin(zi)", |b| b.iter(|| cossin(black_box(zi)))); - c.bench_function("zf.sin_cos()", |b| b.iter(|| black_box(zf).sin_cos())); + println!("cossin(zi): {}", bench_env(zi, |zi| cossin(*zi))); + println!("zf.sin_cos(): {}", bench_env(zf, |zf| zf.sin_cos())); } -fn rpll_bench(c: &mut Criterion) { +fn rpll_bench() { let mut dut = RPLL::new(8); - c.bench_function("RPLL::update(Some(t), 21, 20)", |b| { - b.iter(|| dut.update(black_box(Some(0x241)), 21, 20)) - }); - c.bench_function("RPLL::update(Some(t), sf, sp)", |b| { - b.iter(|| { - dut.update(black_box(Some(0x241)), black_box(21), black_box(20)) - }) - }); + println!( + "RPLL::update(Some(t), 21, 20): {}", + bench_env(Some(0x241), |x| dut.update(*x, 21, 20)) + ); + println!( + "RPLL::update(Some(t), sf, sp): {}", + bench_env((Some(0x241), 21, 20), |(x, p, q)| dut.update(*x, *p, *q)) + ); } -fn pll_bench(c: &mut Criterion) { +fn pll_bench() { let mut dut = PLL::default(); - c.bench_function("PLL::update(t, 12, 11)", |b| { - b.iter(|| dut.update(black_box(0x1234), 12, 1)) - }); - c.bench_function("PLL::update(t, sf, sp)", |b| { - b.iter(|| dut.update(black_box(0x241), black_box(21), black_box(20))) - }); + println!( + "PLL::update(t, 12, 12): {}", + bench_env(0x241, |x| dut.update(*x, 12, 12)) + ); + println!( + "PLL::update(t, sf, sp): {}", + bench_env((0x241, 21, 20), |(x, p, q)| dut.update(*x, *p, *q)) + ); } -fn iir_int_bench(c: &mut Criterion) { +fn iir_int_bench() { let dut = iir_int::IIR::default(); let mut xy = iir_int::Vec5::default(); - c.bench_function("int_iir::IIR::update(s, x)", |b| { - b.iter(|| dut.update(&mut xy, black_box(0x2832))) - }); + println!( + "int_iir::IIR::update(s, x): {}", + bench_env(0x2832, |x| dut.update(&mut xy, *x)) + ); } -fn iir_bench(c: &mut Criterion) { +fn iir_bench() { let dut = iir::IIR::default(); let mut xy = iir::Vec5::default(); - c.bench_function("int::IIR::update(s, x)", |b| { - b.iter(|| dut.update(&mut xy, black_box(0.32241))) - }); + println!( + "int::IIR::update(s, x): {}", + bench_env(0.32241, |x| dut.update(&mut xy, *x)) + ); } -criterion_group!(trig, atan2_bench, cossin_bench); -criterion_group!(pll, rpll_bench, pll_bench); -criterion_group!(iir, iir_int_bench, iir_bench); -criterion_main!(trig, pll, iir); +fn main() { + atan2_bench(); + cossin_bench(); + rpll_bench(); + pll_bench(); + iir_int_bench(); + iir_bench(); +} From 04250360c1b24ffcf9e1a0877b5534b733755cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20J=C3=B6rdens?= Date: Wed, 17 Feb 2021 18:40:03 +0100 Subject: [PATCH 22/27] deps: make miniconf a patch --- Cargo.toml | 3 ++- dsp/Cargo.toml | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eeade26..dd46840 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,8 +45,9 @@ paste = "1" dsp = { path = "dsp" } ad9959 = { path = "ad9959" } smoltcp-nal = "0.1.0" +miniconf = "0.1" -[dependencies.miniconf] +[patch.crates-io.miniconf] git = "https://github.com/quartiq/miniconf.git" branch = "rs/issue-21/terminal-array-elements" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 875012d..1fefdd7 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -8,10 +8,7 @@ edition = "2018" libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } generic-array = "0.14" - -[dependencies.miniconf] -git = "https://github.com/quartiq/miniconf.git" -branch = "rs/issue-21/terminal-array-elements" +miniconf = "0.1" [dev-dependencies] easybench = "1.0" From 2ac7568d5bf81c8effc0949251da732ec5930797 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 19 Feb 2021 10:36:39 +0100 Subject: [PATCH 23/27] Updating dependencies --- Cargo.lock | 71 +++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 6 ++++- dsp/Cargo.toml | 1 + 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5ebc04..cd59705 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -348,6 +348,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "derive_stringset" +version = "0.1.0" +source = "git+https://github.com/quartiq/miniconf.git?branch=develop#97ace3d8268075235cb67a2a8740d200bea1fe30" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dsp" version = "0.1.0" @@ -355,6 +365,7 @@ dependencies = [ "criterion", "generic-array 0.14.4", "libm", + "miniconf", "ndarray", "num", "rand", @@ -386,6 +397,17 @@ dependencies = [ "void", ] +[[package]] +name = "embedded-nal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae46eb1b02de5a76d9d0ea21d657ff5b0ad2cc47f3a7723608227b1dd1b3eb18" +dependencies = [ + "heapless", + "nb 1.0.0", + "no-std-net", +] + [[package]] name = "enum-iterator" version = "0.6.0" @@ -596,6 +618,31 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniconf" +version = "0.1.0" +source = "git+https://github.com/quartiq/miniconf.git?branch=develop#97ace3d8268075235cb67a2a8740d200bea1fe30" +dependencies = [ + "derive_stringset", + "heapless", + "minimq", + "serde", + "serde-json-core", +] + +[[package]] +name = "minimq" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c5e626690b6f62e15710cf9815e5ca25ee54084899298c100a14b2504c80a46" +dependencies = [ + "bit_field", + "embedded-nal", + "enum-iterator", + "generic-array 0.14.4", + "heapless", +] + [[package]] name = "nb" version = "0.1.3" @@ -624,6 +671,12 @@ dependencies = [ "rawpointer", ] +[[package]] +name = "no-std-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2178127478ae4ee9be7180bc9c3bffb6354dd7238400db567102f98c413a9f35" + [[package]] name = "num" version = "0.3.1" @@ -952,8 +1005,7 @@ dependencies = [ [[package]] name = "serde-json-core" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89fd6016a00149b485f66da701f76d909210d319040c97b6eff300f6e2ba2153" +source = "git+https://github.com/rust-embedded-community/serde-json-core.git?branch=master#ee06ac91bc43b72450a92198a00d9e5c5b9946d2" dependencies = [ "heapless", "serde", @@ -1002,6 +1054,17 @@ dependencies = [ "managed", ] +[[package]] +name = "smoltcp-nal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e5aeb4818706fd74c35917692008d29a5314483c8180300a582253718ce57a" +dependencies = [ + "embedded-nal", + "heapless", + "smoltcp", +] + [[package]] name = "stabilizer" version = "0.4.1" @@ -1018,13 +1081,13 @@ dependencies = [ "heapless", "log", "mcp23017", + "miniconf", "nb 1.0.0", "panic-halt", "panic-semihosting", "paste", "serde", - "serde-json-core", - "smoltcp", + "smoltcp-nal", "stm32h7xx-hal", ] diff --git a/Cargo.toml b/Cargo.toml index dd46840..599e595 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,11 @@ miniconf = "0.1" [patch.crates-io.miniconf] git = "https://github.com/quartiq/miniconf.git" -branch = "rs/issue-21/terminal-array-elements" +branch = "develop" + +[patch.crates-io.serde-json-core] +git = "https://github.com/rust-embedded-community/serde-json-core.git" +branch = "master" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 516b6e2..674a9cb 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -9,6 +9,7 @@ libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } generic-array = "0.14" num = { version = "0.3.1", default-features = false } +miniconf = "0.1" [dev-dependencies] criterion = "0.3" From c6ef78cdc516999b78bf55559fd825042a6c4755 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 19 Feb 2021 10:44:46 +0100 Subject: [PATCH 24/27] Pulling back easybench changes --- Cargo.lock | 529 +------------------------------------------ dsp/Cargo.toml | 3 +- dsp/benches/micro.rs | 92 ++++---- 3 files changed, 57 insertions(+), 567 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd59705..2c6434f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,17 +40,6 @@ dependencies = [ "embedded-hal", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -96,24 +85,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c147d86912d04bef727828fda769a76ca81629a46d8ba311a8d58a26aa91473d" -[[package]] -name = "bstr" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - -[[package]] -name = "bumpalo" -version = "3.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9" - [[package]] name = "byteorder" version = "1.4.2" @@ -135,23 +106,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "bitflags", - "textwrap", - "unicode-width", -] - -[[package]] -name = "const_fn" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" - [[package]] name = "cortex-m" version = "0.6.7" @@ -244,110 +198,6 @@ dependencies = [ "cortex-m 0.7.1", ] -[[package]] -name = "criterion" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot", - "csv", - "itertools 0.10.0", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_cbor", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" -dependencies = [ - "cast", - "itertools 0.9.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d" -dependencies = [ - "cfg-if", - "const_fn", - "crossbeam-utils", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "csv" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97" -dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - [[package]] name = "derive_stringset" version = "0.1.0" @@ -362,21 +212,20 @@ dependencies = [ name = "dsp" version = "0.1.0" dependencies = [ - "criterion", + "easybench", "generic-array 0.14.4", "libm", "miniconf", "ndarray", - "num", "rand", "serde", ] [[package]] -name = "either" -version = "1.6.1" +name = "easybench" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "355215cf95ddc4db0459d5313c9b146bedd43453305e3f0f1c4e8fde7f8d3884" [[package]] name = "embedded-dma" @@ -467,12 +316,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "half" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" - [[package]] name = "hash32" version = "0.1.1" @@ -501,15 +344,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "hermit-abi" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -dependencies = [ - "libc", -] - [[package]] name = "indexmap" version = "1.6.1" @@ -520,45 +354,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "js-sys" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.86" @@ -603,21 +398,6 @@ dependencies = [ "embedded-hal", ] -[[package]] -name = "memchr" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "memoffset" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" -dependencies = [ - "autocfg", -] - [[package]] name = "miniconf" version = "0.1.0" @@ -677,19 +457,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2178127478ae4ee9be7180bc9c3bffb6354dd7238400db567102f98c413a9f35" -[[package]] -name = "num" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" -dependencies = [ - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - [[package]] name = "num-complex" version = "0.3.1" @@ -709,28 +476,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.14" @@ -740,22 +485,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - [[package]] name = "panic-halt" version = "0.2.0" @@ -778,34 +507,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5d65c4d95931acda4498f675e332fcbdc9a06705cd07086c510e9b6009cd1c1" -[[package]] -name = "plotters" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" - -[[package]] -name = "plotters-svg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" -dependencies = [ - "plotters-backend", -] - [[package]] name = "ppv-lite86" version = "0.2.10" @@ -882,55 +583,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" -[[package]] -name = "rayon" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" -dependencies = [ - "autocfg", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "lazy_static", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" -dependencies = [ - "byteorder", -] - -[[package]] -name = "regex-syntax" -version = "0.6.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" - [[package]] name = "rtic-core" version = "0.3.1" @@ -957,27 +609,6 @@ dependencies = [ "semver", ] -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "semver" version = "0.9.0" @@ -1011,16 +642,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_cbor" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" -dependencies = [ - "half", - "serde", -] - [[package]] name = "serde_derive" version = "1.0.123" @@ -1032,17 +653,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_json" -version = "1.0.62" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "smoltcp" version = "0.7.0" @@ -1138,37 +748,12 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "tinytemplate" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ada8616fad06a2d0c455adc530de4ef57605a8120cc65da9653e0e9623ca74" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - [[package]] name = "unicode-xid" version = "0.2.1" @@ -1202,114 +787,8 @@ dependencies = [ "vcell", ] -[[package]] -name = "walkdir" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "wasm-bindgen" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64" - -[[package]] -name = "web-sys" -version = "0.3.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 674a9cb..1fefdd7 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -8,11 +8,10 @@ edition = "2018" libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } generic-array = "0.14" -num = { version = "0.3.1", default-features = false } miniconf = "0.1" [dev-dependencies] -criterion = "0.3" +easybench = "1.0" rand = "0.8" ndarray = "0.14" diff --git a/dsp/benches/micro.rs b/dsp/benches/micro.rs index 6ecc090..8c34256 100644 --- a/dsp/benches/micro.rs +++ b/dsp/benches/micro.rs @@ -1,68 +1,80 @@ use core::f32::consts::PI; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use dsp::{atan2, cossin, iir, iir_int, PLL, RPLL}; +use dsp::{atan2, cossin}; +use dsp::{iir, iir_int}; +use dsp::{pll::PLL, rpll::RPLL}; +use easybench::bench_env; -fn atan2_bench(c: &mut Criterion) { +fn atan2_bench() { let xi = (10 << 16) as i32; let xf = xi as f32 / i32::MAX as f32; let yi = (-26_328 << 16) as i32; let yf = yi as f32 / i32::MAX as f32; - c.bench_function("atan2(y, x)", |b| { - b.iter(|| atan2(black_box(yi), black_box(xi))) - }); - c.bench_function("y.atan2(x)", |b| { - b.iter(|| black_box(yf).atan2(black_box(xf))) - }); + println!( + "atan2(yi, xi): {}", + bench_env((yi, xi), |(yi, xi)| atan2(*yi, *xi)) + ); + println!( + "yf.atan2(xf): {}", + bench_env((yf, xf), |(yf, xf)| yf.atan2(*xf)) + ); } -fn cossin_bench(c: &mut Criterion) { +fn cossin_bench() { let zi = -0x7304_2531_i32; let zf = zi as f32 / i32::MAX as f32 * PI; - c.bench_function("cossin(zi)", |b| b.iter(|| cossin(black_box(zi)))); - c.bench_function("zf.sin_cos()", |b| b.iter(|| black_box(zf).sin_cos())); + println!("cossin(zi): {}", bench_env(zi, |zi| cossin(*zi))); + println!("zf.sin_cos(): {}", bench_env(zf, |zf| zf.sin_cos())); } -fn rpll_bench(c: &mut Criterion) { +fn rpll_bench() { let mut dut = RPLL::new(8); - c.bench_function("RPLL::update(Some(t), 21, 20)", |b| { - b.iter(|| dut.update(black_box(Some(0x241)), 21, 20)) - }); - c.bench_function("RPLL::update(Some(t), sf, sp)", |b| { - b.iter(|| { - dut.update(black_box(Some(0x241)), black_box(21), black_box(20)) - }) - }); + println!( + "RPLL::update(Some(t), 21, 20): {}", + bench_env(Some(0x241), |x| dut.update(*x, 21, 20)) + ); + println!( + "RPLL::update(Some(t), sf, sp): {}", + bench_env((Some(0x241), 21, 20), |(x, p, q)| dut.update(*x, *p, *q)) + ); } -fn pll_bench(c: &mut Criterion) { +fn pll_bench() { let mut dut = PLL::default(); - c.bench_function("PLL::update(t, 12, 11)", |b| { - b.iter(|| dut.update(black_box(0x1234), 12, 1)) - }); - c.bench_function("PLL::update(t, sf, sp)", |b| { - b.iter(|| dut.update(black_box(0x241), black_box(21), black_box(20))) - }); + println!( + "PLL::update(t, 12, 12): {}", + bench_env(0x241, |x| dut.update(*x, 12, 12)) + ); + println!( + "PLL::update(t, sf, sp): {}", + bench_env((0x241, 21, 20), |(x, p, q)| dut.update(*x, *p, *q)) + ); } -fn iir_int_bench(c: &mut Criterion) { +fn iir_int_bench() { let dut = iir_int::IIR::default(); let mut xy = iir_int::Vec5::default(); - c.bench_function("int_iir::IIR::update(s, x)", |b| { - b.iter(|| dut.update(&mut xy, black_box(0x2832))) - }); + println!( + "int_iir::IIR::update(s, x): {}", + bench_env(0x2832, |x| dut.update(&mut xy, *x)) + ); } -fn iir_bench(c: &mut Criterion) { +fn iir_bench() { let dut = iir::IIR::default(); let mut xy = iir::Vec5::default(); - c.bench_function("int::IIR::update(s, x)", |b| { - b.iter(|| dut.update(&mut xy, black_box(0.32241))) - }); + println!( + "int::IIR::update(s, x): {}", + bench_env(0.32241, |x| dut.update(&mut xy, *x)) + ); } -criterion_group!(trig, atan2_bench, cossin_bench); -criterion_group!(pll, rpll_bench, pll_bench); -criterion_group!(iir, iir_int_bench, iir_bench); -criterion_main!(trig, pll, iir); +fn main() { + atan2_bench(); + cossin_bench(); + rpll_bench(); + pll_bench(); + iir_int_bench(); + iir_bench(); +} From 04dff30dce01272de282ff2b96eea6f589e8a79b Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 19 Feb 2021 10:45:53 +0100 Subject: [PATCH 25/27] Fixing dependencies: --- Cargo.lock | 36 ++++++++++++++++++++++++++++++++++++ dsp/Cargo.toml | 1 + 2 files changed, 37 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 2c6434f..7fa03f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,6 +217,7 @@ dependencies = [ "libm", "miniconf", "ndarray", + "num", "rand", "serde", ] @@ -457,6 +458,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2178127478ae4ee9be7180bc9c3bffb6354dd7238400db567102f98c413a9f35" +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-complex" version = "0.3.1" @@ -476,6 +490,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" diff --git a/dsp/Cargo.toml b/dsp/Cargo.toml index 1fefdd7..4c675ff 100644 --- a/dsp/Cargo.toml +++ b/dsp/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" libm = "0.2.1" serde = { version = "1.0", features = ["derive"], default-features = false } generic-array = "0.14" +num = { version = "0.3.1", default-features = false } miniconf = "0.1" [dev-dependencies] From 76f2f749f19233c6e2b91cbf92e71962bc839dfc Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 19 Feb 2021 10:57:12 +0100 Subject: [PATCH 26/27] Removing information about legacy server --- README.md | 5 +-- stabilizer.py | 112 -------------------------------------------------- 2 files changed, 2 insertions(+), 115 deletions(-) delete mode 100644 stabilizer.py diff --git a/README.md b/README.md index 7f0967b..017ee7e 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,5 @@ See https://github.com/sinara-hw/Stabilizer ## Protocol -Stabilizer can be configured via newline-delimited JSON over TCP. -It listens on port 1235. [stabilizer.py](stabilizer.py) contains a reference -implementation of the protocol. +Stabilizer can be configured via MQTT under the topic `stabilizer/settings/`. Refer to +[`miniconf`](https://github.com/quartiq/miniconf) for more information about topics. diff --git a/stabilizer.py b/stabilizer.py deleted file mode 100644 index 0f1e206..0000000 --- a/stabilizer.py +++ /dev/null @@ -1,112 +0,0 @@ -import json -import asyncio -from collections import OrderedDict as OD -import logging - -import numpy as np - -logger = logging.getLogger() - - -class StabilizerError(Exception): - pass - - -class StabilizerConfig: - async def connect(self, host, port=1235): - self.reader, self.writer = await asyncio.open_connection(host, port) - - async def set(self, channel, iir): - value = OD([("channel", channel), ("iir", iir.as_dict())]) - request = { - "req": "Write", - "attribute": "stabilizer/iir{}/state".format(channel), - "value": json.dumps(value, separators=[',', ':']).replace('"', "'"), - } - s = json.dumps(request, separators=[',', ':']) - assert "\n" not in s - logger.debug("send %s", s) - self.writer.write(s.encode("ascii") + b"\n") - r = (await self.reader.readline()).decode() - logger.debug("recv %s", r) - ret = json.loads(r, object_pairs_hook=OD) - if ret["code"] != 200: - raise StabilizerError(ret) - return ret - - -class IIR: - t_update = 2e-6 - full_scale = float((1 << 15) - 1) - - def __init__(self): - self.ba = np.zeros(5, np.float32) - self.y_offset = 0. - self.y_min = -self.full_scale - 1 - self.y_max = self.full_scale - - def as_dict(self): - iir = OD() - iir["ba"] = [float(_) for _ in self.ba] - iir["y_offset"] = self.y_offset - iir["y_min"] = self.y_min - iir["y_max"] = self.y_max - return iir - - def configure_pi(self, kp, ki, g=0.): - ki = np.copysign(ki, kp)*self.t_update*2 - g = np.copysign(g, kp) - eps = np.finfo(np.float32).eps - if abs(ki) < eps: - a1, b0, b1 = 0., kp, 0. - else: - if abs(g) < eps: - c = 1. - else: - c = 1./(1. + ki/g) - a1 = 2*c - 1. - b0 = ki*c + kp - b1 = ki*c - a1*kp - if abs(b0 + b1) < eps: - raise ValueError("low integrator gain and/or gain limit") - self.ba[0] = b0 - self.ba[1] = b1 - self.ba[2] = 0. - self.ba[3] = a1 - self.ba[4] = 0. - - def set_x_offset(self, o): - b = self.ba[:3].sum()*self.full_scale - self.y_offset = b*o - - -if __name__ == "__main__": - import argparse - p = argparse.ArgumentParser() - p.add_argument("-s", "--stabilizer", default="10.0.16.99") - p.add_argument("-c", "--channel", default=0, type=int, - help="Stabilizer channel to configure") - p.add_argument("-o", "--offset", default=0., type=float, - help="input offset, in units of full scale") - p.add_argument("-p", "--proportional-gain", default=1., type=float, - help="Proportional gain, in units of 1") - p.add_argument("-i", "--integral-gain", default=0., type=float, - help="Integral gain, in units of Hz, " - "sign taken from proportional-gain") - - args = p.parse_args() - - loop = asyncio.get_event_loop() - # loop.set_debug(True) - logging.basicConfig(level=logging.DEBUG) - - async def main(): - i = IIR() - i.configure_pi(args.proportional_gain, args.integral_gain) - i.set_x_offset(args.offset) - s = StabilizerConfig() - await s.connect(args.stabilizer) - assert args.channel in range(2) - r = await s.set(args.channel, i) - - loop.run_until_complete(main()) From 28db428829a12c11d6dfd8a6cd11e620cd1098db Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Fri, 19 Feb 2021 11:02:46 +0100 Subject: [PATCH 27/27] Fixing bench tests --- dsp/benches/micro.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dsp/benches/micro.rs b/dsp/benches/micro.rs index 8c34256..1f2cc1f 100644 --- a/dsp/benches/micro.rs +++ b/dsp/benches/micro.rs @@ -1,7 +1,7 @@ use core::f32::consts::PI; use dsp::{atan2, cossin}; use dsp::{iir, iir_int}; -use dsp::{pll::PLL, rpll::RPLL}; +use dsp::{PLL, RPLL}; use easybench::bench_env; fn atan2_bench() {