Repo of no-std crates for my personal embedded projects

Refactor power mode API

+65 -60
+65 -60
sachy-shtc3/src/lib.rs
··· 35 35 //! use sachy_shtc3::ShtC3; 36 36 //! 37 37 //! let dev = I2cdev::new("/dev/i2c-1").unwrap(); 38 - //! let mut sht = ShtC3::new(dev); 38 + //! let mut sht = ShtC3::new(dev, Default::default()); 39 39 //! ``` 40 40 //! 41 41 //! ### Device Info ··· 45 45 //! ```no_run 46 46 //! use linux_embedded_hal::{Delay, I2cdev}; 47 47 //! use sachy_shtc3::ShtC3; 48 - //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); 48 + //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), Default::default()); 49 49 //! let device_id = sht.device_identifier().unwrap(); 50 50 //! let raw_id = sht.raw_id_register().unwrap(); 51 51 //! ``` ··· 59 59 //! use linux_embedded_hal::{Delay, I2cdev}; 60 60 //! use sachy_shtc3::{ShtC3, PowerMode}; 61 61 //! 62 - //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); 62 + //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), Default::default()); 63 63 //! let mut delay = Delay; 64 64 //! 65 - //! let temperature = sht.measure_temperature(PowerMode::NormalMode, &mut delay).unwrap(); 66 - //! let humidity = sht.measure_humidity(PowerMode::NormalMode, &mut delay).unwrap(); 67 - //! let combined = sht.measure(PowerMode::NormalMode, &mut delay).unwrap(); 65 + //! let temperature = sht.measure_temperature(&mut delay).unwrap(); 66 + //! let humidity = sht.measure_humidity(&mut delay).unwrap(); 67 + //! let combined = sht.measure(&mut delay).unwrap(); 68 68 //! 69 69 //! println!("Temperature: {} °C", temperature.as_degrees_celsius()); 70 70 //! println!("Humidity: {} %RH", humidity.as_percent()); ··· 82 82 //! ```no_run 83 83 //! use linux_embedded_hal::{Delay, I2cdev}; 84 84 //! use sachy_shtc3::{ShtC3, PowerMode}; 85 - //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); 85 + //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), PowerMode::LowPower); 86 86 //! let mut delay = Delay; 87 - //! let measurement = sht.measure(PowerMode::LowPower, &mut delay).unwrap(); 87 + //! let measurement = sht.measure(&mut delay).unwrap(); 88 88 //! ``` 89 89 //! 90 90 //! ### Measurements (Non-Blocking) ··· 97 97 //! use linux_embedded_hal::I2cdev; 98 98 //! use sachy_shtc3::{ShtC3, PowerMode}; 99 99 //! 100 - //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); 100 + //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), PowerMode::NormalMode); 101 101 //! 102 - //! sht.start_measurement(PowerMode::NormalMode).unwrap(); 102 + //! sht.start_measurement().unwrap(); 103 103 //! // Wait for at least `max_measurement_duration(&sht, PowerMode::NormalMode)` µs 104 104 //! let result = sht.get_measurement_result().unwrap(); 105 105 //! ``` ··· 129 129 //! ```no_run 130 130 //! use linux_embedded_hal::{Delay, I2cdev}; 131 131 //! use sachy_shtc3::{ShtC3, PowerMode}; 132 - //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap()); 132 + //! let mut sht = ShtC3::new(I2cdev::new("/dev/i2c-1").unwrap(), PowerMode::NormalMode); 133 133 //! let mut delay = Delay; 134 134 //! sht.reset(&mut delay).unwrap(); 135 135 //! ``` ··· 169 169 /// note][an-low-power] by Sensirion. 170 170 /// 171 171 /// [an-low-power]: https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/2_Humidity_Sensors/Sensirion_Humidity_Sensors_SHTC3_Low_Power_Measurement_Mode.pdf 172 - #[derive(Debug, Copy, Clone, PartialEq, Eq)] 172 + #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] 173 173 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 174 174 pub enum PowerMode { 175 175 /// Normal measurement. 176 + #[default] 176 177 NormalMode, 177 178 /// Low power measurement: Less energy consumption, but repeatability and 178 179 /// accuracy of measurements are negatively impacted. ··· 262 263 i2c: I2C, 263 264 /// The I²C device address. 264 265 address: u8, 266 + mode: PowerMode, 265 267 } 266 268 267 269 impl<I2C> ShtC3<I2C> { 268 270 /// Create a new instance of the driver for the SHTC3. 269 271 #[inline] 270 - pub const fn new(i2c: I2C) -> Self { 271 - Self { i2c, address: 0x70 } 272 + pub const fn new(i2c: I2C, mode: PowerMode) -> Self { 273 + Self { 274 + i2c, 275 + address: 0x70, 276 + mode, 277 + } 272 278 } 273 279 274 280 /// Get the device's wakeup delay duration in microseconds ··· 289 295 /// - Normal mode: 12.1 ms 290 296 /// - Low power mode: 0.8 ms 291 297 #[inline(always)] 292 - pub const fn max_measurement_duration(&self, mode: PowerMode) -> u32 { 293 - match mode { 298 + pub const fn max_measurement_duration(&self) -> u32 { 299 + match self.mode { 294 300 PowerMode::NormalMode => 12100, 295 301 PowerMode::LowPower => 800, 296 302 } ··· 421 427 }) 422 428 .await?; 423 429 424 - delay.delay_us(self.max_measurement_duration(mode)).await; 430 + delay.delay_us(self.max_measurement_duration()).await; 425 431 426 432 let mut buf = [0; 6]; 427 433 self.read_with_crc_async(&mut buf).await?; ··· 543 549 } 544 550 545 551 /// Start a combined temperature / humidity measurement. 546 - pub fn start_measurement(&mut self, mode: PowerMode) -> Result<(), Error<I2C::Error>> { 547 - self.start_measure_partial(mode, MeasurementOrder::TemperatureFirst) 552 + pub fn start_measurement(&mut self) -> Result<(), Error<I2C::Error>> { 553 + self.start_measure_partial(self.mode, MeasurementOrder::TemperatureFirst) 548 554 } 549 555 550 556 /// Start a temperature measurement. 551 - pub fn start_temperature_measurement( 552 - &mut self, 553 - mode: PowerMode, 554 - ) -> Result<(), Error<I2C::Error>> { 555 - self.start_measure_partial(mode, MeasurementOrder::TemperatureFirst) 557 + pub fn start_temperature_measurement(&mut self) -> Result<(), Error<I2C::Error>> { 558 + self.start_measure_partial(self.mode, MeasurementOrder::TemperatureFirst) 556 559 } 557 560 558 561 /// Start a humidity measurement. 559 - pub fn start_humidity_measurement(&mut self, mode: PowerMode) -> Result<(), Error<I2C::Error>> { 560 - self.start_measure_partial(mode, MeasurementOrder::HumidityFirst) 562 + pub fn start_humidity_measurement(&mut self) -> Result<(), Error<I2C::Error>> { 563 + self.start_measure_partial(self.mode, MeasurementOrder::HumidityFirst) 561 564 } 562 565 563 566 /// Read the result of a temperature / humidity measurement. ··· 609 612 I2C: I2c<SevenBitAddress>, 610 613 { 611 614 /// Wait the maximum time needed for the given measurement mode 612 - pub fn wait_for_measurement(&mut self, mode: PowerMode, delay: &mut impl BlockingDelayNs) { 613 - delay.delay_us(self.max_measurement_duration(mode)); 615 + pub fn wait_for_measurement(&mut self, delay: &mut impl BlockingDelayNs) { 616 + delay.delay_us(self.max_measurement_duration()); 614 617 } 615 618 616 619 /// Run a temperature/humidity measurement and return the combined result. ··· 618 621 /// This is a blocking function call. 619 622 pub fn measure( 620 623 &mut self, 621 - mode: PowerMode, 622 624 delay: &mut impl BlockingDelayNs, 623 625 ) -> Result<Measurement, Error<I2C::Error>> { 624 - self.start_measurement(mode)?; 625 - self.wait_for_measurement(mode, delay); 626 + self.start_measurement()?; 627 + self.wait_for_measurement(delay); 626 628 self.get_measurement_result() 627 629 } 628 630 ··· 634 636 /// and only read the first half of the measurement response. 635 637 pub fn measure_temperature( 636 638 &mut self, 637 - mode: PowerMode, 638 639 delay: &mut impl BlockingDelayNs, 639 640 ) -> Result<Temperature, Error<I2C::Error>> { 640 - self.start_temperature_measurement(mode)?; 641 - self.wait_for_measurement(mode, delay); 641 + self.start_temperature_measurement()?; 642 + self.wait_for_measurement(delay); 642 643 self.get_temperature_measurement_result() 643 644 } 644 645 ··· 650 651 /// and only read the first half of the measurement response. 651 652 pub fn measure_humidity( 652 653 &mut self, 653 - mode: PowerMode, 654 654 delay: &mut impl BlockingDelayNs, 655 655 ) -> Result<Humidity, Error<I2C::Error>> { 656 - self.start_humidity_measurement(mode)?; 657 - self.wait_for_measurement(mode, delay); 656 + self.start_humidity_measurement()?; 657 + self.wait_for_measurement(delay); 658 658 self.get_humidity_measurement_result() 659 659 } 660 660 } ··· 683 683 [Transaction::write(SHT_ADDR, alloc::vec![0xef, 0xc8]) 684 684 .with_error(ErrorKind::Other)]; 685 685 let mock = I2cMock::new(&expectations); 686 - let mut sht = ShtC3::new(mock); 686 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 687 687 let err = sht.send_command(Command::ReadIdRegister).unwrap_err(); 688 688 assert_eq!(err, Error::I2c(ErrorKind::Other)); 689 689 sht.destroy().done(); ··· 693 693 #[test] 694 694 fn validate_crc() { 695 695 let mock = I2cMock::new(&[]); 696 - let sht = ShtC3::new(mock); 696 + let sht = ShtC3::new(mock, PowerMode::NormalMode); 697 697 698 698 // Not enough data 699 699 sht.validate_crc(&[]).unwrap(); ··· 730 730 // Valid CRC 731 731 let expectations = [Transaction::read(SHT_ADDR, alloc::vec![0xbe, 0xef, 0x92])]; 732 732 let mock = I2cMock::new(&expectations); 733 - let mut sht = ShtC3::new(mock); 733 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 734 734 sht.read_with_crc(&mut buf).unwrap(); 735 735 assert_eq!(buf, [0xbe, 0xef, 0x92]); 736 736 sht.destroy().done(); ··· 738 738 // Invalid CRC 739 739 let expectations = [Transaction::read(SHT_ADDR, alloc::vec![0xbe, 0xef, 0x00])]; 740 740 let mock = I2cMock::new(&expectations); 741 - let mut sht = ShtC3::new(mock); 741 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 742 742 match sht.read_with_crc(&mut buf) { 743 743 Err(Error::Crc) => {} 744 744 Err(_) => panic!("Invalid error: Must be Crc"), ··· 755 755 #[test] 756 756 fn new_shtc3() { 757 757 let mock = I2cMock::new(&[]); 758 - let sht = ShtC3::new(mock); 758 + let sht = ShtC3::new(mock, PowerMode::NormalMode); 759 759 assert_eq!(sht.address, 0x70); 760 760 sht.destroy().done(); 761 761 } ··· 775 775 Transaction::read(SHT_ADDR, alloc::vec![msb, lsb, crc]), 776 776 ]; 777 777 let mock = I2cMock::new(&expectations); 778 - let mut sht = ShtC3::new(mock); 778 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 779 779 let val = sht.raw_id_register().unwrap(); 780 780 assert_eq!(val, (msb as u16) << 8 | (lsb as u16)); 781 781 sht.destroy().done(); ··· 792 792 Transaction::read(SHT_ADDR, alloc::vec![msb, lsb, crc]), 793 793 ]; 794 794 let mock = I2cMock::new(&expectations); 795 - let mut sht = ShtC3::new(mock); 795 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 796 796 let ident = sht.device_identifier().unwrap(); 797 797 assert_eq!(ident, 0b01000111); 798 798 sht.destroy().done(); ··· 823 823 ), 824 824 ]; 825 825 let mock = I2cMock::new(&expectations); 826 - let mut sht = ShtC3::new(mock); 826 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 827 827 let mut delay = NoopDelay; 828 - let measurement = sht.measure(PowerMode::NormalMode, &mut delay).unwrap(); 828 + let measurement = sht.measure(&mut delay).unwrap(); 829 829 assert_eq!(measurement.temperature.as_millidegrees_celsius(), 23_730); // 23.7°C 830 830 assert_eq!(measurement.humidity.as_millipercent(), 62_968); // 62.9 %RH 831 831 sht.destroy().done(); ··· 852 852 ), 853 853 ]; 854 854 let mock = I2cMock::new(&expectations); 855 - let mut sht = ShtC3::new(mock); 855 + let mut sht = ShtC3::new(mock, PowerMode::LowPower); 856 856 let mut delay = NoopDelay; 857 - let measurement = sht.measure(PowerMode::LowPower, &mut delay).unwrap(); 857 + let measurement = sht.measure(&mut delay).unwrap(); 858 858 assert_eq!(measurement.temperature.as_millidegrees_celsius(), 23_730); // 23.7°C 859 859 assert_eq!(measurement.humidity.as_millipercent(), 62_968); // 62.9 %RH 860 860 sht.destroy().done(); ··· 871 871 Transaction::read(SHT_ADDR, alloc::vec![0b0110_0100, 0b1000_1011, 0b1100_0111]), 872 872 ]; 873 873 let mock = I2cMock::new(&expectations); 874 - let mut sht = ShtC3::new(mock); 874 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 875 875 let mut delay = NoopDelay; 876 876 let temperature = sht 877 - .measure_temperature(PowerMode::NormalMode, &mut delay) 877 + .measure_temperature(&mut delay) 878 878 .unwrap(); 879 879 assert_eq!(temperature.as_millidegrees_celsius(), 23_730); // 23.7°C 880 880 sht.destroy().done(); ··· 891 891 Transaction::read(SHT_ADDR, alloc::vec![0b1010_0001, 0b0011_0011, 0b0001_1100]), 892 892 ]; 893 893 let mock = I2cMock::new(&expectations); 894 - let mut sht = ShtC3::new(mock); 894 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 895 895 let mut delay = NoopDelay; 896 896 let humidity = sht 897 - .measure_humidity(PowerMode::NormalMode, &mut delay) 897 + .measure_humidity(&mut delay) 898 898 .unwrap(); 899 899 assert_eq!(humidity.as_millipercent(), 62_968); // 62.9 %RH 900 900 sht.destroy().done(); ··· 907 907 [Transaction::write(SHT_ADDR, alloc::vec![0x60, 0x9C]) 908 908 .with_error(ErrorKind::Other)]; 909 909 let mock = I2cMock::new(&expectations); 910 - let mut sht = ShtC3::new(mock); 910 + let mut sht = ShtC3::new(mock, PowerMode::LowPower); 911 911 let err = sht 912 - .measure(PowerMode::LowPower, &mut NoopDelay) 912 + .measure(&mut NoopDelay) 913 913 .unwrap_err(); 914 914 assert_eq!(err, Error::I2c(ErrorKind::Other)); 915 915 sht.destroy().done(); ··· 924 924 fn sleep() { 925 925 let expectations = [Transaction::write(SHT_ADDR, alloc::vec![0xB0, 0x98])]; 926 926 let mock = I2cMock::new(&expectations); 927 - let mut sht = ShtC3::new(mock); 927 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 928 928 sht.sleep().unwrap(); 929 929 sht.destroy().done(); 930 930 } ··· 934 934 fn wakeup() { 935 935 let expectations = [Transaction::write(SHT_ADDR, alloc::vec![0x35, 0x17])]; 936 936 let mock = I2cMock::new(&expectations); 937 - let mut sht = ShtC3::new(mock); 937 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 938 938 sht.wakeup(&mut NoopDelay).unwrap(); 939 939 sht.destroy().done(); 940 940 } ··· 944 944 fn reset() { 945 945 let expectations = [Transaction::write(SHT_ADDR, alloc::vec![0x80, 0x5D])]; 946 946 let mock = I2cMock::new(&expectations); 947 - let mut sht = ShtC3::new(mock); 947 + let mut sht = ShtC3::new(mock, PowerMode::NormalMode); 948 948 sht.reset(&mut NoopDelay).unwrap(); 949 949 sht.destroy().done(); 950 950 } ··· 955 955 956 956 #[test] 957 957 fn shortcut_function() { 958 - let c3 = ShtC3::new(I2cMock::new(&[])); 958 + let c3 = ShtC3::new(I2cMock::new(&[]), PowerMode::NormalMode); 959 + 960 + assert_eq!(c3.max_measurement_duration(), 12100); 961 + 962 + let i2c = c3.destroy(); 963 + 964 + let c3 = ShtC3::new(i2c, PowerMode::LowPower); 959 965 960 - assert_eq!(c3.max_measurement_duration(PowerMode::NormalMode), 12100); 961 - assert_eq!(c3.max_measurement_duration(PowerMode::LowPower), 800); 966 + assert_eq!(c3.max_measurement_duration(), 800); 962 967 963 968 c3.destroy().done(); 964 969 }