BBB 0.0.3 → 0.0.4

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/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - jruby-19mode
5
- - rbx-19mode
4
+ - 2.0.0
5
+ - rbx-2.2.1
6
6
  - ruby-head
7
7
  - jruby-head
data/Gemfile CHANGED
@@ -6,4 +6,6 @@ gem 'coveralls', require: false
6
6
 
7
7
  group :test do
8
8
  gem 'pry'
9
+ gem 'rubysl', :platform => :rbx
10
+ gem 'racc', :platform => :rbx
9
11
  end
@@ -0,0 +1,31 @@
1
+ require 'BBB'
2
+
3
+ ##
4
+ # Setup the AnalogPin Circuit
5
+ #
6
+ class Circuit < BBB::Circuit
7
+ def initialize
8
+ # Attach temperature sensor to pin P9_40
9
+ attach BBB::Components::Analog, pin: :P9_40, as: :thermometer
10
+ end
11
+ end
12
+
13
+ ##
14
+ # Setup the actual Applicaiton
15
+ #
16
+ class TemperatureExampleApp < BBB::Application
17
+ # Run this on the BeagleBoneBlack
18
+ board BBB::Board.new
19
+
20
+ # Connect the circuit to the board
21
+ circuit Circuit.new
22
+
23
+ # This is the basic run loop
24
+ def run
25
+ puts thermometer.read
26
+ end
27
+ end
28
+
29
+ # Initialize the app
30
+ app = TemperatureExampleApp.new
31
+ app.start
data/examples/led.rb CHANGED
@@ -17,7 +17,7 @@ class LedExampleApplication < BBB::Application
17
17
  # Run this on the BeableBoneBlack
18
18
  board BBB::Board.new
19
19
 
20
- # Connection the led circuit
20
+ # Connect the led circuit
21
21
  circuit Circuit.new
22
22
 
23
23
  # This is the basic run loop
data/examples/sketches.rb CHANGED
@@ -73,8 +73,8 @@ module Thunderball
73
73
 
74
74
  def Stabalizer
75
75
  def initialize(opts={})
76
- @escs = opts[:escs]
77
- @gyo = opts[:gyro]
76
+ @escs = opts[:escs]
77
+ @gyo = opts[:gyro]
78
78
  @accelerometer = opts[:accelerometer]
79
79
  end
80
80
 
