diff mbox series

[libgpiod,16/16] bindings: rust: provide line_config.set_output_values()

Message ID 20230113215210.616812-17-brgl@bgdev.pl
State New
Headers show
Series treewide: continue beating libgpiod v2 into shape for an upcoming release | expand

Commit Message

Bartosz Golaszewski Jan. 13, 2023, 9:52 p.m. UTC
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

Add a new function to line config allowing to set a list of output values
for requested lines. This works very similarily to the C++ version of the
new C interface.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
 bindings/rust/libgpiod/src/lib.rs           |  1 +
 bindings/rust/libgpiod/src/line_config.rs   | 24 +++++++-
 bindings/rust/libgpiod/tests/line_config.rs | 62 +++++++++++++++++++++
 3 files changed, 86 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/bindings/rust/libgpiod/src/lib.rs b/bindings/rust/libgpiod/src/lib.rs
index a5d018c..f268ceb 100644
--- a/bindings/rust/libgpiod/src/lib.rs
+++ b/bindings/rust/libgpiod/src/lib.rs
@@ -71,6 +71,7 @@  pub enum OperationType {
     InfoEventGetLineInfo,
     LineConfigNew,
     LineConfigAddSettings,
+    LineConfigSetOutputValues,
     LineConfigGetOffsets,
     LineConfigGetSettings,
     LineRequestReconfigLines,
diff --git a/bindings/rust/libgpiod/src/line_config.rs b/bindings/rust/libgpiod/src/line_config.rs
index 2169bf1..b276cf0 100644
--- a/bindings/rust/libgpiod/src/line_config.rs
+++ b/bindings/rust/libgpiod/src/line_config.rs
@@ -7,7 +7,7 @@  use std::collections::HashMap;
 
 use super::{
     gpiod,
-    line::{Offset, Settings},
+    line::{Offset, Settings, Value},
     Error, OperationType, Result,
 };
 
@@ -77,6 +77,28 @@  impl Config {
         }
     }
 
+    /// Set output values for a number of lines.
+    pub fn set_output_values(&mut self, values: &[Value]) -> Result<&mut Self> {
+        let mut mapped_values = Vec::new();
+        for value in values {
+            mapped_values.push(value.value());
+        }
+
+        let ret = unsafe {
+            gpiod::gpiod_line_config_set_output_values(self.config, mapped_values.as_ptr(),
+                                                       values.len() as u64)
+        };
+
+        if ret == -1 {
+            Err(Error::OperationFailed(
+                OperationType::LineConfigSetOutputValues,
+                errno::errno(),
+            ))
+        } else {
+            Ok(self)
+        }
+    }
+
     /// Get a mapping of offsets to line settings stored by this object.
     pub fn line_settings(&self) -> Result<HashMap<Offset, Settings>> {
         let mut map: HashMap<Offset, Settings> = HashMap::new();
diff --git a/bindings/rust/libgpiod/tests/line_config.rs b/bindings/rust/libgpiod/tests/line_config.rs
index 92a7af3..96ce127 100644
--- a/bindings/rust/libgpiod/tests/line_config.rs
+++ b/bindings/rust/libgpiod/tests/line_config.rs
@@ -5,9 +5,11 @@ 
 mod common;
 
 mod line_config {
+    use libgpiod::chip::Chip;
     use libgpiod::line::{
         self, Bias, Direction, Drive, Edge, EventClock, SettingKind, SettingVal, Value,
     };
+    use gpiosim_sys::Sim;
 
     #[test]
     fn settings() {
@@ -76,4 +78,64 @@  mod line_config {
             SettingVal::OutputValue(Value::Active)
         );
     }
+
+    #[test]
+    fn set_global_output_values() {
+        let sim = Sim::new(Some(4), None, true).unwrap();
+        let mut settings = line::Settings::new().unwrap();
+        settings.set_direction(Direction::Output).unwrap();
+
+        let mut config = line::Config::new().unwrap();
+        config
+            .add_line_settings(&[0, 1, 2, 3], settings)
+            .unwrap()
+            .set_output_values(&[
+                Value::Active,
+                Value::InActive,
+                Value::Active,
+                Value::InActive
+            ])
+            .unwrap();
+
+        let chip = Chip::open(&sim.dev_path()).unwrap();
+        let _request = chip.request_lines(None, &config);
+
+        assert_eq!(sim.val(0).unwrap(), gpiosim_sys::Value::Active);
+        assert_eq!(sim.val(1).unwrap(), gpiosim_sys::Value::InActive);
+        assert_eq!(sim.val(2).unwrap(), gpiosim_sys::Value::Active);
+        assert_eq!(sim.val(3).unwrap(), gpiosim_sys::Value::InActive);
+    }
+
+    #[test]
+    fn read_back_global_output_values() {
+        let mut settings = line::Settings::new().unwrap();
+        settings
+            .set_direction(Direction::Output)
+            .unwrap()
+            .set_output_value(Value::Active)
+            .unwrap();
+
+        let mut config = line::Config::new().unwrap();
+        config
+            .add_line_settings(&[0, 1, 2, 3], settings)
+            .unwrap()
+            .set_output_values(&[
+                Value::Active,
+                Value::InActive,
+                Value::Active,
+                Value::InActive,
+            ])
+            .unwrap();
+
+        assert_eq!(
+            config
+                .line_settings()
+                .unwrap()
+                .get(&1)
+                .unwrap()
+                .output_value()
+                .unwrap(),
+            Value::InActive
+        );
+    }
 }