BBB 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/lib/BBB.rb +13 -17
  2. data/lib/BBB/application.rb +4 -21
  3. data/lib/BBB/circuit.rb +18 -33
  4. data/lib/BBB/components/analog_component.rb +29 -6
  5. data/lib/BBB/components/led.rb +39 -9
  6. data/lib/BBB/components/pinnable.rb +90 -4
  7. data/lib/BBB/components/servo.rb +43 -0
  8. data/lib/BBB/pins/analog_pin.rb +39 -0
  9. data/lib/BBB/pins/digital_pin.rb +106 -0
  10. data/lib/BBB/pins/io/ain.rb +58 -0
  11. data/lib/BBB/pins/io/gpio.rb +77 -0
  12. data/lib/BBB/pins/io/mapped.rb +39 -0
  13. data/lib/BBB/pins/io/pin_mapper.rb +224 -0
  14. data/lib/BBB/pins/io/pwm.rb +61 -0
  15. data/lib/BBB/pins/pinnable.rb +78 -0
  16. data/lib/BBB/pins/pwm_pin.rb +43 -0
  17. data/lib/BBB/version.rb +1 -1
  18. data/spec/application_spec.rb +1 -26
  19. data/spec/circuit_spec.rb +0 -1
  20. data/spec/components/analog_component_spec.rb +36 -0
  21. data/spec/components/led_spec.rb +14 -19
  22. data/spec/components/pinnable_spec.rb +73 -8
  23. data/spec/components/servo_spec.rb +6 -0
  24. data/spec/pins/analog_pin_spec.rb +33 -0
  25. data/spec/pins/digital_input_pin_spec.rb +13 -0
  26. data/spec/pins/digital_output_pin_spec.rb +14 -0
  27. data/spec/pins/digital_pin_spec.rb +66 -0
  28. data/spec/pins/io/mapped_spec.rb +41 -0
  29. data/spec/{board → pins/io}/pin_mapper_spec.rb +2 -2
  30. data/spec/pins/pinnable_spec.rb +68 -0
  31. data/spec/pins/pwm_pin_spec.rb +29 -0
  32. metadata +34 -37
  33. data/lib/BBB/adc/analog_pin.rb +0 -42
  34. data/lib/BBB/adc/setup.rb +0 -20
  35. data/lib/BBB/board/base.rb +0 -45
  36. data/lib/BBB/board/json_pin_mapper.rb +0 -203
  37. data/lib/BBB/board/pin_mapper.rb +0 -20
  38. data/lib/BBB/board/test_board.rb +0 -12
  39. data/lib/BBB/gpio/base.rb +0 -56
  40. data/lib/BBB/gpio/digital_pin.rb +0 -69
  41. data/lib/BBB/gpio/pin_converter.rb +0 -28
  42. data/lib/BBB/io/analog_pin.rb +0 -24
  43. data/lib/BBB/io/digital_pin.rb +0 -67
  44. data/lib/BBB/io/mock_pin.rb +0 -8
  45. data/lib/BBB/io/pinnable.rb +0 -12
  46. data/spec/adc/analog_pin_spec.rb +0 -100
  47. data/spec/adc/setup_spec.rb +0 -9
  48. data/spec/board/board_spec.rb +0 -49
  49. data/spec/gpio/base_spec.rb +0 -48
  50. data/spec/gpio/digital_pin_spec.rb +0 -100
  51. data/spec/gpio/pin_converter_spec.rb +0 -19
  52. data/spec/io/digital_pin_spec.rb +0 -14
  53. data/spec/io/mock_pin_spec.rb +0 -13
  54. data/spec/io/pinnable_spec.rb +0 -13
