Removing MQTT interface

master
Ryan Summers 2021-01-30 15:00:58 +01:00
parent e954ba3c52
commit b73286c188
8 changed files with 45 additions and 125 deletions

7
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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"

View File

@ -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<Settings>,
mqtt_interface: MqttInterface<Settings, NetworkStack>,
// 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)]

View File

@ -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::{

View File

@ -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<

View File

@ -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<T: miniconf::StringSet> {
client: core::cell::RefCell<MqttClient<minimq::consts::U256, NetworkStack>>,
subscribed: bool,
pub settings: core::cell::RefCell<T>,
}
impl<T> MqttInterface<T>
where
T: miniconf::StringSet
{
pub fn new(stack: NetworkStack, settings: T) -> Self {
let client: MqttClient<minimq::consts::U256, _> = 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<Action, ()> {
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<consts::U512> = match command {
"settings" => {
// Handle settings failures
let mut response: String<consts::U512> = 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)
}
}

View File

@ -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;