From e59df63baa7b97a5f006b9946a741b594fdee779 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 4 Dec 2021 21:24:44 +0100 Subject: [PATCH] added temperature sensor module --- examples/temp-sensor.rs | 49 ++++--------------------- src/lib.rs | 1 + src/temp_sensor.rs | 81 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 41 deletions(-) create mode 100644 src/temp_sensor.rs diff --git a/examples/temp-sensor.rs b/examples/temp-sensor.rs index 860bfd4..d448c7c 100644 --- a/examples/temp-sensor.rs +++ b/examples/temp-sensor.rs @@ -1,26 +1,14 @@ #![no_main] #![no_std] use cortex_m_rt::entry; -use embedded_hal::blocking::i2c::SevenBitAddress; use panic_rtt_target as _; use rtt_target::{rprintln, rtt_init_print}; use va108xx_hal::{ - i2c::{I2cMaster, I2cSpeed, MasterConfig}, - pac::{self, interrupt, I2CA}, + pac::{self, interrupt}, prelude::*, timer::{default_ms_irq_handler, set_up_ms_timer, Delay}, }; - -#[allow(dead_code)] -enum RegAddresses { - Temperature = 0x00, - Configuration = 0x01, - THystSetpoint = 0x02, - TOsSetPoint = 0x03, - OneShot = 0x04, -} - -const ADT75_I2C_ADDR: u8 = 0b1001000; +use vorago_reb1::temp_sensor::Adt75TempSensor; #[entry] fn main() -> ! { @@ -39,34 +27,13 @@ fn main() -> ! { cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); } - let ms_cfg = MasterConfig::default(); - let mut i2ca: I2cMaster = I2cMaster::i2ca( - dp.I2CA, - ms_cfg, - 50.mhz(), - I2cSpeed::Regular100khz, - Some(&mut dp.SYSCONFIG), - ); - - let mut cmd: [u8; 4] = [0; 4]; - cmd[0] = RegAddresses::Temperature as u8; - let mut reply: [u8; 4] = [0; 4]; - i2ca.write(ADT75_I2C_ADDR, &cmd[0..1]) - .expect("I2C send transfer failed"); + let mut temp_sensor = Adt75TempSensor::new(dp.I2CA, 50.mhz(), Some(&mut dp.SYSCONFIG)) + .expect("Creating temperature sensor struct failed"); loop { - i2ca.read(ADT75_I2C_ADDR, &mut reply[0..2]) - .expect("I2C read transfer failed"); - let adc_code = (((reply[0] as u16) << 8) | reply[1] as u16) >> 4; - let temp_celcius: f32; - if ((adc_code >> 11) & 0x01) == 0 { - // Sign bit not set, positiv value - // Divide ADC code by 16 according to datasheet - temp_celcius = adc_code as f32 / 16.0; - } else { - // Calculation for negative values, assuming all 12 bits are used - temp_celcius = (adc_code - 4096) as f32 / 16.0; - } - rprintln!("Temperature in Celcius: {}", temp_celcius); + let temp = temp_sensor + .read_temperature() + .expect("Failed reading temperature"); + rprintln!("Temperature in Celcius: {}", temp); delay.delay_ms(500); } } diff --git a/src/lib.rs b/src/lib.rs index 4ccc9a9..09ad829 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,3 +2,4 @@ pub mod button; pub mod leds; +pub mod temp_sensor; diff --git a/src/temp_sensor.rs b/src/temp_sensor.rs new file mode 100644 index 0000000..173382d --- /dev/null +++ b/src/temp_sensor.rs @@ -0,0 +1,81 @@ +//! # API for the On-Board Analog Devices ADT75 temperature sensor +//! +//! [Datasheet](https://www.analog.com/media/en/technical-documentation/data-sheets/ADT75.pdf) +//! +//! ## Examples +//! +//! - [Temperature Sensor example](https://github.com/robamu-org/vorago-reb1-rs/blob/main/examples/temp-sensor.rs) +use cortex_m::prelude::_embedded_hal_blocking_i2c_Write; +use embedded_hal::blocking::i2c::{Read, SevenBitAddress}; +use va108xx_hal::{ + i2c::{Error, I2cMaster, I2cSpeed, MasterConfig}, + pac::{I2CA, SYSCONFIG}, + time::Hertz, +}; + +const ADT75_I2C_ADDR: u8 = 0b1001000; + +pub struct Adt75TempSensor { + sensor_if: I2cMaster, + cmd_buf: [u8; 1], + current_reg: RegAddresses, +} + +#[derive(PartialEq, Debug, Copy, Clone)] +pub enum RegAddresses { + Temperature = 0x00, + Configuration = 0x01, + THystSetpoint = 0x02, + TOsSetPoint = 0x03, + OneShot = 0x04, +} + +impl Adt75TempSensor { + pub fn new( + i2ca: I2CA, + sys_clk: impl Into + Copy, + sys_cfg: Option<&mut SYSCONFIG>, + ) -> Result { + let mut sensor = Adt75TempSensor { + sensor_if: I2cMaster::i2ca( + i2ca, + MasterConfig::default(), + sys_clk, + I2cSpeed::Regular100khz, + sys_cfg, + ), + cmd_buf: [RegAddresses::Temperature as u8], + current_reg: RegAddresses::Temperature, + }; + sensor.select_reg(RegAddresses::Temperature)?; + Ok(sensor) + } + + pub fn select_reg(&mut self, reg: RegAddresses) -> Result<(), Error> { + if reg != self.current_reg { + self.cmd_buf[0] = reg as u8; + self.current_reg = reg; + self.sensor_if.write(ADT75_I2C_ADDR, &self.cmd_buf[0..1])?; + } + Ok(()) + } + + pub fn read_temperature(&mut self) -> Result { + if self.current_reg != RegAddresses::Temperature { + self.select_reg(RegAddresses::Temperature)?; + } + let mut reply: [u8; 2] = [0; 2]; + self.sensor_if.read(ADT75_I2C_ADDR, &mut reply)?; + let adc_code = (((reply[0] as u16) << 8) | reply[1] as u16) >> 4; + let temp_celcius: f32; + if ((adc_code >> 11) & 0x01) == 0 { + // Sign bit not set, positiv value + // Divide ADC code by 16 according to datasheet + temp_celcius = adc_code as f32 / 16.0; + } else { + // Calculation for negative values, assuming all 12 bits are used + temp_celcius = (adc_code - 4096) as f32 / 16.0; + } + Ok(temp_celcius) + } +}