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
data/lib/BBB/adc/setup.rb DELETED
@@ -1,20 +0,0 @@
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
@@ -1,45 +0,0 @@
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.respond_to?(:mode) && pin.mode == :output
29
- end
30
- end
31
-
32
- def connect_io_pin(pin)
33
- converted_pin = pin_converter.convert(pin)
34
- pin.pin_io = converted_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
@@ -1,203 +0,0 @@
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
@@ -1,20 +0,0 @@
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
- pin_mapping_file = File.expand_path("../../../../resources/pin_mappings.json", __FILE__)
9
- MAP = JSONPinMapper.convert(pin_mapping_file)
10
-
11
- def self.map(pin_symbol, type=:gpio)
12
- begin
13
- MAP.pins.fetch(pin_symbol.upcase.to_sym)
14
- rescue Exception => e
15
- raise UnknownPinException, "Pin #{pin_symbol} could not be mapped"
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,12 +0,0 @@
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
data/lib/BBB/gpio/base.rb DELETED
@@ -1,56 +0,0 @@
1
- module BBB
2
- module GPIO
3
- class Base
4
- attr_reader :position, :converted_position
5
- attr_reader :file_class
6
-
7
- def initialize(position=nil, opts={})
8
- initialize_base(position, opts)
9
- end
10
-
11
- def initialize_base(pin_position, opts)
12
- @mock = opts.fetch(:mock, false)
13
- self.position = pin_position
14
- @file_class = @mock ? StringIO : File
15
- export
16
- end
17
-
18
- def position=(position, mock=false)
19
- @position = position
20
- @converted_position = Board::PinMapper.map(position).gpio
21
- end
22
-
23
- def gpio_path
24
- "/sys/class/gpio"
25
- end
26
-
27
- def export_path
28
- gpio_path + "/export"
29
- end
30
-
31
- def unexport_path
32
- gpio_path + "/unexport"
33
- end
34
-
35
- def gpio_direction_input
36
- "in"
37
- end
38
-
39
- def gpio_direction_output
40
- "out"
41
- end
42
-
43
- def gpio_pin_dir
44
- "#{gpio_path}/gpio#{converted_position}"
45
- end
46
-
47
- def export
48
- file_class.open(export_path, "w") { |f| f.write("#{ converted_position }") }
49
- end
50
-
51
- def unexport
52
- file_class.open(unexport_path, "w") { |f| f.write("#{converted_position}") }
53
- end
54
- end
55
- end
56
- end
@@ -1,69 +0,0 @@
1
- module BBB
2
- module GPIO
3
- class DigitalPin < Base
4
- attr_reader :mode, :io
5
-
6
- def initialize(position, mode, opts={})
7
- initialize_base(position, opts)
8
- @mode = validate_mode(mode)
9
- set_mode
10
- end
11
-
12
- def direction
13
- case mode
14
- when :input
15
- gpio_direction_input
16
- when :output
17
- gpio_direction_output
18
- end
19
- end
20
-
21
- def file_mode
22
- case mode
23
- when :input
24
- "r"
25
- when :output
26
- "w+"
27
- end
28
- end
29
-
30
- def set_mode
31
- direction_file = gpio_pin_dir + "/direction"
32
- file_class.open(direction_file, "w") {|f| f.write(direction); f.flush}
33
- end
34
-
35
- def io
36
- return @io unless @io.nil?
37
-
38
- value_file = gpio_pin_dir + "/value"
39
- @io = file_class.open(value_file, file_mode)
40
- end
41
-
42
- def write(value)
43
- io.rewind
44
- io.write value_map[value]
45
- io.flush
46
- end
47
-
48
- def read
49
- io.rewind
50
- value_map[io.read]
51
- end
52
-
53
- private
54
-
55
- def validate_mode(mode)
56
- if [:input, :output].include?(mode)
57
- return mode
58
- else
59
- raise UnknownPinModeException, "Pin mode: #{mode} is now known"
60
- end
61
- end
62
-
63
- def value_map
64
- @value_map ||= {:high=>1, :low=>0, 1=>:high, 0=>:low}
65
- end
66
-
67
- end
68
- end
69
- end
@@ -1,28 +0,0 @@
1
- module BBB
2
- module GPIO
3
- class PinConverter
4
- attr_reader :mock
5
-
6
- def initialize(opts={})
7
- @mock = opts.fetch(:mock, false)
8
- end
9
-
10
- ##
11
- # Currently only converts IO::DigitalPins
12
- #
13
- def convert(pin, opts={})
14
- opts = {:mock=>mock}.merge(opts)
15
-
16
- base_class = pin.class.to_s.split("::").last
17
- if GPIO.const_defined?(base_class)
18
- klass = GPIO::const_get(base_class.to_sym)
19
- return klass.new(pin.position, pin.mode, opts)
20
- elsif ADC.const_defined?(base_class)
21
- klass = ADC::const_get(base_class.to_sym)
22
- return klass.new(pin.position, opts)
23
- end
24
- end
25
-
26
- end
27
- end
28
- end