Adding WIP updates for StringSet

This commit is contained in:
Ryan Summers 2021-01-26 19:14:23 +01:00
parent f0e7c153ba
commit a772ccc38a
8 changed files with 137 additions and 56 deletions

67
Cargo.lock generated
View File

@ -341,13 +341,24 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "derive_stringset"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "dsp" name = "dsp"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"criterion", "criterion",
"libm", "libm",
"miniconf",
"serde", "serde",
"serde-json-core 0.1.0",
] ]
[[package]] [[package]]
@ -375,6 +386,17 @@ dependencies = [
"void", "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]] [[package]]
name = "enum-iterator" name = "enum-iterator"
version = "0.6.0" version = "0.6.0"
@ -556,6 +578,27 @@ dependencies = [
"autocfg", "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]] [[package]]
name = "nb" name = "nb"
version = "0.1.3" version = "0.1.3"
@ -571,6 +614,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
[[package]]
name = "no-std-net"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2178127478ae4ee9be7180bc9c3bffb6354dd7238400db567102f98c413a9f35"
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.14" version = "0.2.14"
@ -641,9 +690,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.7" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -784,6 +833,16 @@ dependencies = [
"serde", "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]] [[package]]
name = "serde_cbor" name = "serde_cbor"
version = "0.11.1" version = "0.11.1"
@ -843,12 +902,14 @@ dependencies = [
"heapless", "heapless",
"log", "log",
"mcp23017", "mcp23017",
"miniconf",
"minimq",
"nb 1.0.0", "nb 1.0.0",
"panic-halt", "panic-halt",
"panic-semihosting", "panic-semihosting",
"paste", "paste",
"serde", "serde",
"serde-json-core", "serde-json-core 0.1.0",
"smoltcp", "smoltcp",
"stm32h7xx-hal", "stm32h7xx-hal",
] ]

View File

@ -45,7 +45,12 @@ enum-iterator = "0.6.0"
paste = "1" paste = "1"
dsp = { path = "dsp" } dsp = { path = "dsp" }
ad9959 = { path = "ad9959" } 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] [dependencies.mcp23017]
git = "https://github.com/mrd0ll4r/mcp23017.git" git = "https://github.com/mrd0ll4r/mcp23017.git"

View File

@ -7,6 +7,12 @@ edition = "2018"
[dependencies] [dependencies]
libm = "0.2.1" libm = "0.2.1"
serde = { version = "1.0", features = ["derive"], default-features = false } 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] [dev-dependencies]
criterion = "0.3" criterion = "0.3"

View File

