origen_link 0.1.0.pre0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/bin/start_link_server +20 -0
  3. data/config/application.rb +0 -0
  4. data/config/boot.rb +3 -2
  5. data/config/commands.rb +0 -0
  6. data/config/version.rb +1 -1
  7. data/lib/origen_link.rb +1 -15
  8. data/lib/origen_link/callback_handlers.rb +13 -0
  9. data/lib/origen_link/server/jtag.rb +180 -0
  10. data/lib/origen_link/server/pin.rb +125 -0
  11. data/lib/origen_link/server/sequencer.rb +353 -0
  12. data/lib/origen_link/{includes_vector_based.rb → server_com.rb} +32 -7
  13. data/lib/origen_link/test/top_level.rb +48 -0
  14. data/lib/origen_link/test/top_level_controller.rb +44 -0
  15. data/lib/origen_link/test/vector_based.rb +25 -0
  16. data/lib/origen_link/vector_based.rb +254 -53
  17. data/lib/tasks/origen_link.rake +0 -0
  18. data/pattern/example.rb +0 -0
  19. data/pattern/jtag_100_operations.rb +0 -0
  20. data/pattern/jtag_comm_fail_test.rb +0 -0
  21. data/pattern/jtag_comm_test.rb +0 -0
  22. data/templates/web/index.md.erb +0 -0
  23. data/templates/web/layouts/_basic.html.erb +0 -0
  24. data/templates/web/partials/_navbar.html.erb +0 -0
  25. data/templates/web/release_notes.md.erb +0 -0
  26. metadata +32 -18
  27. data/lib/origen_link/test/regression_tests.rb +0 -68
  28. data/lib/origen_link/test/test_dut.rb +0 -46
  29. data/lib/origen_link/test/test_dut_controller.rb +0 -42
  30. data/lib/origen_link/test/vector_based_redefs.rb +0 -17
  31. data/lib/origen_link_server/LinkSequencer.rb +0 -333
  32. data/lib/origen_link_server/LinkTCPServer.rb +0 -45
  33. data/lib/origen_link_server/jtag_interface.rb +0 -177
  34. data/lib/origen_link_server/pin_interface.rb +0 -134
  35. data/lib/origen_link_server/test/test_Sequencer.rb +0 -51
@@ -1,7 +1,5 @@
1
1
  module OrigenLink
2
- class VectorBased
3
- include OrigenTesters::VectorBasedTester
4
-
2
+ module ServerCom
5
3
  # send_cmd(cmdstr, argstr)
6
4
  # cmdstr is a valid command. <category>_<command>
7
5
  # Ex: 'pin_assign'
@@ -29,7 +27,7 @@ module OrigenLink
29
27
  # open a connection to the server, send the command and wait for a response
30
28
  TCPSocket.open(@address, @port) do |link|
31
29
  t2 = Time.now
32
- link.puts(cmdstr + ':' + argstr)
30
+ link.write(cmdstr + ':' + argstr + "\n\n")
33
31
  t3 = Time.now
34
32
  response = link.gets
35
33
  t4 = Time.now
@@ -46,8 +44,35 @@ module OrigenLink
46
44
  @total_recv_time += (t4 - t3)
47
45
  @max_receive_time = (t4 - t3) if @max_receive_time < (t4 - t3)
48
46
  @total_packets += 1
49
- Origen.log.error 'nil reponse from server (likely died) for command(' + cmdstr + ':' + argstr + ')' if response.nil?
50
- response # ensure the response is passed along
47
+ Origen.log.error 'nil response from server (likely died) for command(' + cmdstr + ':' + argstr + ')' if response.nil?
48
+ response # ensure the response is passed along
49
+ end
50
+
51
+ def send_batch(vector_batch)
52
+ t2 = 0
53
+ t3 = 0
54
+ t4 = 0
55
+ t5 = 0
56
+ response = []
57
+ t1 = Time.now
58
+ TCPSocket.open(@address, @port) do |link|
59
+ t2 = Time.now
60
+ vector_batch_str = vector_batch.join("\n") + "\n\n"
61
+ link.write(vector_batch_str)
62
+ t3 = Time.now
63
+ while line = link.gets
64
+ response << line.chomp
65
+ end
66
+ t4 = Time.now
67
+ end
68
+ t5 = Time.now
69
+ @total_comm_time += (t5 - t1)
70
+ @total_connect_time += (t2 - t1)
71
+ @total_xmit_time += (t3 - t2)
72
+ @total_recv_time += (t4 - t3)
73
+ @max_receive_time = (t4 - t3) if @max_receive_time < (t4 - t3)
74
+ @total_packets += 1
75
+ response
51
76
  end
