From db80221815a711127b4b45c8c9019c241ac13849 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 12 Dec 2021 20:56:23 +0100 Subject: [PATCH] add Chip Select handling --- src/lib.rs | 100 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3a10f2c..292d7dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,10 @@ #![no_std] use core::{marker::PhantomData, slice::IterMut}; -use embedded_hal::{blocking::spi::Transfer, digital::v2::InputPin, spi::FullDuplex}; +use embedded_hal::{ + blocking::spi::Transfer, + digital::v2::{InputPin, OutputPin}, + spi::FullDuplex, +}; //================================================================================================== // Type-level support @@ -152,23 +156,13 @@ pub enum AdcError { } #[derive(Debug)] -pub enum Error { +pub enum Error { Adc(AdcError), Spi(SpiE), -} - -pub enum ErrorWithEoc { - Error(Error), Pin(PinE), } -impl From for ErrorWithEoc { - fn from(other: AdcError) -> Self { - ErrorWithEoc::Error(Error::Adc(other)) - } -} - -impl From for Error { +impl From for Error { fn from(other: AdcError) -> Self { Error::Adc(other) } @@ -180,29 +174,34 @@ impl From for Error { pub struct Max116xx10Bit< SPI, + CS, MAX: HasChannels, CLOCKED = ExternallyClocked, DELAY = WithoutWakeupDelay, > { - pub clk_mode: ClockMode, - pub ref_mode: RefMode, + clk_mode: ClockMode, + ref_mode: RefMode, spi: SPI, + cs: CS, pending_op: PendingOp, max: PhantomData, clocked: PhantomData, delay: PhantomData, } -impl Max116xx10Bit +impl + Max116xx10Bit where SPI: Transfer + FullDuplex, + CS: OutputPin, { /// Create a new generic MAX116xx instance. - pub fn new(spi: SPI, ref_mode: RefMode) -> Result> { - let mut max_dev: Max116xx10Bit = Max116xx10Bit { + pub fn new(spi: SPI, cs: CS, ref_mode: RefMode) -> Result> { + let mut max_dev = Max116xx10Bit { clk_mode: CLOCKED::CLK_SEL, ref_mode, spi, + cs, pending_op: PendingOp::None, max: PhantomData, delay: PhantomData, @@ -213,12 +212,15 @@ where } #[inline] - fn send_wrapper(&mut self, byte: u8) -> Result<(), Error> { - nb::block!(self.spi.send(byte)).map_err(|e| Error::Spi(e)) + fn send_wrapper(&mut self, byte: u8) -> Result<(), Error> { + self.cs.set_low().map_err(|e| Error::Pin(e))?; + nb::block!(self.spi.send(byte)).map_err(|e| Error::Spi(e))?; + self.cs.set_high().map_err(|e| Error::Pin(e))?; + Ok(()) } #[inline] - pub fn setup(&mut self) -> Result<(), Error> { + pub fn setup(&mut self) -> Result<(), Error> { self.send_wrapper(self.get_setup_byte()) } @@ -227,12 +229,12 @@ where &mut self, avg_conv: AveragingConversions, avg_res: AveragingResults, - ) -> Result<(), Error> { + ) -> Result<(), Error> { self.send_wrapper(Self::get_averaging_byte(avg_conv, avg_res)) } #[inline] - pub fn reset_adc(&mut self, fifo_only: bool) -> Result<(), Error> { + pub fn reset_adc(&mut self, fifo_only: bool) -> Result<(), Error> { let mut reset_byte = 0b0001_0000; if fifo_only { reset_byte |= 1 << 3; @@ -258,10 +260,11 @@ where Ok((1 << 7) | (channel_num << 3) | ((scan_mode as u8) << 1)) } } -impl - Max116xx10Bit +impl + Max116xx10Bit where SPI: Transfer + FullDuplex, + CS: OutputPin, { #[inline] fn request_wrapper( @@ -269,7 +272,7 @@ where channel_num: u8, scan_mode: ScanMode, op_type: PendingOp, - ) -> Result<(), Error> { + ) -> Result<(), Error> { if self.pending_op != PendingOp::None { return Err(Error::Adc(AdcError::PendingOperation)); } @@ -280,7 +283,7 @@ where Ok(()) } - pub fn request_single_channel(&mut self, channel_num: u8) -> Result<(), Error> { + pub fn request_single_channel(&mut self, channel_num: u8) -> Result<(), Error> { self.request_wrapper( channel_num, ScanMode::ConvertChannelNOnce, @@ -288,37 +291,41 @@ where ) } - pub fn request_multiple_channels_0_to_n(&mut self, n: u8) -> Result<(), Error> { + pub fn request_multiple_channels_0_to_n(&mut self, n: u8) -> Result<(), Error> { self.request_wrapper(n, ScanMode::Scan0ToChannelN, PendingOp::MultiChannel) } - pub fn request_multiple_channels_n_to_highest(&mut self, n: u8) -> Result<(), Error> { + pub fn request_multiple_channels_n_to_highest( + &mut self, + n: u8, + ) -> Result<(), Error> { self.request_wrapper(n, ScanMode::ScanChannelNToHighest, PendingOp::MultiChannel) } - pub fn get_single_channel( + pub fn get_single_channel>( &mut self, eoc_pin: &mut I, - ) -> nb::Result> { + ) -> nb::Result> { if self.pending_op != PendingOp::SingleChannel { - return Err(nb::Error::Other(ErrorWithEoc::Error(Error::Adc( - AdcError::NoPendingOperation, - )))); + return Err(nb::Error::Other(Error::Adc(AdcError::NoPendingOperation))); } let is_low = match eoc_pin.is_low() { Ok(low) => low, Err(e) => { - return Err(nb::Error::Other(ErrorWithEoc::Pin(e))); + return Err(nb::Error::Other(Error::Pin(e))); } }; if is_low { let mut dummy_cmd: [u8; 2] = [0; 2]; - match self.spi.transfer(&mut dummy_cmd) { + self.cs.set_low().map_err(|e| Error::Pin(e))?; + let transfer_result = self.spi.transfer(&mut dummy_cmd); + self.cs.set_high().map_err(|e| Error::Pin(e))?; + match transfer_result { Ok(reply) => { self.pending_op = PendingOp::None; Ok(((reply[0] as u16) << 6) | (reply[1] as u16 >> 2)) } - Err(e) => Err(nb::Error::Other(ErrorWithEoc::Error(Error::Spi(e)))), + Err(e) => Err(nb::Error::Other(Error::Spi(e))), } } else { Err(nb::Error::WouldBlock) @@ -326,15 +333,17 @@ where } } -impl Max116xx10Bit +impl + Max116xx10Bit where SPI: Transfer + FullDuplex, + CS: OutputPin, { pub fn read_single_channel( &mut self, buf: &mut [u8], channel_num: u8, - ) -> Result> { + ) -> Result> { if buf.len() < 3 { return Err(Error::Adc(AdcError::CmdBufTooSmall)); } @@ -347,7 +356,9 @@ where }; buf[1] = 0x00; buf[2] = 0x00; + self.cs.set_low().map_err(|e| Error::Pin(e))?; let reply = self.spi.transfer(&mut buf[0..3]).ok().unwrap(); + self.cs.set_high().map_err(|e| Error::Pin(e))?; Ok(((reply[1] as u16) << 6) | (reply[2] as u16 >> 2)) } @@ -356,7 +367,7 @@ where buf: &mut [u8], result_iter: &mut IterMut, n: u8, - ) -> Result<(), Error> { + ) -> Result<(), Error> { let mut iter = buf.iter_mut(); let mut next_byte: &mut u8; for idx in 0..n + 1 { @@ -367,10 +378,12 @@ where } next_byte = iter.next().ok_or(Error::Adc(AdcError::CmdBufTooSmall))?; *next_byte = 0x00; + self.cs.set_low().map_err(|e| Error::Pin(e))?; let reply = self .spi .transfer(&mut buf[0..((n + 1) * 2 + 1) as usize]) .map_err(|e| Error::Spi(e))?; + self.cs.set_high().map_err(|e| Error::Pin(e))?; let mut reply_iter = reply.iter(); // Skip first reply byte reply_iter.next().unwrap(); @@ -389,7 +402,7 @@ where buf: &mut [u8], result_iter: &mut IterMut, n: u8, - ) -> Result<(), Error> { + ) -> Result<(), Error> { let mut iter = buf.iter_mut(); let mut next_byte: &mut u8; if n > MAX::NUM - 1 { @@ -404,11 +417,12 @@ where } next_byte = iter.next().ok_or(Error::Adc(AdcError::CmdBufTooSmall))?; *next_byte = 0x00; + self.cs.set_low().map_err(|e| Error::Pin(e))?; let reply = self .spi .transfer(&mut buf[0..(conversions * 2 + 1) as usize]) - .ok() - .unwrap(); + .map_err(|e| Error::Spi(e))?; + self.cs.set_high().map_err(|e| Error::Pin(e))?; let mut reply_iter = reply.iter(); // Skip first reply byte reply_iter.next().unwrap();