@ -3,19 +3,16 @@
#![no_main] #![no_main]
#![cfg_attr(feature = "nightly", feature(core_intrinsics))] #![cfg_attr(feature = "nightly", feature(core_intrinsics))]
use stm32h7xx_hal as hal; use miniconf::StringSet;
#[macro_use] use stm32h7xx_hal as hal;
extern crate log;
use rtic::cyccnt::{Instant, U32Ext}; use rtic::cyccnt::{Instant, U32Ext};
use heapless::{consts::*, String}; use stabilizer::hardware;
use stabilizer::{hardware, server};
use dsp::iir; 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; 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! // The number of cascaded IIR biquads per channel. Select 1 or 2!
const IIR_CASCADE_LENGTH: usize = 1; const IIR_CASCADE_LENGTH: usize = 1;
#[derive(miniconf::StringSet)] #[derive(Default, StringSet)]
struct Settings { struct Settings {
afe_gain: [hardware::AfeGain; 2], pub afe_gain: [hardware::AfeGain; 2],
iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2], //iir: [[iir::IIR; IIR_CASCADE_LENGTH]; 2],
} }
#[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)] #[rtic::app(device = stm32h7xx_hal::stm32, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
@ -37,7 +34,6 @@ const APP: () = {
afes: (AFE0, AFE1), afes: (AFE0, AFE1),
adcs: (Adc0Input, Adc1Input), adcs: (Adc0Input, Adc1Input),
dacs: (Dac0Output, Dac1Output), dacs: (Dac0Output, Dac1Output),
net_interface: hardware::Ethernet,
mqtt_interface: hardware::MqttInterface<Settings>, mqtt_interface: hardware::MqttInterface<Settings>,
// Format: iir_state[ch][cascade-no][coeff] // Format: iir_state[ch][cascade-no][coeff]
@ -62,10 +58,10 @@ const APP: () = {
stabilizer.adc_dac_timer.start(); stabilizer.adc_dac_timer.start();
init::LateResources { init::LateResources {
mqtt_interface: hardware::MqttInterface::new(stabilizer.net.stack, Settings::default()),
afes: stabilizer.afes, afes: stabilizer.afes,
adcs: stabilizer.adcs, adcs: stabilizer.adcs,
dacs: stabilizer.dacs, dacs: stabilizer.dacs,
net_interface: stabilizer.net.interface,
} }
} }
@ -130,22 +126,18 @@ const APP: () = {
time += 1; 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()) { match c.resources.mqtt_interface.lock(|interface| interface.update(time).unwrap()) {
Action::Sleep => cortex_m::asm::wfi(), MqttAction::Sleep => cortex_m::asm::wfi(),
Action::Continue => {}, MqttAction::Continue => {},
Action::CommitSettings => c.spawn.settings_update().unwrap(); MqttAction::CommitSettings => c.spawn.settings_update().unwrap(),
} }
} }
} }
#[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])] #[task(priority = 1, resources=[mqtt_interface, afes, iir_ch])]
fn settings_update(c: settings_update::Context) { fn settings_update(c: settings_update::Context) {
let settings = c.resources.mqtt_interface.current_settings(); let settings = c.resources.mqtt_interface.settings.borrow();
c.resources.iir_ch.lock(|iir_ch| *iir_ch = settings.iir); //c.resources.iir_ch.lock(|iir_ch| *iir_ch = settings.iir);
c.resources.afes.0.set_gain(settings.afe_gain[0]); c.resources.afes.0.set_gain(settings.afe_gain[0]);
c.resources.afes.1.set_gain(settings.afe_gain[1]); c.resources.afes.1.set_gain(settings.afe_gain[1]);
} }

View File