52
77
 
53
78
  # setup_cmd_response_logger
@@ -60,7 +85,7 @@ module OrigenLink
60
85
  # if the server died (which hopefully it never will) response is nil
61
86
  case response.chr
62
87
  when 'P'
63
- Origen.log.info command + ' setup was successful'
88
+ Origen.log.debug command + ' setup was successful'
64
89
  when 'F'
65
90
  Origen.log.error command + ' setup FAILED with the following message:'
66
91
  Origen.log.error response.chomp
@@ -0,0 +1,48 @@
1
+ module OrigenLink
2
+ module Test
3
+ class TopLevel
4
+ include Origen::TopLevel
5
+
6
+ def initialize(options = {})
7
+ instantiate_pins(options)
8
+ instantiate_registers(options)
9
+ instantiate_sub_blocks(options)
10
+ end
11
+
12
+ def instantiate_pins(options = {})
13
+ options = {
14
+ jtag_comm_config: false,
15
+ invalid_pin_number_test: false,
16
+ missing_pinmap_test: false
17
+ }.merge(options)
18
+ add_pin :tclk
19
+ add_pin :tdi
20
+ add_pin :tdo
21
+ add_pin :tms
22
+ add_pin :resetb
23
+ add_pins :port_a, size: 8
24
+
25
+ pin_pattern_order :tclk, :tms, :tdi, :tdo, only: true if options[:jtag_comm_config]
26
+
27
+ # if tester.link? #.to_s == 'OrigenLink::VectorBased'
28
+ if tester.to_s == 'OrigenLink::VectorBased'
29
+ if options[:invalid_pin_number_test]
30
+ tester.pinmap = 'tclk,119,tms,1900,tdi,116,tdo,124'
31
+ else
32
+ tester.pinmap = 'tclk,119,tms,6,tdi,116,tdo,124' unless options[:missing_pinmap_test]
33
+ end
34
+ tester.pinorder = 'tclk,tms,tdi,tdo'
35
+ end
36
+ end
37
+
38
+ def instantiate_registers(options = {})
39
+ reg :testreg, 0 do |reg|
40
+ reg.bits 31..0, :value
41
+ end
42
+ end
43
+
44
+ def instantiate_sub_blocks(options = {})
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,44 @@
1
+ module OrigenLink
2
+ module Test
3
+ class TopLevelController
4
+ include Origen::Controller
5
+
6
+ include OrigenJTAG
7
+
8
+ JTAG_CONFIG = {
9
+ #:tclk_format => :rl,
10
+ tclk_format: :rh,
11
+ #:tclk_multiple => 1,
12
+ tclk_multiple: 4,
13
+ tdo_strobe: :tclk_high,
14
+ tdo_store_cycle: 3,
15
+ init_state: :idle
16
+ }
17
+
18
+ def startup(options)
19
+ pp 'Enter test mode' do
20
+ # if tester.link?
21
+ if tester.to_s == 'OrigenLink::VectorBased'
22
+ tester.initialize_pattern
23
+ # below is for testing return format timing, requires tclk to be rl and multiple of 1
24
+ # tester.pinformat = 'func_25mhz,tclk,rl'
25
+ # tester.pintiming = 'func_25mhz,tdi,0,tms,0,tdo,1'
26
+ end
27
+ tester.set_timeset('func_25mhz', 40) # Where 40 is the period in ns
28
+ tester.wait time_in_us: 100
29
+ end
30
+ end
31
+
32
+ def shutdown(options)
33
+ pp 'Reset the device' do
34
+ pin(:resetb).drive!(0)
35
+ pin(:tclk).drive!(0)
36
+ end
37
+ # if tester.link?
38
+ if tester.to_s == 'OrigenLink::VectorBased'
39
+ tester.finalize_pattern
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,25 @@
1
+ require 'origen_link/vector_based'
2
+
3
+ module OrigenLink
4
+ module Test
5
+ class VectorBased < ::OrigenLink::VectorBased
6
+ attr_accessor :message, :microcodestr, :test_response
7
+
8
+ def send_cmd(cmdstr, argstr)
9
+ @message = cmdstr + ':' + argstr
10
+ @test_response
11
+ end
12
+
13
+ def send_batch(vector_batch)
14
+ @test_response
15
+ end
16
+
17
+ def setup_cmd_response_logger(command, response)
18
+ end
19
+
20
+ def microcode(msg)
21
+ @microcodestr = @microcodestr + msg
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,6 @@
1
+ require 'origen_testers'
2
+ require 'origen_link/server_com'
3
+ require 'origen_link/callback_handlers'
1
4
  module OrigenLink
