pi_piper 2.0.beta.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +3 -3
  6. data/Gemfile.lock +39 -26
  7. data/LICENCE.md +23 -0
  8. data/README.md +53 -16
  9. data/Rakefile +4 -22
  10. data/examples/2_bit_counter/2_bit_counter.rb +21 -0
  11. data/examples/7-segment/7-segment.rb +37 -0
  12. data/examples/dsl_switch/dsl_switch.rb +15 -0
  13. data/examples/elro/README.md +75 -0
  14. data/examples/elro/docs/elro-dips.jpg +0 -0
  15. data/examples/elro/docs/elro-switch.jpg +0 -0
  16. data/examples/elro/docs/setup.jpg +0 -0
  17. data/examples/elro/docs/wireplan.jpg +0 -0
  18. data/examples/elro/docs/wrl10534.jpg +0 -0
  19. data/examples/elro/elro.rb +15 -0
  20. data/examples/elro/lib/elro_switch.rb +51 -0
  21. data/examples/elro/lib/elro_util.rb +64 -0
  22. data/examples/elro/spec/elro_spec.rb +35 -0
  23. data/examples/elro/spec/elro_util_spec.rb +51 -0
  24. data/examples/elro/spec/spec_helper.rb +6 -0
  25. data/examples/mcp3008/circuit.png +0 -0
  26. data/examples/mcp3008/mcp3008.rb +55 -0
  27. data/examples/mcp3008_spi/mcp3008_spi.rb +24 -0
  28. data/examples/morse_code/circuit.png +0 -0
  29. data/examples/morse_code/morse_code.rb +49 -0
  30. data/examples/simple_switch/circuit.png +0 -0
  31. data/examples/simple_switch/simple_switch.rb +10 -0
  32. data/lib/pi_piper.rb +5 -3
  33. data/lib/pi_piper/bcm2835.rb +84 -14
  34. data/lib/pi_piper/i2c.rb +0 -1
  35. data/lib/pi_piper/libbcm2835.so +0 -0
  36. data/lib/pi_piper/pin.rb +102 -63
  37. data/lib/pi_piper/pin_error.rb +3 -0
  38. data/lib/pi_piper/pin_values.rb +35 -0
  39. data/lib/pi_piper/platform.rb +5 -5
  40. data/lib/pi_piper/pwm.rb +95 -0
  41. data/lib/pi_piper/spi.rb +30 -45
  42. data/lib/pi_piper/stub_driver.rb +124 -0
  43. data/lib/pi_piper/version.rb +3 -0
  44. data/pi_piper.gemspec +24 -29
  45. data/spec/bcm2835_spec.rb +132 -0
  46. data/spec/i2c_spec.rb +62 -0
  47. data/spec/pin_spec.rb +140 -0
  48. data/spec/pwm_spec.rb +83 -0
  49. data/spec/spec_helper.rb +7 -0
  50. data/spec/spi_spec.rb +38 -0
  51. data/spec/stub_driver_spec.rb +140 -0
  52. metadata +100 -26
  53. data/Manifest +0 -14
  54. data/lib/pi_piper/libbcm2835.img +0 -0
@@ -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
@@ -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
- GPIO_PUD_OFF = 0
5
- GPIO_PUD_DOWN = 1
6
- GPIO_PUD_UP = 2
6
+ include PiPiper::PinValues
7
7
 