@ -527,15 +527,25 @@ pub fn setup(
let sockets = { let sockets = {
// Note(unsafe): Configuration is only called once, so we only access the global // Note(unsafe): Configuration is only called once, so we only access the global
// storage a single time. // 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 mut sockets = smoltcp::socket::SocketSet::new(socket_storage);
let tcp_socket = { let tcp_socket = {
let rx_buffer = {
// Note(unsafe): Configuration is only called once, so we only access the global // Note(unsafe): Configuration is only called once, so we only access the global
// storage a single time. // storage a single time.
let rx_storage = unsafe { &mut NET_STORE.rx_storage[..] }; let storage = unsafe { &mut NET_STORE.rx_storage[..] };
let tx_storage = unsafe { &mut NET_STORE.tx_storage[..] }; smoltcp::socket::TcpSocketBuffer::new(storage)
smoltcp::socket::TcpSocket::new(rx_storage, tx_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); sockets.add(tcp_socket);

View File

@ -17,12 +17,14 @@ mod eeprom;
mod pounder; mod pounder;
mod smoltcp_nal; mod smoltcp_nal;
mod timers; mod timers;
mod mqtt_interface;
pub use adc::{Adc0Input, Adc1Input}; pub use adc::{Adc0Input, Adc1Input};
pub use afe::Gain as AfeGain; pub use afe::Gain as AfeGain;
pub use dac::{Dac0Output, Dac1Output}; pub use dac::{Dac0Output, Dac1Output};
pub use digital_input_stamper::InputStamper; pub use digital_input_stamper::InputStamper;
pub use pounder::DdsOutput; pub use pounder::DdsOutput;
pub use mqtt_interface::{MqttInterface, Action as MqttAction};
// Type alias for the analog front-end (AFE) for ADC0. // Type alias for the analog front-end (AFE) for ADC0.
pub type AFE0 = afe::ProgrammableGainAmplifier< pub type AFE0 = afe::ProgrammableGainAmplifier<
@ -37,7 +39,7 @@ pub type AFE1 = afe::ProgrammableGainAmplifier<
>; >;
// Type alias for the ethernet interface on Stabilizer. // Type alias for the ethernet interface on Stabilizer.
type Ethernet = smoltcp::iface::EthernetInterface< pub type Ethernet = smoltcp::iface::EthernetInterface<
'static, 'static,
'static, 'static,
'static, 'static,

View File

@ -1,6 +1,11 @@
use super::NetworkStack; 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 { pub enum Action {
Continue, Continue,
@ -8,10 +13,10 @@ pub enum Action {
CommitSettings, CommitSettings,
} }
struct MqttInterface<T: miniconf::StringSet> { pub struct MqttInterface<T: miniconf::StringSet> {
client: MqttClient<minimq::consts::U256, NetworkStack>, client: core::cell::RefCell<MqttClient<minimq::consts::U256, NetworkStack>>,
subscribed: bool, subscribed: bool,
settings: T, pub settings: core::cell::RefCell<T>,
} }
impl<T> MqttInterface<T> impl<T> MqttInterface<T>
@ -25,29 +30,25 @@ where
stack).unwrap(); stack).unwrap();
Self { Self {
client, client: core::cell::RefCell::new(client),
subscribed: false, subscribed: false,
settings, settings: core::cell::RefCell::new(settings),
} }
} }
pub fn current_settings(&self) -> &T { pub fn update(&mut self, time: u32) -> Result<Action, ()> {
&self.settings
}
pub fn update(&mut self, time: u32) -> Result<bool, ()> { 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.borrow_mut().is_connected().unwrap() {
self.client.borrow_mut().subscribe("stabilizer/settings/#", &[]).unwrap();
if !self.subscribed && self.client.is_connected().unwrap() { self.client.borrow_mut().subscribe("stabilizer/commit", &[]).unwrap();
self.client.subscribe("stabilizer/settings/#", &[]);
self.client.subscribe("stabilizer/commit", &[]);
} }
let mut commit = false; let mut commit = false;
match self.client.poll(|client, topic, message, properties| { match self.client.borrow_mut().poll(|client, topic, message, properties| {
let split = topic.split('/').iter(); let mut split = topic.split('/');
// TODO: Verify topic ID against our ID. // TODO: Verify topic ID against our ID.
let id = split.next().unwrap(); let id = split.next().unwrap();
@ -57,10 +58,10 @@ where
"settings" => { "settings" => {
// Handle settings failures // Handle settings failures
let mut response: String<consts::U512> = String::new(); let mut response: String<consts::U512> = 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(), Ok(_) => write!(&mut response, "{} written", topic).unwrap(),
Err(error) => { Err(error) => {
write!(&mut response, "Settings failure: {}", error).unwrap(); write!(&mut response, "Settings failure: {:?}", error).unwrap();
} }
}; };
@ -68,8 +69,9 @@ where
}, },
"commit" => { "commit" => {
commit = true; 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 // Publish the response to the request over MQTT using the ResponseTopic property if
@ -81,7 +83,7 @@ where
false false
} }
}).or(Some(&Property::ResponseTopic("stabilizer/log"))).unwrap() { }).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(_) => {}, Ok(_) => {},
@ -90,7 +92,7 @@ where
}; };
let action = if commit { let action = if commit {
Action::Commit Action::CommitSettings
} else if sleep { } else if sleep {
Action::Sleep Action::Sleep
} else { } else {

View File

@ -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( fn open(
&self, &self,
_mode: nal::Mode, _mode: nal::Mode,