2
5
  # OrigenLink::VectorBased
3
6
  # This class is meant to be used for live silicon debug. Vector data that Origen
@@ -9,15 +12,15 @@ module OrigenLink
9
12
  # Integration instructions
10
13
  # Set the pin map (must be done first) and pin order
11
14
  # if tester.link?
12
- # tester.pinmap = 'tclk,26,tms,19,tdi,16,tdo,23'
13
- # tester.pinorder = 'tclk,tms,tdi,tdo'
15
+ # tester.pinmap = 'tclk,26,tms,19,tdi,16,tdo,23'
16
+ # tester.pinorder = 'tclk,tms,tdi,tdo'
14
17
  # end
15
18
  #
16
19
  # Set Origen to only generate vectors for pins in the pinmap (order should match)
17
- # pin_pattern_order :tclk, :tms, :tdi, :tdo, only: true if tester.link?
20
+ # pin_pattern_order :tclk, :tms, :tdi, :tdo, only: true if tester.link?
18
21
  #
19
22
  # At the beginning of the Startup method add this line
20
- # tester.initialize_pattern if tester.link?
23
+ # tester.initialize_pattern if tester.link?
21
24
  #
22
25
  # At the end of the Shutdown method add this line
23
26
  # tester.finalize_pattern if tester.link?
@@ -25,12 +28,15 @@ module OrigenLink
25
28
  # Create a link environment with the IP address and socket number of a link server
26
29
  # $tester = OrigenLink::VectorBased.new('192.168.0.2', 12777)
27
30
  class VectorBased
28
- # include OrigenTesters::VectorBasedTester
31
+ include OrigenTesters::VectorBasedTester
32
+ include ServerCom
29
33
 
30
34
  # these attributes are exposed for testing purposes, a user would not need to read them
31
- attr_reader :fail_count, :vector_count, :total_comm_time, :total_connect_time, :total_xmit_time, :total_recv_time, :total_packets, :vector_repeatcount, :tsets_programmed
35
+ attr_reader :fail_count, :vector_count, :total_comm_time, :total_connect_time, :total_xmit_time
36
+ attr_reader :total_recv_time, :total_packets, :vector_repeatcount, :tsets_programmed, :captured_data
37
+ attr_reader :vector_batch, :store_pins_batch, :comment_batch
32
38
 
33
- def initialize(address, port)
39
+ def initialize(address, port, options = {})
34
40
  @address = address
35
41
  @port = port
36
42
  @fail_count = 0
@@ -47,16 +53,47 @@ module OrigenLink
47
53
  @max_receive_time = 0
48
54
  @tsets_programmed = {}
49
55
  @tset_count = 1
56
+ @store_pins = []
57
+ @captured_data = []
58
+ # A tester seems to be unable to register as a callback handler, so for now instantiating a
59
+ # dedicated object to implement the handlers related to this tester
60
+ CallbackHandlers.new
61
+ @vector_batch = []
62
+ @store_pins_batch = {}
63
+ @comment_batch = {}
64
+ @batch_vectors = true
65
+ end
66
+
67
+ # push_comment
68
+ # This method intercepts comments so they can be correctly placed in the output file
69
+ # when vector batching is used
70
+ def push_comment(msg)
71
+ if @batch_vectors
72
+ key = @vector_batch.length
73
+ if @comment_batch.key?(key)
74
+ @comment_batch[key] = @comment_batch[key] + "\n" + msg
75
+ else
76
+ @comment_batch[key] = msg
77
+ end
78
+ else
79
+ microcode msg
80
+ end
50
81
  end
51
82
 
52
83
  # push_vector
53
84
  # This method intercepts vector data from Origen, removes white spaces and compresses repeats
54
85
  def push_vector(options)
55
86
  programmed_data = options[:pin_vals].gsub(/\s+/, '')
87
+ unless options[:timeset]
88
+ puts 'No timeset defined!'
89
+ puts 'Add one to your top level startup method or target like this:'
90
+ puts '$tester.set_timeset("nvmbist", 40) # Where 40 is the period in ns'
91
+ exit 1
92
+ end
56
93
  tset = options[:timeset].name
