some too detailed adc config

master
Astro 2019-09-14 00:46:48 +02:00
parent f2dcb8b08d
commit 76e30c0f7c
5 changed files with 120 additions and 18 deletions

View File

@ -68,7 +68,7 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
.map(|data| data.data())
}
fn read_reg<R: Register>(&mut self, reg: &R) -> Result<R::Data, AdcError<SPI::Error>> {
pub fn read_reg<R: Register>(&mut self, reg: &R) -> Result<R::Data, AdcError<SPI::Error>> {
let mut reg_data = R::Data::empty();
let address = 0x40 | reg.address();
let mut checksum = Checksum::new(self.checksum_mode);
@ -85,7 +85,7 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
Ok(reg_data)
}
fn write_reg<R: Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> {
pub fn write_reg<R: Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> {
let address = reg.address();
let mut checksum = Checksum::new(match self.checksum_mode {
ChecksumMode::Off => ChecksumMode::Off,
@ -102,7 +102,7 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
Ok(())
}
fn update_reg<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>>
pub fn update_reg<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>>
where
R: Register,
F: FnOnce(&mut R::Data) -> A,

View File

@ -1,4 +1,6 @@
mod regs;
use core::fmt;
pub mod regs;
mod checksum;
pub use checksum::ChecksumMode;
mod adc;
@ -16,6 +18,7 @@ impl<SPI> From<SPI> for AdcError<SPI> {
}
}
#[derive(Clone, Copy, Debug)]
#[repr(u8)]
pub enum Input {
Ain0 = 0,
@ -51,6 +54,27 @@ impl From<u8> for Input {
}
}
impl fmt::Display for Input {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use Input::*;
match self {
Ain0 => "ain0",
Ain1 => "ain1",
Ain2 => "ain2",
Ain3 => "ain3",
Ain4 => "ain4",
TemperaturePos => "temperature+",
TemperatureNeg => "temperature-",
AnalogSupplyPos => "analogsupply+",
AnalogSupplyNeg => "analogsupply-",
RefPos => "ref+",
RefNeg => "ref-",
_ => "<INVALID>",
}.fmt(fmt)
}
}
/// Reference source for ADC conversion
#[repr(u8)]
pub enum RefSource {
@ -74,6 +98,19 @@ impl From<u8> for RefSource {
}
}
impl fmt::Display for RefSource {
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use RefSource::*;
match self {
External => "external",
Internal => "internal",
Avdd1MinusAvss => "avdd1-avss",
_ => "<INVALID>",
}.fmt(fmt)
}
}
#[repr(u8)]
pub enum PostFilter {
F27SPS = 0b010,

View File

@ -40,7 +40,7 @@ macro_rules! def_reg {
}
};
($Reg: ident, $index: ty, $reg: ident, $addr: expr, $size: expr) => {
struct $Reg { pub index: $index, }
pub struct $Reg { pub index: $index, }
impl Register for $Reg {
type Data = $reg::Data;
fn address(&self) -> u8 {

View File

@ -30,6 +30,18 @@ enum Token {
Disable,
#[token = "setup"]
Setup,
#[token = "ref+"]
RefPos,
#[token = "ref-"]
RefNeg,
#[token = "ain+"]
AinPos,
#[token = "ain-"]
AinNeg,
#[token = "unipolar"]
Unipolar,
#[token = "burnout"]
Burnout,
#[regex = "[0-9]+"]
Number,
@ -47,14 +59,24 @@ pub enum Error {
#[derive(Debug)]
pub enum ShowCommand {
ReportMode,
Channel(u8),
}
#[derive(Debug)]
pub enum ChannelCommand {
Enable,
Disable,
Setup(u8),
EnableInput(InputBuffer),
DisableInput(InputBuffer),
}
#[derive(Clone, Copy, Debug)]
pub enum InputBuffer {
RefPos,
RefNeg,
AinPos,
AinNeg,
}
#[derive(Debug)]
@ -99,6 +121,19 @@ impl Command {
};
}
macro_rules! channel_input {
($channel: expr, $input: tt) => {
choice![
End =>
Ok(Command::Show(ShowCommand::Channel($channel))),
Enable =>
end![Command::Channel($channel, ChannelCommand::EnableInput(InputBuffer::$input))],
Disable =>
end![Command::Channel($channel, ChannelCommand::DisableInput(InputBuffer::$input))],
]
};
}
// Command grammar
choice![
Quit => Ok(Command::Quit),
@ -120,6 +155,8 @@ impl Command {
},
]? as u8;
choice![
End =>
Ok(Command::Show(ShowCommand::Channel(channel))),
Enable =>
Ok(Command::Channel(channel, ChannelCommand::Enable)),
Disable =>
@ -134,6 +171,10 @@ impl Command {
]? as u8;
end!(Command::Channel(channel, ChannelCommand::Setup(setup)))
},
RefPos => channel_input!(channel, RefPos),
RefNeg => channel_input!(channel, RefNeg),
AinPos => channel_input!(channel, AinPos),
AinNeg => channel_input!(channel, AinNeg),
]
},
]

View File

@ -231,20 +231,44 @@ fn main() -> ! {
}
if socket.may_recv() && socket.may_send() {
let command = socket.recv(|buf| session.feed(buf));
let output = socket.recv(|buf| session.feed(buf));
match command {
match output {
Ok(SessionOutput::Nothing) => {}
Ok(SessionOutput::Command(Command::Quit)) =>
socket.close(),
Ok(SessionOutput::Command(Command::Report(mode))) => {
let _ = writeln!(socket, "Report mode: {:?}", mode);
}
Ok(SessionOutput::Command(Command::Show(ShowCommand::ReportMode))) => {
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
}
Ok(SessionOutput::Command(command)) => {
let _ = writeln!(socket, "Not implemented: {:?}", command);
Ok(SessionOutput::Command(command)) => match command {
Command::Quit =>
socket.close(),
Command::Report(mode) => {
let _ = writeln!(socket, "Report mode: {:?}", mode);
}
Command::Show(ShowCommand::ReportMode) => {
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
}
Command::Show(ShowCommand::Channel(index)) => {
let _ = writeln!(socket, "Channel {:?} configuration", index);
adc.read_reg(&ad7172::regs::Channel { index })
.map(|data| {
let _ = writeln!(socket, "{} setup={}",
if data.enabled() { "enabled" } else { "disabled" },
data.setup()
);
let _ = writeln!(socket, "ain+={} ain-={}",
data.a_in_pos(), data.a_in_neg()
);
});
adc.read_reg(&ad7172::regs::SetupCon { index })
.map(|data| {
let _ = writeln!(socket, "{} burnout={}, ref={}",
if data.bi_unipolar() { "bipolar" } else { "unipolar" },
if data.burnout_en() { "enabled" } else { "disabled" },
data.ref_sel()
);
});
}
command => {
// TODO: remove for exhaustion check
let _ = writeln!(socket, "Not implemented: {:?}", command);
}
}
Ok(SessionOutput::Error(e)) => {
let _ = writeln!(socket, "Command error: {:?}", e);