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.
- data/lib/BBB.rb +13 -17
- data/lib/BBB/application.rb +4 -21
- data/lib/BBB/circuit.rb +18 -33
- data/lib/BBB/components/analog_component.rb +29 -6
- data/lib/BBB/components/led.rb +39 -9
- data/lib/BBB/components/pinnable.rb +90 -4
- data/lib/BBB/components/servo.rb +43 -0
- data/lib/BBB/pins/analog_pin.rb +39 -0
- data/lib/BBB/pins/digital_pin.rb +106 -0
- data/lib/BBB/pins/io/ain.rb +58 -0
- data/lib/BBB/pins/io/gpio.rb +77 -0
- data/lib/BBB/pins/io/mapped.rb +39 -0
- data/lib/BBB/pins/io/pin_mapper.rb +224 -0
- data/lib/BBB/pins/io/pwm.rb +61 -0
- data/lib/BBB/pins/pinnable.rb +78 -0
- data/lib/BBB/pins/pwm_pin.rb +43 -0
- data/lib/BBB/version.rb +1 -1
- data/spec/application_spec.rb +1 -26
- data/spec/circuit_spec.rb +0 -1
- data/spec/components/analog_component_spec.rb +36 -0
- data/spec/components/led_spec.rb +14 -19
- data/spec/components/pinnable_spec.rb +73 -8
- data/spec/components/servo_spec.rb +6 -0
- data/spec/pins/analog_pin_spec.rb +33 -0
- data/spec/pins/digital_input_pin_spec.rb +13 -0
- data/spec/pins/digital_output_pin_spec.rb +14 -0
- data/spec/pins/digital_pin_spec.rb +66 -0
- data/spec/pins/io/mapped_spec.rb +41 -0
- data/spec/{board → pins/io}/pin_mapper_spec.rb +2 -2
- data/spec/pins/pinnable_spec.rb +68 -0
- data/spec/pins/pwm_pin_spec.rb +29 -0
- metadata +34 -37
- data/lib/BBB/adc/analog_pin.rb +0 -42
- data/lib/BBB/adc/setup.rb +0 -20
- data/lib/BBB/board/base.rb +0 -45
- data/lib/BBB/board/json_pin_mapper.rb +0 -203
- data/lib/BBB/board/pin_mapper.rb +0 -20
- data/lib/BBB/board/test_board.rb +0 -12
- data/lib/BBB/gpio/base.rb +0 -56
- data/lib/BBB/gpio/digital_pin.rb +0 -69
- data/lib/BBB/gpio/pin_converter.rb +0 -28
- data/lib/BBB/io/analog_pin.rb +0 -24
- data/lib/BBB/io/digital_pin.rb +0 -67
- data/lib/BBB/io/mock_pin.rb +0 -8
- data/lib/BBB/io/pinnable.rb +0 -12
- data/spec/adc/analog_pin_spec.rb +0 -100
- data/spec/adc/setup_spec.rb +0 -9
- data/spec/board/board_spec.rb +0 -49
- data/spec/gpio/base_spec.rb +0 -48
- data/spec/gpio/digital_pin_spec.rb +0 -100
- data/spec/gpio/pin_converter_spec.rb +0 -19
- data/spec/io/digital_pin_spec.rb +0 -14
- data/spec/io/mock_pin_spec.rb +0 -13
- 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
data/spec/application_spec.rb
CHANGED
@@ -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
@@ -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
|
data/spec/components/led_spec.rb
CHANGED
@@ -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
|
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.
|
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.
|
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 "
|
28
|
-
led.
|
29
|
-
led.
|
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
|
36
|
-
led.
|
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
|
-
|
8
|
-
|
9
|
-
|
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 "
|
14
|
-
|
15
|
-
|
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
|