57
94
  if @vector_count > 0
58
95
  # compressing repeats as we go
59
- if (programmed_data == @previous_vectordata) && (@previous_tset == tset)
96
+ if (programmed_data == @previous_vectordata) && (@previous_tset == tset) && @store_pins.empty?
60
97
  @vector_repeatcount += 1
61
98
  else
62
99
  # all repeats of the previous vector have been counted
@@ -74,6 +111,65 @@ module OrigenLink
74
111
  @vector_count += 1
75
112
  end
76
113
 
114
+ # Capture a vector
115
+ #
116
+ # This method applies a store vector request to the previous vector, note that is does
117
+ # not actually generate a new vector.
118
+ #
119
+ # The captured data is added to the captured_data array.
120
+ #
121
+ # This method is indended to be used by pin drivers, see the #capture method for the application
122
+ # level API.
123
+ #
124
+ # @example
125
+ # $tester.cycle # This is the vector you want to capture
126
+ # $tester.store # This applies the store request
127
+ def store(*pins)
128
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
129
+ fail 'The store is not implemented yet on Link'
130
+ end
131
+
132
+ # Capture the next vector generated
133
+ #
134
+ # This method applies a store request to the next vector to be generated,
135
+ # note that is does not actually generate a new vector.
136
+ #
137
+ # The captured data is added to the captured_data array.
138
+ #
139
+ # This method is indended to be used by pin drivers, see the #capture method for the application
140
+ # level API.
141
+ #
142
+ # @example
143
+ # tester.store_next_cycle
144
+ # tester.cycle # This is the vector that will be captured
145
+ def store_next_cycle(*pins)
146
+ options = pins.last.is_a?(Hash) ? pins.pop : {}
147
+ flush_vector
148
+ @store_pins = pins
149
+ end
150
+
151
+ # Capture any store data within the given block, return it and then internally clear the tester's
152
+ # capture memory.
153
+ #
154
+ # @example
155
+ #
156
+ # v = tester.capture do
157
+ # my_reg.store!
158
+ # end
159
+ # v # => Data value read from my_reg on the DUT
160
+ def capture(*args)
161
+ if block_given?
162
+ yield
163
+ synchronize
164
+ d = @captured_data
165
+ @captured_data = []
166
+ d
167
+ else
168
+ # On other testers capture is an alias of store
169
+ store(*args)
170
+ end
171
+ end
172
+
77
173
  # flush_vector
78
174
  # Just as the name suggests, this method "flushes" a vector. This is necessary because
79
175
  # of repeat compression (a vector isn't sent until different vector data is encountered)
@@ -81,36 +177,116 @@ module OrigenLink
81
177
  # Don't forget to flush when you're in debug mode. Otherwise, the last vector of a
82
178
  # write command won't be sent to the server.
83
179
  def flush_vector(programmed_data = '', tset = '')
84
- if @vector_repeatcount > 1
85
- repeat_prefix = "repeat#{@vector_repeatcount},"
180
+ # prevent server crash when vector_flush is used during debug
181
+ unless @previous_vectordata == ''
182
+ if @vector_repeatcount > 1
183
+ repeat_prefix = "repeat#{@vector_repeatcount},"
184
+ else
185
+ repeat_prefix = ''
186
+ end
187
+ if @tsets_programmed[@previous_tset]
188
+ tset_prefix = "tset#{@tsets_programmed[@previous_tset]},"
189
+ else
190
+ tset_prefix = ''
191
+ end
192
+
193
+ if @batch_vectors
194
+ @vector_batch << 'pin_cycle:' + tset_prefix + repeat_prefix + @previous_vectordata
195
+ # store capture pins for batch processing
196
+ unless @store_pins.empty?
197
+ @store_pins_batch[@vector_batch.length - 1] = @store_pins
198
+ end
199
+ else
200
+ process_vector_response(send_cmd('pin_cycle', tset_prefix + repeat_prefix + @previous_vectordata))
201
+ end
202
+
203
+ # make sure that only requested vectors are stored when batching is enabled
204
+ @store_pins = []
205
+ end
206
+
207
+ @vector_repeatcount = 1
208
+ @previous_vectordata = programmed_data
209
+ @previous_tset = tset
210
+ end
211
+
212
+ # synchronize
213
+ # This method will synchronize the DUT state with Origen. All generated
214
+ # vectors are sent to the DUT for execution and the responses are processed
215
+ def synchronize(output_file = '')
216
+ flush_vector
217
+ if @batch_vectors
218
+ process_response(send_batch(@vector_batch), output_file)
219
+ end
220
+ @vector_batch = []
221
+ @store_pins_batch.clear
222
+ @comment_batch.clear
223
+ end
224
+
225
+ # process_response
226
+ # This method will process a server response. Send log info to the output,
227
+ # keep track of fail count and captured data
228
+ def process_response(response, output_file = '')
229
+ if response.is_a?(Array)
230
+ # if called from finalize_pattern -> synchronize, open the output_file and store results
231
+ output_obj = nil
232
+ output_obj = File.open(output_file, 'a+') unless output_file == ''
233
+ response.each_index do |index|
234
+ # restore store pins state for processing
235
+ if @store_pins_batch.key?(index)
236
+ @store_pins = @store_pins_batch[index]
237
+ else
238
+ @store_pins = []
239
+ end
240
+ if @comment_batch.key?(index)
241
+ unless output_file == ''
242
+ # get the header placed correctly
243
+ if index == response.length - 1
244
+ output_obj.puts 'last comment'
245
+ output_obj.lineno = 0
246
+ end
247
+ output_obj.puts(@comment_batch[index])
248
+ end
249
+ end
250
+ process_vector_response(response[index], output_obj)
251
+ end
252
+ output_obj.close unless output_file == ''
86
253
  else
