beaglebone 1.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.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +6 -0
- data/beaglebone.gemspec +12 -0
- data/examples/ain.rb +92 -0
- data/examples/gpio.rb +196 -0
- data/examples/i2c.rb +110 -0
- data/examples/pwm.rb +63 -0
- data/examples/shiftregister.rb +12 -0
- data/examples/spi.rb +62 -0
- data/examples/uart.rb +64 -0
- data/lib/beaglebone/ain.rb +480 -0
- data/lib/beaglebone/beaglebone.rb +287 -0
- data/lib/beaglebone/gpio.rb +598 -0
- data/lib/beaglebone/i2c.rb +186 -0
- data/lib/beaglebone/pwm.rb +479 -0
- data/lib/beaglebone/shiftregister.rb +21 -0
- data/lib/beaglebone/spi.rb +322 -0
- data/lib/beaglebone/uart.rb +388 -0
- data/lib/beaglebone.rb +8 -0
- metadata +63 -0
@@ -0,0 +1,287 @@
|
|
1
|
+
# This is the main module for this gem. You generally do not want to call these methods directly.
|
2
|
+
module Beaglebone
|
3
|
+
# Hash of pins and their uses
|
4
|
+
PINS = {
|
5
|
+
:USR0 => { :gpio => 53, :led => 'usr0' },
|
6
|
+
:USR1 => { :gpio => 54, :led => 'usr1' },
|
7
|
+
:USR2 => { :gpio => 55, :led => 'usr2' },
|
8
|
+
:USR3 => { :gpio => 56, :led => 'usr3' },
|
9
|
+
|
10
|
+
:P8_1 => { :dgnd => 'Digital Ground' },
|
11
|
+
:P8_2 => { :dgnd => 'Digital Ground' },
|
12
|
+
|
13
|
+
:P8_3 => { :gpio => 38, :mmc => 'mmc1_dat6' },
|
14
|
+
:P8_4 => { :gpio => 39, :mmc => 'mmc1_dat7' },
|
15
|
+
:P8_5 => { :gpio => 34, :mmc => 'mmc1_dat2' },
|
16
|
+
:P8_6 => { :gpio => 35, :mmc => 'mmc1_dat3' },
|
17
|
+
|
18
|
+
:P8_7 => { :gpio => 66, :timer => 'timer4' },
|
19
|
+
:P8_8 => { :gpio => 67, :timer => 'timer7' },
|
20
|
+
:P8_9 => { :gpio => 69, :timer => 'timer5' },
|
21
|
+
:P8_10 => { :gpio => 68, :timer => 'timer6' },
|
22
|
+
|
23
|
+
:P8_11 => { :gpio => 45 },
|
24
|
+
:P8_12 => { :gpio => 44 },
|
25
|
+
|
26
|
+
# You can emable PWM as listed below
|
27
|
+
# P8_13 *OR* P8_19 (EHRPWM2B, EHRPWM2A),
|
28
|
+
# P9_14 *OR* P9_16 (EHRPWM1A, EHRPWM1B),
|
29
|
+
# P9_21 *OR* P9_22 (EHRPWM0B, EHRPWM0A).
|
30
|
+
# there are also ecap pwms on pins P9_28 and P9_42
|
31
|
+
|
32
|
+
:P8_13 => { :gpio => 23, :pwm => 'pwm_2b', :pwm_id => 2, :pwm_mux => 4 },
|
33
|
+
|
34
|
+
:P8_14 => { :gpio => 26 },
|
35
|
+
:P8_15 => { :gpio => 47 },
|
36
|
+
:P8_16 => { :gpio => 46 },
|
37
|
+
:P8_17 => { :gpio => 27 },
|
38
|
+
:P8_18 => { :gpio => 66 },
|
39
|
+
|
40
|
+
:P8_19 => { :gpio => 22, :pwm => 'pwm_2a', :pwm_id => 2, :pwm_mux => 4 },
|
41
|
+
|
42
|
+
# You can only use the mmc pins if booting from SD and disabling mmc
|
43
|
+
# mmc reset behavior is unclear
|
44
|
+
# Best option is to not use the MMC1_CLK and MMC1_CMD signals at all and tie them low.
|
45
|
+
:P8_20 => { :gpio => 63, :mmc => 'mmc1_cmd' },
|
46
|
+
:P8_21 => { :gpio => 62, :mmc => 'mmc1_clk' },
|
47
|
+
:P8_22 => { :gpio => 37, :mmc => 'mmc1_dat5' },
|
48
|
+
:P8_23 => { :gpio => 36, :mmc => 'mmc1_dat4' },
|
49
|
+
:P8_24 => { :gpio => 33, :mmc => 'mmc1_dat1' },
|
50
|
+
:P8_25 => { :gpio => 32, :mmc => 'mmc1_dat0' },
|
51
|
+
|
52
|
+
:P8_26 => { :gpio => 61 },
|
53
|
+
:P8_27 => { :gpio => 86, :lcd => 'lcd_vsync' },
|
54
|
+
:P8_28 => { :gpio => 88, :lcd => 'lcd_pclk' },
|
55
|
+
:P8_29 => { :gpio => 87, :lcd => 'lcd_hsync' },
|
56
|
+
:P8_30 => { :gpio => 89, :lcd => 'lcd_ac_bias' },
|
57
|
+
:P8_31 => { :gpio => 10, :lcd => 'lcd_data14', :uart => 'uart5_ctsn', :uart_id => 5 },
|
58
|
+
:P8_32 => { :gpio => 11, :lcd => 'lcd_data15', :uart => 'uart5_rtsn', :uart_id => 5 },
|
59
|
+
:P8_33 => { :gpio => 9, :lcd => 'lcd_data13', :uart => 'uart4_rtsn', :uart_id => 4 },
|
60
|
+
:P8_34 => { :gpio => 81, :lcd => 'lcd_data11', :pwm => 'pwm_1b', :pwm_id => 1, :pwm_mux => 2, :uart => 'uart3_rtsn', :uart_id => 3 },
|
61
|
+
:P8_35 => { :gpio => 8, :lcd => 'lcd_data12', :uart => 'uart4_ctsn' },
|
62
|
+
:P8_36 => { :gpio => 80, :lcd => 'lcd_data10', :pwm => 'pwm_1a', :pwm_id => 1, :pwm_mux => 2, :uart => 'uart3_ctsn', :uart_id => 3 },
|
63
|
+
:P8_37 => { :gpio => 78, :lcd => 'lcd_data8', :uart => 'uart5_txd', :uart_id => 5 },
|
64
|
+
:P8_38 => { :gpio => 79, :lcd => 'lcd_data9', :uart => 'uart5_rxd', :uart_id => 5 },
|
65
|
+
:P8_39 => { :gpio => 76, :lcd => 'lcd_data6' },
|
66
|
+
:P8_40 => { :gpio => 77, :lcd => 'lcd_data7' },
|
67
|
+
:P8_41 => { :gpio => 74, :lcd => 'lcd_data4' },
|
68
|
+
:P8_42 => { :gpio => 75, :lcd => 'lcd_data5' },
|
69
|
+
:P8_43 => { :gpio => 72, :lcd => 'lcd_data2' },
|
70
|
+
:P8_44 => { :gpio => 73, :lcd => 'lcd_data3' },
|
71
|
+
:P8_45 => { :gpio => 70, :lcd => 'lcd_data0', :pwm => 'pwm_2a', :pwm_id => 2, :pwm_mux => 3 },
|
72
|
+
:P8_46 => { :gpio => 71, :lcd => 'lcd_data1', :pwm => 'pwm_2b', :pwm_id => 2, :pwm_mux => 3 },
|
73
|
+
|
74
|
+
:P9_1 => { :dgnd => 'ground' },
|
75
|
+
:P9_2 => { :dgnd => 'ground' },
|
76
|
+
:P9_3 => { :vdd_3v3 => '3.3 volts' },
|
77
|
+
:P9_4 => { :vdd_3v3 => '3.3 volts' },
|
78
|
+
:P9_5 => { :vdd_5v => '5 volts' },
|
79
|
+
:P9_6 => { :vdd_5v => '5 volts' },
|
80
|
+
:P9_7 => { :sys_5v => '5 volts' },
|
81
|
+
:P9_8 => { :sys_5v => '5 volts' },
|
82
|
+
:P9_9 => { :pwr_but => 'power button' },
|
83
|
+
:P9_10 => { :sys_resetn => 'reset button' },
|
84
|
+
|
85
|
+
:P9_11 => { :gpio => 30, :uart => 'uart4_rxd', :uart_id => 4 },
|
86
|
+
:P9_12 => { :gpio => 60 },
|
87
|
+
:P9_13 => { :gpio => 31, :uart => 'uart4_txd', :uart_id => 4 },
|
88
|
+
:P9_14 => { :gpio => 40, :pwm => 'pwm_1a', :pwm_id => 1, :pwm_mux => 6 },
|
89
|
+
:P9_15 => { :gpio => 48 },
|
90
|
+
:P9_16 => { :gpio => 51, :pwm => 'pwm_1b', :pwm_id => 1, :pwm_mux => 6 },
|
91
|
+
#17 and 18 are not currently working for gpio in 3.8
|
92
|
+
#:P9_17 => { :gpio => 4, :i2c => 'i2c1_scl', :i2c_id => 1, :spi => 'spi0_cs0', :spi_id => 0 },
|
93
|
+
#:P9_18 => { :gpio => 5, :i2c => 'i2c1_sda', :i2c_id => 1, :spi => 'spi0_d1', :spi_id => 0 },
|
94
|
+
:P9_17 => { :i2c => 'i2c1_scl', :i2c_id => 1, :spi => 'spi0_cs0', :spi_id => 0 },
|
95
|
+
:P9_18 => { :i2c => 'i2c1_sda', :i2c_id => 1, :spi => 'spi0_d1', :spi_id => 0 },
|
96
|
+
:P9_19 => { :i2c => 'i2c2_scl', :i2c_id => 2, :uart => 'uart1_rtsn', :uart_id => 1, :spi => 'spi1_cs1', :spi_id => 1 },
|
97
|
+
:P9_20 => { :i2c => 'i2c2_sda', :i2c_id => 2, :uart => 'uart1_ctsn', :uart_id => 1, :spi => 'spi1_cs0', :spi_id => 1 },
|
98
|
+
:P9_21 => { :gpio => 3, :pwm => 'pwm_0b', :pwm_id => 0, :pwm_mux => 3, :i2c => 'i2c2_scl', :i2c_id => 2, :uart => 'uart2_txd', :uart_id => 2, :spi => 'spi0_d0', :spi_id => 0 },
|
99
|
+
:P9_22 => { :gpio => 2, :pwm => 'pwm_0a', :pwm_id => 0, :pwm_mux => 3, :i2c => 'i2c2_sda', :i2c_id => 2, :uart => 'uart2_rxd', :uart_id => 2, :spi => 'spi0_sclk', :spi_id => 0 },
|
100
|
+
:P9_23 => { :gpio => 49 },
|
101
|
+
:P9_24 => { :gpio => 15, :i2c => 'i2c1_scl', :i2c_id => 1, :uart => 'uart1_txd', :uart_id => 1 },
|
102
|
+
:P9_25 => { :gpio => 117 },
|
103
|
+
:P9_26 => { :gpio => 14, :i2c => 'i2c1_sda', :i2c_id => 2, :uart => 'uart1_rxd', :uart_id => 1 },
|
104
|
+
:P9_27 => { :gpio => 125 },
|
105
|
+
:P9_28 => { :gpio => 123, :pwm => 'ecappwm2', :pwm_id => 3, :pwm_mux => 4, :ecap => 2, :spi => 'spi1_cs0', :spi_id => 1 },
|
106
|
+
:P9_29 => { :gpio => 121, :pwm => 'pwm_0b', :pwm_id => 0, :pwm_mux => 1, :spi => 'spi1_d0', :spi_id => 1 },
|
107
|
+
:P9_30 => { :gpio => 122, :spi => 'spi1_d1', :spi_id => 1 },
|
108
|
+
:P9_31 => { :gpio => 120, :pwm => 'pwm_0a', :pwm_id => 0, :pwm_mux => 1, :spi => 'spi1_sclk', :spi_id => 1 },
|
109
|
+
|
110
|
+
:P9_32 => { :vdd_adc => 'analog output 1.8v' },
|
111
|
+
:P9_33 => { :analog => 4 },
|
112
|
+
:P9_34 => { :gnda_adc => 'analog ground' },
|
113
|
+
:P9_35 => { :analog => 6 },
|
114
|
+
:P9_36 => { :analog => 5 },
|
115
|
+
:P9_37 => { :analog => 2 },
|
116
|
+
:P9_38 => { :analog => 3 },
|
117
|
+
:P9_39 => { :analog => 0 },
|
118
|
+
:P9_40 => { :analog => 1 },
|
119
|
+
|
120
|
+
:P9_41 => { :gpio => 20 },
|
121
|
+
:P9_42 => { :gpio => 7, :pwm => 'ecappwm0', :pwm_id => 4, :pwm_mux => 0, :ecap => 0, :uart => 'uart3_txd', :uart_id => 3, :spi => 'spi1_sclk', :spi_id => 1 },
|
122
|
+
:P9_43 => { :dgnd => 'ground' },
|
123
|
+
:P9_44 => { :dgnd => 'ground' },
|
124
|
+
:P9_45 => { :dgnd => 'ground' },
|
125
|
+
:P9_46 => { :dgnd => 'ground' },
|
126
|
+
}.freeze
|
127
|
+
|
128
|
+
# Generic device trees
|
129
|
+
TREES = {
|
130
|
+
:UART => { :global => nil, :pin => 'BB-UART' },
|
131
|
+
:ADC => { :global => 'BB-ADC', :pin => nil },
|
132
|
+
:PWM => { :global => 'am33xx_pwm', :pin => 'bone_pwm_' },
|
133
|
+
}.freeze
|
134
|
+
|
135
|
+
# UART device hash
|
136
|
+
UARTS = {
|
137
|
+
:UART1 => { :id => 1, :rx => :P9_26, :tx => :P9_24, :dev => '/dev/ttyO1' },
|
138
|
+
:UART2 => { :id => 2, :rx => :P9_22, :tx => :P9_21, :dev => '/dev/ttyO2' },
|
139
|
+
:UART3 => { :id => 3, :rx => nil, :tx => :P9_42, :dev => '/dev/ttyO3' },
|
140
|
+
:UART4 => { :id => 4, :rx => :P9_11, :tx => :P9_13, :dev => '/dev/ttyO4' },
|
141
|
+
:UART5 => { :id => 5, :rx => :P8_38, :tx => :P8_37, :dev => '/dev/ttyO5' },
|
142
|
+
}.freeze
|
143
|
+
|
144
|
+
# I2C device hash
|
145
|
+
I2CS = {
|
146
|
+
:I2C0 => { :id => 0, :dev => '/dev/i2c-0' },
|
147
|
+
:I2C1 => { :id => 2, :dev => '/dev/i2c-2', :scl => :P9_17, :sda => :P9_18, :devicetree => 'BB-I2C1' },
|
148
|
+
:I2C2 => { :id => 1, :dev => '/dev/i2c-1', :scl => :P9_19, :sda => :P9_20 },
|
149
|
+
#alternate pins for i2c1
|
150
|
+
:I2C1A => { :id => 2, :dev => '/dev/i2c-2', :scl => :P9_24, :sda => :P9_26, :devicetree => 'BB-I2C1A1' },
|
151
|
+
}.freeze
|
152
|
+
|
153
|
+
# SPI device hash
|
154
|
+
SPIS = {
|
155
|
+
:counter => 1,
|
156
|
+
:SPI0 => { :id => 0, :dev => '/dev/spidev', :devicetree => 'BB-SPIDEV0',
|
157
|
+
:cs0 => :P9_17, :sclk => :P9_22, :d0 => :P9_21, :d1 => :P9_18,
|
158
|
+
:pins => [ :P9_17, :P9_18, :P9_21, :P9_22 ] },
|
159
|
+
|
160
|
+
:SPI1 => { :id => 1, :dev => '/dev/spidev', :devicetree => 'BB-SPIDEV1',
|
161
|
+
:cs0 => :P9_28, :sclk => :P9_31, :d0 => :P9_29, :d1 => :P9_30,
|
162
|
+
:pins => [ :P9_28, :P9_29, :P9_30, :P9_31 ] },
|
163
|
+
|
164
|
+
#alternate pins for SPI2
|
165
|
+
:SPI1A => { :id => 1, :dev => '/dev/spidev', :devicetree => 'BB-SPIDEV1A1',
|
166
|
+
:cs0 => :P9_20, :sclk => :P9_42, :d0 => :P9_29, :d1 => :P9_30,
|
167
|
+
:pins => [ :P9_20, :P9_29, :P9_30, :P9_42 ] },
|
168
|
+
|
169
|
+
}
|
170
|
+
|
171
|
+
@pinstatus = {}
|
172
|
+
@pinmutex = Mutex.new
|
173
|
+
@loaded_dtbs = []
|
174
|
+
|
175
|
+
class << self
|
176
|
+
attr_accessor :pinstatus, :pinmutex, :loaded_dtbs
|
177
|
+
|
178
|
+
# get hash entry for pin
|
179
|
+
def get_pin_status(pin, key = nil)
|
180
|
+
pinmutex.synchronize do
|
181
|
+
if key
|
182
|
+
pinstatus[pin] ? pinstatus[pin][key] : nil
|
183
|
+
else
|
184
|
+
pinstatus[pin]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
# set hash entry for pin
|
190
|
+
def set_pin_status(pin, key, value)
|
191
|
+
pinmutex.synchronize do
|
192
|
+
pinstatus[pin] ||= {}
|
193
|
+
pinstatus[pin][key] = value
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# delete pin's hash entry
|
198
|
+
def delete_pin_status(pin, key = nil)
|
199
|
+
pinmutex.synchronize do
|
200
|
+
if key.nil?
|
201
|
+
pinstatus.delete(pin)
|
202
|
+
else
|
203
|
+
pinstatus[pin].delete(key) if pinstatus[pin]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# disable pin
|
209
|
+
def disable_pin(pin)
|
210
|
+
status = get_pin_status(pin)
|
211
|
+
|
212
|
+
if status
|
213
|
+
case status[:type]
|
214
|
+
when :gpio
|
215
|
+
Beaglebone::GPIO.disable_gpio_pin(pin)
|
216
|
+
when :pwm
|
217
|
+
Beaglebone::PWM.disable_pwm_pin(pin)
|
218
|
+
else
|
219
|
+
#we can't disable any other pin types at this time
|
220
|
+
raise StandardError, "Cannot disable pin: #{pin} in #{status[:type]} mode"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# check if a pin of given type is valid
|
226
|
+
def check_valid_pin(pin, type = nil)
|
227
|
+
#check to see if pin exists
|
228
|
+
pin = pin.to_sym.upcase
|
229
|
+
raise ArgumentError, "No such PIN: #{pin.to_s}" unless PINS[pin]
|
230
|
+
|
231
|
+
if type
|
232
|
+
raise StandardError, "Pin does not support #{type}: #{pin.to_s}" unless PINS[pin][type]
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# return capemgr directory
|
237
|
+
def get_capemgr_dir
|
238
|
+
Dir.glob('/sys/devices/bone_capemgr.*').first
|
239
|
+
end
|
240
|
+
|
241
|
+
# check if device tree is loaded
|
242
|
+
def device_tree_loaded?(name)
|
243
|
+
!!File.open("#{get_capemgr_dir}/slots").read.match(/,#{name}$/)
|
244
|
+
end
|
245
|
+
|
246
|
+
# load a device tree
|
247
|
+
def device_tree_load(name)
|
248
|
+
return true if loaded_dtbs.include?(name)
|
249
|
+
|
250
|
+
if device_tree_loaded?(name)
|
251
|
+
loaded_dtbs << name
|
252
|
+
return true
|
253
|
+
end
|
254
|
+
|
255
|
+
File.open("#{get_capemgr_dir}/slots", 'w') { |f| f.write(name) }
|
256
|
+
|
257
|
+
raise StandardError, "Unable to load device tree: #{name}" unless device_tree_loaded?(name)
|
258
|
+
sleep(0.25)
|
259
|
+
true
|
260
|
+
end
|
261
|
+
|
262
|
+
# unload a device tree, return false if not loaded, return true if it unloads
|
263
|
+
def device_tree_unload(name)
|
264
|
+
return false unless device_tree_loaded?(name)
|
265
|
+
|
266
|
+
dtb_id = File.open("#{get_capemgr_dir}/slots", 'r').read.scan(/^ ?(\d+): .*?,#{name}/).flatten.first
|
267
|
+
|
268
|
+
File.open("#{get_capemgr_dir}/slots", 'w') { |f| f.write("-#{dtb_id}") }
|
269
|
+
|
270
|
+
raise StandardError, "Unable to unload device tree: #{name}" if device_tree_loaded?(name)
|
271
|
+
|
272
|
+
true
|
273
|
+
end
|
274
|
+
|
275
|
+
# cleanup all the things
|
276
|
+
def cleanup
|
277
|
+
Beaglebone::AIN.cleanup
|
278
|
+
Beaglebone::PWM.cleanup
|
279
|
+
Beaglebone::GPIO.cleanup
|
280
|
+
Beaglebone::UART.cleanup
|
281
|
+
Beaglebone::I2C.cleanup
|
282
|
+
Beaglebone::SPI.cleanup
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|