beaglebone 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,186 @@
1
+ module Beaglebone
2
+
3
+ module I2C
4
+
5
+ I2C_SLAVE = 0x0703
6
+
7
+ @i2cstatus = {}
8
+ @i2cmutex = Mutex.new
9
+
10
+ class << self
11
+ attr_accessor :i2cstatus, :i2cmutex
12
+
13
+ def write(i2c, address, data)
14
+ check_i2c_enabled(i2c)
15
+
16
+ lock_i2c(i2c) do
17
+ i2c_fd = get_i2c_status(i2c, :fd_i2c)
18
+
19
+ #set the slave address to communicate with
20
+ i2c_fd.ioctl(I2C_SLAVE, address)
21
+
22
+ i2c_fd.syswrite(data)
23
+ end
24
+
25
+ end
26
+
27
+ def read(i2c, address, bytes=1, register=nil)
28
+ check_i2c_enabled(i2c)
29
+
30
+ data = ''
31
+ lock_i2c(i2c) do
32
+ i2c_fd = get_i2c_status(i2c, :fd_i2c)
33
+
34
+ #set the slave address to communicate with
35
+ i2c_fd.ioctl(I2C_SLAVE, address)
36
+
37
+ i2c_fd.syswrite(register) if register
38
+
39
+ data = i2c_fd.sysread(bytes)
40
+ end
41
+
42
+ data
43
+ end
44
+
45
+ def file(i2c)
46
+ check_i2c_enabled(i2c)
47
+ get_i2c_status(i2c, :fd_i2c)
48
+ end
49
+
50
+ def setup(i2c)
51
+ check_i2c_valid(i2c)
52
+
53
+ #make sure i2c not already enabled
54
+ return if get_i2c_status(i2c)
55
+
56
+ i2cinfo = I2CS[i2c]
57
+
58
+ #ensure dtb is loaded
59
+ Beaglebone::device_tree_load("#{i2cinfo[:devicetree]}") if i2cinfo[:devicetree]
60
+
61
+ #open the i2c device
62
+ i2c_fd = File.open(i2cinfo[:dev], 'r+')
63
+
64
+ Beaglebone::set_pin_status(i2cinfo[:scl], :i2c, i2cinfo[:id])
65
+ Beaglebone::set_pin_status(i2cinfo[:scl], :type, :i2c)
66
+ Beaglebone::set_pin_status(i2cinfo[:scl], :fd_i2c, i2c_fd)
67
+
68
+ Beaglebone::set_pin_status(i2cinfo[:sda], :i2c, i2cinfo[:id])
69
+ Beaglebone::set_pin_status(i2cinfo[:sda], :type, :i2c)
70
+ Beaglebone::set_pin_status(i2cinfo[:sda], :fd_i2c, i2c_fd)
71
+
72
+ set_i2c_status(i2c, :fd_i2c, i2c_fd)
73
+ set_i2c_status(i2c, :mutex, Mutex.new)
74
+ end
75
+
76
+ def disable(i2c)
77
+ check_i2c_valid(i2c)
78
+ check_i2c_enabled(i2c)
79
+
80
+ disable_i2c_pin(I2CS[i2c][:sda]) if I2CS[i2c][:sda]
81
+ disable_i2c_pin(I2CS[i2c][:scl]) if I2CS[i2c][:scl]
82
+
83
+ delete_i2c_status(i2c)
84
+
85
+ #removing i2c tree causes a crash... can't really disable.
86
+ #Beaglebone::device_tree_unload("#{I2CS[i2c][:devicetree]}") if I2CS[i2c][:devicetree]
87
+
88
+ end
89
+
90
+ def cleanup
91
+ #reset all i2cs we've used and unload the device tree
92
+ i2cstatus.clone.keys.each { |i2c| disable(i2c)}
93
+ end
94
+
95
+ private
96
+
97
+ def disable_i2c_pin(pin)
98
+ Beaglebone::check_valid_pin(pin, :i2c)
99
+
100
+ Beaglebone::delete_pin_status(pin)
101
+ end
102
+
103
+ def check_i2c_valid(i2c)
104
+ raise ArgumentError, "Invalid i2c Specified #{i2c.to_s}" unless I2CS[i2c] && I2CS[i2c][:sda]
105
+ i2cinfo = I2CS[i2c.to_sym.upcase]
106
+
107
+ unless i2cinfo[:scl] && [nil,:i2c].include?(Beaglebone::get_pin_status(i2cinfo[:scl], :type))
108
+ raise StandardError, "SCL Pin for #{i2c.to_s} in use"
109
+ end
110
+
111
+ unless i2cinfo[:sda] && [nil,:i2c].include?(Beaglebone::get_pin_status(i2cinfo[:sda], :type))
112
+ raise StandardError, "SDA Pin for #{i2c.to_s} in use"
113
+ end
114
+
115
+ end
116
+
117
+ def check_i2c_enabled(i2c)
118
+ raise ArgumentError, "i2c not enabled #{i2c.to_s}" unless get_i2c_status(i2c)
119
+ end
120
+
121
+ def lock_i2c(i2c)
122
+ check_i2c_enabled(i2c)
123
+ mutex = get_i2c_status(i2c, :mutex)
124
+
125
+ mutex.synchronize do
126
+ yield
127
+ end
128
+ end
129
+
130
+ def get_i2c_status(i2c, key = nil)
131
+ i2cmutex.synchronize do
132
+ if key
133
+ i2cstatus[i2c] ? i2cstatus[i2c][key] : nil
134
+ else
135
+ i2cstatus[i2c]
136
+ end
137
+ end
138
+ end
139
+
140
+ def set_i2c_status(i2c, key, value)
141
+ i2cmutex.synchronize do
142
+ i2cstatus[i2c] ||= {}
143
+ i2cstatus[i2c][key] = value
144
+ end
145
+ end
146
+
147
+ def delete_i2c_status(i2c, key = nil)
148
+ i2cmutex.synchronize do
149
+ if key.nil?
150
+ i2cstatus.delete(i2c)
151
+ else
152
+ i2cstatus[i2c].delete(key) if i2cstatus[i2c]
153
+ end
154
+ end
155
+ end
156
+
157
+ end
158
+ end
159
+
160
+ #oo interface
161
+ class I2CDevice
162
+
163
+ def initialize(i2c)
164
+ @i2c = i2c
165
+ I2C::setup(@i2c)
166
+ end
167
+
168
+ def read(address, bytes=1, register=nil)
169
+ I2C::read(@i2c, address, bytes, register)
170
+ end
171
+
172
+ def write(address, data)
173
+ I2C::write(@i2c, address, data)
174
+ end
175
+
176
+ def disable
177
+ I2C::disable(@i2c)
178
+ end
179
+
180
+ def file
181
+ I2C::file(@i2c)
182
+ end
183
+
184
+ end
185
+
186
+ end
@@ -0,0 +1,479 @@
1
+ # == pwm.rb
2
+ # This file contains the PWM control methods
3
+ module Beaglebone #:nodoc:
4
+ # AIN
5
+ # procedural methods for PWM control
6
+ # == Summary
7
+ # #start is called to enable a PWM pin
8
+ module PWM
9
+
10
+ # Polarity hash
11
+ POLARITIES = { :NORMAL => 0, :INVERTED => 1 }
12
+
13
+ class << self
14
+
15
+ # Initialize a PWM pin
16
+ #
17
+ # @param pin should be a symbol representing the header pin
18
+ # @param duty should specify the duty cycle
19
+ # @param frequency should specify cycles per second
20
+ # @param polarity optional, should specify the polarity, :NORMAL or :INVERTED
21
+ # @param run optional, if false, pin will be configured but will not run
22
+ #
23
+ # @example
24
+ # PWM.start(:P9_14, 90, 10, :NORMAL)
25
+ def start(pin, duty=nil, frequency=nil, polarity=nil, run=true)
26
+ #make sure the pwm controller dtb is loaded
27
+ Beaglebone::device_tree_load(TREES[:PWM][:global])
28
+
29
+ Beaglebone::check_valid_pin(pin, :pwm)
30
+
31
+ #if pin is enabled for something else, disable it
32
+ if Beaglebone::get_pin_status(pin) && Beaglebone::get_pin_status(pin, :type) != :pwm
33
+ Beaglebone::disable_pin(pin)
34
+ end
35
+
36
+ #load device tree for pin if not already loaded
37
+ unless Beaglebone::get_pin_status(pin, :type) == :pwm
38
+ Beaglebone::device_tree_load("#{TREES[:PWM][:pin]}#{pin}")
39
+ Beaglebone::set_pin_status(pin, :type, :pwm)
40
+ end
41
+
42
+ duty_fd = File.open("#{pwm_directory(pin)}/duty", 'r+')
43
+ period_fd = File.open("#{pwm_directory(pin)}/period", 'r+')
44
+ polarity_fd = File.open("#{pwm_directory(pin)}/polarity", 'r+')
45
+ run_fd = File.open("#{pwm_directory(pin)}/run", 'r+')
46
+
47
+ Beaglebone::set_pin_status(pin, :fd_duty, duty_fd)
48
+ Beaglebone::set_pin_status(pin, :fd_period, period_fd)
49
+ Beaglebone::set_pin_status(pin, :fd_polarity, polarity_fd)
50
+ Beaglebone::set_pin_status(pin, :fd_run, run_fd)
51
+
52
+
53
+ read_period_value(pin)
54
+ read_duty_value(pin)
55
+ read_polarity_value(pin)
56
+
57
+ run_fd.write('0')
58
+ run_fd.flush
59
+
60
+ set_polarity(pin, polarity) if polarity
61
+ set_frequency(pin, frequency) if frequency
62
+ set_duty_cycle(pin, duty) if duty
63
+
64
+ if run
65
+ run_fd.write('1')
66
+ run_fd.flush
67
+ end
68
+
69
+ raise StandardError, "Could not start PWM: #{pin}" unless read_run_value(pin) == 1
70
+ true
71
+ end
72
+
73
+ # Returns true if specified pin is enabled in PWM mode, else false
74
+ def enabled?(pin)
75
+ return true if Beaglebone::get_pin_status(pin, :type) == :pwm
76
+
77
+ return false unless valid?(pin)
78
+ if Dir.exists?(pwm_directory(pin))
79
+
80
+ start(pin, nil, nil, nil, false)
81
+ return true
82
+ end
83
+ false
84
+ end
85
+
86
+ # Stop PWM output on specified pin
87
+ #
88
+ # @param pin should be a symbol representing the header pin
89
+ def stop(pin)
90
+ Beaglebone::check_valid_pin(pin, :pwm)
91
+
92
+ return false unless enabled?(pin)
93
+
94
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless Beaglebone::get_pin_status(pin, :type) == :pwm
95
+
96
+ run_fd = Beaglebone::get_pin_status(pin, :fd_run)
97
+
98
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless run_fd
99
+
100
+ run_fd.write('0')
101
+ run_fd.flush
102
+
103
+ raise StandardError, "Could not stop PWM: #{pin}" unless read_run_value(pin) == 0
104
+ true
105
+ end
106
+
107
+ # Start PWM output on specified pin. Pin must have been previously started
108
+ #
109
+ # @param pin should be a symbol representing the header pin
110
+ def run(pin)
111
+ Beaglebone::check_valid_pin(pin, :pwm)
112
+
113
+ return false unless enabled?(pin)
114
+
115
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless Beaglebone::get_pin_status(pin, :type) == :pwm
116
+
117
+ run_fd = Beaglebone::get_pin_status(pin, :fd_run)
118
+
119
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless run_fd
120
+
121
+ run_fd.write('1')
122
+ run_fd.flush
123
+
124
+ raise StandardError, "Could not start PWM: #{pin}" unless read_run_value(pin) == 1
125
+ true
126
+
127
+ end
128
+
129
+ # Set polarity on specified pin
130
+ #
131
+ # @param pin should be a symbol representing the header pin
132
+ # @param polarity should specify the polarity, :NORMAL or :INVERTED
133
+ # @example
134
+ # PWM.set_polarity(:P9_14, :INVERTED)
135
+ def set_polarity(pin, polarity)
136
+ check_valid_polarity(polarity)
137
+ check_pwm_enabled(pin)
138
+
139
+ polarity_fd = Beaglebone::get_pin_status(pin, :fd_polarity)
140
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless polarity_fd
141
+
142
+ polarity_fd.write(POLARITIES[polarity.to_sym].to_s)
143
+ polarity_fd.flush
144
+
145
+ raise StandardError, "Could not set polarity: #{pin}" unless read_polarity_value(pin) == POLARITIES[polarity.to_sym]
146
+
147
+ end
148
+
149
+ # Set duty cycle of specified pin in percentage
150
+ #
151
+ # @param pin should be a symbol representing the header pin
152
+ # @param duty should specify the duty cycle in percentage
153
+ # @example
154
+ # PWM.set_duty_cycle(:P9_14, 25)
155
+ def set_duty_cycle(pin, duty, newperiod=nil)
156
+
157
+ raise ArgumentError, "Duty cycle must be >= 0 and <= 100, #{duty} invalid" if duty < 0 || duty > 100
158
+ check_pwm_enabled(pin)
159
+
160
+
161
+ fd = Beaglebone::get_pin_status(pin, :fd_duty)
162
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
163
+
164
+ period = newperiod || Beaglebone::get_pin_status(pin, :period)
165
+
166
+ value = ((duty * period) / 100).to_i
167
+
168
+ fd.write(value.to_s)
169
+ fd.flush
170
+
171
+ raise StandardError, "Could not set duty cycle: #{pin} (#{value})" unless read_duty_value(pin) == value
172
+
173
+ value
174
+
175
+ end
176
+
177
+
178
+ # Set duty cycle of specified pin in nanoseconds
179
+ #
180
+ # @param pin should be a symbol representing the header pin
181
+ # @param duty should specify the duty cycle in nanoseconds
182
+ # @example
183
+ # PWM.set_duty_cycle_ns(:P9_14, 2500000)
184
+ def set_duty_cycle_ns(pin, duty)
185
+
186
+ check_pwm_enabled(pin)
187
+
188
+ fd = Beaglebone::get_pin_status(pin, :fd_duty)
189
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
190
+
191
+ period = Beaglebone::get_pin_status(pin, :period)
192
+
193
+ duty = duty.to_i
194
+
195
+ if duty < 0 || duty > period
196
+ raise ArgumentError, "Duty cycle ns must be >= 0 and <= #{period} (current period), #{duty} invalid"
197
+ end
198
+
199
+ value = duty
200
+
201
+ fd.write(value.to_s)
202
+ fd.flush
203
+
204
+ raise StandardError, "Could not set duty cycle: #{pin} (#{value})" unless read_duty_value(pin) == value
205
+
206
+ value
207
+ end
208
+
209
+ # Set frequency of specified pin in cycles per second
210
+ #
211
+ # @param pin should be a symbol representing the header pin
212
+ # @param frequency should specify the frequency in cycles per second
213
+ # @example
214
+ # PWM.set_frequency(:P9_14, 100)
215
+ def set_frequency(pin, frequency)
216
+ frequency = frequency.to_i
217
+ raise ArgumentError, "Frequency must be > 0 and <= 1000000000, #{frequency} invalid" if frequency < 1 || frequency > 1000000000
218
+ check_pwm_enabled(pin)
219
+
220
+ fd = Beaglebone::get_pin_status(pin, :fd_period)
221
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
222
+
223
+ duty_ns = Beaglebone::get_pin_status(pin, :duty)
224
+ duty_pct = Beaglebone::get_pin_status(pin, :duty_pct)
225
+
226
+ value = (1000000000 / frequency).to_i
227
+
228
+ #we can't set the frequency lower than the previous duty cycle
229
+ #adjust if necessary
230
+ if duty_ns > value
231
+ set_duty_cycle(pin, Beaglebone::get_pin_status(pin, :duty_pct), value)
232
+ end
233
+
234
+ fd.write(value.to_s)
235
+ fd.flush
236
+
237
+ raise StandardError, "Could not set frequency: #{pin} (#{value})" unless read_period_value(pin) == value
238
+
239
+ #adjust the duty cycle if we haven't already
240
+ if duty_ns <= value
241
+ set_duty_cycle(pin, duty_pct, value)
242
+ end
243
+
244
+ value
245
+ end
246
+
247
+ # Set frequency of specified pin based on period duration
248
+ #
249
+ # @param pin should be a symbol representing the header pin
250
+ # @param period should specify the length of a cycle in nanoseconds
251
+ #
252
+ # @example
253
+ # PWM.set_frequency_ns(:P9_14, 100000000)
254
+ def set_period_ns(pin, period)
255
+ period = period.to_i
256
+ raise ArgumentError, "period must be > 0 and <= 1000000000, #{period} invalid" if period < 1 || period > 1000000000
257
+ check_pwm_enabled(pin)
258
+
259
+ fd = Beaglebone::get_pin_status(pin, :fd_period)
260
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
261
+
262
+ duty_ns = Beaglebone::get_pin_status(pin, :duty)
263
+ value = period.to_i
264
+
265
+ #we can't set the frequency lower than the previous duty cycle
266
+ #adjust if necessary
267
+ if duty_ns > value
268
+ set_duty_cycle(pin, Beaglebone::get_pin_status(pin, :duty_pct), value)
269
+ end
270
+
271
+ fd.write(value.to_s)
272
+ fd.flush
273
+
274
+ raise StandardError, "Could not set period: #{pin} (#{value})" unless read_period_value(pin) == value
275
+
276
+ #adjust the duty cycle if we haven't already
277
+ if duty_ns <= value
278
+ set_duty_cycle(pin, Beaglebone::get_pin_status(pin, :duty_pct), value)
279
+ end
280
+
281
+ value
282
+ end
283
+
284
+ #reset all PWM pins we've used to IN and unexport them
285
+ def cleanup
286
+ get_pwm_pins.each { |x| disable_pwm_pin(x) }
287
+ end
288
+
289
+ # Return an array of PWM pins in use
290
+ #
291
+ # @return [Array<Symbol>]
292
+ #
293
+ # @example
294
+ # PWM.get_pwm_pins => [:P9_13, :P9_14]
295
+ def get_pwm_pins
296
+ Beaglebone.pinstatus.clone.select { |x,y| x if y[:type] == :pwm}.keys
297
+ end
298
+
299
+ # Disable a PWM pin
300
+ #
301
+ # @param pin should be a symbol representing the header pin
302
+ def disable_pwm_pin(pin)
303
+ Beaglebone::check_valid_pin(pin, :pwm)
304
+ Beaglebone::delete_pin_status(pin) if Beaglebone::device_tree_unload("#{TREES[:PWM][:pin]}#{pin}")
305
+ end
306
+
307
+ private
308
+
309
+ #ensure pin is valid pwm pin
310
+ def valid?(pin)
311
+ #check to see if pin exists
312
+ pin = pin.to_sym.upcase
313
+
314
+ return false unless PINS[pin]
315
+ return false unless PINS[pin][:pwm]
316
+
317
+ true
318
+ end
319
+
320
+ #ensure pin is pwm enabled
321
+ def check_pwm_enabled(pin)
322
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless enabled?(pin)
323
+ end
324
+
325
+ #read run file
326
+ def read_run_value(pin)
327
+ check_pwm_enabled(pin)
328
+
329
+ fd = Beaglebone::get_pin_status(pin, :fd_run)
330
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
331
+
332
+ fd.rewind
333
+ fd.read.strip.to_i
334
+ end
335
+
336
+ #read polarity file
337
+ def read_polarity_value(pin)
338
+ check_pwm_enabled(pin)
339
+
340
+ fd = Beaglebone::get_pin_status(pin, :fd_polarity)
341
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
342
+
343
+ fd.rewind
344
+ value = fd.read.strip.to_i
345
+
346
+ Beaglebone::set_pin_status(pin, :polarity, value)
347
+
348
+ end
349
+
350
+ #read duty file
351
+ def read_duty_value(pin)
352
+ check_pwm_enabled(pin)
353
+
354
+ fd = Beaglebone::get_pin_status(pin, :fd_duty)
355
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
356
+
357
+ fd.rewind
358
+ value = fd.read.strip.to_i
359
+
360
+ Beaglebone::set_pin_status(pin, :duty, value)
361
+ Beaglebone::set_pin_status(pin, :duty_pct, ((value * 100) / Beaglebone::get_pin_status(pin, :period).to_i))
362
+
363
+ value
364
+ end
365
+
366
+ #read period file
367
+ def read_period_value(pin)
368
+ check_pwm_enabled(pin)
369
+
370
+ fd = Beaglebone::get_pin_status(pin, :fd_period)
371
+ raise StandardError, "Pin is not PWM enabled: #{pin}" unless fd
372
+
373
+ fd.rewind
374
+ value = fd.read.strip.to_i
375
+
376
+ Beaglebone::set_pin_status(pin, :period, value)
377
+ Beaglebone::set_pin_status(pin, :duty_pct, ((Beaglebone::get_pin_status(pin, :duty).to_i * 100) / value).to_i)
378
+
379
+ value
380
+ end
381
+
382
+ #return sysfs directory for pwm control
383
+ def pwm_directory(pin)
384
+ raise StandardError, 'Invalid Pin' unless valid?(pin)
385
+ Dir.glob("/sys/devices/ocp.*/pwm_test_#{pin}.*").first
386
+ end
387
+
388
+ #ensure polarity is valid
389
+ def check_valid_polarity(polarity)
390
+ #check to see if mode is valid
391
+ polarity = polarity.to_sym.upcase
392
+ raise ArgumentError, "No such polarity: #{polarity.to_s}" unless POLARITIES.include?(polarity)
393
+ end
394
+
395
+ end
396
+ end
397
+
398
+ # Object Oriented PWM Implementation.
399
+ # This treats the pin as an object.
400
+ class PWMPin
401
+
402
+ # Initialize a PWM pin
403
+ #
404
+ #
405
+ # @param duty should specify the duty cycle
406
+ # @param frequency should specify cycles per second
407
+ # @param polarity optional, should specify the polarity, :NORMAL or :INVERTED
408
+ # @param run optional, if false, pin will be configured but will not run
409
+ #
410
+ # @example
411
+ # p9_14 = PWMPin.new(:P9_14, 90, 10, :NORMAL)
412
+ def initialize(pin, duty=nil, frequency=nil, polarity=nil, run=true)
413
+ @pin = pin
414
+ PWM::start(@pin, duty, frequency, polarity, run)
415
+ end
416
+
417
+ # Stop PWM output on pin
418
+ def stop
419
+ PWM::stop(@pin)
420
+ end
421
+
422
+ # Start PWM output on pin. Pin must have been previously started
423
+ def run
424
+ PWM::run(@pin)
425
+ end
426
+
427
+ # Set polarity on pin
428
+ #
429
+ # @param polarity should specify the polarity, :NORMAL or :INVERTED
430
+ # @example
431
+ # p9_14.set_polarity(:INVERTED)
432
+ def set_polarity(polarity)
433
+ PWM::set_polarity(@pin, polarity)
434
+ end
435
+
436
+ # Set duty cycle of pin in percentage
437
+ #
438
+ #
439
+ # @param duty should specify the duty cycle in percentage
440
+ # @example
441
+ # p9_14.set_duty_cycle(25)
442
+ def set_duty_cycle(duty, newperiod=nil)
443
+ PWM::set_duty_cycle(@pin, duty, newperiod)
444
+ end
445
+
446
+ # Set duty cycle of pin in nanoseconds
447
+ #
448
+ # @param duty should specify the duty cycle in nanoseconds
449
+ # @example
450
+ # p9_14.set_duty_cycle_ns(2500000)
451
+ def set_duty_cycle_ns(duty)
452
+ PWM::set_duty_cycle_ns(@pin, duty)
453
+ end
454
+
455
+ # Set frequency of pin in cycles per second
456
+ #
457
+ # @param frequency should specify the frequency in cycles per second
458
+ # @example
459
+ # p9_14.set_frequency(100)
460
+ def set_frequency(frequency)
461
+ PWM::set_frequency(@pin, frequency)
462
+ end
463
+
464
+ # Set frequency of pin based on period duration
465
+ #
466
+ # @param period should specify the length of a cycle in nanoseconds
467
+ # @example
468
+ # p9_14.set_frequency_ns(100000000)
469
+ def set_period_ns(period)
470
+ PWM::set_period_ns(@pin, period)
471
+ end
472
+
473
+ # Disable PWM pin
474
+ def disable_pwm_pin
475
+ PWM::disable_pwm_pin(@pin)
476
+ end
477
+ end
478
+
479
+ end
@@ -0,0 +1,21 @@
1
+ module Beaglebone
2
+ class ShiftRegister
3
+
4
+ def initialize(latch_pin, clock_pin, data_pin, lsb=nil)
5
+
6
+ @latch_pin = latch_pin
7
+ @clock_pin = clock_pin
8
+ @data_pin = data_pin
9
+ @lsb = lsb
10
+
11
+ GPIO::pin_mode(@latch_pin, :OUT)
12
+ GPIO::pin_mode(@clock_pin, :OUT)
13
+ GPIO::pin_mode(@data_pin, :OUT)
14
+ end
15
+
16
+ def shiftout(data, lsb=nil)
17
+ GPIO::shift_out(@latch_pin, @clock_pin, @data_pin, data, lsb || @lsb)
18
+ end
19
+
20
+ end
21
+ end