adc_mcp3008/
lib.rs

1//! A platform agnostic driver to interface with the MCP3008 / MCP3004 ADC's.
2//!
3//! This driver was built using [`embedded-hal`] traits.
4//!
5//! [`embedded-hal`]: https://docs.rs/embedded-hal/~0.1
6//!
7
8#![deny(missing_docs)]
9#![deny(warnings)]
10#![feature(unsize)]
11#![no_std]
12
13extern crate embedded_hal as hal;
14
15use hal::blocking::spi::Transfer;
16use hal::spi::{Mode, Phase, Polarity};
17use hal::digital::OutputPin;
18
19/// SPI mode
20pub const MODE: Mode = Mode {
21    phase: Phase::CaptureOnFirstTransition,
22    polarity: Polarity::IdleLow,
23};
24
25/// MCP3008 driver
26pub struct Mcp3008<SPI, CS> {
27    spi: SPI,
28    cs: CS,
29}
30
31/// MCP3004 driver
32pub struct Mcp3004<SPI, CS> {
33    spi: SPI,
34    cs: CS,
35}
36
37impl<SPI, CS, E> Mcp3008<SPI, CS>
38    where SPI: Transfer<u8, Error = E>,
39          CS: OutputPin
40{
41    /// Creates a new driver from an SPI peripheral and a chip select
42    /// digital I/O pin.
43    pub fn new(spi: SPI, cs: CS) -> Result<Self, E> {
44        let mcp3008 = Mcp3008 { spi: spi, cs: cs };
45
46        Ok(mcp3008)
47    }
48
49    /// Read a MCP3008 ADC channel and return the 10 bit value as a u16
50    pub fn read_channel(&mut self, ch: Channels8) -> Result<u16, E> {
51        self.cs.set_low();
52
53        let mut buffer = [0u8; 3];
54        buffer[0] = 1;
55        buffer[1] = ((1 << 3) | (ch as u8)) << 4;
56
57        self.spi.transfer(&mut buffer)?;
58
59        self.cs.set_high();
60
61        let r = (((buffer[1] as u16) << 8) | (buffer[2] as u16)) & 0x3ff;
62        Ok(r)
63    }
64}
65
66impl<SPI, CS, E> Mcp3004<SPI, CS>
67    where SPI: Transfer<u8, Error = E>,
68          CS: OutputPin
69{
70    /// Creates a new driver from an SPI peripheral and a chip select 
71    /// digital I/O pin.
72    pub fn new(spi: SPI, cs: CS) -> Result<Self, E> {
73        let mcp3004 = Mcp3004 { spi: spi, cs: cs };
74
75        Ok(mcp3004)
76    }
77
78    /// Read a MCP3004 ADC channel and return the 10 bit value as a u16
79    pub fn read_channel(&mut self, ch: Channels4) -> Result<u16, E> {
80        self.cs.set_low();
81
82        let mut buffer = [0u8; 3];
83        buffer[0] = 1;
84        buffer[1] = ((1 << 3) | (ch as u8)) << 4;
85
86        self.spi.transfer(&mut buffer)?;
87
88        self.cs.set_high();
89
90        let r = (((buffer[1] as u16) << 8) | (buffer[2] as u16)) & 0x3ff;
91        Ok(r)
92    }
93}
94
95/// Channel list for MCP3008
96#[derive(Clone, Copy)]
97#[allow(missing_docs)]
98pub enum Channels8 {
99    CH0,
100    CH1,
101    CH2,
102    CH3,
103    CH4,
104    CH5,
105    CH6,
106    CH7,
107}
108
109/// Channel list for MCP3004
110#[derive(Clone, Copy)]
111#[allow(missing_docs)]
112pub enum Channels4 {
113    CH0,
114    CH1,
115    CH2,
116    CH3,
117}