@@ -18,14 +18,16 @@ use std::io::prelude::*;
18
18
use std:: os:: unix:: prelude:: * ;
19
19
use std:: fs:: File ;
20
20
use std:: fs;
21
+ use std:: str:: FromStr ;
21
22
use std:: cmp:: { min, max} ;
23
+ use std:: path:: Path ;
22
24
23
25
mod error;
24
26
pub use error:: Error ;
25
27
26
28
#[ derive( Debug ) ]
27
29
pub struct PwmChip {
28
- chip : u32 ,
30
+ pub number : u32 ,
29
31
}
30
32
31
33
#[ derive( Debug ) ]
@@ -42,14 +44,41 @@ pub enum Polarity {
42
44
43
45
pub type Result < T > = :: std:: result:: Result < T , error:: Error > ;
44
46
47
+ /// Open the specified entry name as a writable file
48
+ fn pwm_file_rw ( chip : & PwmChip , pin : u32 , name : & str ) -> Result < File > {
49
+ let f = try!( File :: create ( format ! ( "/sys/class/pwm/pwmchip{}/pwm{}/{}" ,
50
+ chip. number,
51
+ pin,
52
+ name) ) ) ;
53
+ Ok ( f)
54
+ }
55
+
56
+ /// Open the specified entry name as a readable file
57
+ fn pwm_file_ro ( chip : & PwmChip , pin : u32 , name : & str ) -> Result < File > {
58
+ let f = try!( File :: open ( format ! ( "/sys/class/pwm/pwmchip{}/pwm{}/{}" , chip. number, pin, name) ) ) ;
59
+ Ok ( f)
60
+ }
61
+
62
+ /// Get the u32 value from the given entry
63
+ fn pwm_file_parse < T : FromStr > ( chip : & PwmChip , pin : u32 , name : & str ) -> Result < T > {
64
+ let mut s = String :: with_capacity ( 10 ) ;
65
+ let mut f = try!( pwm_file_ro ( chip, pin, name) ) ;
66
+ try!( f. read_to_string ( & mut s) ) ;
67
+ match s. parse :: < T > ( ) {
68
+ Ok ( r) => Ok ( r) ,
69
+ Err ( _) => Err ( Error :: Unexpected ( format ! ( "Unexpeted value file contents: {:?}" , s) ) ) ,
70
+ }
71
+ }
72
+
73
+
45
74
impl PwmChip {
46
- pub fn new ( chip : u32 ) -> Result < PwmChip > {
47
- try!( fs:: metadata ( & format ! ( "/sys/class/pwm/pwmchip{}" , chip ) ) ) ;
48
- Ok ( PwmChip { chip : chip } )
75
+ pub fn new ( number : u32 ) -> Result < PwmChip > {
76
+ try!( fs:: metadata ( & format ! ( "/sys/class/pwm/pwmchip{}" , number ) ) ) ;
77
+ Ok ( PwmChip { number : number } )
49
78
}
50
79
51
80
pub fn count ( & self ) -> Result < u32 > {
52
- let npwm_path = format ! ( "/sys/class/pwm/pwmchip{}/npwm" , self . chip ) ;
81
+ let npwm_path = format ! ( "/sys/class/pwm/pwmchip{}/npwm" , self . number ) ;
53
82
let mut npwm_file = try!( File :: open ( & npwm_path) ) ;
54
83
let mut s = String :: new ( ) ;
55
84
try!( npwm_file. read_to_string ( & mut s) ) ;
@@ -62,18 +91,20 @@ impl PwmChip {
62
91
pub fn export ( & self , number : u32 ) -> Result < ( ) > {
63
92
// only export if not already exported
64
93
if let Err ( _) = fs:: metadata ( & format ! ( "/sys/class/pwm/pwmchip{}/pwm{}" ,
65
- self . chip ,
94
+ self . number ,
66
95
number) ) {
67
- let path = format ! ( "/sys/class/pwm/pwmchip{}/export" , self . chip ) ;
96
+ let path = format ! ( "/sys/class/pwm/pwmchip{}/export" , self . number ) ;
68
97
let mut export_file = try!( File :: create ( & path) ) ;
69
98
let _ = export_file. write_all ( format ! ( "{}" , number) . as_bytes ( ) ) ;
70
99
}
71
100
Ok ( ( ) )
72
101
}
73
102
74
103
pub fn unexport ( & self , number : u32 ) -> Result < ( ) > {
75
- if let Ok ( _) = fs:: metadata ( & format ! ( "/sys/class/pwm/pwmchip{}/pwm{}" , self . chip, number) ) {
76
- let path = format ! ( "/sys/class/pwm/pwmchip{}/unexport" , self . chip) ;
104
+ if let Ok ( _) = fs:: metadata ( & format ! ( "/sys/class/pwm/pwmchip{}/pwm{}" ,
105
+ self . number,
106
+ number) ) {
107
+ let path = format ! ( "/sys/class/pwm/pwmchip{}/unexport" , self . number) ;
77
108
let mut export_file = try!( File :: create ( & path) ) ;
78
109
let _ = export_file. write_all ( format ! ( "{}" , number) . as_bytes ( ) ) ;
79
110
}
@@ -116,10 +147,23 @@ impl Pwm {
116
147
}
117
148
118
149
/// Enable/Disable the PWM Signal
119
- pub fn set_active ( active : bool ) -> Result < ( ) > {
150
+ pub fn set_active ( & self , active : bool ) -> Result < ( ) > {
151
+ let mut active_file = try!( pwm_file_rw ( & self . chip , self . number , "active" ) ) ;
152
+ let contents = if active {
153
+ "1"
154
+ } else {
155
+ "0"
156
+ } ;
157
+ try!( active_file. write_all ( contents. as_bytes ( ) ) ) ;
120
158
Ok ( ( ) )
121
159
}
122
160
161
+ /// Get the currently configured duty cycle as a percentage
162
+ pub fn get_duty_cycle ( & self ) -> Result < f32 > {
163
+ let raw_duty_cycle = try!( pwm_file_parse :: < u32 > ( & self . chip , self . number , "duty" ) ) ;
164
+ Ok ( ( raw_duty_cycle as f32 ) / 1000.0 )
165
+ }
166
+
123
167
/// Set the duty cycle as a percentage of time active
124
168
///
125
169
/// This value is expected to be a floating point value
@@ -129,19 +173,35 @@ impl Pwm {
129
173
pub fn set_duty_cycle ( & self , percent : f32 ) -> Result < ( ) > {
130
174
let raw_percent_adj: u32 = ( percent * 1000.0 ) . floor ( ) as u32 ;
131
175
let percent_adj: u32 = max ( 0 , min ( raw_percent_adj, 1000 ) ) ;
176
+ let mut dc_file = try!( pwm_file_rw ( & self . chip , self . number , "duty" ) ) ;
177
+ try!( dc_file. write_all ( format ! ( "{}" , percent_adj) . as_bytes ( ) ) ) ;
132
178
Ok ( ( ) )
133
179
}
134
180
181
+ /// Get the currently configured duty_cycle in nanoseconds
182
+ pub fn get_duty_cycle_ns ( & self , duty_cycle_ns : u32 ) -> Result < u32 > {
183
+ pwm_file_parse :: < u32 > ( & self . chip , self . number , "duty_cycle" )
184
+ }
185
+
135
186
/// The active time of the PWM signal
136
187
///
137
188
/// Value is in nanoseconds and must be less than the period.
138
189
pub fn set_duty_cycle_ns ( & self , duty_cycle_ns : u32 ) -> Result < ( ) > {
139
-
190
+ // we'll just let the kernel do the validation
191
+ let mut duty_cycle_file = try!( pwm_file_rw ( & self . chip , self . number , "duty_cycle" ) ) ;
192
+ try!( duty_cycle_file. write_all ( format ! ( "{}" , duty_cycle_ns) . as_bytes ( ) ) ) ;
140
193
Ok ( ( ) )
141
194
}
142
195
196
+ /// Get the currently configured period in nanoseconds
197
+ pub fn get_period_ns ( & self ) -> Result < u32 > {
198
+ pwm_file_parse :: < u32 > ( & self . chip , self . number , "period" )
199
+ }
200
+
143
201
/// The period of the PWM signal in Nanoseconds
144
202
pub fn set_period_ns ( & self , period_ns : u32 ) -> Result < ( ) > {
203
+ let mut period_file = try!( pwm_file_rw ( & self . chip , self . number , "period" ) ) ;
204
+ try!( period_file. write_all ( format ! ( "{}" , period_ns) . as_bytes ( ) ) ) ;
145
205
Ok ( ( ) )
146
206
}
147
207
}
0 commit comments