@@ -0,0 +1,61 @@
1
+ module BBB
2
+ module Pins
3
+ module IO
4
+ class PWM
5
+ include Mapped
6
+
7
+ attr_reader :handles, :position
8
+
9
+ def initialize(position)
10
+ @position = position
11
+ self.export
12
+ @handles = get_file_handles
13
+ end
14
+
15
+ def path
16
+ return @path unless @path.nil?
17
+ @path = Dir.glob("/sys/devices/ocp.*/pwm_test_#{pin_map.key}.*").first
18
+ end
19
+
20
+ def get_file_handles
21
+ handles = {}
22
+ files = %w(duty period polarity run)
23
+
24
+ files.each do |file|
25
+ file_path = File.expand_path(file, path)
26
+ handles[file.to_sym] = File.open(file_path, "r+")
27
+ end
28
+
29
+ return handles
30
+ end
31
+
32
+ def export
33
+ cape_dir = "/sys/devices/bone_capemgr.*/slots"
34
+ dir = Dir.glob(cape_dir)
35
+ if dir.length == 0
36
+ raise BoardError, "unable to access the capemgr directory: #{cape_dir}"
37
+ end
38
+
39
+ pin_map_key = pin_map.key # This calls the pin map, which raises an error in case pin can't be mapped.
40
+ system("echo am33xx_pwm > #{dir.first}")
41
+ system("echo bone_pwm_#{pin_map_key} > #{dir.first}")
42
+ end
43
+
44
+ def write(symbol, value)
45
+ handle = handles[symbol]
46
+ handle.rewind
47
+ handle.write(value)
48
+ handle.flush
49
+ return value
50
+ end
51
+
52
+ def read(symbol)
53
+ handle = handles[symbol]
54
+ handle.rewind
55
+ handle.read.to_i
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
@@ -0,0 +1,78 @@
1
+ module BBB
2
+ module Pins
3
+ ##
4
+ # Module which is included in all pins. The module provides the basic
5
+ # interface for a BBB::Pin and also takes care of selecting the right IO
6
+ # class to work with.
7
+ #
8
+ # It defines a #pinnable? method to test if the module is properly included
9
+ # in a pin.
10
+ #
11
+ module Pinnable
12
+ attr_reader :position, :opts
13
+
14
+ ##
15
+ # Initializes a Pin
16
+ #
17
+ # @param position [Symbol] The position of the pin
18
+ # @option opts [Boolean] :mock whether or not to use MockIO
19
+ #
20
+ def initialize(position, opts={})
21
+ @position = position
22
+ @opts = opts
23
+ end
24
+
25
+ ##
26
+ # Returns an instance of the IO class for the pin and memoizes this.
27
+ #
28
+ # @return [IO]
29
+ #
30
+ def io
31
+ @io ||= mock? ? mock_io : default_io
32
+ end
33
+
34
+ ##
35
+ # Return wheter or not this is a mock pin
36
+ #
37
+ # @return [Boolean]
38
+ #
39
+ def mock?
40
+ @mock ||= @opts.fetch(:mock, false)
41
+ end
42
+
43
+ ##
44
+ # Always returns true, method is used to test if module is included.
45
+ #
46
+ # @return [Boolean] true
47
+ #
48
+ def pinnable?
49
+ true
50
+ end
51
+
52
+ private
53
+
54
+ ##
55
+ # If a class includes the Pinnable module, it should overwrite the
56
+ # default_io method. If this is not done, the module raises an error to
57
+ # point the developer into the right direction.
58
+ #
59
+ # The default_io method should return an instantiated object that makes
60
+ # the inteface between the filesystem, drivers etc, and the ruby code.
61
+ # Probably the object will behave like an IO object, relying on the linux
62
+ # kernel and drivers to get things done on the board.
63
+ #
64
+ def default_io
65
+ raise NotImplementedError
66
+ end
67
+
68
+ ##
69
+ # The IO instance used for mock pins. By default this is StringIO.new,
70
+ # however, each class should determine if it defines its own MockIO class.
71
+ # An example of which can be found at the PWMPin.
72
+ #
73
+ def mock_io
74
+ StringIO.new
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,43 @@
1
+ module BBB
2
+ module Pins
3
+ class PWMPin
4
+ include Pinnable
5
+
6
+ %w(duty polarity period run).each do |method|
7
+ define_method("#{method}=".to_sym) do |value|
8
+ io.write(method.to_sym, value.to_i)
9
+ end
10
+
11
+ define_method(method.to_sym) do
12
+ io.read(method.to_sym)
13
+ end
14
+ end
15
+
16
+ def period_hz(herz)
17
+ self.period = 1/herz*10e9
18
+ end
19
+
20
+ private
21
+
22
+ def default_io
23
+ IO::PWM.new(position)
24
+ end
25
+
26
+ class MockIO < StringIO
27
+ def write(symbol, value)
28
+ super(value)
29
+ end
30
+
31
+ def read(symbol)
32
+ rewind
33
+ super().to_i
34
+ end
35
+ end
36
+
37
+ def mock_io
38
+ MockIO.new
39
+ end
40
+
41
+ end
42
+ end
43
+ end
data/lib/BBB/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module BBB
2
- VERSION = "0.0.10"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -6,29 +6,6 @@ describe BBB::Application do
6
6
  lambda { BBB::Application.new }.should_not raise_exception
