automation_hat/digital_output.rs
1//! Digital output control for Automation HAT boards.
2//!
3//! This module provides control for the digital output pins on Automation HAT boards.
4//! Digital outputs provide 5V signals for controlling external devices and have indicator
5//! LEDs to show their current state.
6
7use crate::lights::LED;
8
9use embedded_hal::digital::{OutputPin, PinState};
10use linux_embedded_hal::{
11 CdevPin,
12 gpio_cdev::{Line, LineRequestFlags},
13};
14
15/// Controls a digital output on the Automation HAT.
16///
17/// Digital outputs provide 5V signals for controlling external devices.
18/// When an output is set high, it outputs 5V. Each output can have an associated
19/// LED that automatically indicates the output state.
20pub struct DigitalOutput {
21 /// GPIO pin for the digital output
22 pin: CdevPin,
23 /// Optional LED indicator for this output
24 led: Option<LED>,
25 /// Whether the LED should automatically reflect output state
26 _auto_light: bool,
27 /// Current state of the output (true = high/on, false = low/off)
28 pub value: bool,
29}
30
31impl DigitalOutput {
32 /// Creates a new digital output with automatic LED indication enabled.
33 ///
34 /// # Arguments
35 ///
36 /// * `line` - GPIO line connected to the digital output
37 /// * `led` - Optional LED indicator for this output
38 ///
39 /// # Returns
40 ///
41 /// A new `DigitalOutput` instance with automatic LED indication enabled
42 pub fn new(line: Line, led: Option<LED>) -> Self {
43 let line = line
44 .request(LineRequestFlags::OUTPUT, 0, "AutomationHAT Rust SDK")
45 .unwrap();
46 let pin = CdevPin::new(line).unwrap();
47 DigitalOutput {
48 pin,
49 led,
50 _auto_light: true,
51 value: false,
52 }
53 }
54
55 /// Creates a new digital output with configurable LED indication.
56 ///
57 /// # Arguments
58 ///
59 /// * `line` - GPIO line connected to the digital output
60 /// * `led` - Optional LED indicator for this output
61 /// * `auto_light` - Whether the LED should automatically reflect the output state
62 ///
63 /// # Returns
64 ///
65 /// A new `DigitalOutput` instance with the specified LED behavior
66 pub fn new_with_auto_light(line: Line, led: Option<LED>, auto_light: bool) -> Self {
67 let line = line
68 .request(LineRequestFlags::OUTPUT, 0, "AutomationHAT Rust SDK")
69 .unwrap();
70 let pin = CdevPin::new(line).unwrap();
71 DigitalOutput {
72 pin,
73 led,
74 _auto_light: auto_light,
75 value: false,
76 }
77 }
78
79 /// Sets the state of the digital output.
80 ///
81 /// When `on` is true, the output is set high (5V).
82 /// When `on` is false, the output is set low (0V).
83 /// If auto_light is enabled and an LED is attached, this method will
84 /// also update the LED to reflect the current output state.
85 ///
86 /// # Arguments
87 ///
88 /// * `on` - The desired state of the output (true = high/on, false = low/off)
89 ///
90 /// # Returns
91 ///
92 /// * `Ok(())` - If the output was successfully set
93 /// * `Err(String)` - If setting the output or LED failed, with an error message
94 pub fn write(&mut self, on: bool) -> Result<(), String> {
95 if self._auto_light {
96 if let Some(led) = &mut self.led {
97 match led.set(match on {
98 true => 1.0,
99 false => 0.0,
100 }) {
101 Ok(_) => {}
102 Err(e) => return Err(format!("Unable to set LED state: {}", e)),
103 }
104 }
105 }
106 return match self.pin.set_state(match on {
107 true => PinState::High,
108 false => PinState::Low,
109 }) {
110 Ok(_) => {
111 self.value = on;
112 Ok(())
113 }
114 Err(e) => Err(format!("Unable to set pin state: {}", e)),
115 };
116 }
117}