@@ -0,0 +1,41 @@
1
+ module BBB
2
+ module ADC
3
+ class AnalogPin
4
+ attr_reader :position, :pin_map, :mock
5
+ attr_reader :file_handle
6
+
7
+ def initialize(position, opts={})
8
+ self.position = position
9
+ @mock = opts.fetch(:mock, false)
10
+ @file_handle = get_file_handle(mock)
11
+ end
12
+
13
+ def position=(position)
14
+ map = Board::PinMapper.map(position, :ain)
15
+ unless map.respond_to?(:ain) && !map.ain.nil?
16
+ raise ArgumentError, "#{position} is not a valid AIN pin position"
17
+ end
18
+
19
+ @pin_map = map
20
+ @position = position
21
+ end
22
+
23
+ def ain_path
24
+ "/sys/devices/ocp.3/helper.15/AIN#{pin_map.ain}"
25
+ end
26
+
27
+ def read
28
+ file_handle.read
29
+ end
30
+
31
+ def scale
32
+ pin_map.scale
33
+ end
34
+
35
+ def get_file_handle(mock=false)
36
+ mock ? StringIO.new : File.open(ain_path, "r")
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ module BBB
2
+ module ADC
3
+ def self.setup
4
+ check_if_kernel_module_is_loaded!
5
+ end
6
+
7
+ def self.check_if_kernel_module_is_loaded!
8
+ ains = `find /sys/ -name '*AIN*'`.split("\n")
9
+
10
+ if ains.size > 0
11
+ return true
12
+ else
13
+ raise ModuleNotLoadedException, "Is seems that the ADC module is not
14
+ loaded into the kernel. You might want to try: \n
15
+ sudo modprobe t1_tscadc or add it to the kernel on boot: \n
16
+ echo 't1_tscadc' >> /etc/modules.conf"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,45 @@
1
+ module BBB
2
+ module Board
3
+ ##
4
+ # Base class, designed and tested on BeagleBone Black Revision A5C
5
+ #
6
+ class Base
7
+ attr_reader :gpio, :pin_converter
8
+
9
+ def initialize(pin_converter=nil)
10
+ @pin_converter = pin_converter || self.class.pin_converter
11
+ @pins = {}
12
+ end
13
+
14
+ ##
15
+ # Define methods for a GPIO::PIN
16
+ #
17
+ def setup_pin(pin)
18
+ @pins[pin.position] = pin
19
+
20
+ metaclass = class << self; self; end
21
+ metaclass.class_eval do
22
+ define_method("p#{pin.position.to_s[1..-1]}") do
23
+ @pins[pin.position].read
24
+ end
25
+
26
+ define_method("p#{pin.position.to_s[1..-1]}=") do |value|
27
+ @pins[pin.position].write value
28
+ end if pin.mode == :output
29
+ end
30
+ end
31
+
32
+ def connect_io_pin(pin)
33
+ gpio_pin = pin_converter.convert(pin)
34
+ pin.pin_io = gpio_pin
35
+ setup_pin(pin)
36
+ end
37
+
38
+ private
39
+
40
+ def self.pin_converter
41
+ GPIO::PinConverter.new
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,203 @@
1
+ module BBB
2
+ module Board
3
+ ##
4
+ # This class provides a convenient way of mapping a JSON representation of the
5
+ # pins, taken from the bonescript sourcecode, into Ruby objects. After
6
+ # converting the json to ruby objects the "normal" PinMapper will take the
7
+ # object structure and provide the actual mapping from the pin header
8
+ # positions, like p8_3 to the correct GPIO, I2C or WPM endpoints.
9
+ #
10
+ # This class should not be used directly to provide these mappings it's simply
11
+ # a helper class to get from JSON to Ruby.
12
+ #
13
+ class JSONPinMapper
14
+ class PinMap < Struct.new(:pins, :uart, :i2c); end
15
+ class Pin < Struct.new(:name, :gpio, :led, :mux, :key, :mux_reg_offset,
16
+ :options, :eeprom, :pwm, :ain, :scale); end
17
+ class UART < Struct.new(:devicetree, :rx, :tx); end
18
+ class I2C < Struct.new(:devicetree, :path, :sda, :scl); end
19
+
20
+ attr_reader :data
21
+
22
+ ##
23
+ # Initialize a JSONPinMapper
24
+ #
25
+ # @param [Hash] hash Hash that was converted from json with the keys
26
+ # pinIndex, uart and i2c.
27
+ #
28
+ def initialize(hash)
29
+ @data = hash
30
+ end
31
+
32
+ ##
33
+ # Factor a new JSONPinMapper based on a json_file that get's parsed to a
34
+ # hash.
35
+ #
36
+ # @param [String] json_filename The file that contains the JSON object with
37
+ # pin information
38
+ #
39
+ # @return JSONPinMapper instance
40
+ #
41
+ def self.convert(json_filename)
42
+ file = File.open(json_filename, "r")
43
+ hash = JSON.parse(file.read)
44
+ new(hash).convert
45
+ end
46
+
47
+ ##
48
+ # Convert from a the data hash to ruby objects
49
+ #
50
+ # @return [Struct] with pins, uart and i2c as keys.
51
+ # pins has a
52
+ #
53
+ def convert
54
+ pins = convert_pins(data["pinIndex"])
55
+ uart = convert_uart(data["uarts"])
56
+ i2c = convert_i2c(data["i2c"])
57
+
58
+ PinMap.new(pins, uart, i2c)
59
+ end
60
+
61
+ ##
62
+ # Converts an array of pins into a hash with the pin key as a key and a Pin
63
+ # Struct as a value.
64
+ #
65
+ # Here is an example of a piece of the JSON code containing pin info:
66
+ #
67
+ # {
68
+ # "name": "USR0",
69
+ # "gpio": 53,
70
+ # "led": "usr0",
71
+ # "mux": "gpmc_a5",
72
+ # "key": "USR0",
73
+ # "muxRegOffset": "0x054",
74
+ # "options": [
75
+ # "gpmc_a5",
76
+ # "gmii2_txd0",
77
+ # "rgmii2_td0",
78
+ # "rmii2_txd0",
79
+ # "gpmc_a21",
80
+ # "pr1_mii1_rxd3",
81
+ # "eqep1b_in",
82
+ # "gpio1_21"
83
+ # ]
84
+ # }
85
+ #
86
+ # @param [Array<Hash>] array An array of Pin hashes
87
+ #
88
+ # @return [Hash] a hash with pin keys as keys and pin objects as values.
89
+ #
90
+ def convert_pins(array)
91
+ hash = {}
92
+
93
+ array.each do |pin_hash|
94
+ pin = Pin.new
95
+ pin_hash.each_pair do |key, value|
96
+ pin[underscore(key).to_sym] = value
97
+ end
98
+ hash[pin.key.upcase.to_sym] = pin
99
+ end
100
+
101
+ return hash
102
+ end
103
+
104
+ ##
105
+ # Convert a hash of uarts to a hash with the uart folder (e.g. /dev/tty00)
106
+ # as the key and an uart object as the value.
107
+ #
108
+ # Here is an example of an individual UART hash:
109
+ #
110
+ # "/dev/ttyO1": {
111
+ # "devicetree": "BB-UART1",
112
+ # "rx": "P9_26",
113
+ # "tx": "P9_24"
114
+ # }
115
+ #
116
+ # @param [Hash] data_hash with strings as keys and hashes as values
117
+ #
118
+ # @return [Hash] with strings of uart positions (e.g. /dev/tty00) as keys
119
+ # and uart objects as values
120
+ #
121
+ def convert_uart(data_hash)
122
+ convert_hash_with_hashes(data_hash, UART)
123
+ end
124
+
125
+ ##
126
+ # Convert a hash of I2Cs to a hash with the I2C folder as the key and a i2c
127
+ # object as the value
128
+ #
129
+ # Here is an example of an individual I2C hash:
130
+ #
131
+ # "/dev/i2c-1": {
132
+ # "devicetree": "BB-I2C1",
133
+ # "path": "/dev/i2c-2",
134
+ # "sda": "P9_18",
135
+ # "scl": "P9_17"
136
+ # }
137
+ #
138
+ # @param [Hash] data_hash with strings as keys and hashes as values
139
+ #
140
+ # @return [Hash] with strings of I2C folders as keys and I2C objects as
141
+ # values
142
+ #
143
+ def convert_i2c(data_hash)
144
+ convert_hash_with_hashes(data_hash, I2C)
145
+ end
146
+
147
+ private
148
+
149
+ ##
150
+ # @see #convert_uart
151
+ #
152
+ def convert_hash_with_hashes(data_hash, object)
153
+ hash = {}
154
+
155
+ data_hash.each_pair do |filesystem, info_hash|
156
+ instance = object.new
157
+ info_hash.each_pair do |key, value|
158
+ instance[key] = value
159
+ end
160
+
161
+ hash[filesystem] = instance
162
+ end
163
+
164
+ return hash
165
+ end
166
+
167
+ ##
168
+ # Makes an underscored, lowercase form from the expression in the string.
169
+ #
170
+ # Gracefully copied from ActiveSupport::Inflections
171
+ # http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore
172
+ #
173
+ # Changes '::' to '/' to convert namespaces to paths.
174
+ #
175
+ # 'ActiveModel'.underscore # => "active_model"
176
+ # 'ActiveModel::Errors'.underscore # => "active_model/errors"
177
+ #
178
+ # As a rule of thumb you can think of +underscore+ as the inverse of
179
+ # +camelize+, though there are cases where that does not hold:
180
+ #
181
+ # 'SSLError'.underscore.camelize # => "SslError"
182
+ def underscore(camel_cased_word)
183
+ word = camel_cased_word.to_s.dup
184
+ word.gsub!('::', '/')
185
+ word.gsub!(/(?:([A-Za-z\d])|^)(#{acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
186
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
187
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
188
+ word.tr!("-", "_")
189
+ word.downcase!
190
+ word
191
+ end
192
+
193
+ ##
194
+ # Specifies acronyms. This is a shortcut approach to the full acronym
195
+ # functionality of Rails. Which can be found here:
196
+ # https://github.com/rails/rails/blob/4e327225947b933d5434509e02e98226c581adc1/activesupport/lib/active_support/inflector/inflections.rb#L47
197
+ #
198
+ def acronym_regex
199
+ /#{%w(I2C UART GPIO).join("|")}/
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,19 @@
1
+ module BBB
2
+ module Board
3
+ class PinMapper
4
+ ##
5
+ # Thanks to BoneScript, see the resources/pin_mappings.json.comment
6
+ # for reference to the original BoneScript file.
7
+ #
8
+ MAP = JSONPinMapper.convert("resources/pin_mappings.json")
9
+
10
+ def self.map(pin_symbol, type=:gpio)
11
+ begin
12
+ MAP.pins.fetch(pin_symbol.upcase.to_sym)
13
+ rescue Exception => e
14
+ raise UnknownPinException, "Pin #{pin_symbol} could not be mapped"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ module BBB
2
+ module Board
3
+ class TestBoard < BBB::Board::Base
4
+
5
+ private
6
+
7
+ def self.pin_converter
8
+ GPIO::PinConverter.new(mock:true)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -2,5 +2,4 @@ module BBB
2
2
  class UnknownPinException < ArgumentError; end
3
3
  class UnknownPinModeException < ArgumentError; end
4
4
  class PinsDoNotMatchException < ArgumentError; end
5
- class NotImplementedError < ArgumentError; end
6
5
  end
data/lib/BBB/gpio/base.rb CHANGED
@@ -12,12 +12,12 @@ module BBB
12
12
  @mock = opts.fetch(:mock, false)
13
13
  self.position = pin_position
14
14
  @file_class = @mock ? StringIO : File
15
- export
15
+ export
16
16
  end
17
17
 
18
18
  def position=(position, mock=false)
19
19
  @position = position
20
- @converted_position = PinMapper.map(position)
20
+ @converted_position = Board::PinMapper.map(position).gpio
21
21
  end
22
22
 
23
23
  def gpio_path
@@ -0,0 +1,23 @@
1
+ module BBB
2
+ module IO
3
+ class AnalogPin
4
+ include Pinnable
5
+
6
+ attr_reader :pin_io, :position
7
+
8
+ def initialize(pin_io=nil, position=nil)
9
+ @pin_io = pin_io || MockPin.new
10
+ @position = position
11
+ end
12
+
13
+ def read
14
+ pin_io.read
15
+ end
16
+
17
+ def scale
18
+ pin_io.scale
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -36,11 +36,11 @@ module BBB
36
36
 
37
37
  # Reads digitally from the specified pin on initialize
38
38
  def read
39
- if mode == :input
40
- pin_io.read
41
- else
39
+ if mode == :input
40
+ pin_io.read
41
+ else
42
42
  status
43
- end
43
+ end
44
44
  end
45
45
 
46
46
  # Sets digital write for the pin to HIGH
data/lib/BBB/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module BBB
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/BBB.rb CHANGED
@@ -1,14 +1,22 @@
1
1
  require "BBB/version"
2
- require "BBB/board"
3
- require "BBB/test_board"
2
+
3
+ require "json"
4
+
5
+ require "BBB/board/base"
6
+ require "BBB/board/test_board"
7
+ require "BBB/board/json_pin_mapper"
8
+ require "BBB/board/pin_mapper"
9
+
4
10
  require "BBB/circuit"
5
- require "BBB/pin_mapper"
6
11
  require "BBB/exceptions"
7
12
 
8
13
  require "BBB/gpio/base"
9
14
  require "BBB/gpio/digital_pin"
10
15
  require "BBB/gpio/pin_converter"
11
16
 
17
+ require "BBB/adc/setup"
18
+ require "BBB/adc/analog_pin"
19
+
12
20
  require "BBB/io/pinnable"
13
21
  require "BBB/io/digital_pin"
14
22
  require "BBB/io/mock_pin"