BBB 0.0.10 → 0.1.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.
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