#![deny(missing_docs)]
#![deny(
future_incompatible,
let_underscore,
keyword_idents,
elided_lifetimes_in_paths,
meta_variable_misuse,
noop_method_call,
pointer_structural_match,
unused_lifetimes,
unused_qualifications,
unsafe_op_in_unsafe_fn,
clippy::undocumented_unsafe_blocks,
clippy::debug_assert_with_mut_call,
clippy::empty_line_after_outer_attr,
clippy::panic,
clippy::unwrap_used,
clippy::expect_used,
clippy::redundant_field_names,
clippy::rest_pat_in_fully_bound_structs,
clippy::unneeded_field_pattern,
clippy::useless_let_if_seq,
clippy::default_union_representation,
clippy::checked_conversions,
clippy::dbg_macro
)]
#![warn(clippy::cloned_instead_of_copied, clippy::cognitive_complexity)]
#![allow(
clippy::must_use_candidate,
clippy::doc_markdown,
clippy::missing_errors_doc,
clippy::implicit_hasher
)]
#![feature(unsize)]
#![no_std]
extern crate embedded_hal as hal;
use hal::blocking::spi::Transfer;
use hal::digital::v2::OutputPin;
use hal::spi::{Mode, Phase, Polarity};
pub const MODE: Mode = Mode {
phase: Phase::CaptureOnFirstTransition,
polarity: Polarity::IdleLow,
};
pub struct Mcp320X<SPI, CS> {
spi: SPI,
cs: CS,
}
impl<SPI, CS, E> Mcp320X<SPI, CS>
where
SPI: Transfer<u8, Error = E>,
CS: OutputPin,
{
pub fn new(spi: SPI, cs: CS) -> Mcp320X<SPI, CS> {
Mcp320X { spi, cs }
}
pub fn read_channel<C: Into<u8>>(
&mut self,
ch: C,
) -> Result<u16, McpError<SPI::Error, CS::Error>> {
self.cs.set_low().map_err(McpError::CSError)?;
let ch = ch.into();
let mut buffer = [0u8; 3];
buffer[0] = 1 << 2 | 1 << 1 | (ch & 4) >> 1;
buffer[1] = (ch & 3) << 6;
self.spi.transfer(&mut buffer).map_err(McpError::SPIError)?;
self.cs.set_high().map_err(McpError::CSError)?;
let r = (((buffer[1] as u16) << 8) | (buffer[2] as u16)) & 0x3ff;
Ok(r)
}
}
pub enum McpError<SE, CE> {
SPIError(SE),
CSError(CE),
}
impl<SE, CE> core::fmt::Debug for McpError<SE, CE>
where
SE: core::fmt::Debug,
CE: core::fmt::Debug,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::SPIError(err) => err.fmt(f),
Self::CSError(err) => err.fmt(f),
}
}
}
#[derive(Clone, Copy)]
#[allow(missing_docs)]
pub enum Channels8 {
CH0,
CH1,
CH2,
CH3,
CH4,
CH5,
CH6,
CH7,
}
impl From<Channels8> for u8 {
fn from(c: Channels8) -> u8 {
c as u8
}
}
impl Channels8 {
pub fn list() -> [Channels8; 8] {
[
Self::CH0,
Self::CH1,
Self::CH2,
Self::CH3,
Self::CH4,
Self::CH5,
Self::CH6,
Self::CH7,
]
}
}
#[derive(Clone, Copy)]
#[allow(missing_docs)]
pub enum Channels4 {
CH0,
CH1,
CH2,
CH3,
}
impl From<Channels4> for u8 {
fn from(c: Channels4) -> u8 {
c as u8
}
}
impl Channels4 {
pub fn list() -> [Channels4; 4] {
[Self::CH0, Self::CH1, Self::CH2, Self::CH3]
}
}