summaryrefslogtreecommitdiff
path: root/tmp117-cli
diff options
context:
space:
mode:
authorunitexe <unitexe70@gmail.com>2026-04-08 23:53:17 -0500
committerunitexe <unitexe70@gmail.com>2026-04-08 23:54:28 -0500
commitde3f7ed45185f3a678ba0de04d98cc9ac92de0c8 (patch)
tree3db0159c1370f240d42c1e8b89a67247538f43d1 /tmp117-cli
Initial commit
Diffstat (limited to 'tmp117-cli')
-rw-r--r--tmp117-cli/Cargo.toml11
-rw-r--r--tmp117-cli/src/main.rs379
2 files changed, 390 insertions, 0 deletions
diff --git a/tmp117-cli/Cargo.toml b/tmp117-cli/Cargo.toml
new file mode 100644
index 0000000..79453f5
--- /dev/null
+++ b/tmp117-cli/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "tmp117-cli"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+clap = { version = "4.6.0", features = ["derive"] }
+env_logger = "0.11.10"
+linux-embedded-hal = "0.4.1"
+log = "0.4.29"
+tmp117 = { version = "0.1.0", path = "../tmp117" }
diff --git a/tmp117-cli/src/main.rs b/tmp117-cli/src/main.rs
new file mode 100644
index 0000000..0be782a
--- /dev/null
+++ b/tmp117-cli/src/main.rs
@@ -0,0 +1,379 @@
+use clap::{Parser, Subcommand};
+use linux_embedded_hal::{Delay, I2cdev};
+use log::{info, trace};
+use tmp117::client::TMP117;
+use tmp117::conf::{
+ AlertPinSelect, Configuration, ConversionAveragingMode, ConversionMode, Mode, PinPolarity,
+};
+
+#[derive(Parser)]
+#[command(version, about, long_about = None)]
+struct Args {
+ /// I2C device path
+ #[arg(short('p'), long, default_value = "/dev/i2c-0")]
+ i2c_device_path: String,
+
+ //// Temperature sensor address on I2C bus
+ #[arg(short('a'), long, default_value_t = 0x57)]
+ slave_address: u8,
+
+ //// The command to run
+ #[command(subcommand)]
+ command: Option<Commands>,
+}
+
+#[derive(Subcommand)]
+enum TemperatureCommands {
+ /// Get the temperature from the sensor as raw value or in celsius
+ Get {
+ /// Get the temperature in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+}
+
+#[derive(Subcommand)]
+enum ConfigureCommands {
+ /// Set the configuration register using raw value
+ Set {
+ /// Configuration value
+ #[arg(short, long)]
+ configuration: u16,
+ },
+
+ /// Set the configuration register using named fields
+ SetTyped {
+ /// If true then the ALERT pin reflects the status of the data ready flag otherwise it reflects the status of the alert flags
+ #[arg(short('d'), long, default_value_t = false)]
+ alert_pin_reflects_data_ready: bool,
+
+ /// If true then the ALERT pin is active high otherwise it is active low
+ #[arg(short('p'), long, default_value_t = false)]
+ alert_pin_active_high: bool,
+
+ /// If true then the sensor will operate in thermal mode otherwise it is in alert mode
+ #[arg(short, long, default_value_t = false)]
+ thermal_mode: bool,
+
+ /// The number of conversion results that are collected and averaged (accumulative, not running) before updating temperature register
+ #[arg(short('c'), long, default_value_t = 8)]
+ averaged_conversions: u8,
+ },
+
+ /// Get the configuration from the sensor as raw value
+ Get {},
+
+ /// Get the configuration from the sensor as named fields
+ GetFields {},
+}
+
+#[derive(Subcommand)]
+enum HighLimitCommands {
+ /// Set the high limit as raw value or in celsius
+ Set {
+ /// 16-bit high limit for comparison with the temperature result. One LSB equals 7.8125 m°C. The range of the register is ±256 °C. Negative numbers are represented in binary two's complement format. Following power-up or a general-call reset, the high-limit register is loaded with the stored value from the EEPROM. The factory default reset value is 6000h.
+ #[arg(short, long)]
+ limit: f32,
+
+ /// The provided limit is temperature in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+
+ /// Get the high limit temperature as raw value or in celsius
+ Get {
+ /// Get the high limit in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+}
+
+#[derive(Subcommand)]
+enum LowLimitCommands {
+ /// Set the low limit as raw value or in celsius
+ Set {
+ /// 16-bit low limit for comparison with the temperature result. One LSB equals 7.8125 m°C. The range of the register is ±256 °C. Negative numbers are represented in binary two's complement format. Following power-up or a general-call reset, the high-limit register is loaded with the stored value from the EEPROM. The factory default reset value is 8000h.
+ #[arg(short, long)]
+ limit: f32,
+
+ /// The provided limit is temperature in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+
+ /// Get the low limit temperature as raw value or in celsius
+ Get {
+ /// Get the low limit in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+}
+
+#[derive(Subcommand)]
+enum OffsetCommands {
+ /// Set the temperature offset as raw value or in celsius
+ Set {
+ /// Offset will be added to temperature result after linearization. It has a same resolution of 7.8125 m°C and same range of ±256 °C as the temperature result register. The data format is the same as the temperature register. If the added result is out of boundary, then the temperature result will show as the maximum or minimum value.
+ #[arg(short, long)]
+ offset: f32,
+
+ /// The provided offset is temperature in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+
+ /// Get the temperature offset as raw value or in celsius
+ Get {
+ /// Get the temperature offset in celsius
+ #[arg(short, long, default_value_t = false)]
+ celsius: bool,
+ },
+}
+
+#[derive(Subcommand)]
+enum Commands {
+ /// Interact with temperature register
+ Temperature {
+ #[command(subcommand)]
+ command: TemperatureCommands,
+ },
+
+ /// Interact with configuration register
+ Configure {
+ #[command(subcommand)]
+ command: ConfigureCommands,
+ },
+
+ /// Interact with high limit register
+ HighLimit {
+ #[command(subcommand)]
+ command: HighLimitCommands,
+ },
+
+ /// Interact with low limit register
+ LowLimit {
+ #[command(subcommand)]
+ command: LowLimitCommands,
+ },
+
+ /// Interact with temperature offset register
+ Offset {
+ #[command(subcommand)]
+ command: OffsetCommands,
+ },
+
+ /// Reset the sensor
+ Reset {},
+}
+
+fn main() {
+ env_logger::init();
+
+ let cli = Args::parse();
+
+ trace!("I2C device path: {}", &cli.i2c_device_path);
+ trace!("I2C slave address: {:#04x}", cli.slave_address);
+
+ match &cli.command {
+ Some(Commands::Temperature { command }) => match command {
+ TemperatureCommands::Get { celsius } => {
+ info!("Getting temperature...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ let temperature = tmp117.get_temperature_celsius().unwrap();
+ println!("{:.4} °C", temperature);
+ } else {
+ let temperature = tmp117.get_temperature().unwrap();
+ println!("{:#06x}", temperature);
+ }
+ }
+ },
+ Some(Commands::Configure { command }) => match command {
+ ConfigureCommands::Set { configuration } => {
+ info!("Setting configuration...");
+ trace!("Configuration: {:#06x}", configuration);
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ tmp117.configure(*configuration).unwrap();
+ }
+ ConfigureCommands::SetTyped {
+ alert_pin_reflects_data_ready,
+ alert_pin_active_high,
+ thermal_mode,
+ averaged_conversions,
+ } => {
+ info!("Setting configuration...");
+ trace!(
+ "Alert pin reflects data ready? {}",
+ alert_pin_reflects_data_ready
+ );
+ trace!("Alert pin active high? {}", alert_pin_active_high);
+ trace!("Thermal mode enabled? {}", thermal_mode);
+ trace!("Averaged conversions: {}", averaged_conversions);
+
+ let configuration = Configuration {
+ alert_pin_select: match alert_pin_reflects_data_ready {
+ false => AlertPinSelect::Alert,
+ true => AlertPinSelect::DataReady,
+ },
+ alert_pin_polarity: match alert_pin_active_high {
+ false => PinPolarity::ActiveLow,
+ true => PinPolarity::ActiveHigh,
+ },
+ mode: match thermal_mode {
+ false => Mode::Alert,
+ true => Mode::Thermal,
+ },
+ conversion_averaging_mode: match averaged_conversions {
+ 0 => ConversionAveragingMode::None,
+ 8 => ConversionAveragingMode::Avg8,
+ 32 => ConversionAveragingMode::Avg32,
+ 64 => ConversionAveragingMode::Avg64,
+ _ => todo!("Handle invalid averaging value"),
+ },
+ conversion_mode: ConversionMode::Continuous,
+ };
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ tmp117.configure_typed(configuration).unwrap();
+ }
+ ConfigureCommands::Get {} => {
+ info!("Getting configuration...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ let configuration = tmp117.get_configuration().unwrap();
+ println!("{:#06x}", configuration)
+ }
+ ConfigureCommands::GetFields {} => {
+ info!("Getting configuration...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ let configuration = tmp117.get_configuration_typed().unwrap();
+ println!("{}", configuration);
+ }
+ },
+ Some(Commands::HighLimit { command }) => match command {
+ HighLimitCommands::Set { limit, celsius } => {
+ info!("Setting high limit...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ trace!("Limit (°C): {:.4}", *limit);
+ tmp117.configure_high_limit_celsius(*limit).unwrap();
+ } else {
+ trace!("Limit: {:#06x}", (*limit as i16));
+ tmp117.configure_high_limit(*limit as i16).unwrap();
+ }
+ }
+ HighLimitCommands::Get { celsius } => {
+ info!("Getting high limit...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ let limit = tmp117.get_high_limit_celsius().unwrap();
+ println!("{:.4} °C", limit);
+ } else {
+ let limit = tmp117.get_high_limit().unwrap();
+ println!("{:#06x}", limit);
+ }
+ }
+ },
+ Some(Commands::LowLimit { command }) => match command {
+ LowLimitCommands::Set { limit, celsius } => {
+ info!("Setting low limit...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ trace!("Limit (°C): {:.4}", *limit);
+ tmp117.configure_low_limit_celsius(*limit).unwrap();
+ } else {
+ trace!("Limit: {:#06x}", (*limit as i16));
+ tmp117.configure_low_limit(*limit as i16).unwrap();
+ }
+ }
+ LowLimitCommands::Get { celsius } => {
+ info!("Getting low limit...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ let limit = tmp117.get_low_limit_celsius().unwrap();
+ println!("{:.4} °C", limit);
+ } else {
+ let limit = tmp117.get_low_limit().unwrap();
+ println!("{:#06x}", limit);
+ }
+ }
+ },
+ Some(Commands::Offset { command }) => match command {
+ OffsetCommands::Set { offset, celsius } => {
+ info!("Setting temperature offset...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ trace!("Offset (°C): {:.4}", *offset);
+ tmp117
+ .configure_offset_temperature_celsius(*offset)
+ .unwrap();
+ } else {
+ trace!("Offset: {:#06x}", (*offset as i16));
+ tmp117.configure_offset_temperature(*offset as i16).unwrap();
+ }
+ }
+ OffsetCommands::Get { celsius } => {
+ info!("Getting temperature offset...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+
+ if *celsius {
+ let offset = tmp117.get_offset_temperature_celsius().unwrap();
+ println!("{:.4} °C", offset);
+ } else {
+ let offset = tmp117.get_offset_temperature().unwrap();
+ println!("{:#06x}", offset);
+ }
+ }
+ },
+ Some(Commands::Reset {}) => {
+ info!("Resetting TI TMP117...");
+
+ let i2c = I2cdev::new(&cli.i2c_device_path).unwrap();
+ let delay = Delay;
+ let mut tmp117 = TMP117::new(cli.slave_address, i2c, delay);
+ tmp117.software_reset().unwrap();
+ }
+ None => {}
+ }
+}