katcp 0.1.8 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b2ff660c3d5dc7a953d33929f927b4db105090e1
4
+ data.tar.gz: 260e11b31ab6bdffa5be4e1a0ce0038027a793da
5
+ SHA512:
6
+ metadata.gz: ced30aa287a9971789e7c387a2b5f8f294891c318fe9d3a28e806a12450a44adc3baf20e91a7d589611d3a136260bd46dae20a99390f55611bdba2fc4a8b218d
7
+ data.tar.gz: 618cba5da5aa45443a093ff558f03f14ae3bf936815c69985c4d326007fb45db068a65fa84d72903a94ee4c2a1f83fb6996f8d1f418253b3c9784944e869ac27
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require 'katcp'
6
+
7
+ OPTS = {
8
+ :verbose => false
9
+ }
10
+
11
+ ARGV.options do |op|
12
+ op.program_name = File.basename($0)
13
+
14
+ op.banner = "Usage: #{op.program_name} [OPTIONS] HOST[:PORT] [CMD [ARGS]]"
15
+ op.separator('')
16
+ op.separator('Runs KATCP command CMD with (optional) arguments ARGS on HOST.')
17
+ op.separator('If CMD is not given, just connect and print inform messages.')
18
+ op.separator('Non-standard port can be given as HOST:PORT.')
19
+ op.separator('')
20
+ op.separator("Example: #{op.program_name} roach2 progdev my_design.bof")
21
+ op.separator('')
22
+ op.separator 'Options:'
23
+ op.on_tail("-v", "--[no-]verbose", "Prints inform messages") do |o|
24
+ OPTS[:verbose] = o
25
+ end
26
+ op.on_tail("-h", "--help", "Show this message") do
27
+ puts op
28
+ exit 1
29
+ end
30
+ op.parse!
31
+ end
32
+
33
+ if ARGV.empty?
34
+ puts ARGV.options
35
+ exit 1
36
+ end
37
+
38
+ host, port = ARGV.shift.split(':')
39
+ port ||= ENV['KATCP_PORT'] || '7147'
40
+ port = Integer(port) rescue 7147
41
+
42
+ cmd = ARGV.shift
43
+
44
+ exit_status = 0
45
+
46
+ r = KATCP::RoachClient.new(host, port)
47
+
48
+ if cmd
49
+ informs = r.informs(true)
50
+ puts informs if OPTS[:verbose]
51
+
52
+ resp = r.respond_to?(cmd) ? r.send(cmd, *ARGV) : r.request(cmd, *ARGV)
53
+
54
+ case resp
55
+ when KATCP::Response
56
+ puts resp
57
+ exit_status = resp.ok? ? 0 : 1
58
+ when KATCP::Client
59
+ # Print log informs
60
+ puts resp.informs(true).grep(/^#log/)
61
+ # Handle programmed? and other true/false operations
62
+ when true
63
+ puts resp if OPTS[:verbose]
64
+ exit_status = 0
65
+ when false
66
+ puts resp if OPTS[:verbose]
67
+ exit_status = 1
68
+ else
69
+ puts "got a #{resp.class}: #{resp.inspect}"
70
+ end
71
+
72
+ puts r.informs(true) if OPTS[:verbose]
73
+ else
74
+ puts r.informs(true)
75
+ end
76
+
77
+ r.close
78
+
79
+ exit exit_status
@@ -383,7 +383,7 @@ module KATCP
383
383
  # call-seq:
384
384
  # sensor_dump(*args) -> KATCP::Response
385
385
  #
386
- # Dumps the sensor tree.
386
+ # Dumps the sensor tree. [obsolete?]
387
387
  def sensor_dump(*args)
388
388
  request(:sensor_dump, *args)
389
389
  end
@@ -68,6 +68,8 @@ module KATCP
68
68
  # Returns xaui status word. Bits 2 through 5 are lane sync, bit 6 is
69
69
  # channel bonding status.
70
70
  def xaui_status; get(9); end
71
+ # Returns true if all four lanes are sync'd and bonded.
72
+ def xaui_status_ok?; (get(9) & 0b01111100) == 0b01111100; end
71
73
  # Four least significant bits represent sync status for each lane.
72
74
  # 1 bit = lane sync OK
73
75
  # 0 bit = lane sync BAD
@@ -77,7 +79,7 @@ module KATCP
77
79
  # Returns true if #xaui_sync returns 15
78
80
  def xaui_sync_ok?; xaui_sync == 0b1111; end
79
81
  # Returns true if all four XAUI lanes are bonded
80
- def xaui_bonded?; (get(9) >> 6) & 1; end
82
+ def xaui_bonded?; ((get(9) >> 6) & 1) == 1; end
81
83
 
82
84
  # Get current value of rx_eq_mix parameter.
83
85
  def rx_eq_mix ; (get(10) >> 24) & 0xff; end
@@ -97,6 +99,69 @@ module KATCP
97
99
  def []=(idx, mac)
98
100
  write64(0xc00+2*idx, mac)
99
101
  end
102
+ end # class TenGE
103
+
104
+ # Class used to access CASPER Snapshot blocks. +device_name+ must be used
105
+ # with the bram or dram device in the snapshot block. Other devices in the
106
+ # snapshot block may be hidden/ignored with :skip in the device_typemap or
107
+ # may be exposed/used if desired. Currently this class only uses the memory
108
+ # element and the "trig" register; it does not directly use the "status"
109
+ # register or the optional "trig_offset" or "tr_en_cnt" registers.
110
+ class Snapshot < Bram
111
+ def initialize(katcp_client, device_name)
112
+ super
113
+ @ctrl_name = device_name.sub(/_[bd]ram$/, '_ctrl')
114
+ end
115
+
116
+ # Validate and massage method name
117
+ def self.method_name(name)
118
+ if name !~ /_[bd]ram$/
119
+ raise "invalid name '#{name}' for #{self.name}"
120
+ end
121
+ name.sub!(/_[bd]ram$/, '')
122
+ end
123
+
124
+ # Trigger a new snapshot. +opts+ can be used to control the trigger type
125
+ # using the :trigger key and the write enable using the :wren key:
126
+ #
127
+ # :trigger => :internal means trigger right away
128
+ # :trigger => :external means trigger on the block's trigger input
129
+ # :wren => :internal means to capture every FPGA clock cycle
130
+ # :wren => :external means to capture when the block's we input is high
131
+ #
132
+ # The default behavior is :internal for both.
133
+ def trigger(opts={})
134
+ # Assume internal for both
135
+ trigval = 6
136
+ # Turn off bits if external
137
+ trigval ^= 2 if /^ext/ =~ (opts[:trigger]||opts[:trig])
138
+ trigval ^= 4 if /^ext/ =~ opts[:wren]
139
+ @katcp_client.write(@ctrl_name, trigval)
140
+ @katcp_client.write(@ctrl_name, trigval|1)
141
+ @katcp_client.write(@ctrl_name, trigval)
142
+ end
143
+ end # class Snapshot
144
+
145
+ # Class used to access QDR controller cores
146
+ class QdrCtrl < Bram
147
+ # Resets the QDR controller (re-calibrates)
148
+ def reset
149
+ self[0] = 0
150
+ self[1] = 0xffff_ffff
151
+ self[0] = 0
152
+ end
153
+
154
+ # Returns state of cal_fail bit
155
+ def cal_fail?
156
+ # Bit 8
157
+ (self[1] & (1<<8)) != 0
158
+ end
159
+
160
+ # Returns state of phy_rdy bit (
161
+ def phy_rdy?
162
+ # Bit 0
163
+ (self[1] & (1<<0)) != 0
164
+ end
100
165
  end
101
166
 
102
167
  # Facilitates talking to <tt>tcpborphserver2</tt>, a KATCP server
@@ -146,9 +211,12 @@ module KATCP
146
211
  # :local_port Specifies local port to bind to (default nil)
147
212
  # :socket_timeout Specifies timeout for socket operations
148
213
  # (default DEFAULT_SOCKET_TIMEOUT)
149
- # :typemap Provides a default device typemap (default {}).
150
- # See #device_typemap for details.
214
+ # :typemap Provides a way to override the default device typemap
215
+ # (default {}). See #device_typemap for details.
151
216
  def initialize(*args)
217
+ # If final arg is a Hash, pop it off
218
+ @opts = (Hash === args[-1]) ? args.pop : {}
219
+
152
220
  # List of all devices
153
221
  @devices = [];
154
222
  # List of dynamically defined device attrs (readers only, writers implied)
@@ -156,7 +224,11 @@ module KATCP
156
224
  # @device objects is a Hash of created device objects: key is Class,
157
225
  # value is a Hash mapping device name to instance of Class.
158
226
  @device_objects = {}
159
- # Call super *after* initializing subclass instance variables
227
+ # Merge @opts[:typemap] (if given) into device_typemap.
228
+ # This must be done *before* calling super.
229
+ device_typemap.merge!(@opts[:typemap]) if @opts[:typemap]
230
+ # Call super *after* initializing instance variables and possibly
231
+ # updating typemap.
160
232
  super(*args)
161
233
  end
162
234
 
@@ -206,14 +278,20 @@ module KATCP
206
278
  type, *aliases = typemap[dev] || typemap[dev.to_sym]
207
279
  next if type == :skip
208
280
  # Dynamically define methods and aliases
209
- case type
210
- when Class; device_object(type, dev, *aliases)
211
- when :bram; device_object(Bram, dev, *aliases)
212
- when :tenge; device_object(TenGE, dev, *aliases)
213
- when :roreg; roreg(dev, *aliases)
214
- # else :rwreg or nil (or anything else for that matter) so treat it
215
- # as R/W register.
216
- else rwreg(dev, *aliases)
281
+ begin
282
+ case type
283
+ when Class; device_object(type, dev, *aliases)
284
+ when :bram; device_object(Bram, dev, *aliases)
285
+ when :tenge; device_object(TenGE, dev, *aliases)
286
+ when :snap; device_object(Snapshot, dev, *aliases)
287
+ when :qdrctrl; device_object(QdrCtrl, dev, *aliases)
288
+ when :roreg; roreg(dev, *aliases)
289
+ # else :rwreg or nil (or anything else for that matter) so treat it
290
+ # as R/W register.
291
+ else rwreg(dev, *aliases)
292
+ end
293
+ rescue => e
294
+ STDERR.puts e
217
295
  end
218
296
  end
219
297
  end
@@ -237,6 +315,45 @@ module KATCP
237
315
 
238
316
  protected :undefine_device_attrs
239
317
 
318
+ # This is the default (empty) typemap. It exists here so that subclasses
319
+ # (and their subclasses) have the option of using the following idiom to
320
+ # create their own custom typemap that includes their superclass's typemap:
321
+ #
322
+ # class SomeClass < KATCP::RoachClient
323
+ # DEVICE_TYPEMAP = superclass::DEVICE_TYPEMAP.merge({
324
+ # :some_device => :rwreg
325
+ # })
326
+ # ...
327
+ # end
328
+ #
329
+ # class MyClass < SomeClass
330
+ # DEVICE_TYPEMAP = superclass::DEVICE_TYPEMAP.merge({
331
+ # :switch_gbe_status => :roreg,
332
+ # :switch_gbe => :tenge,
333
+ # :adc_rms_levels => :bram
334
+ # })
335
+ # ...
336
+ # end
337
+ #
338
+ # As defined above, MyClass::DEVICE_TYPEMAP will be:
339
+ #
340
+ # {
341
+ # :some_device => :rwreg,
342
+ # :switch_gbe_status => :roreg,
343
+ # :switch_gbe => :tenge,
344
+ # :adc_rms_levels => :bram
345
+ # }
346
+ #
347
+ # Because the superclass of SomeClass is KATCP::RoachClient, the
348
+ # "superclass::DEVICE_TYPEMAP.merge" part is optional in SomeClass, but it
349
+ # is still recommended since future versions of KATCP::RoachClient may have
350
+ # a non-empty typemap.
351
+ DEVICE_TYPEMAP = {}
352
+
353
+ # Returns the default device typemap Hash (either the one passed to the
354
+ # constructor or an empty Hash). Design specific subclasses can override
355
+ # this method to return a design specific device typemap.
356
+ #
240
357
  # This method's return value controls how methods and aliases are
241
358
  # dynamically generated for devices within the ROACH gateware. If
242
359
  # #device_typemap returns +nil+ or an empty Hash, all devices will be
@@ -259,7 +376,36 @@ module KATCP
259
376
  # will be created. The returned TenGE object
260
377
  # provides convenient ways to read and write
261
378
  # to the TenGE device.
379
+ # :snap (Snapshot) A reader method returning a Snapshot object
380
+ # will be created. The returned Snapshot
381
+ # object provides a trigger method and acts
382
+ # like a Bram object for the Snapshot's
383
+ # memory element. Must be used with the
384
+ # snapshot block's BRAM (or DRAM) device.
385
+ # :qdrctrl (QDR controller) A reader method returning a QdrCtrl object
386
+ # will be created. The returned QdrCtrl
387
+ # object provides methods to reset the QDR
388
+ # controller and check its cal_fail and
389
+ # phy_rdy status bits.
262
390
  # :skip (unwanted device) No method will be created.
391
+ # A class name (custom) A user-supplied class can be given to
392
+ # allow for customized device access.
393
+ #
394
+ # If a class name is specified, the method defined for the corresponding
395
+ # device will return an instance of the given class. The constructor will
396
+ # be passed the KATCP::Client instance and a String specifying the device
397
+ # name. Here is an example of a suitable class definition:
398
+ #
399
+ # class MyDevice
400
+ # def initialize(katcp_client, device_name)
401
+ # # Save client and device name for future use
402
+ # @katcp_client = katcp_client
403
+ # @device_name = device_name
404
+ # end
405
+ #
406
+ # # Other functionality defined here
407
+ #
408
+ # end # class MyDevice
263
409
  #
264
410
  # Methods are only created for devices that actually exist on the device.
265
411
  # If no device exists for a given key, no methods will be created for that
@@ -267,9 +413,9 @@ module KATCP
267
413
  # created unless they are backed by an actual device. Both reader and
268
414
  # writer methods are created for devices for which no key is present.
269
415
  #
270
- # The value can also be an Array whose first element is a Symbol from the
271
- # list above. The remaining elements specify aliases to be created for the
272
- # given attribute methods.
416
+ # The value can also be an Array whose first element is a Symbol (or class
417
+ # name) from the list above. The remaining elements specify aliases to be
418
+ # created for the given attribute methods.
273
419
  #
274
420
  # RoachClient#device_typemap returns on empty Hash so all devices are
275
421
  # treated as read/write registers by default. Gateware specific subclasses
@@ -278,29 +424,33 @@ module KATCP
278
424
  #
279
425
  # Example: The following would lead to the creation of the following
280
426
  # methods and aliases: "input_selector", "input_selector=", "insel",
281
- # "insel=", "switch_gbe_status", "switch_gbe", "adc_rms_levels" (assuming
282
- # the named devices all exist!). No methods would be created for the
283
- # device named "unwanted_reg" even if it exists.
427
+ # "insel=", "switch_gbe_status", "switch_gbe", "adc_rms_levels", and
428
+ # "my_device" (assuming the named devices all exist!). No methods would be
429
+ # created for the device named "unwanted_reg" even if it exists.
284
430
  #
285
431
  # class MyRoachDesign < RoachClient
286
- # DEVICE_TYPEMAP = {
432
+ # DEVICE_TYPEMAP = superclass::DEVICE_TYPEMAP.merge({
287
433
  # :input_selector => [:rwreg, :insel],
288
434
  # :switch_gbe_status => :roreg,
289
435
  # :switch_gbe => :tenge,
290
436
  # :adc_rms_levels => :bram,
437
+ # :my_device => MyDevice,
291
438
  # :unwanted_reg => :skip
292
- # }
439
+ # })
293
440
  #
294
441
  # def device_typemap
295
- # DEVICE_TYPEMAP
442
+ # @device_typemap ||= DEVICE_TYPEMAP.dup
296
443
  # end
297
444
  # end
298
445
  #
299
- # Returns the default device typemap Hash (either the one passed to the
300
- # constructor or an empty Hash). Design specific subclasses can override
301
- # this method to return a design specific device typemap.
446
+ # If the user passes a typemap Hash to the constructor, that Hash is merged
447
+ # into the Hash returned by device_typemap. This can have side effects
448
+ # that might be unwanted if device_typemap returns a Hash that is
449
+ # referenced by a class constant. To avoid that, it is recommended that
450
+ # device_typemap return the instance variable @device_typemap that is
451
+ # lazily initialized with a copy of the class constant as shown above.
302
452
  def device_typemap
303
- (@opts && @opts[:typemap]) || {}
453
+ @device_typemap ||= DEVICE_TYPEMAP.dup
304
454
  end
305
455
 
306
456
  # Allow subclasses to create read accessor method (with optional aliases)
@@ -355,6 +505,9 @@ module KATCP
355
505
  def device_object(clazz, name, *aliases) # :nodoc:
356
506
  name = name.to_s
357
507
  method_name = name.gsub('/', '_')
508
+ if clazz.respond_to?(:method_name)
509
+ method_name = clazz.method_name(method_name)
510
+ end
358
511
  instance_eval <<-"_end"
359
512
  class << self
360
513
  def #{method_name}()
@@ -463,15 +616,21 @@ module KATCP
463
616
  # attributes that were dynamically defined for the previous design are
464
617
  # removed.
465
618
  def progdev(*args)
619
+ # Clear args (i.e. remove all elements) if first element is nil.
620
+ # This also clears args if it is empty, but that is OK since it is
621
+ # essentially a no-op. Any time saved by not clearing an empty args
622
+ # would be lost by checking whether args is already empty! :-)
623
+ args.clear if args[0].nil?
466
624
  prev_socket_timeout = @socket_timeout
467
625
  begin
468
626
  # Adjust @socket_timeout if programming a bitstream
469
627
  @socket_timeout = PROGDEV_SOCKET_TIMEOUT if args[0]
470
- request(:progdev, *args)
628
+ resp = request(:progdev, *args)
471
629
  ensure
472
630
  @socket_timeout = prev_socket_timeout
473
631
  end
474
632
  define_device_attrs
633
+ resp
475
634
  end
476
635
 
477
636
  # Returns true if currently programmed (specifically, it is equivalent to
@@ -3,5 +3,5 @@
3
3
  #++
4
4
 
5
5
  module KATCP
6
- VERSION = "0.1.8"
6
+ VERSION = "0.1.10"
7
7
  end
metadata CHANGED
@@ -1,48 +1,41 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: katcp
3
- version: !ruby/object:Gem::Version
4
- hash: 11
5
- prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 8
10
- version: 0.1.8
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.10
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - David MacMahon
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2013-04-29 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2013-08-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: narray
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 25
29
- segments:
30
- - 0
31
- - 5
32
- - 9
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
33
19
  version: 0.5.9
34
20
  type: :runtime
35
- version_requirements: *id001
36
- description: " Provides KATCP client library for Ruby. KATCP is the Karoo Array Telescope\n Control Protocol.\n"
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.5.9
27
+ description: |2
28
+ Provides KATCP client library for Ruby. KATCP is the Karoo Array Telescope
29
+ Control Protocol.
37
30
  email: davidm@astro.berkeley.edu
38
- executables: []
39
-
31
+ executables:
32
+ - katcpcmd.rb
40
33
  extensions: []
41
-
42
- extra_rdoc_files:
34
+ extra_rdoc_files:
43
35
  - README
44
- files:
36
+ files:
45
37
  - README
38
+ - bin/katcpcmd.rb
46
39
  - lib/katcp.rb
47
40
  - lib/katcp/client.rb
48
41
  - lib/katcp/client/roach.rb
@@ -53,41 +46,29 @@ files:
53
46
  - examples/listdev.rb
54
47
  homepage: http://rb-katcp.rubyforge.org/
55
48
  licenses: []
56
-
49
+ metadata: {}
57
50
  post_install_message:
58
- rdoc_options:
51
+ rdoc_options:
59
52
  - -m
60
53
  - README
61
54
  - --title
62
- - Ruby/KATCP 0.1.8 Documentation
63
- require_paths:
55
+ - Ruby/KATCP 0.1.10 Documentation
56
+ require_paths:
64
57
  - lib
65
- required_ruby_version: !ruby/object:Gem::Requirement
66
- none: false
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- hash: 53
71
- segments:
72
- - 1
73
- - 8
74
- - 1
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
75
62
  version: 1.8.1
76
- required_rubygems_version: !ruby/object:Gem::Requirement
77
- none: false
78
- requirements:
79
- - - ">="
80
- - !ruby/object:Gem::Version
81
- hash: 3
82
- segments:
83
- - 0
84
- version: "0"
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
85
68
  requirements: []
86
-
87
69
  rubyforge_project: rb-katcp
88
- rubygems_version: 1.8.24
70
+ rubygems_version: 2.0.2
89
71
  signing_key:
90
- specification_version: 3
72
+ specification_version: 4
91
73
  summary: KATCP library for Ruby
92
74
  test_files: []
93
-