87
- repeat_prefix = ''
254
+ process_vector_response(response)
88
255
  end
89
- if @tsets_programmed[@previous_tset]
90
- tset_prefix = "tset#{@tsets_programmed[@previous_tset]},"
256
+ end
257
+
258
+ # process_vector_response
259
+ # This method exists to prevent code duplication when handling an array of
260
+ # batched responses versus a single response string.
261
+ def process_vector_response(vector_response, output_obj = nil)
262
+ unless @store_pins.empty?
263
+ msg = " (Captured #{@store_pins.map(&:name).join(', ')})\n"
264
+ capture_data(vector_response)
265
+ vector_response.strip!
266
+ vector_response += msg
267
+ end
268
+ if output_obj.nil?
269
+ microcode vector_response
91
270
  else
92
- tset_prefix = ''
271
+ output_obj.puts(vector_response)
93
272
  end
94
- response = send_cmd('pin_cycle', tset_prefix + repeat_prefix + @previous_vectordata)
95
- microcode response
96
- unless response.chr == 'P'
97
- microcode 'E:' + @previous_vectordata + ' //expected data for previous vector'
273
+
274
+ unless vector_response.chr == 'P'
275
+ # TODO: Put this back with an option to disable, based on a serial or parallel interface being used
276
+ # microcode 'E:' + @previous_vectordata + ' //expected data for previous vector'
98
277
  @fail_count += 1
99
278
  end
100
- @vector_repeatcount = 1
101
- @previous_vectordata = programmed_data
102
- @previous_tset = tset
103
279
  end
104
280
 
105
281
  # initialize_pattern
106
- # At some point in the future this intialization should be done behind the
107
- # scenes without requiring the user to add code to the controller.
108
- #
109
282
  # This method sets initializes variables at the start of a pattern.
110
- # it should be called from the Startup method of the dut controller.
283
+ # it is called automatically when pattern generation starts.
111
284
  def initialize_pattern
112
285
  @fail_count = 0
113
286
  @vector_count = 0
287
+ @vector_batch.delete_if { true }
288
+ @store_pins_batch.clear
289
+ @comment_batch.clear
114
290
 
115
291
  @total_packets = 0
116
292
  @total_comm_time = 0
@@ -121,35 +297,36 @@ module OrigenLink
121
297
  if @pinmap.nil?
122
298
  Origen.log.error('pinmap has not been setup, use tester.pinmap= to initialize a pinmap')
123
299
  else
124
- Origen.log.info('executing pattern with pinmap:' + @pinmap.to_s)
300
+ Origen.log.debug('executing pattern with pinmap:' + @pinmap.to_s)
125
301
  end
126
302
  end
127
303
 
128
304
  # finalize_pattern
129
- # At some point in the future this finalization should be done behind the scenes.
130
- #
131
305
  # This method flushes the final vector. Then, it logs success or failure of the
132
306
  # pattern execution along with execution time information.
