1- //! Linux CDev pin type
1+ //! Implementation of [`embedded-hal`] digital input/output traits using a Linux CDev pin
2+ //!
3+ //! [`embedded-hal`]: https://docs.rs/embedded-hal
24
35/// Newtype around [`gpio_cdev::LineHandle`] that implements the `embedded-hal` traits
46///
5- /// [`gpio_cdev::LineHandle`]: https://docs.rs/gpio-cdev/0.2 .0/gpio_cdev/struct.LineHandle.html
7+ /// [`gpio_cdev::LineHandle`]: https://docs.rs/gpio-cdev/0.5 .0/gpio_cdev/struct.LineHandle.html
68pub struct CdevPin ( pub gpio_cdev:: LineHandle , gpio_cdev:: LineInfo ) ;
79
810impl CdevPin {
911 /// See [`gpio_cdev::Line::request`][0] for details.
1012 ///
11- /// [0]: https://docs.rs/gpio-cdev/0.2 .0/gpio_cdev/struct.Line.html#method.request
13+ /// [0]: https://docs.rs/gpio-cdev/0.5 .0/gpio_cdev/struct.Line.html#method.request
1214 pub fn new ( handle : gpio_cdev:: LineHandle ) -> Result < Self , gpio_cdev:: errors:: Error > {
1315 let info = handle. line ( ) . info ( ) ?;
1416 Ok ( CdevPin ( handle, info) )
1517 }
1618
1719 fn get_input_flags ( & self ) -> gpio_cdev:: LineRequestFlags {
18- let mut flags = gpio_cdev:: LineRequestFlags :: INPUT ;
1920 if self . 1 . is_active_low ( ) {
20- flags . insert ( gpio_cdev:: LineRequestFlags :: ACTIVE_LOW ) ;
21+ return gpio_cdev:: LineRequestFlags :: INPUT | gpio_cdev :: LineRequestFlags :: ACTIVE_LOW ;
2122 }
22- return flags ;
23+ gpio_cdev :: LineRequestFlags :: INPUT
2324 }
2425
2526 fn get_output_flags ( & self ) -> gpio_cdev:: LineRequestFlags {
2627 let mut flags = gpio_cdev:: LineRequestFlags :: OUTPUT ;
28+ if self . 1 . is_active_low ( ) {
29+ flags. insert ( gpio_cdev:: LineRequestFlags :: ACTIVE_LOW ) ;
30+ }
2731 if self . 1 . is_open_drain ( ) {
2832 flags. insert ( gpio_cdev:: LineRequestFlags :: OPEN_DRAIN ) ;
2933 } else if self . 1 . is_open_source ( ) {
@@ -33,35 +37,58 @@ impl CdevPin {
3337 }
3438}
3539
36- impl embedded_hal:: digital:: OutputPin for CdevPin {
40+ /// Converts a pin state to the gpio_cdev compatible numeric value, accounting
41+ /// for the active_low condition.
42+ fn state_to_value ( state : embedded_hal:: digital:: PinState , is_active_low : bool ) -> u8 {
43+ if is_active_low {
44+ match state {
45+ embedded_hal:: digital:: PinState :: High => 0 ,
46+ embedded_hal:: digital:: PinState :: Low => 1 ,
47+ }
48+ } else {
49+ match state {
50+ embedded_hal:: digital:: PinState :: High => 1 ,
51+ embedded_hal:: digital:: PinState :: Low => 0 ,
52+ }
53+ }
54+ }
55+
56+ impl embedded_hal:: digital:: blocking:: OutputPin for CdevPin {
3757 type Error = gpio_cdev:: errors:: Error ;
3858
3959 fn set_low ( & mut self ) -> Result < ( ) , Self :: Error > {
40- self . 0 . set_value ( 0 )
60+ self . 0 . set_value ( state_to_value (
61+ embedded_hal:: digital:: PinState :: Low ,
62+ self . 1 . is_active_low ( ) ,
63+ ) )
4164 }
4265
4366 fn set_high ( & mut self ) -> Result < ( ) , Self :: Error > {
44- self . 0 . set_value ( 1 )
67+ self . 0 . set_value ( state_to_value (
68+ embedded_hal:: digital:: PinState :: High ,
69+ self . 1 . is_active_low ( ) ,
70+ ) )
4571 }
4672}
4773
48- impl embedded_hal:: digital:: InputPin for CdevPin {
74+ impl embedded_hal:: digital:: blocking :: InputPin for CdevPin {
4975 type Error = gpio_cdev:: errors:: Error ;
5076
5177 fn is_high ( & self ) -> Result < bool , Self :: Error > {
52- if !self . 1 . is_active_low ( ) {
53- self . 0 . get_value ( ) . map ( |val| val != 0 )
54- } else {
55- self . 0 . get_value ( ) . map ( |val| val == 0 )
56- }
78+ self . 0 . get_value ( ) . map ( |val| {
79+ val == state_to_value (
80+ embedded_hal:: digital:: PinState :: High ,
81+ self . 1 . is_active_low ( ) ,
82+ )
83+ } )
5784 }
5885
5986 fn is_low ( & self ) -> Result < bool , Self :: Error > {
6087 self . is_high ( ) . map ( |val| !val)
6188 }
6289}
6390
64- impl embedded_hal:: digital:: IoPin < CdevPin , CdevPin > for CdevPin {
91+ impl embedded_hal:: digital:: blocking :: IoPin < CdevPin , CdevPin > for CdevPin {
6592 type Error = gpio_cdev:: errors:: Error ;
6693
6794 fn into_input_pin ( self ) -> Result < CdevPin , Self :: Error > {
@@ -95,10 +122,10 @@ impl embedded_hal::digital::IoPin<CdevPin, CdevPin> for CdevPin {
95122
96123 CdevPin :: new ( line. request (
97124 output_flags,
98- match state {
99- embedded_hal :: digital :: PinState :: High => 1 ,
100- embedded_hal :: digital :: PinState :: Low => 0 ,
101- } ,
125+ state_to_value (
126+ state ,
127+ output_flags . intersects ( gpio_cdev :: LineRequestFlags :: ACTIVE_LOW ) ,
128+ ) ,
102129 & consumer,
103130 ) ?)
104131 }
0 commit comments