Skip to content

Commit

Permalink
Implement basic functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
zandemax committed Jan 18, 2023
1 parent 091c93c commit 5114bbe
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 32 deletions.
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "mcp3461"
name = "mcp346x"
version = "0.1.0"
edition = "2021"
authors = ["Max Zander <[email protected]>"]
Expand All @@ -13,6 +13,7 @@ categories = ["embedded", "hardware-support", "no-std"]
embedded-hal = "1.0.0-alpha.9"
measurements = "0.11"
crc16 = "0.4.0"
bitflags = "1.3"

[profile.release]
lto = true
85 changes: 55 additions & 30 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use embedded_hal::spi::{SpiDevice, SpiBus};
use measurements::Voltage;
use bitflags::bitflags;

#[derive(Debug)]
pub enum Error<E> {
Expand All @@ -12,6 +13,14 @@ pub enum Error<E> {
NotReady,
}

bitflags! {
pub struct StatusRegister: u8 {
const DR_STATUS = 0b00000100;
const CRCCFG_STATUS = 0b00000010;
const POR_STATUS = 0b00000001;
}
}


pub struct MCP346x<SPI, MODE> {
spi: SPI,
Expand All @@ -20,11 +29,11 @@ pub struct MCP346x<SPI, MODE> {
}

fn generate_fast_command_byte(device_address: u8, command: u8) -> [u8;1] {
return (device_address << 6) | (command << 2) | 0b00000000;
return [(device_address << 6) | (command << 2) | 0b00000000;1];
}

fn generate_register_command_byte(device_address: u8, register_address: u8, command_type: u8) -> [u8;1] {
return (device_address << 6) | (register_address << 2) | command_type;
return [(device_address << 6) | (register_address << 2) | command_type;1];
}


Expand All @@ -44,31 +53,48 @@ where
SPI::Bus: SpiBus,
{

fn set_mode(&self, mode: u8) -> Result<(), Error<E>> {
fn tranfer_with_status_register(&mut self, read_buf: &mut [u8], command: &[u8]) -> Result<StatusRegister, Error<E>> {
let mut buf = [0;40];
self.spi.transfer(&mut buf[0..read_buf.len()+8], command).map_err(|e| Error::Spi(e))?;
let mut status_register_raw = [0;1];
status_register_raw.clone_from_slice(&buf[0..8]);
let status_register = StatusRegister::from_bits_truncate(u8::from_be_bytes(status_register_raw));
read_buf.copy_from_slice(&buf[8..read_buf.len()]);
Ok(status_register)
}

fn set_mode(&mut self, mode: u8) -> Result<(), Error<E>> {
let command: [u8;1] = [0;1];
self.spi.write(&command).map_err(Error::Spi)?;
Ok(())
}

fn static_read(&self, register: u8, buf: &mut [u8]) -> Result<&[u8], Error<E>> {
fn static_read(&mut self, register: u8, buf: &mut [u8]) -> Result<(), Error<E>> {
let command: [u8;1] = generate_register_command_byte(self.address, register, 0b01);
self.spi.transfer(&mut buf, &command).map_err(|e| Error::Spi(e));
Ok(buf)
let _ = self.tranfer_with_status_register(buf, &command);
Ok(())
}

fn incremental_read(&self, register: u8, buf: &mut [u8]) -> Result<&[u8], Error<E>> {
fn incremental_read(&mut self, register: u8, buf: &mut [u8]) -> Result<(), Error<E>> {
let command: [u8;1] = generate_register_command_byte(self.address, register, 0b11);
self.spi.transfer(&mut buf, &command).map_err(|e| Error::Spi(e));
Ok(buf)
self.spi.transfer(buf, &command).map_err(|e| Error::Spi(e))?;
Ok(())
}

fn incremental_write(&self, register: u8, buf: &mut[u8]) -> Result<&[u8], Error<E>> {
fn incremental_write(&mut self, register: u8, buf: &mut[u8]) -> Result<(), Error<E>> {
let command: [u8;1] = generate_register_command_byte(self.address, register, 0b10);
self.spi.transfer(buf, &command).map_err(|e| Error::Spi(e));
Ok(buf)
self.spi.transfer(buf, &command).map_err(|e| Error::Spi(e))?;
Ok(())
}

fn read_data_register_16bit(&mut self) -> Result<i16, Error<E>> {
let mut buf: [u8;2] = [0;2];
self.static_read(0x00, &mut buf)?;
let measurement = i16::from_be_bytes(buf);
Ok(measurement)
}

pub fn into_continuous_mode(self) -> Result<MCP346x<SPI, ContinuousMode>, Error<E>> {
pub fn into_continuous_mode(mut self) -> Result<MCP346x<SPI, ContinuousMode>, Error<E>> {
self.set_mode(0b00)?;
Ok(MCP346x {
spi: self.spi,
Expand All @@ -77,7 +103,7 @@ where
})
}

pub fn into_scan_mode(self) -> Result<MCP346x<SPI, ScanMode>, Error<E>> {
pub fn into_scan_mode(mut self) -> Result<MCP346x<SPI, ScanMode>, Error<E>> {
self.set_mode(0b10)?;
Ok(MCP346x {
spi: self.spi,
Expand All @@ -86,7 +112,7 @@ where
})
}

pub fn into_oneshot_mode(self) -> Result<MCP346x<SPI, OneShotMode>, Error<E>> {
pub fn into_oneshot_mode(mut self) -> Result<MCP346x<SPI, OneShotMode>, Error<E>> {
self.set_mode(0b11)?;
Ok(MCP346x {
spi: self.spi,
Expand All @@ -95,40 +121,39 @@ where
})
}

pub fn measure(&self) -> Result<Voltage, Error<E>> {
let buf: [u8;4] = [0;4];
let command: [u8;1] = generate_fast_command_byte(, command);
self.spi.transfer(&mut buf, &command);
Ok(Voltage::from_volts(u32::from_be_bytes(buf) as f64))
pub fn measure(&mut self) -> Result<Voltage, Error<E>> {
self.start_conversion()?;
let measurement = self.read_data_register_16bit()?;
Ok(Voltage::from_volts(measurement as f64))
}

pub fn start_conversion(&self) -> Result<(), Error<E>> {
pub fn start_conversion(&mut self) -> Result<(), Error<E>> {
let command: [u8;1] = generate_fast_command_byte(self.address, 0b1010);
self.spi.write(&command).map_err(|e| Error::Spi(e));
self.spi.write(&command).map_err(|e| Error::Spi(e))?;
Ok(())
}

pub fn standby(&self) -> Result<(), Error<E>> {
pub fn standby(&mut self) -> Result<(), Error<E>> {
let command: [u8;1] = generate_fast_command_byte(self.address, 0b1011);
self.spi.write(&command).map_err(|e| Error::Spi(e));
self.spi.write(&command).map_err(|e| Error::Spi(e))?;
Ok(())
}

pub fn shutdown(&self) -> Result<(), Error<E>> {
pub fn shutdown(&mut self) -> Result<(), Error<E>> {
let command: [u8;1] = generate_fast_command_byte(self.address, 0b1100);
self.spi.write(&command).map_err(|e| Error::Spi(e));
self.spi.write(&command).map_err(|e| Error::Spi(e))?;
Ok(())
}

pub fn full_shutdown(self) -> Result<(), Error<E>> {
pub fn full_shutdown(mut self) -> Result<(), Error<E>> {
let command: [u8;1] = generate_fast_command_byte(self.address, 0b1101);
self.spi.write(&command).map_err(|e| Error::Spi(e));
self.spi.write(&command).map_err(|e| Error::Spi(e))?;
Ok(())
}

pub fn reset(&self) -> Result<MCP346x<SPI, Unconfigured>, Error<E>> {
pub fn reset(mut self) -> Result<MCP346x<SPI, Unconfigured>, Error<E>> {
let command: [u8;1] = generate_fast_command_byte(self.address, 0b1110);
self.spi.write(&command).map_err(|e| Error::Spi(e));
self.spi.write(&command).map_err(|e| Error::Spi(e))?;
Ok(MCP346x { spi: self.spi, mode: Unconfigured, address: self.address })
}
}
Expand Down

0 comments on commit 5114bbe

Please sign in to comment.