beaglebone 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|