Compare commits
No commits in common. "1395e8b410afdf70c0331099ef3097114bb8bf80" and "f2dcb8b08dbcdedffd27d0063ad47c06ee986a4e" have entirely different histories.
1395e8b410
...
f2dcb8b08d
|
@ -31,11 +31,6 @@ dependencies = [
|
||||||
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "0.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bare-metal"
|
name = "bare-metal"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
@ -54,14 +49,6 @@ name = "bitflags"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "btoi"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "build_const"
|
name = "build_const"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -161,7 +148,6 @@ dependencies = [
|
||||||
"alloc-cortex-m 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"alloc-cortex-m 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"btoi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cortex-m 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cortex-m 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cortex-m-rt 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -225,14 +211,6 @@ name = "nb"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.30"
|
version = "0.4.30"
|
||||||
|
@ -409,11 +387,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a316c7ea8e1e9ece54862c992def5a7ac14de9f5832b69d71760680efeeefa"
|
"checksum aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a316c7ea8e1e9ece54862c992def5a7ac14de9f5832b69d71760680efeeefa"
|
||||||
"checksum alloc-cortex-m 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d5f7d01bc93ce089de636f946f7f1fdc5e5d751732367e019c9755440e7aef4"
|
"checksum alloc-cortex-m 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d5f7d01bc93ce089de636f946f7f1fdc5e5d751732367e019c9755440e7aef4"
|
||||||
"checksum as-slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "293dac66b274fab06f95e7efb05ec439a6b70136081ea522d270bc351ae5bb27"
|
"checksum as-slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "293dac66b274fab06f95e7efb05ec439a6b70136081ea522d270bc351ae5bb27"
|
||||||
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
|
|
||||||
"checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
"checksum bare-metal 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
|
||||||
"checksum bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
|
"checksum bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
|
||||||
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
|
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
|
||||||
"checksum btoi 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e4ced8205e70d9e553d008d53ded735808fa6133597318d48f74fc2bf9861471"
|
|
||||||
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
|
||||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||||
"checksum cortex-m 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3df5de9a9829f2ccb7defa8945fa020c6614cd2f6ba9b5f33db9241dcc01985e"
|
"checksum cortex-m 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3df5de9a9829f2ccb7defa8945fa020c6614cd2f6ba9b5f33db9241dcc01985e"
|
||||||
|
@ -432,7 +408,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum logos-derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "13ff1b1068db09ee21d12baf55eccc0900a781a735273e0a606f6f4fbb32a322"
|
"checksum logos-derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "13ff1b1068db09ee21d12baf55eccc0900a781a735273e0a606f6f4fbb32a322"
|
||||||
"checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7"
|
"checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7"
|
||||||
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
||||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
|
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
|
||||||
|
|
|
@ -21,7 +21,6 @@ bit_field = "0.10"
|
||||||
bare-metal = "0.2"
|
bare-metal = "0.2"
|
||||||
logos = { version = "~0.9", default-features = false, features = ["export_derive"] }
|
logos = { version = "~0.9", default-features = false, features = ["export_derive"] }
|
||||||
alloc-cortex-m = "0.3"
|
alloc-cortex-m = "0.3"
|
||||||
btoi = { version = "~0.4", default-features = false }
|
|
||||||
|
|
||||||
[dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
git = "https://github.com/m-labs/smoltcp"
|
git = "https://github.com/m-labs/smoltcp"
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
||||||
/// AD7172-2 implementation
|
/// AD7172-2 implementation
|
||||||
///
|
///
|
||||||
|
@ -27,45 +27,32 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
|
||||||
|
|
||||||
/// `0x00DX` for AD7271-2
|
/// `0x00DX` for AD7271-2
|
||||||
pub fn identify(&mut self) -> Result<u16, AdcError<SPI::Error>> {
|
pub fn identify(&mut self) -> Result<u16, AdcError<SPI::Error>> {
|
||||||
self.read_reg(®s::Id)
|
self.read_reg(&Id)
|
||||||
.map(|id| id.id())
|
.map(|id| id.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_checksum_mode(&mut self, mode: ChecksumMode) -> Result<(), AdcError<SPI::Error>> {
|
pub fn set_checksum_mode(&mut self, mode: ChecksumMode) -> Result<(), AdcError<SPI::Error>> {
|
||||||
// Cannot use update_reg() here because checksum_mode is
|
let mut ifmode = self.read_reg(&IfMode)?;
|
||||||
// updated between read_reg() and write_reg().
|
|
||||||
let mut ifmode = self.read_reg(®s::IfMode)?;
|
|
||||||
ifmode.set_crc(mode);
|
ifmode.set_crc(mode);
|
||||||
self.checksum_mode = mode;
|
self.checksum_mode = mode;
|
||||||
self.write_reg(®s::IfMode, &mut ifmode)?;
|
self.write_reg(&IfMode, &mut ifmode)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_channel(
|
// pub fn setup(&mut self) -> Result<(), SPI::Error> {
|
||||||
&mut self, index: u8, in_pos: Input, in_neg: Input
|
// let mut buf = [0, 0, 0];
|
||||||
) -> Result<(), AdcError<SPI::Error>> {
|
// adc.write_reg(Register::AdcMode, &mut buf)?;
|
||||||
self.update_reg(®s::SetupCon { index }, |data| {
|
// let mut buf = [0, 1, 0];
|
||||||
data.set_bi_unipolar(false);
|
// adc.write_reg(Register::IfMode, &mut buf)?;
|
||||||
})?;
|
// let mut buf = [0, 0, 0];
|
||||||
self.update_reg(®s::FiltCon { index }, |data| {
|
// adc.write_reg(Register::GpioCon, &mut buf)?;
|
||||||
// 10 Hz data rate
|
|
||||||
data.set_odr(0b10011);
|
// Ok(())
|
||||||
})?;
|
// }
|
||||||
// let mut offset = <regs::Offset as regs::Register>::Data::empty();
|
|
||||||
// offset.set_offset(0);
|
|
||||||
// self.write_reg(®s::Offset { index }, &mut offset);
|
|
||||||
self.update_reg(®s::Channel { index }, |data| {
|
|
||||||
data.set_setup(index);
|
|
||||||
data.set_enabled(true);
|
|
||||||
data.set_a_in_pos(in_pos);
|
|
||||||
data.set_a_in_neg(in_neg);
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the channel the data is from
|
/// Returns the channel the data is from
|
||||||
pub fn data_ready(&mut self) -> Result<Option<u8>, AdcError<SPI::Error>> {
|
pub fn data_ready(&mut self) -> Result<Option<u8>, AdcError<SPI::Error>> {
|
||||||
self.read_reg(®s::Status)
|
self.read_reg(&Status)
|
||||||
.map(|status| {
|
.map(|status| {
|
||||||
if status.ready() {
|
if status.ready() {
|
||||||
Some(status.channel())
|
Some(status.channel())
|
||||||
|
@ -77,11 +64,11 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
|
||||||
|
|
||||||
/// Get data
|
/// Get data
|
||||||
pub fn read_data(&mut self) -> Result<u32, AdcError<SPI::Error>> {
|
pub fn read_data(&mut self) -> Result<u32, AdcError<SPI::Error>> {
|
||||||
self.read_reg(®s::Data)
|
self.read_reg(&Data)
|
||||||
.map(|data| data.data())
|
.map(|data| data.data())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_reg<R: regs::Register>(&mut self, reg: &R) -> Result<R::Data, AdcError<SPI::Error>> {
|
fn read_reg<R: Register>(&mut self, reg: &R) -> Result<R::Data, AdcError<SPI::Error>> {
|
||||||
let mut reg_data = R::Data::empty();
|
let mut reg_data = R::Data::empty();
|
||||||
let address = 0x40 | reg.address();
|
let address = 0x40 | reg.address();
|
||||||
let mut checksum = Checksum::new(self.checksum_mode);
|
let mut checksum = Checksum::new(self.checksum_mode);
|
||||||
|
@ -98,7 +85,7 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
|
||||||
Ok(reg_data)
|
Ok(reg_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_reg<R: regs::Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> {
|
fn write_reg<R: Register>(&mut self, reg: &R, reg_data: &mut R::Data) -> Result<(), AdcError<SPI::Error>> {
|
||||||
let address = reg.address();
|
let address = reg.address();
|
||||||
let mut checksum = Checksum::new(match self.checksum_mode {
|
let mut checksum = Checksum::new(match self.checksum_mode {
|
||||||
ChecksumMode::Off => ChecksumMode::Off,
|
ChecksumMode::Off => ChecksumMode::Off,
|
||||||
|
@ -117,7 +104,7 @@ impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
|
||||||
|
|
||||||
fn update_reg<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>>
|
fn update_reg<R, F, A>(&mut self, reg: &R, f: F) -> Result<A, AdcError<SPI::Error>>
|
||||||
where
|
where
|
||||||
R: regs::Register,
|
R: Register,
|
||||||
F: FnOnce(&mut R::Data) -> A,
|
F: FnOnce(&mut R::Data) -> A,
|
||||||
{
|
{
|
||||||
let mut reg_data = self.read_reg(reg)?;
|
let mut reg_data = self.read_reg(reg)?;
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use core::fmt;
|
mod regs;
|
||||||
|
|
||||||
pub mod regs;
|
|
||||||
mod checksum;
|
mod checksum;
|
||||||
pub use checksum::ChecksumMode;
|
pub use checksum::ChecksumMode;
|
||||||
mod adc;
|
mod adc;
|
||||||
|
@ -18,7 +16,6 @@ impl<SPI> From<SPI> for AdcError<SPI> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Input {
|
pub enum Input {
|
||||||
Ain0 = 0,
|
Ain0 = 0,
|
||||||
|
@ -54,27 +51,6 @@ 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
|
/// Reference source for ADC conversion
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum RefSource {
|
pub enum RefSource {
|
||||||
|
@ -98,19 +74,6 @@ 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)]
|
#[repr(u8)]
|
||||||
pub enum PostFilter {
|
pub enum PostFilter {
|
||||||
F27SPS = 0b010,
|
F27SPS = 0b010,
|
||||||
|
|
|
@ -39,12 +39,12 @@ macro_rules! def_reg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($Reg: ident, u8, $reg: ident, $addr: expr, $size: expr) => {
|
($Reg: ident, $index: ty, $reg: ident, $addr: expr, $size: expr) => {
|
||||||
pub struct $Reg { pub index: u8, }
|
struct $Reg { pub index: $index, }
|
||||||
impl Register for $Reg {
|
impl Register for $Reg {
|
||||||
type Data = $reg::Data;
|
type Data = $reg::Data;
|
||||||
fn address(&self) -> u8 {
|
fn address(&self) -> u8 {
|
||||||
$addr + self.index
|
$addr + (self.index as u8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mod $reg {
|
mod $reg {
|
||||||
|
|
|
@ -174,22 +174,6 @@ pub fn init() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timer_pwm(matchr: u32, ilr: u32) {
|
|
||||||
macro_rules! set_timer_pwm {
|
|
||||||
($T: tt) => (
|
|
||||||
let timer = unsafe { &*tm4c129x::$T::ptr() };
|
|
||||||
timer.tamatchr.write(|w| unsafe { w.bits(matchr) });
|
|
||||||
timer.tbmatchr.write(|w| unsafe { w.bits(matchr) });
|
|
||||||
timer.tailr.write(|w| unsafe { w.bits(ilr) });
|
|
||||||
timer.tbilr.write(|w| unsafe { w.bits(ilr) });
|
|
||||||
)
|
|
||||||
}
|
|
||||||
set_timer_pwm!(TIMER2);
|
|
||||||
set_timer_pwm!(TIMER3);
|
|
||||||
set_timer_pwm!(TIMER4);
|
|
||||||
set_timer_pwm!(TIMER5);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mac_address() -> [u8; 6] {
|
pub fn get_mac_address() -> [u8; 6] {
|
||||||
let (userreg0, userreg1) = cortex_m::interrupt::free(|_cs| {
|
let (userreg0, userreg1) = cortex_m::interrupt::free(|_cs| {
|
||||||
let flashctl = unsafe { &*tm4c129x::FLASH_CTRL::ptr() };
|
let flashctl = unsafe { &*tm4c129x::FLASH_CTRL::ptr() };
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use logos::Logos;
|
use logos::Logos;
|
||||||
use btoi::{btoi, ParseIntegerError};
|
|
||||||
use super::session::ReportMode;
|
use super::session::ReportMode;
|
||||||
|
|
||||||
#[derive(Logos, Debug, PartialEq)]
|
#[derive(Logos, Debug, PartialEq)]
|
||||||
|
@ -11,6 +10,10 @@ enum Token {
|
||||||
|
|
||||||
#[token = "Quit"]
|
#[token = "Quit"]
|
||||||
Quit,
|
Quit,
|
||||||
|
#[token = "show"]
|
||||||
|
Show,
|
||||||
|
#[token = "channel"]
|
||||||
|
Channel,
|
||||||
#[token = "report"]
|
#[token = "report"]
|
||||||
Report,
|
Report,
|
||||||
#[token = "mode"]
|
#[token = "mode"]
|
||||||
|
@ -21,8 +24,12 @@ enum Token {
|
||||||
Once,
|
Once,
|
||||||
#[token = "continuous"]
|
#[token = "continuous"]
|
||||||
Continuous,
|
Continuous,
|
||||||
#[token = "pwm"]
|
#[token = "enable"]
|
||||||
Pwm,
|
Enable,
|
||||||
|
#[token = "disable"]
|
||||||
|
Disable,
|
||||||
|
#[token = "setup"]
|
||||||
|
Setup,
|
||||||
|
|
||||||
#[regex = "[0-9]+"]
|
#[regex = "[0-9]+"]
|
||||||
Number,
|
Number,
|
||||||
|
@ -33,13 +40,8 @@ pub enum Error {
|
||||||
Parser,
|
Parser,
|
||||||
UnexpectedEnd,
|
UnexpectedEnd,
|
||||||
UnexpectedToken(Token),
|
UnexpectedToken(Token),
|
||||||
ParseInteger(ParseIntegerError)
|
NoSuchChannel,
|
||||||
}
|
NoSuchSetup,
|
||||||
|
|
||||||
impl From<ParseIntegerError> for Error {
|
|
||||||
fn from(e: ParseIntegerError) -> Self {
|
|
||||||
Error::ParseInteger(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -47,17 +49,27 @@ pub enum ShowCommand {
|
||||||
ReportMode,
|
ReportMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ChannelCommand {
|
||||||
|
Enable,
|
||||||
|
Disable,
|
||||||
|
Setup(u8),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Quit,
|
Quit,
|
||||||
Show(ShowCommand),
|
Show(ShowCommand),
|
||||||
Report(ReportMode),
|
Report(ReportMode),
|
||||||
Pwm {
|
Channel(u8, ChannelCommand),
|
||||||
pwm_match: u32,
|
|
||||||
pwm_reload: u32,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CHANNEL_IDS: &'static [&'static str] = &[
|
||||||
|
"0", "1", "2", "3",
|
||||||
|
];
|
||||||
|
const SETUP_IDS: &'static [&'static str] = CHANNEL_IDS;
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn parse(input: &str) -> Result<Self, Error> {
|
pub fn parse(input: &str) -> Result<Self, Error> {
|
||||||
let mut lexer = Token::lexer(input);
|
let mut lexer = Token::lexer(input);
|
||||||
|
@ -99,26 +111,30 @@ impl Command {
|
||||||
],
|
],
|
||||||
End => Ok(Command::Report(ReportMode::Once)),
|
End => Ok(Command::Report(ReportMode::Once)),
|
||||||
],
|
],
|
||||||
Pwm => {
|
Channel => {
|
||||||
if lexer.token != Token::Number {
|
let channel = choice![
|
||||||
return Err(Error::UnexpectedToken(lexer.token));
|
Number => {
|
||||||
}
|
CHANNEL_IDS.iter()
|
||||||
let pwm_match = btoi(lexer.slice().as_bytes())?;
|
.position(|id| *id == lexer.slice())
|
||||||
lexer.advance();
|
.ok_or(Error::NoSuchChannel)
|
||||||
|
},
|
||||||
if lexer.token != Token::Number {
|
]? as u8;
|
||||||
return Err(Error::UnexpectedToken(lexer.token));
|
choice![
|
||||||
}
|
Enable =>
|
||||||
let pwm_reload = btoi(lexer.slice().as_bytes())?;
|
Ok(Command::Channel(channel, ChannelCommand::Enable)),
|
||||||
lexer.advance();
|
Disable =>
|
||||||
|
Ok(Command::Channel(channel, ChannelCommand::Enable)),
|
||||||
if lexer.token != Token::End {
|
Setup => {
|
||||||
return Err(Error::UnexpectedToken(lexer.token));
|
let setup = choice![
|
||||||
}
|
Number => {
|
||||||
|
SETUP_IDS.iter()
|
||||||
end!(Command::Pwm {
|
.position(|id| *id == lexer.slice())
|
||||||
pwm_match, pwm_reload,
|
.ok_or(Error::NoSuchSetup)
|
||||||
})
|
},
|
||||||
|
]? as u8;
|
||||||
|
end!(Command::Channel(channel, ChannelCommand::Setup(setup)))
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,9 +85,6 @@ macro_rules! create_socket {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// In nanoseconds
|
|
||||||
const REPORT_INTERVAL: u64 = 100_000;
|
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
let mut stdout = hio::hstdout().unwrap();
|
let mut stdout = hio::hstdout().unwrap();
|
||||||
|
@ -149,10 +146,6 @@ fn main() -> ! {
|
||||||
writeln!(stdout, "Corrupt ADC id: {:04X}", id).unwrap(),
|
writeln!(stdout, "Corrupt ADC id: {:04X}", id).unwrap(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// SENS0_{P,N}
|
|
||||||
adc.setup_channel(0, ad7172::Input::Ain0, ad7172::Input::Ain1).unwrap();
|
|
||||||
// SENS1_{P,N}
|
|
||||||
adc.setup_channel(1, ad7172::Input::Ain2, ad7172::Input::Ain3).unwrap();
|
|
||||||
|
|
||||||
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() {
|
||||||
|
@ -202,43 +195,31 @@ fn main() -> ! {
|
||||||
(Session::new(), tcp_handle7),
|
(Session::new(), tcp_handle7),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut last_report = get_time();
|
let mut read_times = [0, 0];
|
||||||
let mut next_report = get_time();
|
let mut data = None;
|
||||||
// cumulative (sum, count)
|
// if a socket has sent the latest data
|
||||||
let mut sample = [(0u64, 0usize); 2];
|
|
||||||
let mut report = [None; 2];
|
|
||||||
loop {
|
loop {
|
||||||
// ADC input
|
let _ = adc.data_ready()
|
||||||
adc.data_ready()
|
.and_then(|channel|
|
||||||
.unwrap_or_else(|e| {
|
channel.map(|channel|
|
||||||
writeln!(stdout, "ADC error: {:?}", e);
|
adc.read_data().map(|new_data| {
|
||||||
None
|
|
||||||
}).map(|channel| {
|
|
||||||
let data = adc.read_data().unwrap();
|
|
||||||
sample[usize::from(channel)].0 += u64::from(data);
|
|
||||||
sample[usize::from(channel)].1 += 1;
|
|
||||||
});
|
|
||||||
let now = get_time();
|
let now = get_time();
|
||||||
if now >= next_report {
|
read_times[0] = read_times[1];
|
||||||
if now < next_report + REPORT_INTERVAL {
|
read_times[1] = now;
|
||||||
// Try to keep interval constant
|
data = Some((now, Ok((channel, new_data))));
|
||||||
next_report += REPORT_INTERVAL;
|
|
||||||
} else {
|
|
||||||
// Bad jitter, catch up
|
|
||||||
next_report = now + REPORT_INTERVAL;
|
|
||||||
}
|
|
||||||
for (channel, sample) in sample.iter().enumerate() {
|
|
||||||
if sample.1 > 0 {
|
|
||||||
// TODO: calculate med instead of avg?
|
|
||||||
report[channel] = Some(sample.0 / (sample.1 as u64));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (session, _) in sessions_handles.iter_mut() {
|
for (session, _) in sessions_handles.iter_mut() {
|
||||||
session.set_report_pending();
|
session.set_report_pending();
|
||||||
}
|
}
|
||||||
last_report = get_time();
|
})
|
||||||
|
).unwrap_or(Ok(()))
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
let now = get_time();
|
||||||
|
data = Some((now, Err(e)));
|
||||||
|
for (session, _) in sessions_handles.iter_mut() {
|
||||||
|
session.set_report_pending();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
for (session, tcp_handle) in sessions_handles.iter_mut() {
|
for (session, tcp_handle) in sessions_handles.iter_mut() {
|
||||||
let socket = &mut *sockets.get::<TcpSocket>(*tcp_handle);
|
let socket = &mut *sockets.get::<TcpSocket>(*tcp_handle);
|
||||||
if !socket.is_open() {
|
if !socket.is_open() {
|
||||||
|
@ -250,23 +231,20 @@ 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 command = socket.recv(|buf| session.feed(buf));
|
||||||
|
|
||||||
match output {
|
match command {
|
||||||
Ok(SessionOutput::Nothing) => {}
|
Ok(SessionOutput::Nothing) => {}
|
||||||
Ok(SessionOutput::Command(command)) => match command {
|
Ok(SessionOutput::Command(Command::Quit)) =>
|
||||||
Command::Quit =>
|
|
||||||
socket.close(),
|
socket.close(),
|
||||||
Command::Report(mode) => {
|
Ok(SessionOutput::Command(Command::Report(mode))) => {
|
||||||
let _ = writeln!(socket, "Report mode: {:?}", mode);
|
let _ = writeln!(socket, "Report mode: {:?}", mode);
|
||||||
}
|
}
|
||||||
Command::Show(ShowCommand::ReportMode) => {
|
Ok(SessionOutput::Command(Command::Show(ShowCommand::ReportMode))) => {
|
||||||
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
|
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
|
||||||
}
|
}
|
||||||
Command::Pwm { pwm_match, pwm_reload } => {
|
Ok(SessionOutput::Command(command)) => {
|
||||||
board::set_timer_pwm(pwm_match, pwm_reload);
|
let _ = writeln!(socket, "Not implemented: {:?}", command);
|
||||||
let _ = writeln!(socket, "PWM duty cycle: {}/{}", pwm_match, pwm_reload);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(SessionOutput::Error(e)) => {
|
Ok(SessionOutput::Error(e)) => {
|
||||||
let _ = writeln!(socket, "Command error: {:?}", e);
|
let _ = writeln!(socket, "Command error: {:?}", e);
|
||||||
|
@ -275,13 +253,19 @@ fn main() -> ! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if socket.may_send() && session.is_report_pending() {
|
if socket.may_send() && session.is_report_pending() {
|
||||||
let _ = write!(socket, "t={}", last_report);
|
match &data {
|
||||||
for (channel, report_data) in report.iter().enumerate() {
|
Some((time, Ok((channel, input)))) => {
|
||||||
report_data.map(|report_data| {
|
let interval = read_times[1] - read_times[0];
|
||||||
let _ = write!(socket, " sens{}={:06X}", channel, report_data);
|
let _ = writeln!(socket, "t={}-{} channel={} input={}\r", time, interval, channel, input);
|
||||||
});
|
}
|
||||||
|
Some((time, Err(ad7172::AdcError::ChecksumMismatch(Some(expected), Some(input))))) => {
|
||||||
|
let _ = writeln!(socket, "t={} checksum_expected={:02X} checksum_input={:02X}\r", time, expected, input);
|
||||||
|
}
|
||||||
|
Some((time, Err(e))) => {
|
||||||
|
let _ = writeln!(socket, "t={} adc_error={:?}\r", time, e);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
let _ = writeln!(socket, "");
|
|
||||||
session.mark_report_sent();
|
session.mark_report_sent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue