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
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