pi_piper 2.0.beta.4 → 2.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.rspec +3 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -3
- data/Gemfile.lock +39 -26
- data/LICENCE.md +23 -0
- data/README.md +53 -16
- data/Rakefile +4 -22
- data/examples/2_bit_counter/2_bit_counter.rb +21 -0
- data/examples/7-segment/7-segment.rb +37 -0
- data/examples/dsl_switch/dsl_switch.rb +15 -0
- data/examples/elro/README.md +75 -0
- data/examples/elro/docs/elro-dips.jpg +0 -0
- data/examples/elro/docs/elro-switch.jpg +0 -0
- data/examples/elro/docs/setup.jpg +0 -0
- data/examples/elro/docs/wireplan.jpg +0 -0
- data/examples/elro/docs/wrl10534.jpg +0 -0
- data/examples/elro/elro.rb +15 -0
- data/examples/elro/lib/elro_switch.rb +51 -0
- data/examples/elro/lib/elro_util.rb +64 -0
- data/examples/elro/spec/elro_spec.rb +35 -0
- data/examples/elro/spec/elro_util_spec.rb +51 -0
- data/examples/elro/spec/spec_helper.rb +6 -0
- data/examples/mcp3008/circuit.png +0 -0
- data/examples/mcp3008/mcp3008.rb +55 -0
- data/examples/mcp3008_spi/mcp3008_spi.rb +24 -0
- data/examples/morse_code/circuit.png +0 -0
- data/examples/morse_code/morse_code.rb +49 -0
- data/examples/simple_switch/circuit.png +0 -0
- data/examples/simple_switch/simple_switch.rb +10 -0
- data/lib/pi_piper.rb +5 -3
- data/lib/pi_piper/bcm2835.rb +84 -14
- data/lib/pi_piper/i2c.rb +0 -1
- data/lib/pi_piper/libbcm2835.so +0 -0
- data/lib/pi_piper/pin.rb +102 -63
- data/lib/pi_piper/pin_error.rb +3 -0
- data/lib/pi_piper/pin_values.rb +35 -0
- data/lib/pi_piper/platform.rb +5 -5
- data/lib/pi_piper/pwm.rb +95 -0
- data/lib/pi_piper/spi.rb +30 -45
- data/lib/pi_piper/stub_driver.rb +124 -0
- data/lib/pi_piper/version.rb +3 -0
- data/pi_piper.gemspec +24 -29
- data/spec/bcm2835_spec.rb +132 -0
- data/spec/i2c_spec.rb +62 -0
- data/spec/pin_spec.rb +140 -0
- data/spec/pwm_spec.rb +83 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/spi_spec.rb +38 -0
- data/spec/stub_driver_spec.rb +140 -0
- metadata +100 -26
- data/Manifest +0 -14
- data/lib/pi_piper/libbcm2835.img +0 -0
data/lib/pi_piper/i2c.rb
CHANGED
@@ -28,7 +28,6 @@ module PiPiper
|
|
28
28
|
|
29
29
|
def self.clock=(clock)
|
30
30
|
valid_clocks = Platform.driver.i2c_allowed_clocks
|
31
|
-
|
32
31
|
raise "Invalid clock rate. Valid clocks are 100 kHz, 399.3610 kHz, 1.666 MHz and 1.689 MHz" unless valid_clocks.include? clock
|
33
32
|
|
34
33
|
Platform.driver.i2c_set_clock clock
|
Binary file
|
data/lib/pi_piper/pin.rb
CHANGED
@@ -1,72 +1,114 @@
|
|
1
|
+
require_relative 'pin_values'
|
2
|
+
|
1
3
|
module PiPiper
|
2
4
|
# Represents a GPIO pin on the Raspberry Pi
|
3
5
|
class Pin
|
4
|
-
|
5
|
-
GPIO_PUD_DOWN = 1
|
6
|
-
GPIO_PUD_UP = 2
|
6
|
+
include PiPiper::PinValues
|
7
7
|
|
8
|
-
attr_reader :pin, :last_value, :
|
8
|
+
attr_reader :pin, :last_value, :direction, :invert
|
9
9
|
|
10
10
|
#Initializes a new GPIO pin.
|
11
11
|
#
|
12
12
|
# @param [Hash] options A hash of options
|
13
13
|
# @option options [Fixnum] :pin The pin number to initialize. Required.
|
14
|
-
#
|
15
|
-
# @option options [
|
16
|
-
#
|
17
|
-
#
|
14
|
+
#
|
15
|
+
# @option options [Symbol] :direction The direction of communication,
|
16
|
+
# either :in or :out. Defaults to :in.
|
17
|
+
#
|
18
|
+
# @option options [Boolean] :invert Indicates if the value read from the
|
19
|
+
# physical pin should be inverted. Defaults to false.
|
20
|
+
#
|
21
|
+
# @option options [Symbol] :trigger Indicates when the wait_for_change
|
22
|
+
# method will detect a change, either :rising, :falling, or :both edge
|
23
|
+
# triggers. Defaults to :both.
|
24
|
+
#
|
25
|
+
# @option options [Symbol] :pull Indicates if and how pull mode must be
|
26
|
+
# set when pin direction is set to :in. Either :up, :down or :offing.
|
27
|
+
# Defaults to :off.
|
28
|
+
#
|
18
29
|
def initialize(options)
|
19
|
-
options = {:direction => :in,
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@trigger = options[:trigger]
|
24
|
-
@pull = options[:pull]
|
30
|
+
options = { :direction => :in,
|
31
|
+
:invert => false,
|
32
|
+
:trigger => :both,
|
33
|
+
:pull => :off }.merge(options)
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
35
|
+
@pin = options[:pin]
|
36
|
+
@direction = options[:direction]
|
37
|
+
@invert = options[:invert]
|
38
|
+
@trigger = options[:trigger]
|
39
|
+
@pull = options[:pull]
|
30
40
|
|
31
|
-
|
41
|
+
raise ArgumentError, 'Pin # required' unless @pin
|
42
|
+
unless valid_pull?
|
43
|
+
raise PiPiper::PinError, 'Invalid pull mode. Options are :up, :down or :float (default)'
|
44
|
+
end
|
45
|
+
unless valid_direction?
|
46
|
+
raise PiPiper::PinError, 'Invalid direction. Options are :in or :out'
|
47
|
+
end
|
48
|
+
if @direction != :in && [:up, :down].include?(@pull)
|
49
|
+
raise PiPiper::PinError, 'Unable to use pull-ups : pin direction must be :in for this'
|
50
|
+
end
|
51
|
+
unless valid_trigger?
|
52
|
+
raise PiPiper::PinError, 'Invalid trigger. Options are :rising, :falling, or :both'
|
53
|
+
end
|
32
54
|
|
55
|
+
if @direction == :out
|
56
|
+
Platform.driver.pin_output(@pin)
|
57
|
+
else
|
58
|
+
Platform.driver.pin_input(@pin)
|
59
|
+
end
|
33
60
|
pull!(@pull)
|
34
61
|
|
35
62
|
read
|
36
63
|
end
|
37
|
-
|
38
|
-
# If the pin has been initialized for output this method will set the
|
64
|
+
|
65
|
+
# If the pin has been initialized for output this method will set the
|
66
|
+
# logic level high.
|
39
67
|
def on
|
40
|
-
Platform.driver.pin_set(pin,
|
68
|
+
Platform.driver.pin_set(pin, GPIO_HIGH) if direction == :out
|
41
69
|
end
|
42
|
-
|
70
|
+
|
43
71
|
# Tests if the logic level is high.
|
44
72
|
def on?
|
45
73
|
not off?
|
46
74
|
end
|
47
|
-
|
48
|
-
# If the pin has been initialized for output this method will set
|
75
|
+
|
76
|
+
# If the pin has been initialized for output this method will set
|
77
|
+
# the logic level low.
|
49
78
|
def off
|
50
|
-
Platform.driver.pin_set(pin,
|
79
|
+
Platform.driver.pin_set(pin, GPIO_LOW) if direction == :out
|
51
80
|
end
|
52
|
-
|
81
|
+
|
53
82
|
# Tests if the logic level is low.
|
54
83
|
def off?
|
55
|
-
value ==
|
84
|
+
value == GPIO_LOW
|
56
85
|
end
|
57
86
|
|
58
|
-
|
87
|
+
def value
|
88
|
+
@value ||= read
|
89
|
+
end
|
90
|
+
|
91
|
+
# If the pin has been initialized for output this method will either raise
|
92
|
+
# or lower the logic level depending on `new_value`.
|
59
93
|
# @param [Object] new_value If false or 0 the pin will be set to off, otherwise on.
|
60
94
|
def update_value(new_value)
|
61
|
-
!new_value || new_value ==
|
95
|
+
!new_value || new_value == GPIO_LOW ? off : on
|
62
96
|
end
|
97
|
+
alias_method :value=, :update_value
|
63
98
|
|
64
|
-
# When the pin has been initialized in input mode, internal resistors can
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
99
|
+
# When the pin has been initialized in input mode, internal resistors can
|
100
|
+
# be pulled up or down (respectively with :up and :down).
|
101
|
+
#
|
102
|
+
# Pulling an input pin will prevent noise from triggering it when the input
|
103
|
+
# is floating.
|
104
|
+
#
|
105
|
+
# For instance when nothing is plugged in, pulling the pin-up will make
|
106
|
+
# subsequent value readings to return 'on' (or high, or 1...).
|
107
|
+
# @param [Symbol] state Indicates if and how pull mode must be set when
|
108
|
+
# pin direction is set to :in. Either :up, :down or :offing. Defaults to :off.
|
68
109
|
def pull!(state)
|
69
|
-
|
110
|
+
raise PiPiper::PinError, "Unable to use pull-ups : pin direction must be ':in' for this" if
|
111
|
+
@direction != :in and [:up, :down].include?(state)
|
70
112
|
@pull = case state
|
71
113
|
when :up then GPIO_PUD_UP
|
72
114
|
when :down then GPIO_PUD_DOWN
|
@@ -79,7 +121,8 @@ module PiPiper
|
|
79
121
|
@pull
|
80
122
|
end
|
81
123
|
|
82
|
-
# If the pin direction is input, it will return the current state of
|
124
|
+
# If the pin direction is input, it will return the current state of
|
125
|
+
# pull-up/pull-down resistor, either :up, :down or :off.
|
83
126
|
def pull?
|
84
127
|
case @pull
|
85
128
|
when GPIO_PUD_UP then :up
|
@@ -93,42 +136,38 @@ module PiPiper
|
|
93
136
|
last_value != value
|
94
137
|
end
|
95
138
|
|
96
|
-
#
|
139
|
+
# Blocks until a logic level change occurs. The initializer option
|
140
|
+
# `:trigger` modifies what edge this method will release on.
|
97
141
|
def wait_for_change
|
98
|
-
|
99
|
-
File.open(edge_file, "w") { |f| f.write("both") }
|
100
|
-
loop do
|
101
|
-
fd.read
|
102
|
-
IO.select(nil, nil, [fd], nil)
|
103
|
-
read
|
104
|
-
if changed?
|
105
|
-
next if @trigger == :rising and value == 0
|
106
|
-
next if @trigger == :falling and value == 1
|
107
|
-
break
|
108
|
-
end
|
109
|
-
end
|
142
|
+
Platform.driver.pin_wait_for(@pin, @trigger)
|
110
143
|
end
|
111
|
-
|
112
|
-
# Reads the current value from the pin. Without calling this method
|
113
|
-
#
|
114
|
-
|
115
|
-
|
144
|
+
|
145
|
+
# Reads the current value from the pin. Without calling this method
|
146
|
+
# first, `value`, `last_value` and `changed?` will not be updated.
|
147
|
+
#
|
148
|
+
# In short, you must call this method if you are curious about the
|
149
|
+
# current state of the pin.
|
150
|
+
def read
|
116
151
|
val = Platform.driver.pin_read(@pin)
|
152
|
+
@last_value = @value
|
117
153
|
@value = invert ? (val ^ 1) : val
|
118
154
|
end
|
119
|
-
|
120
|
-
|
121
|
-
def
|
122
|
-
|
155
|
+
|
156
|
+
private
|
157
|
+
def method_missing(method, *args, &block)
|
158
|
+
Platform.driver.send(method, @pin, *args, &block)
|
159
|
+
end
|
160
|
+
|
161
|
+
def valid_trigger?
|
162
|
+
[:rising, :falling, :both].include?(@trigger)
|
123
163
|
end
|
124
164
|
|
125
|
-
def
|
126
|
-
|
165
|
+
def valid_direction?
|
166
|
+
[:in, :out].include?(@direction)
|
127
167
|
end
|
128
168
|
|
129
|
-
def
|
130
|
-
|
169
|
+
def valid_pull?
|
170
|
+
[:up, :down, :float, :off].include? @pull
|
131
171
|
end
|
132
|
-
|
133
172
|
end
|
134
173
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module PiPiper
|
2
|
+
module PinValues
|
3
|
+
GPIO_PUD_OFF = 0
|
4
|
+
GPIO_PUD_DOWN = 1
|
5
|
+
GPIO_PUD_UP = 2
|
6
|
+
|
7
|
+
GPIO_HIGH = 1
|
8
|
+
GPIO_LOW = 0
|
9
|
+
|
10
|
+
GPIO_FSEL_INPT = 0b000
|
11
|
+
GPIO_FSEL_OUTP = 0b001
|
12
|
+
GPIO_FSEL_ALT0 = 0b100
|
13
|
+
GPIO_FSEL_ALT1 = 0b101
|
14
|
+
GPIO_FSEL_ALT2 = 0b110
|
15
|
+
GPIO_FSEL_ALT3 = 0b111
|
16
|
+
GPIO_FSEL_ALT4 = 0b011
|
17
|
+
GPIO_FSEL_ALT5 = 0b010
|
18
|
+
GPIO_FSEL_MASK = 0b111
|
19
|
+
|
20
|
+
|
21
|
+
PWM_PIN = {
|
22
|
+
12 => {:channel => 0, :alt_fun => GPIO_FSEL_ALT0},
|
23
|
+
13 => {:channel => 1, :alt_fun => GPIO_FSEL_ALT0},
|
24
|
+
18 => {:channel => 0, :alt_fun => GPIO_FSEL_ALT5},
|
25
|
+
19 => {:channel => 1, :alt_fun => GPIO_FSEL_ALT5},
|
26
|
+
40 => {:channel => 0, :alt_fun => GPIO_FSEL_ALT0},
|
27
|
+
41 => {:channel => 1, :alt_fun => GPIO_FSEL_ALT0},
|
28
|
+
45 => {:channel => 1, :alt_fun => GPIO_FSEL_ALT0},
|
29
|
+
52 => {:channel => 0, :alt_fun => GPIO_FSEL_ALT1},
|
30
|
+
53 => {:channel => 1, :alt_fun => GPIO_FSEL_ALT1}
|
31
|
+
}
|
32
|
+
|
33
|
+
PWM_MODE = [:balanced, :markspace]
|
34
|
+
end
|
35
|
+
end
|
data/lib/pi_piper/platform.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
#require 'bcm2835.rb'
|
2
1
|
module PiPiper
|
3
2
|
|
4
3
|
#Hardware abstraction manager. Not intended for direct use.
|
@@ -8,10 +7,13 @@ module PiPiper
|
|
8
7
|
#gets the current platform driver. Defaults to BCM2835.
|
9
8
|
def self.driver
|
10
9
|
unless @@driver
|
11
|
-
|
10
|
+
require 'pi_piper/bcm2835'
|
12
11
|
PiPiper::Bcm2835.init
|
13
12
|
@@driver = PiPiper::Bcm2835
|
14
|
-
at_exit
|
13
|
+
at_exit do
|
14
|
+
Bcm2835.unexport_all
|
15
|
+
Bcm2835.close
|
16
|
+
end
|
15
17
|
end
|
16
18
|
@@driver
|
17
19
|
end
|
@@ -19,7 +21,5 @@ module PiPiper
|
|
19
21
|
def self.driver=(instance)
|
20
22
|
@@driver = instance
|
21
23
|
end
|
22
|
-
|
23
24
|
end
|
24
|
-
|
25
25
|
end
|
data/lib/pi_piper/pwm.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require_relative 'pin_values'
|
2
|
+
|
3
|
+
module PiPiper
|
4
|
+
|
5
|
+
# Represents a Pwm output on the Raspberry Pi (only GPIO18 is avaliable on header)
|
6
|
+
class Pwm
|
7
|
+
include PiPiper::PinValues
|
8
|
+
|
9
|
+
attr_reader :value, :options
|
10
|
+
|
11
|
+
# Initializes a new PWM pin.
|
12
|
+
#
|
13
|
+
# @param [Hash] options A hash of options
|
14
|
+
# @option options [Fixnum] :pin The pin number to initialize. Required.
|
15
|
+
def initialize(options)
|
16
|
+
@options = {
|
17
|
+
:mode => :balanced,
|
18
|
+
:clock => 19.2.megahertz,
|
19
|
+
:range => 1024,
|
20
|
+
:start => true,
|
21
|
+
:value => 0
|
22
|
+
}.merge(options)
|
23
|
+
|
24
|
+
unless PWM_PIN[@options[:pin]]
|
25
|
+
raise ArgumentError, ":pin should be one of #{PWM_PIN.keys} not #{@options[:pin]}"
|
26
|
+
end
|
27
|
+
|
28
|
+
unless PWM_MODE.include? @options[:mode]
|
29
|
+
raise ArgumentError, ":mode should be one of #{PWM_MODE}, not #{@options[:mode]}"
|
30
|
+
end
|
31
|
+
|
32
|
+
self.value= @options.delete(:value)
|
33
|
+
self.pin= @options[:pin]
|
34
|
+
self.range= @options[:range]
|
35
|
+
self.clock= @options[:clock]
|
36
|
+
|
37
|
+
@options.delete(:start) ? self.on : self.off
|
38
|
+
end
|
39
|
+
|
40
|
+
# Start the Pwm signal
|
41
|
+
def on
|
42
|
+
@on = true
|
43
|
+
Platform.driver.pwm_mode(PWM_PIN[@options[:pin]][:channel], PWM_MODE.index(options[:mode]), 1)
|
44
|
+
end
|
45
|
+
|
46
|
+
alias :start :on
|
47
|
+
|
48
|
+
# Stop the Pwm signal
|
49
|
+
def off
|
50
|
+
@on = false
|
51
|
+
Platform.driver.pwm_mode(PWM_PIN[@options[:pin]][:channel], PWM_MODE.index(options[:mode]), 0)
|
52
|
+
end
|
53
|
+
|
54
|
+
alias :stop :off
|
55
|
+
|
56
|
+
def on?
|
57
|
+
@on
|
58
|
+
end
|
59
|
+
|
60
|
+
def off?
|
61
|
+
not on?
|
62
|
+
end
|
63
|
+
|
64
|
+
def value=(new_value)
|
65
|
+
@value = sanitize_value(new_value)
|
66
|
+
Platform.driver.pwm_data(PWM_PIN[@options[:pin]][:channel], data(@value))
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def range=(range)
|
72
|
+
Platform.driver.pwm_range(PWM_PIN[@options[:pin]][:channel], range)
|
73
|
+
end
|
74
|
+
|
75
|
+
def clock=(clock)
|
76
|
+
Platform.driver.pwm_clock(get_clock_divider(clock))
|
77
|
+
end
|
78
|
+
|
79
|
+
def pin=(bcm_pin_number)
|
80
|
+
Platform.driver.gpio_select_function(bcm_pin_number, PWM_PIN[@options[:pin]][:alt_fun])
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_clock_divider(clock)
|
84
|
+
(19.2.megahertz.to_f / clock).to_i
|
85
|
+
end
|
86
|
+
|
87
|
+
def data(sanitized_value)
|
88
|
+
(sanitized_value * @options[:range]).to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
def sanitize_value(raw_value)
|
92
|
+
[0, [raw_value, 1].min ].max
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/pi_piper/spi.rb
CHANGED
@@ -1,36 +1,3 @@
|
|
1
|
-
#--
|
2
|
-
#Modifications Copyright 2013, Jason Whitehorn and released under the terms
|
3
|
-
#of the license included in README.md
|
4
|
-
#
|
5
|
-
#Based on works, Copyright (c) 2012 Joshua Nussbaum
|
6
|
-
#
|
7
|
-
#MIT License
|
8
|
-
#
|
9
|
-
#Permission is hereby granted, free of charge, to any person obtaining
|
10
|
-
#a copy of this software and associated documentation files (the
|
11
|
-
#"Software"), to deal in the Software without restriction, including
|
12
|
-
#without limitation the rights to use, copy, modify, merge, publish,
|
13
|
-
#distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
-
#
|
15
|
-
#permit persons to whom the Software is furnished to do so, subject to
|
16
|
-
#the following conditions:
|
17
|
-
#
|
18
|
-
#The above copyright notice and this permission notice shall be
|
19
|
-
#included in all copies or substantial portions of the Software.
|
20
|
-
#
|
21
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
22
|
-
#EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
23
|
-
#MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
24
|
-
#NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
25
|
-
#LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
26
|
-
#OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
27
|
-
#WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
28
|
-
#++
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
1
|
module PiPiper
|
35
2
|
# class for SPI interfaces on the Raspberry Pi
|
36
3
|
class Spi
|
@@ -48,18 +15,24 @@ module PiPiper
|
|
48
15
|
# No CS, control it yourself
|
49
16
|
CHIP_SELECT_NONE = 3
|
50
17
|
|
18
|
+
# SPI Modes
|
19
|
+
SPI_MODE0 = 0
|
20
|
+
SPI_MODE1 = 1
|
21
|
+
SPI_MODE2 = 2
|
22
|
+
SPI_MODE3 = 3
|
23
|
+
|
51
24
|
#Sets the SPI mode. Defaults to mode (0,0).
|
52
25
|
def self.set_mode(cpol, cpha)
|
53
26
|
mode = SPI_MODE0 #default
|
54
27
|
mode = SPI_MODE1 if cpol == 0 and cpha == 1
|
55
28
|
mode = SPI_MODE2 if cpol == 1 and cpha == 0
|
56
29
|
mode = SPI_MODE3 if cpol == 1 and cpha == 1
|
57
|
-
|
30
|
+
Platform.driver.spi_set_data_mode mode
|
58
31
|
end
|
59
32
|
|
60
33
|
#Begin an SPI block. All SPI communications should be wrapped in a block.
|
61
34
|
def self.begin(chip=nil, &block)
|
62
|
-
|
35
|
+
Platform.driver.spi_begin
|
63
36
|
chip = CHIP_SELECT_0 if !chip && block_given?
|
64
37
|
spi = new(chip)
|
65
38
|
|
@@ -72,7 +45,19 @@ module PiPiper
|
|
72
45
|
|
73
46
|
# Not needed when #begin is called with a block
|
74
47
|
def self.end
|
75
|
-
|
48
|
+
Platform.driver.spi_end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Uses /dev/spidev0.0 to write to the SPI
|
52
|
+
# NOTE: Requires that you have /dev/spidev0.0
|
53
|
+
# see: http://learn.adafruit.com/adafruit-raspberry-pi-educational-linux-distro/overview
|
54
|
+
# most likely requires `chmod 666 /dev/spidev0.0`
|
55
|
+
#
|
56
|
+
# @example Writing red, green, blue to a string of WS2801 pixels
|
57
|
+
# PiPiper::Spi.spidev_out([255,0,0,0,255,0,0,0,255])
|
58
|
+
#
|
59
|
+
def self.spidev_out(array)
|
60
|
+
Platform.driver.spidev_out(array)
|
76
61
|
end
|
77
62
|
|
78
63
|
# Sets the SPI clock frequency
|
@@ -92,7 +77,7 @@ module PiPiper
|
|
92
77
|
20000000 => 16 #20 MHz
|
93
78
|
}
|
94
79
|
divider = options[frequency]
|
95
|
-
|
80
|
+
Platform.driver.spi_clock(divider)
|
96
81
|
end
|
97
82
|
|
98
83
|
def bit_order(order=MSBFIRST)
|
@@ -104,7 +89,7 @@ module PiPiper
|
|
104
89
|
end
|
105
90
|
end
|
106
91
|
|
107
|
-
|
92
|
+
Platform.driver.spi_bit_order(order)
|
108
93
|
end
|
109
94
|
|
110
95
|
# Activate a specific chip so that communication can begin
|
@@ -126,13 +111,13 @@ module PiPiper
|
|
126
111
|
# @yield
|
127
112
|
# @param [optional, CHIP_SELECT_*] chip the chip select line options
|
128
113
|
def chip_select(chip=CHIP_SELECT_0)
|
129
|
-
chip = @chip if @chip
|
130
|
-
|
114
|
+
chip = @chip if @chip
|
115
|
+
Platform.driver.spi_chip_select(chip)
|
131
116
|
if block_given?
|
132
117
|
begin
|
133
118
|
yield
|
134
119
|
ensure
|
135
|
-
|
120
|
+
Platform.driver.spi_chip_select(CHIP_SELECT_NONE)
|
136
121
|
end
|
137
122
|
end
|
138
123
|
end
|
@@ -151,7 +136,7 @@ module PiPiper
|
|
151
136
|
chip = @chip if @chip
|
152
137
|
chip = CHIP_SELECT_0 unless chip
|
153
138
|
|
154
|
-
|
139
|
+
Platform.driver.spi_chip_select_polarity(chip, active_low ? 0 : 1)
|
155
140
|
end
|
156
141
|
|
157
142
|
# Read from the bus
|
@@ -171,7 +156,7 @@ module PiPiper
|
|
171
156
|
if count
|
172
157
|
write([0xFF] * count)
|
173
158
|
else
|
174
|
-
enable {
|
159
|
+
enable { Platform.driver.spi_transfer(0) }
|
175
160
|
end
|
176
161
|
end
|
177
162
|
|
@@ -197,9 +182,9 @@ module PiPiper
|
|
197
182
|
enable do
|
198
183
|
case data
|
199
184
|
when Numeric
|
200
|
-
|
185
|
+
Platform.driver.spi_transfer(data)
|
201
186
|
when Enumerable
|
202
|
-
|
187
|
+
Platform.driver.spi_transfer_bytes(data)
|
203
188
|
else
|
204
189
|
raise ArgumentError.new("#{data.class} is not valid data. Use Numeric or an Enumerable of numbers")
|
205
190
|
end
|