bitwizard 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bitwizardctl +27 -17
- data/lib/bitwizard.rb +33 -21
- data/lib/bitwizard/motor.rb +5 -5
- data/lib/bitwizard/nfets.rb +9 -9
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23272ef83658a302c5044c1b5595726519d7bea9
|
4
|
+
data.tar.gz: cc86e53099c37b6c5ef21374957101ede0d951e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 343f4e71083472dfa41c755fcf1a7da50f2d4ccdfcb2d58e5a332cc01650a847b422d9f2303336c709b624a6ee14cc2e4ebbcf682922ec0d4bfc41433ac33766
|
7
|
+
data.tar.gz: 31e561c6996c160e9fd222a561ac6fecbe88d6ae67f85091d0c478fffe93ee172d2588909d7892c75c09218cb5eda58727ccf4564adf868917ac673c8be9c051
|
data/bin/bitwizardctl
CHANGED
@@ -11,23 +11,24 @@ class BasicLogger
|
|
11
11
|
end
|
12
12
|
|
13
13
|
Options = {
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
14
|
+
bus: :spi,
|
15
|
+
verbose: false,
|
16
|
+
scan: true
|
17
17
|
}
|
18
18
|
|
19
19
|
class BitWizardCTL
|
20
20
|
|
21
21
|
DetailedHelp = {
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
|
22
|
+
scan: { text: "Scans for available boards" },
|
23
|
+
list: { text: "Lists all the found boards" },
|
24
|
+
eeprom: { args: "<addr>", text: "Read the eeprom from the specified address(es), or all found boards if none given" },
|
25
|
+
features: { args: "<addr>", text: "Returns all of the features of the specified board" },
|
26
|
+
exit: { text: "Exits the program" },
|
27
|
+
help: { text: "Lists all the valid commands, or detailed help for a given command" },
|
28
|
+
pwm: { args: "<addr> [port [value/'enable'/'disable']]", text: "Get/Set the PWM value for a certain port on a board" },
|
29
|
+
stepper: { args: "<addr> <'current'/'target'/'delay'> [value]", text: "Get/Set a value for a stepper motor on the specified board" },
|
30
|
+
motor: { args: "<addr> <'A'/'B'> <speed/'stop'>", text: "Change speed of a motor on the specified board" }
|
31
|
+
}.sort
|
31
32
|
|
32
33
|
def initialize
|
33
34
|
@defaultlogger = BasicLogger.new if Options[:verbose]
|
@@ -130,7 +131,7 @@ class BitWizardCTL
|
|
130
131
|
def get_board(addr)
|
131
132
|
board = @boards[addr] if @boards.has_key? addr
|
132
133
|
unless board then
|
133
|
-
board = BitWizard::Board.detect :
|
134
|
+
board = BitWizard::Board.detect address: addr, bus: Options[:bus], logger: (@defaultlogger if Options[:verbose])
|
134
135
|
@boards[addr] = board if board.valid?
|
135
136
|
end
|
136
137
|
|
@@ -162,7 +163,7 @@ class BitWizardCTL
|
|
162
163
|
@boards = { }
|
163
164
|
(0..0xff).step(2) do |address|
|
164
165
|
begin
|
165
|
-
temp = BitWizard::Board.detect :
|
166
|
+
temp = BitWizard::Board.detect address: address, bus: Options[:bus], logger: (@defaultlogger if Options[:verbose])
|
166
167
|
next unless temp.valid?
|
167
168
|
|
168
169
|
@boards[temp.address] = temp
|
@@ -178,6 +179,15 @@ class BitWizardCTL
|
|
178
179
|
end
|
179
180
|
end
|
180
181
|
|
182
|
+
def cmd_features(*args)
|
183
|
+
raise ArgumentError.new "Wrong number of arguments (#{args.count} for 1)" unless args.count == 1
|
184
|
+
|
185
|
+
addr = parse_addr args[0]
|
186
|
+
board = get_board addr
|
187
|
+
|
188
|
+
puts "0x#{addr.to_s(16)}: #{board.features.join(", ")}"
|
189
|
+
end
|
190
|
+
|
181
191
|
def cmd_eeprom(*args)
|
182
192
|
if args.count == 0 then
|
183
193
|
@boards.each do |_, board|
|
@@ -207,7 +217,7 @@ class BitWizardCTL
|
|
207
217
|
addr = parse_addr addr
|
208
218
|
board = get_board addr
|
209
219
|
|
210
|
-
raise ArgumentError.new "Board doesn't support PWM actions" unless board.
|
220
|
+
raise ArgumentError.new "Board doesn't support PWM actions" unless board.features.include? :pwm
|
211
221
|
|
212
222
|
puts "0x#{addr.to_s(16)}:"
|
213
223
|
|
@@ -247,7 +257,7 @@ class BitWizardCTL
|
|
247
257
|
addr = parse_addr addr
|
248
258
|
board = get_board addr
|
249
259
|
|
250
|
-
raise ArgumentError.new "Board doesn't support stepper actions" unless board.
|
260
|
+
raise ArgumentError.new "Board doesn't support stepper actions" unless board.features.include? :stepper
|
251
261
|
|
252
262
|
case type
|
253
263
|
when :current
|
@@ -275,7 +285,7 @@ class BitWizardCTL
|
|
275
285
|
addr = parse_addr addr
|
276
286
|
board = get_board addr
|
277
287
|
|
278
|
-
raise ArgumentError.new "Board doesn't support motor actions" unless board.
|
288
|
+
raise ArgumentError.new "Board doesn't support motor actions" unless board.features.include? :motor
|
279
289
|
|
280
290
|
if value.is_a? String
|
281
291
|
board.motor_stop motor
|
data/lib/bitwizard.rb
CHANGED
@@ -12,27 +12,27 @@ module BitWizard
|
|
12
12
|
# @option options [Logger] :logger A logger you want to attach to the board.
|
13
13
|
def Board.detect(options)
|
14
14
|
options = {
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
15
|
+
address: -1,
|
16
|
+
bus: :spi,
|
17
|
+
logger: NullLogger.new
|
18
18
|
}.merge(options).merge({
|
19
|
-
:
|
20
|
-
:
|
19
|
+
type: :auto_detect,
|
20
|
+
skip_check: false
|
21
21
|
})
|
22
22
|
|
23
23
|
options[:logger] = NullLogger.new unless options[:logger]
|
24
24
|
|
25
25
|
temp = BitWizard::Board.new options
|
26
|
-
correct = temp.
|
26
|
+
correct = temp.instance_variable_get(:@constructor).call(options.merge({skip_check: true})) if temp.valid?
|
27
27
|
|
28
28
|
correct.instance_variable_set(:@type, temp.type)
|
29
29
|
correct.instance_variable_set(:@version, temp.version)
|
30
|
-
correct.instance_variable_set(:@
|
30
|
+
correct.instance_variable_set(:@features, temp.features)
|
31
31
|
|
32
32
|
correct
|
33
33
|
end
|
34
34
|
|
35
|
-
attr_reader :type, :version, :address, :bus, :
|
35
|
+
attr_reader :type, :version, :address, :bus, :features
|
36
36
|
attr_accessor :logger
|
37
37
|
|
38
38
|
#Creates a generic board handle for reading and writing directly.
|
@@ -42,14 +42,16 @@ module BitWizard
|
|
42
42
|
# @option options [Symbol] :type The board type, defaults to auto detecting. (identifier)
|
43
43
|
# @option options [Symbol] :bus The bus it's connected to. (:spi or :i2c)
|
44
44
|
# @option options [Boolean] :skip_check Skip the self check that runs on creation.
|
45
|
+
# @option options [Number] :clock The clockrate you want to run the communication with.
|
45
46
|
# @option options [Logger] :logger Add a logger here to log data that's sent and received.
|
46
47
|
def initialize(options)
|
47
48
|
options = {
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
49
|
+
address: -1,
|
50
|
+
type: :auto_detect,
|
51
|
+
bus: :spi,
|
52
|
+
skip_check: false,
|
53
|
+
clock: 45000,
|
54
|
+
logger: NullLogger.new
|
53
55
|
}.merge(options)
|
54
56
|
|
55
57
|
raise ArgumentError.new "Bus must be :spi or :i2c." unless options[:bus] == :spi or options[:bus] == :i2c
|
@@ -102,6 +104,7 @@ module BitWizard
|
|
102
104
|
def address=(new_address)
|
103
105
|
raise ArgumentError.new "#{new_address} is not a valid address" unless new_address.is_a? Fixnum and (0..255).include? new_address and new_address|1 != new_address
|
104
106
|
|
107
|
+
# Run a quick check so that there isn't a board on the other address.
|
105
108
|
old_address = @address
|
106
109
|
@address = new_address
|
107
110
|
identifier = read(0x01, 20).pack("C*").split("\0")[0]
|
@@ -113,8 +116,11 @@ module BitWizard
|
|
113
116
|
end
|
114
117
|
end
|
115
118
|
|
116
|
-
|
119
|
+
# Unlock the change register
|
120
|
+
write 0xf1, 0x55
|
117
121
|
write 0xf2, 0xaa
|
122
|
+
|
123
|
+
# Perform the change
|
118
124
|
write 0xf0, new_address
|
119
125
|
|
120
126
|
@address = new_address
|
@@ -135,8 +141,8 @@ module BitWizard
|
|
135
141
|
if name =~ @type then
|
136
142
|
@address = data[:default_address] unless (0..255).include? @address
|
137
143
|
found_board = {
|
138
|
-
:
|
139
|
-
:
|
144
|
+
name: name,
|
145
|
+
data: data
|
140
146
|
}
|
141
147
|
break
|
142
148
|
end
|
@@ -145,14 +151,15 @@ module BitWizard
|
|
145
151
|
raise ArgumentError.new "Board type is 'auto_detect', but invalid address #{@address} given." if @type == :auto_detect and not (0..255).include? @address
|
146
152
|
|
147
153
|
identifier = read(0x01, 20).pack("C*").split("\0")[0]
|
148
|
-
raise ArgumentError.new "No response from board" if identifier.empty?
|
154
|
+
raise ArgumentError.new "No response from board" if not identifier or identifier.empty?
|
149
155
|
|
150
156
|
if @type == :auto_detect then
|
151
157
|
Known_Boards.each do |name, data|
|
152
158
|
if name =~ identifier then
|
153
159
|
@type, @version = *identifier.split
|
154
160
|
@type = @type.to_sym
|
155
|
-
@
|
161
|
+
@constructor = data[:constructor]
|
162
|
+
@features = data[:features]
|
156
163
|
break
|
157
164
|
end
|
158
165
|
end
|
@@ -162,7 +169,7 @@ module BitWizard
|
|
162
169
|
Known_Boards.each do |name, data|
|
163
170
|
if name =~ identifier then
|
164
171
|
@version = identifier.split[1]
|
165
|
-
@
|
172
|
+
@features = data[:features]
|
166
173
|
raise ArgumentError.new "Board reports type #{real_name}, which does not match #{@type}" unless found_board[:data] == data
|
167
174
|
break
|
168
175
|
end
|
@@ -184,6 +191,7 @@ module BitWizard
|
|
184
191
|
data = PiPiper::Spi.begin do |spi|
|
185
192
|
spi.write @address | 1, reg, *Array.new(count, 0)
|
186
193
|
end[2..-1]
|
194
|
+
|
187
195
|
@logger.debug("SPI [0x#{@address.to_s(16)}] --> 0x#{reg.to_s(16)}: #{data.pack("C*").inspect}")
|
188
196
|
data
|
189
197
|
end
|
@@ -192,16 +200,20 @@ module BitWizard
|
|
192
200
|
@logger.debug("I2C [0x#{@address.to_s(16)}] <-- 0x#{reg.to_s(16)}: #{value.is_a? Array and value.pack("C*").inspect or value.inspect}")
|
193
201
|
PiPiper::I2C.begin do |i2c|
|
194
202
|
data = [reg]
|
203
|
+
|
195
204
|
data << value unless value.is_a? Array
|
196
205
|
data += value if value.is_a? Array
|
197
206
|
|
198
|
-
i2c.write({ :
|
207
|
+
i2c.write({ to: @address, data: data })
|
199
208
|
end
|
200
209
|
end
|
201
210
|
|
202
211
|
def i2c_read(reg, count)
|
212
|
+
PiPiper::I2C.begin do |i2c|
|
213
|
+
i2c.write({ to: @address | 1, data: [reg] })
|
214
|
+
end
|
203
215
|
data = PiPiper::I2C.begin do |i2c|
|
204
|
-
|
216
|
+
PiPiper::Platform.driver.i2c_set_address(@address | 1)
|
205
217
|
i2c.read count
|
206
218
|
end
|
207
219
|
@logger.debug("I2C [0x#{@address.to_s(16)}] --> 0x#{reg.to_s(16)}: #{data.pack("C*").inspect}")
|
data/lib/bitwizard/motor.rb
CHANGED
@@ -8,10 +8,10 @@ module BitWizard
|
|
8
8
|
# @param [optional, Hash] options A Hash of options.
|
9
9
|
def initialize(options={})
|
10
10
|
options = {
|
11
|
-
:
|
11
|
+
bus: :spi
|
12
12
|
}.merge(options)
|
13
13
|
options = options.merge({
|
14
|
-
:
|
14
|
+
type: "#{options[:bus]}_motor".to_sym,
|
15
15
|
})
|
16
16
|
|
17
17
|
super(options)
|
@@ -147,9 +147,9 @@ module BitWizard
|
|
147
147
|
end
|
148
148
|
|
149
149
|
Known_Boards[/(spi|i2c)_motor/] = {
|
150
|
-
:
|
151
|
-
:
|
152
|
-
:
|
150
|
+
default_address: 0x90,
|
151
|
+
constructor: Proc.new { |options| BitWizard::Boards::Motor.new options },
|
152
|
+
features: [ :motor, :stepper, :pwm ]
|
153
153
|
}
|
154
154
|
|
155
155
|
end
|
data/lib/bitwizard/nfets.rb
CHANGED
@@ -11,11 +11,11 @@ module BitWizard
|
|
11
11
|
# @option options [Number] :num The number of FETs on the board (3 or 7)
|
12
12
|
def initialize(options={})
|
13
13
|
options = {
|
14
|
-
:
|
15
|
-
:
|
14
|
+
num: 3,
|
15
|
+
bus: :spi
|
16
16
|
}.merge(options)
|
17
17
|
options = options.merge({
|
18
|
-
:
|
18
|
+
type: "#{options[:bus]}_#{options[:num]}fets".to_sym,
|
19
19
|
})
|
20
20
|
|
21
21
|
raise ArgumentError.new "Number of FETs must be 3 or 7" unless options[:num] == 3 or options[:num] == 7
|
@@ -173,14 +173,14 @@ module BitWizard
|
|
173
173
|
end
|
174
174
|
|
175
175
|
Known_Boards[/(spi|i2c)_3fets/] = {
|
176
|
-
:
|
177
|
-
:
|
178
|
-
:
|
176
|
+
default_address: 0x8a,
|
177
|
+
constructor: Proc.new { |options| BitWizard::Boards::FETs.new options.merge({ num: 3 }) },
|
178
|
+
features: [ :input, :output, :stepper, :pwm ]
|
179
179
|
}
|
180
180
|
Known_Boards[/(spi|i2c)_7fets/] = {
|
181
|
-
:
|
182
|
-
:
|
183
|
-
:
|
181
|
+
default_address: 0x88,
|
182
|
+
constructor: Proc.new { |options| BitWizard::Boards::FETs.new options.merge({ num: 7 }) },
|
183
|
+
features: [ :input, :output, :stepper, :pwm ]
|
184
184
|
}
|
185
185
|
|
186
186
|
end
|