Compare commits
4 Commits
426be0d5f1
...
ee4d24de6a
Author | SHA1 | Date |
---|---|---|
Astro | ee4d24de6a | |
Astro | b969f5c057 | |
Astro | 700ab47f0e | |
Astro | b6af43feda |
|
@ -2,7 +2,7 @@ use embedded_hal::digital::v2::OutputPin;
|
||||||
use embedded_hal::blocking::spi::Transfer;
|
use embedded_hal::blocking::spi::Transfer;
|
||||||
use super::checksum::{ChecksumMode, Checksum};
|
use super::checksum::{ChecksumMode, Checksum};
|
||||||
use super::AdcError;
|
use super::AdcError;
|
||||||
use super::{regs, regs::RegisterData, Input, RefSource};
|
use super::{regs, regs::RegisterData, Input};
|
||||||
|
|
||||||
/// AD7172-2 implementation
|
/// AD7172-2 implementation
|
||||||
///
|
///
|
||||||
|
|
|
@ -63,16 +63,19 @@ macro_rules! def_reg {
|
||||||
|
|
||||||
macro_rules! reg_bit {
|
macro_rules! reg_bit {
|
||||||
($getter: ident, $byte: expr, $bit: expr, $doc: expr) => {
|
($getter: ident, $byte: expr, $bit: expr, $doc: expr) => {
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $getter(&self) -> bool {
|
pub fn $getter(&self) -> bool {
|
||||||
self.0[$byte].get_bit($bit)
|
self.0[$byte].get_bit($bit)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($getter: ident, $setter: ident, $byte: expr, $bit: expr, $doc: expr) => {
|
($getter: ident, $setter: ident, $byte: expr, $bit: expr, $doc: expr) => {
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $getter(&self) -> bool {
|
pub fn $getter(&self) -> bool {
|
||||||
self.0[$byte].get_bit($bit)
|
self.0[$byte].get_bit($bit)
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $setter(&mut self, value: bool) {
|
pub fn $setter(&mut self, value: bool) {
|
||||||
self.0[$byte].set_bit($bit, value);
|
self.0[$byte].set_bit($bit, value);
|
||||||
|
@ -82,32 +85,38 @@ macro_rules! reg_bit {
|
||||||
|
|
||||||
macro_rules! reg_bits {
|
macro_rules! reg_bits {
|
||||||
($getter: ident, $byte: expr, $bits: expr, $doc: expr) => {
|
($getter: ident, $byte: expr, $bits: expr, $doc: expr) => {
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $getter(&self) -> u8 {
|
pub fn $getter(&self) -> u8 {
|
||||||
self.0[$byte].get_bits($bits)
|
self.0[$byte].get_bits($bits)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($getter: ident, $setter: ident, $byte: expr, $bits: expr, $doc: expr) => {
|
($getter: ident, $setter: ident, $byte: expr, $bits: expr, $doc: expr) => {
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $getter(&self) -> u8 {
|
pub fn $getter(&self) -> u8 {
|
||||||
self.0[$byte].get_bits($bits)
|
self.0[$byte].get_bits($bits)
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $setter(&mut self, value: u8) {
|
pub fn $setter(&mut self, value: u8) {
|
||||||
self.0[$byte].set_bits($bits, value);
|
self.0[$byte].set_bits($bits, value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($getter: ident, $byte: expr, $bits: expr, $ty: ty, $doc: expr) => {
|
($getter: ident, $byte: expr, $bits: expr, $ty: ty, $doc: expr) => {
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $getter(&self) -> $ty {
|
pub fn $getter(&self) -> $ty {
|
||||||
self.0[$byte].get_bits($bits) as $ty
|
self.0[$byte].get_bits($bits) as $ty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($getter: ident, $setter: ident, $byte: expr, $bits: expr, $ty: ty, $doc: expr) => {
|
($getter: ident, $setter: ident, $byte: expr, $bits: expr, $ty: ty, $doc: expr) => {
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $getter(&self) -> $ty {
|
pub fn $getter(&self) -> $ty {
|
||||||
self.0[$byte].get_bits($bits).into()
|
self.0[$byte].get_bits($bits).into()
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
#[doc = $doc]
|
#[doc = $doc]
|
||||||
pub fn $setter(&mut self, value: $ty) {
|
pub fn $setter(&mut self, value: $ty) {
|
||||||
self.0[$byte].set_bits($bits, value as u8);
|
self.0[$byte].set_bits($bits, value as u8);
|
||||||
|
@ -156,11 +165,13 @@ impl channel::Data {
|
||||||
reg_bits!(setup, set_setup, 0, 4..=5, "Setup number");
|
reg_bits!(setup, set_setup, 0, 4..=5, "Setup number");
|
||||||
|
|
||||||
/// Which input is connected to positive input of this channel
|
/// Which input is connected to positive input of this channel
|
||||||
|
#[allow(unused)]
|
||||||
pub fn a_in_pos(&self) -> Input {
|
pub fn a_in_pos(&self) -> Input {
|
||||||
((self.0[0].get_bits(0..=1) << 3) |
|
((self.0[0].get_bits(0..=1) << 3) |
|
||||||
self.0[1].get_bits(5..=7)).into()
|
self.0[1].get_bits(5..=7)).into()
|
||||||
}
|
}
|
||||||
/// Set which input is connected to positive input of this channel
|
/// Set which input is connected to positive input of this channel
|
||||||
|
#[allow(unused)]
|
||||||
pub fn set_a_in_pos(&mut self, value: Input) {
|
pub fn set_a_in_pos(&mut self, value: Input) {
|
||||||
let value = value as u8;
|
let value = value as u8;
|
||||||
self.0[0].set_bits(0..=1, value >> 3);
|
self.0[0].set_bits(0..=1, value >> 3);
|
||||||
|
@ -207,11 +218,13 @@ impl filt_con::Data {
|
||||||
|
|
||||||
def_reg!(Offset, u8, offset, 0x30, 3);
|
def_reg!(Offset, u8, offset, 0x30, 3);
|
||||||
impl offset::Data {
|
impl offset::Data {
|
||||||
|
#[allow(unused)]
|
||||||
pub fn offset(&self) -> u32 {
|
pub fn offset(&self) -> u32 {
|
||||||
(u32::from(self.0[0]) << 16) |
|
(u32::from(self.0[0]) << 16) |
|
||||||
(u32::from(self.0[1]) << 8) |
|
(u32::from(self.0[1]) << 8) |
|
||||||
u32::from(self.0[2])
|
u32::from(self.0[2])
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
pub fn set_offset(&mut self, value: u32) {
|
pub fn set_offset(&mut self, value: u32) {
|
||||||
self.0[0] = (value >> 16) as u8;
|
self.0[0] = (value >> 16) as u8;
|
||||||
self.0[1] = (value >> 8) as u8;
|
self.0[1] = (value >> 8) as u8;
|
||||||
|
@ -221,11 +234,13 @@ impl offset::Data {
|
||||||
|
|
||||||
def_reg!(Gain, u8, gain, 0x38, 3);
|
def_reg!(Gain, u8, gain, 0x38, 3);
|
||||||
impl gain::Data {
|
impl gain::Data {
|
||||||
|
#[allow(unused)]
|
||||||
pub fn gain(&self) -> u32 {
|
pub fn gain(&self) -> u32 {
|
||||||
(u32::from(self.0[0]) << 16) |
|
(u32::from(self.0[0]) << 16) |
|
||||||
(u32::from(self.0[1]) << 8) |
|
(u32::from(self.0[1]) << 8) |
|
||||||
u32::from(self.0[2])
|
u32::from(self.0[2])
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
pub fn set_gain(&mut self, value: u32) {
|
pub fn set_gain(&mut self, value: u32) {
|
||||||
self.0[0] = (value >> 16) as u8;
|
self.0[0] = (value >> 16) as u8;
|
||||||
self.0[1] = (value >> 8) as u8;
|
self.0[1] = (value >> 8) as u8;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
use core::fmt;
|
||||||
use nom::{
|
use nom::{
|
||||||
IResult,
|
IResult,
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::{tag, take_while1},
|
bytes::complete::{tag, take_while1},
|
||||||
character::{is_digit, complete::char},
|
character::{is_digit, complete::char},
|
||||||
combinator::{map, value},
|
combinator::{map, value},
|
||||||
sequence::{preceded, tuple, Tuple},
|
sequence::preceded,
|
||||||
multi::fold_many1,
|
multi::fold_many1,
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
};
|
};
|
||||||
|
@ -12,7 +13,7 @@ use btoi::{btoi, ParseIntegerError};
|
||||||
use super::session::ReportMode;
|
use super::session::ReportMode;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Parser(ErrorKind),
|
Parser(ErrorKind),
|
||||||
Incomplete,
|
Incomplete,
|
||||||
|
@ -39,9 +40,43 @@ impl From<ParseIntegerError> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match self {
|
||||||
|
Error::Incomplete =>
|
||||||
|
"incomplete input".fmt(fmt),
|
||||||
|
Error::UnexpectedInput(c) => {
|
||||||
|
"unexpected input: ".fmt(fmt)?;
|
||||||
|
c.fmt(fmt)
|
||||||
|
}
|
||||||
|
Error::Parser(e) => {
|
||||||
|
"parser: ".fmt(fmt)?;
|
||||||
|
(e as &dyn core::fmt::Debug).fmt(fmt)
|
||||||
|
}
|
||||||
|
Error::ParseInteger(e) => {
|
||||||
|
"parsing number: ".fmt(fmt)?;
|
||||||
|
e.fmt(fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ShowCommand {
|
pub enum ShowCommand {
|
||||||
ReportMode,
|
ReportMode,
|
||||||
|
Pid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum PidParameter {
|
||||||
|
Target,
|
||||||
|
KP,
|
||||||
|
KI,
|
||||||
|
KD,
|
||||||
|
OutputMin,
|
||||||
|
OutputMax,
|
||||||
|
IntegralMin,
|
||||||
|
IntegralMax,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -53,6 +88,10 @@ pub enum Command {
|
||||||
width: u32,
|
width: u32,
|
||||||
total: u32,
|
total: u32,
|
||||||
},
|
},
|
||||||
|
Pid {
|
||||||
|
parameter: PidParameter,
|
||||||
|
value: f32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fn whitespace(input: &[u8]) -> IResult<&[u8], ()> {
|
fn whitespace(input: &[u8]) -> IResult<&[u8], ()> {
|
||||||
|
@ -113,17 +152,54 @@ fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
Ok((input, Ok(Command::Pwm { width, total })))
|
Ok((input, Ok(Command::Pwm { width, total })))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command(input: &[u8]) -> IResult<&[u8], Command> {
|
fn pid_parameter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
alt((value(Command::Quit, tag("quit")),
|
let (input, parameter) =
|
||||||
report
|
alt((value(PidParameter::Target, tag("target")),
|
||||||
|
value(PidParameter::KP, tag("kp")),
|
||||||
|
value(PidParameter::KI, tag("ki")),
|
||||||
|
value(PidParameter::KD, tag("kd")),
|
||||||
|
value(PidParameter::OutputMin, tag("output_min")),
|
||||||
|
value(PidParameter::OutputMax, tag("output_max")),
|
||||||
|
value(PidParameter::IntegralMin, tag("integral_min")),
|
||||||
|
value(PidParameter::IntegralMax, tag("integral_max"))
|
||||||
|
))(input)?;
|
||||||
|
let (input, _) = whitespace(input)?;
|
||||||
|
// TODO: parse float
|
||||||
|
let (input, value) = unsigned(input)?;
|
||||||
|
let result = value
|
||||||
|
.map(|value| Command::Pid { parameter, value: value as f32 })
|
||||||
|
.map_err(|e| e.into());
|
||||||
|
Ok((input, result))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pid(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
|
let (input, _) = tag("pid")(input)?;
|
||||||
|
let (input, _) = whitespace(input)?;
|
||||||
|
|
||||||
|
alt((
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
pid_parameter
|
||||||
|
),
|
||||||
|
|input| Ok((input, Ok(Command::Show(ShowCommand::Pid))))
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
|
alt((value(Ok(Command::Quit), tag("quit")),
|
||||||
|
|input| report(input).map(|(input, command)| {
|
||||||
|
(input, Ok(command))
|
||||||
|
}),
|
||||||
|
pwm,
|
||||||
|
pid,
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn parse(input: &[u8]) -> Result<Self, Error> {
|
pub fn parse(input: &[u8]) -> Result<Self, Error> {
|
||||||
match command(input) {
|
match command(input) {
|
||||||
Ok((b"", command)) =>
|
Ok((b"", result)) =>
|
||||||
Ok(command),
|
result,
|
||||||
Ok((input_remain, _)) =>
|
Ok((input_remain, _)) =>
|
||||||
Err(Error::UnexpectedInput(input_remain[0])),
|
Err(Error::UnexpectedInput(input_remain[0])),
|
||||||
Err(e) =>
|
Err(e) =>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn, proc_macro_hygiene)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use cortex_m_rt::{entry, heap_start};
|
use cortex_m_rt::entry;
|
||||||
use core::fmt::{self, Write};
|
use core::fmt::{self, Write};
|
||||||
use smoltcp::time::Instant;
|
use smoltcp::time::Instant;
|
||||||
use smoltcp::wire::{IpCidr, IpAddress, EthernetAddress};
|
use smoltcp::wire::{IpCidr, IpAddress, EthernetAddress};
|
||||||
|
@ -41,6 +41,7 @@ use command_parser::{Command, ShowCommand};
|
||||||
mod session;
|
mod session;
|
||||||
use self::session::{Session, SessionOutput};
|
use self::session::{Session, SessionOutput};
|
||||||
mod ad7172;
|
mod ad7172;
|
||||||
|
mod pid;
|
||||||
|
|
||||||
pub struct UART0;
|
pub struct UART0;
|
||||||
|
|
||||||
|
@ -77,6 +78,15 @@ macro_rules! create_socket {
|
||||||
|
|
||||||
/// In nanoseconds
|
/// In nanoseconds
|
||||||
const REPORT_INTERVAL: u64 = 100_000;
|
const REPORT_INTERVAL: u64 = 100_000;
|
||||||
|
const DEFAULT_PID_PARAMETERS: pid::Parameters = pid::Parameters {
|
||||||
|
kp: 1.0,
|
||||||
|
ki: 1.0,
|
||||||
|
kd: 1.0,
|
||||||
|
output_min: 0.0,
|
||||||
|
output_max: 0xffff as f32,
|
||||||
|
integral_min: 0.0,
|
||||||
|
integral_max: 0xffff as f32,
|
||||||
|
};
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
@ -143,6 +153,8 @@ fn main() -> ! {
|
||||||
// SENS1_{P,N}
|
// SENS1_{P,N}
|
||||||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
||||||
|
|
||||||
|
let mut pid = pid::Controller::new(DEFAULT_PID_PARAMETERS.clone());
|
||||||
|
|
||||||
let mut hardware_addr = EthernetAddress(board::get_mac_address());
|
let mut hardware_addr = EthernetAddress(board::get_mac_address());
|
||||||
if hardware_addr.is_multicast() {
|
if hardware_addr.is_multicast() {
|
||||||
println!("programmed MAC address is invalid, using default");
|
println!("programmed MAC address is invalid, using default");
|
||||||
|
@ -200,7 +212,7 @@ fn main() -> ! {
|
||||||
// ADC input
|
// ADC input
|
||||||
adc.data_ready()
|
adc.data_ready()
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
writeln!(stdout, "ADC error: {:?}", e);
|
writeln!(stdout, "ADC error: {:?}", e).unwrap();
|
||||||
None
|
None
|
||||||
}).map(|channel| {
|
}).map(|channel| {
|
||||||
let data = adc.read_data().unwrap();
|
let data = adc.read_data().unwrap();
|
||||||
|
@ -241,21 +253,61 @@ fn main() -> ! {
|
||||||
if socket.may_recv() && socket.may_send() {
|
if socket.may_recv() && socket.may_send() {
|
||||||
let output = socket.recv(|buf| session.feed(buf));
|
let output = socket.recv(|buf| session.feed(buf));
|
||||||
|
|
||||||
|
// TODO: use "{}" to display pretty errors
|
||||||
match output {
|
match output {
|
||||||
Ok(SessionOutput::Nothing) => {}
|
Ok(SessionOutput::Nothing) => {}
|
||||||
Ok(SessionOutput::Command(command)) => match command {
|
Ok(SessionOutput::Command(command)) => match command {
|
||||||
Command::Quit =>
|
Command::Quit =>
|
||||||
socket.close(),
|
socket.close(),
|
||||||
Command::Report(mode) => {
|
Command::Report(mode) => {
|
||||||
let _ = writeln!(socket, "Report mode: {:?}", mode);
|
let _ = writeln!(socket, "Report mode: {}", mode);
|
||||||
}
|
}
|
||||||
Command::Show(ShowCommand::ReportMode) => {
|
Command::Show(ShowCommand::ReportMode) => {
|
||||||
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
|
let _ = writeln!(socket, "Report mode: {}", session.report_mode());
|
||||||
|
}
|
||||||
|
Command::Show(ShowCommand::Pid) => {
|
||||||
|
let _ = writeln!(socket, "PID settings");
|
||||||
|
let _ = writeln!(socket, "target: {:.4}", pid.get_target());
|
||||||
|
let p = pid.get_parameters();
|
||||||
|
macro_rules! out {
|
||||||
|
($p: tt) => {
|
||||||
|
let _ = writeln!(socket, "{}: {:.4}", stringify!($p), p.$p);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
out!(kp);
|
||||||
|
out!(ki);
|
||||||
|
out!(kd);
|
||||||
|
out!(output_min);
|
||||||
|
out!(output_max);
|
||||||
|
out!(integral_min);
|
||||||
|
out!(integral_max);
|
||||||
}
|
}
|
||||||
Command::Pwm { width, total } => {
|
Command::Pwm { width, total } => {
|
||||||
board::set_timer_pwm(width, total);
|
board::set_timer_pwm(width, total);
|
||||||
let _ = writeln!(socket, "PWM duty cycle: {}/{}", width, total);
|
let _ = writeln!(socket, "PWM duty cycle: {}/{}", width, total);
|
||||||
}
|
}
|
||||||
|
Command::Pid { parameter, value } => {
|
||||||
|
use command_parser::PidParameter::*;
|
||||||
|
match parameter {
|
||||||
|
Target =>
|
||||||
|
pid.set_target(value),
|
||||||
|
KP =>
|
||||||
|
pid.update_parameters(|parameters| parameters.kp = value),
|
||||||
|
KI =>
|
||||||
|
pid.update_parameters(|parameters| parameters.ki = value),
|
||||||
|
KD =>
|
||||||
|
pid.update_parameters(|parameters| parameters.kd = value),
|
||||||
|
OutputMin =>
|
||||||
|
pid.update_parameters(|parameters| parameters.output_min = value),
|
||||||
|
OutputMax =>
|
||||||
|
pid.update_parameters(|parameters| parameters.output_max = value),
|
||||||
|
IntegralMin =>
|
||||||
|
pid.update_parameters(|parameters| parameters.integral_min = value),
|
||||||
|
IntegralMax =>
|
||||||
|
pid.update_parameters(|parameters| parameters.integral_max = value),
|
||||||
|
}
|
||||||
|
let _ = writeln!(socket, "PID parameter updated");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(SessionOutput::Error(e)) => {
|
Ok(SessionOutput::Error(e)) => {
|
||||||
let _ = writeln!(socket, "Command error: {:?}", e);
|
let _ = writeln!(socket, "Command error: {:?}", e);
|
||||||
|
|
|
@ -56,10 +56,22 @@ impl Controller {
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_target(&mut self) -> f32 {
|
||||||
|
self.target
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_target(&mut self, target: f32) {
|
pub fn set_target(&mut self, target: f32) {
|
||||||
self.target = target;
|
self.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_parameters(&self) -> &Parameters {
|
||||||
|
&self.parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_parameters<F: FnOnce(&mut Parameters)>(&mut self, f: F) {
|
||||||
|
f(&mut self.parameters);
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.integral = 0.0;
|
self.integral = 0.0;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
|
use core::fmt;
|
||||||
use super::command_parser::{Command, Error as ParserError};
|
use super::command_parser::{Command, Error as ParserError};
|
||||||
|
|
||||||
const MAX_LINE_LEN: usize = 64;
|
const MAX_LINE_LEN: usize = 64;
|
||||||
|
@ -60,6 +61,16 @@ pub enum ReportMode {
|
||||||
Continuous,
|
Continuous,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ReportMode {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match self {
|
||||||
|
ReportMode::Off => "off",
|
||||||
|
ReportMode::Once => "once",
|
||||||
|
ReportMode::Continuous => "continuous",
|
||||||
|
}.fmt(fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum SessionOutput {
|
pub enum SessionOutput {
|
||||||
Nothing,
|
Nothing,
|
||||||
Command(Command),
|
Command(Command),
|
||||||
|
|
Loading…
Reference in New Issue