origen_link 0.1.0.pre0 → 0.1.0

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.
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