133
- def finalize_pattern(programmed_data = '')
134
- flush_vector(programmed_data)
307
+ def finalize_pattern(output_file)
308
+ Origen.log.debug('Pattern generation completed. Sending all stored vector data')
309
+ synchronize(output_file)
310
+ # for debug, report communication times
311
+ Origen.log.debug("total communication time: #{@total_comm_time}")
312
+ Origen.log.debug("total connect time: #{@total_connect_time}")
313
+ Origen.log.debug("total transmit time: #{@total_xmit_time}")
314
+ Origen.log.debug("total receive time: #{@total_recv_time}")
315
+ Origen.log.debug("total packets: #{@total_packets}")
316
+ Origen.log.debug("total time per packet: #{@total_comm_time / @total_packets}")
317
+ Origen.log.debug("connect time per packet: #{@total_connect_time / @total_packets}")
318
+ Origen.log.debug("transmit time per packet: #{@total_xmit_time / @total_packets}")
319
+ Origen.log.debug("receive time per packet: #{@total_recv_time / @total_packets}")
320
+ Origen.log.debug("max packet time: #{@max_packet_time}")
321
+ Origen.log.debug("max duration command - #{@longest_packet}")
322
+ Origen.log.debug("max receive time: #{@max_receive_time}")
135
323
  if @fail_count == 0
136
- Origen.log.success("PASS - pattern execution passed (#{@vector_count} vectors pass)")
324
+ # Origen.log.success("PASS - pattern execution passed (#{@vector_count} vectors pass)")
325
+ Origen.app.stats.report_pass
137
326
  else
138
- Origen.log.error("FAIL - pattern execution failed (#{@fail_count} failures)")
327
+ # Origen.log.error("FAIL - pattern execution failed (#{@fail_count} failures)")
328
+ Origen.app.stats.report_fail
139
329
  end
140
- # for debug, report communication times
141
- Origen.log.info("total communication time: #{@total_comm_time}")
142
- Origen.log.info("total connect time: #{@total_connect_time}")
143
- Origen.log.info("total transmit time: #{@total_xmit_time}")
144
- Origen.log.info("total receive time: #{@total_recv_time}")
145
- Origen.log.info("total packets: #{@total_packets}")
146
- Origen.log.info("total time per packet: #{@total_comm_time / @total_packets}")
147
- Origen.log.info("connect time per packet: #{@total_connect_time / @total_packets}")
148
- Origen.log.info("transmit time per packet: #{@total_xmit_time / @total_packets}")
149
- Origen.log.info("receive time per packet: #{@total_recv_time / @total_packets}")
150
- Origen.log.info("max packet time: #{@max_packet_time}")
151
- Origen.log.info('max duration command - ' + @longest_packet)
152
- Origen.log.info("max receive time: #{@max_receive_time}")
153
330
  end
154
331
 
155
332
  # to_s
@@ -162,14 +339,6 @@ module OrigenLink
162
339
  'OrigenLink::VectorBased'
163
340
  end
164
341
 
165
- # link?
166
- # returns true.
167
- #
168
- # This method indicates to user code that link is the tester environment.
169
- def link?
170
- true
171
- end
172
-
173
342
  # pinmap=
174
343
  # This method is used to setup the pin map on the debugger device.
175
344
  # The argument should be a string with <pin name>, <gpio #>, <pin name>
@@ -250,5 +419,37 @@ module OrigenLink
250
419
  end
251
420
  @tsets_programmed[name]
252
421
  end
422
+
423
+ private
424
+
425
+ def capture_data(response)
426
+ if @store_pins.size > 1
427
+ fail 'Data capture on multiple pins is not implemented yet'
428
+ else
429
+ captured_data[0] ||= 0
430
+ captured_data[0] = (captured_data[0] << 1) | extract_value(response, @store_pins[0])
431
+ @store_pins = []
432
+ end
433
+ end
434
+
435
+ def extract_value(response, pin)
436
+ v = response[index_of(pin) + 2]
437
+ if v == '`'
438
+ 1
439
+ elsif v == '.'
440
+ 0
441
+ else
442
+ fail "Failed to extract value for pin #{pin.name}, character in response is: #{v}"
443
+ end
444
+ end
445
+
446
+ # Returns the vector index (position) of the given pin
447
+ def index_of(pin)
448
+ i = @pinorder.split(',').index(pin.name.to_s)
449
+ unless i
450
+ fail "Data capture of pin #{pin.name} has been requested, but it has not been included in the Link pinmap!"
451
+ end
452
+ i
453
+ end
253
454
  end
254
455
  end