From 5a5d08f92768c48949cb175605055b853e559c5c Mon Sep 17 00:00:00 2001 From: Diego Barrios Romero Date: Sun, 4 Nov 2018 21:32:46 +0100 Subject: Initial version --- src/interface.rs | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/interface.rs (limited to 'src/interface.rs') diff --git a/src/interface.rs b/src/interface.rs new file mode 100644 index 0000000..2bf14f2 --- /dev/null +++ b/src/interface.rs @@ -0,0 +1,142 @@ +//! I2C/SPI interfaces + +#![deny(missing_docs)] + +extern crate embedded_hal as hal; +use hal::blocking; +use Error; + +/// I2C interface +#[derive(Debug, Default)] +pub struct I2cInterface { + pub(crate) i2c: I2C, + pub(crate) address : u8, +} + +/// SPI interface +#[derive(Debug, Default)] +pub struct SpiInterface { + pub(crate) spi: SPI, + pub(crate) cs: CS +} + +/// Write data +pub trait WriteData { + /// Error type + type Error; + /// Write to an u8 register + fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error>; + /// Write data. The first element corresponds to the starting address. + fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error>; +} + +impl WriteData for I2cInterface +where + I2C: blocking::i2c::Write +{ + type Error = E; + fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error> { + let payload: [u8; 2] = [register, data]; + self.i2c + .write(self.address, &payload) + .map_err(Error::Comm) + } + + fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error> { + self.i2c + .write(self.address, &payload) + .map_err(Error::Comm) + } +} + +impl WriteData for SpiInterface +where + SPI: blocking::spi::Write, + CS: hal::digital::OutputPin +{ + type Error = E; + fn write_register(&mut self, register: u8, data: u8) -> Result<(), Error> { + self.cs.set_low(); + + let payload: [u8; 2] = [register + 0x80, data]; + let result = self.spi + .write(&payload) + .map_err(Error::Comm); + + self.cs.set_high(); + result + } + + fn write_data(&mut self, payload: &mut [u8]) -> Result<(), Error> { + self.cs.set_low(); + payload[0] += 0x80; + let result = self.spi + .write(&payload) + .map_err(Error::Comm); + + self.cs.set_high(); + result + } +} + + +/// Read data +pub trait ReadData { + /// Error type + type Error; + /// Read an u8 register + fn read_register(&mut self, register: u8) -> Result>; + /// Read some data. The first element corresponds to the starting address. + fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Error>; +} + +impl ReadData for I2cInterface +where + I2C: blocking::i2c::WriteRead +{ + type Error = E; + fn read_register(&mut self, register: u8) -> Result> { + let mut data = [0]; + self.i2c + .write_read(self.address, &[register], &mut data) + .map_err(Error::Comm) + .and(Ok(data[0])) + } + + fn read_data(&mut self, payload: &mut [u8]) -> Result<(), Error> { + let len = payload.len(); + self.i2c + .write_read(self.address, &[payload[0]], &mut payload[1..=(len-1)]) + .map_err(Error::Comm) + } +} + +impl ReadData for SpiInterface +where + SPI: blocking::spi::Transfer, + CS: hal::digital::OutputPin +{ + type Error = E; + fn read_register(&mut self, register: u8) -> Result> { + self.cs.set_low(); + let mut data = [register, 0]; + let result = self.spi + .transfer(&mut data) + .map_err(Error::Comm); + self.cs.set_high(); + match result { + Ok(result) => Ok(result[1]), + Err(e) => Err(e) + } + } + + fn read_data(&mut self, mut payload: &mut [u8]) -> Result<(), Error> { + self.cs.set_low(); + let result = self.spi + .transfer(&mut payload) + .map_err(Error::Comm); + self.cs.set_high(); + result?; + Ok(()) + } +} -- cgit v1.2.3-54-g00ecf