7
7
  end
8
8
 
9
- class MockCircuit
10
- def components; {}; end
11
- end
12
-
13
- class TestBoardApp < BBB::Application
14
- board "board"
15
- circuit MockCircuit.new
16
- end
17
-
18
- it "defaults board to class variable board" do
19
- TestBoardApp.instance_variable_get('@_board').should eql("board")
20
- end
21
-
22
- it "sets the board as an instance variable" do
23
- app = TestBoardApp.new
24
- app.board.should eql("board")
25
- end
26
-
27
- it "sets a circuit" do
28
- app = TestBoardApp.new
29
- app.circuit.class.should eql(MockCircuit)
30
- end
31
-
32
9
  class TestLedCircuit < BBB::Circuit
33
10
  def initialize
34
11
  attach BBB::Components::Led, pin: :P8_3, as: :led
@@ -36,7 +13,6 @@ describe BBB::Application do
36
13
  end
37
14
 
38
15
  class TestConnectionApp < BBB::Application
39
- board BBB::Board::TestBoard.new
40
16
  circuit TestLedCircuit.new
41
17
 
42
18
  def run
@@ -49,13 +25,12 @@ describe BBB::Application do
49
25
 
50
26
  app.circuit.respond_to?(:led).should be_true
51
27
  app.circuit.led.should_receive(:on!)
52
- app.led.should eql(app.circuit.led)
53
28
 
29
+ app.led.should eql(app.circuit.led)
54
30
  app.led.on!
55
31
  end
56
32
 
57
33
  class FunctionsInApp < BBB::Application
58
- board BBB::Board::TestBoard.new
59
34
  circuit TestLedCircuit.new
60
35
 
61
36
  def run
data/spec/circuit_spec.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe BBB::Circuit do
4
- let(:circuit) {BBB::Circuit.new}
5
4
  let(:c) { BBB::Circuit.new }
6
5
  # You can't really avoid some integration testing here
7
6
  let(:led) { BBB::Components::Led }
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe BBB::Components::AnalogComponent do
4
+ let(:component) { BBB::Components::AnalogComponent.new }
5
+ let(:component_class) { BBB::Components::AnalogComponent }
6
+
7
+ it "includes Pinnable module" do
8
+ component.pinnable?.should be_true
9
+ end
10
+
11
+ it "registers AnalogPin" do
12
+ component_class.pins.should eql([BBB::Pins::AnalogPin])
13
+ end
14
+
15
+ context "initialized" do
16
+ before :each do
17
+ @c = component
18
+ @c.initialize_pins(:P8_13)
19
+ end
20
+
21
+ it "#pin" do
22
+ @c.pin.class.should eql(BBB::Pins::AnalogPin)
23
+ end
24
+
25
+ it "#read" do
26
+ @c.pin.should_receive(:read)
27
+ @c.read
28
+ end
29
+
30
+ it "#value aliasses #read" do
31
+ @c.should_receive(:read)
32
+ @c.value
33
+ end
34
+ end
35
+
36
+ end
@@ -3,42 +3,37 @@ require 'spec_helper'
3
3
  describe BBB::Components::Led do
4
4
  let(:led) {BBB::Components::Led.new}
5
5
 
6
+ before :each do
7
+ led.initialize_pins(:P8_4, mock: true)
8
+ end
9
+
6
10
  it "initializes off" do
7
- led.off?.should be_true
11
+ led.off?
8
12
  end
9
13
 
10
14
  it "set state: on" do
15
+ led.pin.should_receive(:on!)
11
16
  led.on!
12
- led.on?.should be_true
13
17
  end
14
18
 
15
19
  it "set state: off" do
16
- led.on!
20
+ led.pin.should_receive(:off!)
17
21
  led.off!
18
- led.off?.should be_true
19
22
  end
20
23
 
21
24
  it "check state: on?" do
22
- led.off!
23
- led.on!
24
- led.on?.should be_true
25
+ led.pin.should_receive(:on?)
26
+ led.on?
25
27
  end
26
28
 