8
- attr_reader :pin, :last_value, :value, :direction, :invert
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
- # @option options [Symbol] :direction The direction of communication, either :in or :out. Defaults to :in.
15
- # @option options [Boolean] :invert Indicates if the value read from the physical pin should be inverted. Defaults to false.
16
- # @option options [Symbol] :trigger Indicates when the wait_for_change method will detect a change, either :rising, :falling, or :both edge triggers. Defaults to :both.
17
- # @option options [Symbol] :pull Indicates if and how pull mode must be set when pin direction is set to :in. Either :up, :down or :offing. Defaults to :off.
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, :invert => false, :trigger => :both, :pull => :off}.merge options
20
- @pin = options[:pin]
21
- @direction = options[:direction]
22
- @invert = options[:invert]
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
- raise "Invalid pull mode. Options are :up, :down or :float (default)" unless [:up, :down, :float, :off].include? @pull
27
- raise "Unable to use pull-ups : pin direction must be ':in' for this" if @direction != :in && [:up, :down].include?(@pull)
28
- raise "Invalid direction. Options are :in or :out" unless [:in, :out].include? @direction
29
- raise "Invalid trigger. Options are :rising, :falling, or :both" unless [:rising, :falling, :both].include? @trigger
35
+ @pin = options[:pin]
36
+ @direction = options[:direction]
37
+ @invert = options[:invert]
38
+ @trigger = options[:trigger]
39
+ @pull = options[:pull]
30
40
 
31
- @direction == :out ? Platform.driver.pin_output(@pin) : Platform.driver.pin_input(@pin)
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 logic level high.
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, 1) if direction == :out
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 the logic level low.
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, 0) if direction == :out
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 == 0
84
+ value == GPIO_LOW
56
85
  end
57
86
 
58
- # If the pin has been initialized for output this method will either raise or lower the logic level depending on `new_value`.
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 == 0 ? off : on
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 be pulled up or down (respectively with :up and :down).
65
- # Pulling an input pin wil prevent noise from triggering it when the input is floating.
66
- # For instance when nothing is plugged in, pulling the pin-up will make subsequent value readings to return 'on' (or high, or 1...).
67
- # @param [Symbol] state Indicates if and how pull mode must be set when pin direction is set to :in. Either :up, :down or :offing. Defaults to :off.
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
- return nil unless @direction == :in
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 pull-up/pull-down resistor, either :up, :down or :off.
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
- # blocks until a logic level change occurs. The initializer option `:trigger` modifies what edge this method will release on.
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
- fd = File.open(value_file, "r")
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 first, `value`, `last_value` and `changed?` will not be updated.
113
- # In short, you must call this method if you are curious about the current state of the pin.
114
- def read
115
- @last_value = @value
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
- private
121
- def value_file
122
- "/sys/class/gpio/gpio#{pin}/value"
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 edge_file
126
- "/sys/class/gpio/gpio#{pin}/edge"
165
+ def valid_direction?
166
+ [:in, :out].include?(@direction)
127
167
  end
128
168
 
129
- def direction_file
130
- "/sys/class/gpio/gpio#{pin}/direction"
169
+ def valid_pull?
170
+ [:up, :down, :float, :off].include? @pull
131
171
  end
132
-
133
172
  end
134
173
  end
@@ -0,0 +1,3 @@
1
+ module PiPiper
2
+ class PinError < StandardError; end
3
+ 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
@@ -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
- #require 'bcm2835.rb'
10
+ require 'pi_piper/bcm2835'
12
11
  PiPiper::Bcm2835.init
13
12
  @@driver = PiPiper::Bcm2835
14
- at_exit { Bcm2835.close }
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
@@ -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
@@ -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
- Bcm2835.spi_set_data_mode mode
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
- Bcm2835.spi_begin
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
- Bcm2835.spi_end
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
- Bcm2835.spi_clock(divider)
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
- Bcm2835.spi_bit_order(order)
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
- Bcm2835.spi_chip_select(chip)
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
- Bcm2835.spi_chip_select(CHIP_SELECT_NONE)
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
- Bcm2835.spi_chip_select_polarity(chip, active_low ? 0 : 1)
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 { Bcm2835.spi_transfer(0) }
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
- Bcm2835.spi_transfer(data)
185
+ Platform.driver.spi_transfer(data)
201
186
  when Enumerable
202
- Bcm2835.spi_transfer_bytes(data)
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