27
- it "provides access to state "do
28
- led.on!
29
- led.state.should eql(:high)
30
- led.off!
31
- led.state.should eql(:low)
29
+ it "check state: on?" do
30
+ led.pin.should_receive(:off?)
31
+ led.off?
32
32
  end
33
33
 
34
34
  context "#pinnable include" do
35
- it "responds to pinnable actions" do
36
- led.respond_to?(:register_pin_positions)
37
- end
38
-
39
- it "sets the right pin position" do
40
- led.register_pin_positions(:P8_3)
41
- led.pin.position.should eql(:P8_3)
35
+ it "responds to pinnable?" do
36
+ led.pinnable?.should be_true
42
37
  end
43
38
  end
44
39
 
@@ -1,19 +1,84 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe BBB::Components::Pinnable do
4
+ class DummyPin
5
+ include BBB::Pins::Pinnable
6
+ end
7
+
4
8
  class DummyComponent
5
9
  include BBB::Components::Pinnable
10
+ uses DummyPin
11
+ end
12
+
13
+ class DoubleDummyComponent
14
+ include BBB::Components::Pinnable
15
+ uses DummyPin, DummyPin
16
+ end
17
+
18
+ let(:dummy) { DummyComponent }
19
+ let(:double_dummy) { DoubleDummyComponent }
20
+
21
+ context "#initialize_pins" do
22
+ it "with single position" do
23
+ DummyPin.should_receive(:new).once.and_return(@mock_pin)
24
+ c = dummy.new
25
+ c.initialize_pins(:P8_3)
26
+ c.pins[0].should eql(@mock_pin)
27
+ end
28
+
29
+ it "with single position and options" do
30
+ DummyPin.should_receive(:new).with(:P8_3, {:key=>"value"}).once
31
+ .and_return(@mock_pin)
32
+ c = dummy.new
33
+ c.initialize_pins(:P8_3, key: "value")
34
+ c.pins[0].should eql(@mock_pin)
35
+ end
36
+
37
+ it "with multiple positions" do
38
+ DummyPin.should_receive(:new).exactly(2).times.and_return(@mock_pin)
39
+ c = double_dummy.new
40
+ c.initialize_pins(:P8_3, :P8_4)
41
+ c.pins[0].should eql(@mock_pin)
42
+ c.pins[1].should eql(@mock_pin)
43
+ end
44
+
45
+ it "with multiple positions and options" do
46
+ DummyPin.should_receive(:new).with(:P8_3, {:key=>"value"}).once
47
+ .and_return(@mock_pin)
48
+ DummyPin.should_receive(:new).with(:P8_4, {:key=>"value"}).once
49
+ .and_return(@mock_pin)
50
+ c = double_dummy.new
51
+ c.initialize_pins(:P8_3, :P8_4, key: "value")
52
+ c.pins[0].should eql(@mock_pin)
53
+ c.pins[1].should eql(@mock_pin)
54
+ end
55
+
56
+ it "verifies the pin count" do
57
+ c = dummy.new
58
+ c.should_receive(:verify_pin_position_count).with([:P8_3])
59
+ c.initialize_pins(:P8_3)
60
+ end
61
+ end
62
+
63
+ context "#verify_pin_position_count" do
64
+
65
+ it "raises exception when counts don't match" do
66
+ c = dummy.new
67
+ lambda do
68
+ c.verify_pin_position_count([:foo, :bar])
69
+ end.should raise_exception(BBB::PinsDoNotMatchException)
70
+ end
6
71
 
7
- def initialize
8
- pin = Struct.new(:position)
9
- @pins = [pin.new(0), pin.new(1)]
72
+ it "does not raise an exception when counts do match" do
73
+ c = dummy.new
74
+ lambda do
75
+ c.verify_pin_position_count([:foo])
76
+ end.should_not raise_exception
10
77
  end
11
78
  end
12
79
 
13
- it "knows how to register pins" do
14
- comp = DummyComponent.new
15
- comp.register_pin_positions(:P8_3, :P8_4)
16
- comp.pins[0].position.should eql(:P8_3)
17
- comp.pins[1].position.should eql(:P8_4)
80
+ it "should respond to pinnable?" do
81
+ c = dummy.new
82
+ c.pinnable?.should be_true
18
83
  end
19
84
  end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe BBB::Components::Servo do
4
+ let(:servo) { BBB::Components::Servo.new }
5
+
6
+ end