origen_arm_debug 0.10.1 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/application.rb +3 -3
- data/config/boot.rb +5 -0
- data/config/commands.rb +14 -9
- data/config/version.rb +4 -4
- data/lib/origen_arm_debug.rb +7 -11
- data/lib/origen_arm_debug/ap.rb +14 -0
- data/lib/origen_arm_debug/ap_controller.rb +27 -0
- data/lib/origen_arm_debug/dap.rb +89 -0
- data/lib/origen_arm_debug/dap_controller.rb +14 -0
- data/lib/origen_arm_debug/dp_controller.rb +17 -0
- data/lib/origen_arm_debug/helpers.rb +28 -0
- data/lib/origen_arm_debug/jtag_ap.rb +10 -0
- data/lib/origen_arm_debug/jtag_ap_controller.rb +6 -0
- data/lib/origen_arm_debug/jtag_dp.rb +59 -0
- data/lib/origen_arm_debug/jtag_dp_controller.rb +140 -0
- data/lib/origen_arm_debug/mem_ap.rb +33 -283
- data/lib/origen_arm_debug/mem_ap_controller.rb +81 -0
- data/lib/origen_arm_debug/sw_dp.rb +65 -0
- data/lib/origen_arm_debug/sw_dp_controller.rb +47 -0
- data/lib/{origen_arm_debug → origen_arm_debug_dev}/dut.rb +11 -15
- data/lib/origen_arm_debug_dev/dut_jtag.rb +32 -0
- data/lib/{origen_arm_debug → origen_arm_debug_dev}/dut_swd.rb +7 -1
- data/pattern/workout.rb +61 -0
- data/templates/web/index.md.erb +16 -4
- metadata +38 -48
- data/config/development.rb +0 -17
- data/config/environment.rb +0 -3
- data/config/users.rb +0 -19
- data/lib/origen_arm_debug/driver.rb +0 -113
- data/lib/origen_arm_debug/dut_jtag.rb +0 -19
- data/lib/origen_arm_debug/swj_dp.rb +0 -426
- data/pattern/read_write_reg.rb +0 -33
- data/pattern/read_write_reg_jtag.rb +0 -17
- data/pattern/read_write_reg_swd.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06b61282c9205efdb49a4a8cd5532e9dc718b7f6
|
4
|
+
data.tar.gz: 525f141f5fb7002bb9af7809ae71af1e2a71cdc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02092bbc25a5b1da0e119445204a2cc47bb03426de293dd16e9495611038db7162604e5209f1031ccf4ef5f87040fc088992abea497c572acdddb5a196b2e127
|
7
|
+
data.tar.gz: da718b20deba251a76896c7c10031b9b9c154f1dbb4da68fc5634328c16823f651b906d759093fe61b169f5e16de17aea8db22db2e21236715f73c901cc2726b
|
data/config/application.rb
CHANGED
@@ -23,14 +23,14 @@ class OrigenARMDebugApplication < Origen::Application
|
|
23
23
|
# Auto correct violations where possible whenever 'origen lint' is run
|
24
24
|
auto_correct: true,
|
25
25
|
# Limit the testing for large legacy applications
|
26
|
-
level: :easy,
|
26
|
+
#level: :easy,
|
27
27
|
# Run on these directories/files by default
|
28
28
|
#files: ["lib", "config/application.rb"],
|
29
29
|
}
|
30
30
|
|
31
31
|
# Ensure that all tests pass before allowing a release to continue
|
32
32
|
def validate_release
|
33
|
-
if !system("origen examples") || !system("origen specs")
|
33
|
+
if !system("origen examples") # || !system("origen specs")
|
34
34
|
puts "Sorry but you can't release with failing tests, please fix them and try again."
|
35
35
|
exit 1
|
36
36
|
else
|
@@ -42,7 +42,7 @@ class OrigenARMDebugApplication < Origen::Application
|
|
42
42
|
def before_deploy_site
|
43
43
|
Dir.chdir Origen.root do
|
44
44
|
system "origen examples -c"
|
45
|
-
system "origen specs -c"
|
45
|
+
# system "origen specs -c"
|
46
46
|
dir = "#{Origen.root}/web/output/coverage"
|
47
47
|
FileUtils.remove_dir(dir, true) if File.exists?(dir)
|
48
48
|
system "mv #{Origen.root}/coverage #{dir}"
|
data/config/boot.rb
ADDED
data/config/commands.rb
CHANGED
@@ -17,20 +17,18 @@ aliases ={
|
|
17
17
|
# Now branch to the specific task code
|
18
18
|
case @command
|
19
19
|
|
20
|
-
when "specs"
|
21
|
-
|
22
|
-
|
20
|
+
# when "specs"
|
21
|
+
# require "rspec"
|
22
|
+
# exit RSpec::Core::Runner.run(['spec'])
|
23
23
|
|
24
|
-
when "examples"
|
24
|
+
when "examples" # , "test"
|
25
25
|
Origen.load_application
|
26
26
|
status = 0
|
27
27
|
|
28
28
|
# Pattern generator tests
|
29
|
-
ARGV = %w(
|
29
|
+
ARGV = %w(workout -t jtag -e j750 -r approved)
|
30
30
|
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
31
|
-
ARGV = %w(
|
32
|
-
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
33
|
-
ARGV = %w(read_write_reg_swd -t swd -r approved)
|
31
|
+
ARGV = %w(workout -t swd -e j750 -r approved)
|
34
32
|
load "#{Origen.top}/lib/origen/commands/generate.rb"
|
35
33
|
|
36
34
|
if Origen.app.stats.changed_files == 0 &&
|
@@ -44,6 +42,12 @@ when "examples"
|
|
44
42
|
status = 1
|
45
43
|
end
|
46
44
|
puts
|
45
|
+
# if @command == "test"
|
46
|
+
# Origen.app.unload_target!
|
47
|
+
# require "rspec"
|
48
|
+
# result = RSpec::Core::Runner.run(['spec'])
|
49
|
+
# status = status == 1 ? 1 : result
|
50
|
+
# end
|
47
51
|
exit status
|
48
52
|
|
49
53
|
# Always leave an else clause to allow control to fall back through to the
|
@@ -52,8 +56,9 @@ when "examples"
|
|
52
56
|
# origen -h, you can do this be assigning the required text to @application_commands
|
53
57
|
# before handing control back to Origen. Un-comment the example below to get started.
|
54
58
|
else
|
59
|
+
#specs Run the specs (unit tests), -c will enable coverage
|
60
|
+
#test Run both specs and examples, -c will enable coverage
|
55
61
|
@application_commands = <<-EOT
|
56
|
-
specs Run the specs (unit tests), -c will enable coverage
|
57
62
|
examples Run the examples (tests), -c will enable coverage
|
58
63
|
EOT
|
59
64
|
|
data/config/version.rb
CHANGED
data/lib/origen_arm_debug.rb
CHANGED
@@ -3,14 +3,10 @@ require_relative '../config/application.rb'
|
|
3
3
|
require 'origen_jtag'
|
4
4
|
require 'origen_swd'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
# def arm_debug
|
14
|
-
# @arm_debug ||= Driver.new(self)
|
15
|
-
# end
|
16
|
-
end
|
6
|
+
require 'origen_arm_debug/helpers'
|
7
|
+
require 'origen_arm_debug/dap'
|
8
|
+
require 'origen_arm_debug/jtag_dp'
|
9
|
+
require 'origen_arm_debug/sw_dp'
|
10
|
+
require 'origen_arm_debug/ap.rb'
|
11
|
+
require 'origen_arm_debug/mem_ap'
|
12
|
+
require 'origen_arm_debug/jtag_ap'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'origen_arm_debug/ap_controller'
|
2
|
+
module OrigenARMDebug
|
3
|
+
# Generic Access Port (AP)
|
4
|
+
class AP
|
5
|
+
include Origen::Model
|
6
|
+
|
7
|
+
# Wait states for data to be transferred from AP-Reg to RDBUFF (on read)
|
8
|
+
attr_reader :apreg_access_wait
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@apreg_access_wait = options[:apreg_access_wait] || 0
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module OrigenARMDebug
|
2
|
+
class APController
|
3
|
+
include Origen::Controller
|
4
|
+
include Helpers
|
5
|
+
|
6
|
+
def write_register(reg_or_val, options = {})
|
7
|
+
if reg_or_val.try(:owner) == model
|
8
|
+
log "Write AP (#{model.name}) register #{reg_or_val.name.to_s.upcase}: #{reg_or_val.data.to_hex}" do
|
9
|
+
parent.dp.write_register(reg_or_val)
|
10
|
+
apreg_access_wait.cycles
|
11
|
+
end
|
12
|
+
else
|
13
|
+
fail 'No Resource-specific transport defined for MDM-AP (#model.name})'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_register(reg_or_val, options = {})
|
18
|
+
if reg_or_val.try(:owner) == model
|
19
|
+
log "Read AP (#{model.name}) register #{reg_or_val.name.to_s.upcase}: #{Origen::Utility.read_hex(reg_or_val)}" do
|
20
|
+
parent.dp.read_register(reg_or_val, apacc_wait_states: apreg_access_wait)
|
21
|
+
end
|
22
|
+
else
|
23
|
+
fail 'No Resource-specific transport defined for MDM-AP (#model.name})'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'origen_arm_debug/dap_controller'
|
2
|
+
module OrigenARMDebug
|
3
|
+
# This is the top-level model that instantiates the DP and APs
|
4
|
+
class DAP
|
5
|
+
include Origen::Model
|
6
|
+
|
7
|
+
attr_reader :dps, :mem_aps, :jtag_aps, :ext_aps
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@dps = []
|
11
|
+
@mem_aps = [] # Array of MEM-APs
|
12
|
+
@jtag_aps = [] # Array of JTAG-APs
|
13
|
+
@ext_aps = [] # Array of 'extension' APs
|
14
|
+
instantiate_subblocks(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def instantiate_subblocks(options = {})
|
18
|
+
if options[:swd] || parent.respond_to?(:swd)
|
19
|
+
dps << sub_block(:sw_dp, class_name: 'OrigenARMDebug::SW_DP')
|
20
|
+
end
|
21
|
+
|
22
|
+
if options[:jtag] || parent.respond_to?(:jtag)
|
23
|
+
dps << sub_block(:jtag_dp, class_name: 'OrigenARMDebug::JTAG_DP')
|
24
|
+
end
|
25
|
+
|
26
|
+
Array(options[:mem_aps]).each do |name, base_address|
|
27
|
+
if base_address.is_a?(Hash)
|
28
|
+
ap_opts = { class_name: 'OrigenARMDebug::MemAP' }.merge(base_address)
|
29
|
+
else
|
30
|
+
ap_opts = { class_name: 'OrigenARMDebug::MemAP', base_address: base_address }
|
31
|
+
end
|
32
|
+
|
33
|
+
add_ap(name, ap_opts)
|
34
|
+
end
|
35
|
+
|
36
|
+
Array(options[:jtag_aps]).each do |name, base_address|
|
37
|
+
if base_address.is_a?(Hash)
|
38
|
+
ap_opts = { class_name: 'OrigenARMDebug::JTAGAP' }.merge(base_address)
|
39
|
+
else
|
40
|
+
ap_opts = { class_name: 'OrigenARMDebug::JTAGAP', base_address: base_address }
|
41
|
+
end
|
42
|
+
|
43
|
+
add_ap(name, ap_opts)
|
44
|
+
end
|
45
|
+
|
46
|
+
Array(options[:aps]).each do |name, opts|
|
47
|
+
if opts.is_a?(Hash)
|
48
|
+
klass = opts.delete(:class_name)
|
49
|
+
addr = opts.delete(:base_address)
|
50
|
+
if klass.nil? || addr.nil?
|
51
|
+
fail "[ARM DEBUG] Error: Must specify class_name and base_address if using 'aps' hash to define APs"
|
52
|
+
end
|
53
|
+
ap_opts = { class_name: klass, base_address: addr }.merge(opts)
|
54
|
+
else
|
55
|
+
fail "[ARM DEBUG] Error: Must specify class_name and base_address if using 'aps' hash to define APs"
|
56
|
+
end
|
57
|
+
|
58
|
+
add_ap(name, ap_opts)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Method to add additional Access Ports (MEM-AP)
|
63
|
+
#
|
64
|
+
# @param [Integer] name Short name for mem_ap that is being created
|
65
|
+
# @param [Hash] options Implemenation specific details
|
66
|
+
#
|
67
|
+
# @examples
|
68
|
+
# arm_debug.add_ap('alt_ahbapi', { class_name: 'OrigenARMDebug::MemAP', base_address: 0x02000000 })
|
69
|
+
#
|
70
|
+
def add_ap(name, options)
|
71
|
+
domain name.to_sym
|
72
|
+
ap = sub_block(name.to_sym, options)
|
73
|
+
|
74
|
+
if options[:class_name] == 'OrigenARMDebug::MemAP'
|
75
|
+
mem_aps << ap
|
76
|
+
elsif options[:class_name] == 'OrigenARMDebug::JTAGAP'
|
77
|
+
jtag_aps << ap
|
78
|
+
else
|
79
|
+
ext_aps << ap
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns an array containing all APs
|
84
|
+
def aps
|
85
|
+
mem_aps + jtag_aps + ext_aps
|
86
|
+
end
|
87
|
+
end
|
88
|
+
Driver = DAP # For legacy API compatibility
|
89
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module OrigenARMDebug
|
2
|
+
class DAPController
|
3
|
+
include Origen::Controller
|
4
|
+
include Helpers
|
5
|
+
|
6
|
+
# Returns the currently enabled DP (or the only DP if only one
|
7
|
+
# of them).
|
8
|
+
# If no dp is enabled before calling this, it will choose the
|
9
|
+
# SW_DP by default.
|
10
|
+
def dp
|
11
|
+
dps.first
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module OrigenARMDebug
|
2
|
+
# Common methods shared between the SW and JTAG DP controllers
|
3
|
+
module DPController
|
4
|
+
# Alias for the ctrlstat register
|
5
|
+
def ctrl_stat
|
6
|
+
ctrlstat
|
7
|
+
end
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
def select_ap_reg(reg)
|
11
|
+
address = reg.address & 0xFFFF_FFF0
|
12
|
+
if model.select.data != address
|
13
|
+
model.select.write!(address)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module OrigenARMDebug
|
2
|
+
# Generic helper methods shared by the various controllers
|
3
|
+
module Helpers
|
4
|
+
def extract_data(reg_or_val, options = {})
|
5
|
+
if reg_or_val.respond_to?('data')
|
6
|
+
reg_or_val.data
|
7
|
+
else
|
8
|
+
reg_or_val
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def extract_address(reg_or_val, options = {})
|
13
|
+
addr = options[:address] || options[:addr]
|
14
|
+
return addr if addr
|
15
|
+
return reg_or_val.address if reg_or_val.respond_to?('address')
|
16
|
+
return reg_or_val.addr if reg_or_val.respond_to?('addr')
|
17
|
+
fail 'No address given, if supplying a data value instead of a register object, you must supply an :address option'
|
18
|
+
end
|
19
|
+
|
20
|
+
def log(msg)
|
21
|
+
cc "[ARM Debug] #{msg}"
|
22
|
+
if block_given?
|
23
|
+
yield
|
24
|
+
cc "[ARM Debug] /#{msg}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'origen_arm_debug/jtag_dp_controller'
|
2
|
+
module OrigenARMDebug
|
3
|
+
class JTAG_DP
|
4
|
+
include Origen::Model
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
add_reg :ir, 0, size: 4
|
8
|
+
|
9
|
+
# Virtual reg used to represent all of the various 35-bit scan chains
|
10
|
+
reg :dr, 0, size: 35 do |reg|
|
11
|
+
reg.bit 34..3, :data
|
12
|
+
reg.bit 2..1, :a
|
13
|
+
reg.bit 0, :rnw
|
14
|
+
end
|
15
|
+
|
16
|
+
reg :idcode, 0b1110, access: :ro do |reg|
|
17
|
+
reg.bit 31..28, :version
|
18
|
+
reg.bit 27..12, :partno
|
19
|
+
reg.bit 11..1, :designer
|
20
|
+
reg.bit 0, :bit0, reset: 1
|
21
|
+
end
|
22
|
+
|
23
|
+
reg :ctrlstat, 0x4 do |reg|
|
24
|
+
reg.bit 31, :csyspwrupack
|
25
|
+
reg.bit 30, :csyspwrupreq
|
26
|
+
reg.bit 29, :cdbgpwrupack
|
27
|
+
reg.bit 28, :cdbgpwrupreq
|
28
|
+
reg.bit 27, :cdbgrstack
|
29
|
+
reg.bit 26, :cdbgrstreq
|
30
|
+
reg.bit 23..12, :trncnt
|
31
|
+
reg.bit 11..8, :masklane
|
32
|
+
reg.bit 5, :stickyerr
|
33
|
+
reg.bit 4, :stickycmp
|
34
|
+
reg.bit 3..2, :trnmode
|
35
|
+
reg.bit 1, :stickyorun
|
36
|
+
reg.bit 0, :orundetect
|
37
|
+
end
|
38
|
+
|
39
|
+
reg :select, 0x8 do |reg|
|
40
|
+
reg.bit 31..24, :apsel
|
41
|
+
reg.bit 7..4, :apbanksel
|
42
|
+
end
|
43
|
+
|
44
|
+
add_reg :rdbuff, 0xC, access: :ro, reset: 0
|
45
|
+
|
46
|
+
reg :abort, 0b1000, access: :wo do |reg|
|
47
|
+
reg.bit 0, :dapabort
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def select
|
52
|
+
reg(:select)
|
53
|
+
end
|
54
|
+
|
55
|
+
def abort
|
56
|
+
reg(:abort)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'origen_arm_debug/dp_controller'
|
2
|
+
module OrigenARMDebug
|
3
|
+
class JTAG_DPController
|
4
|
+
include Origen::Controller
|
5
|
+
include Helpers
|
6
|
+
include DPController
|
7
|
+
|
8
|
+
def write_register(reg, options = {})
|
9
|
+
unless reg.writable?
|
10
|
+
fail "The :#{reg.name} register is not writeable!"
|
11
|
+
end
|
12
|
+
|
13
|
+
# DP register write
|
14
|
+
if reg.owner == model
|
15
|
+
# Don't log this one, not really a DP reg and will be included
|
16
|
+
# in the JTAG driver log anyway
|
17
|
+
if reg.name == :ir
|
18
|
+
dut.jtag.write_ir(reg)
|
19
|
+
else
|
20
|
+
|
21
|
+
log "Write JTAG-DP register #{reg.name.to_s.upcase}: #{reg.data.to_hex}" do
|
22
|
+
if reg.name == :abort
|
23
|
+
ir.write!(reg.offset)
|
24
|
+
dr.reset
|
25
|
+
dr.overlay(nil)
|
26
|
+
dr[2..0].write(0)
|
27
|
+
dr[34..3].copy_all(reg)
|
28
|
+
dut.jtag.write_dr(dr)
|
29
|
+
|
30
|
+
# DPACC
|
31
|
+
elsif reg.name == :ctrlstat || reg.name == :select
|
32
|
+
dr.reset
|
33
|
+
dr.overlay(nil)
|
34
|
+
dr[0].write(0)
|
35
|
+
dr[2..1].write(reg.offset >> 2)
|
36
|
+
dr[34..3].copy_all(reg)
|
37
|
+
ir.write!(0b1010)
|
38
|
+
dut.jtag.write_dr(dr)
|
39
|
+
|
40
|
+
else
|
41
|
+
fail "Can't write #{reg.name}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# AP register write
|
47
|
+
else
|
48
|
+
|
49
|
+
unless reg.owner.is_a?(AP)
|
50
|
+
fail 'The JTAG-DP can only write to DP or AP registers!'
|
51
|
+
end
|
52
|
+
|
53
|
+
select_ap_reg(reg)
|
54
|
+
dr.reset
|
55
|
+
dr.overlay(nil)
|
56
|
+
dr[0].write(0)
|
57
|
+
dr[2..1].write(reg.offset >> 2)
|
58
|
+
dr[34..3].copy_all(reg)
|
59
|
+
ir.write!(0b1011)
|
60
|
+
dut.jtag.write_dr(dr, options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def read_register(reg, options = {})
|
65
|
+
unless reg.readable?
|
66
|
+
fail "The :#{reg.name} register is not readable!"
|
67
|
+
end
|
68
|
+
|
69
|
+
if reg.owner == model
|
70
|
+
# Don't log this one, not really a DP reg and will be included
|
71
|
+
# in the JTAG driver log anyway
|
72
|
+
if reg.name == :ir
|
73
|
+
dut.jtag.read_ir(reg)
|
74
|
+
else
|
75
|
+
|
76
|
+
log "Read JTAG-DP register #{reg.name.to_s.upcase}: #{Origen::Utility.read_hex(reg)}" do
|
77
|
+
if reg.name == :idcode
|
78
|
+
ir.write!(reg.offset)
|
79
|
+
dut.jtag.read_dr(reg)
|
80
|
+
|
81
|
+
# DPACC
|
82
|
+
elsif reg.name == :ctrlstat || reg.name == :select || reg.name == :rdbuff
|
83
|
+
|
84
|
+
# Part 1 - Request read from DP-Register by writing to DPACC with RnW=1
|
85
|
+
dr.reset
|
86
|
+
dr.overlay(nil)
|
87
|
+
dr[0].write(1)
|
88
|
+
dr[2..1].write(reg.offset >> 2)
|
89
|
+
dr[34..3].write(0)
|
90
|
+
ir.write!(0b1010)
|
91
|
+
dut.jtag.write_dr(dr)
|
92
|
+
|
93
|
+
# Part 2 - Now read real data from RDBUFF (DP-Reg)
|
94
|
+
dr.reset
|
95
|
+
dr.overlay(nil)
|
96
|
+
dr[0].write(1)
|
97
|
+
dr[2..1].write(rdbuff.offset >> 2)
|
98
|
+
dr[34..3].copy_all(reg)
|
99
|
+
dut.jtag.read_dr(dr, options)
|
100
|
+
|
101
|
+
else
|
102
|
+
fail "Can't read #{reg.name}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# AP register read
|
108
|
+
else
|
109
|
+
unless reg.owner.is_a?(AP)
|
110
|
+
fail 'The JTAG-DP can only write to DP or AP registers!'
|
111
|
+
end
|
112
|
+
|
113
|
+
# Part 1 - Request read from AP-Register by writing to APACC with RnW=1
|
114
|
+
select_ap_reg(reg)
|
115
|
+
dr.reset
|
116
|
+
dr.overlay(nil)
|
117
|
+
dr[0].write(1)
|
118
|
+
dr[2..1].write(reg.offset >> 2)
|
119
|
+
dr[34..3].write(0)
|
120
|
+
ir.write!(0b1011)
|
121
|
+
dut.jtag.write_dr(dr)
|
122
|
+
|
123
|
+
# Calling AP should provide any delay parameter for wait states between AP read request
|
124
|
+
# and when the data is available at the RDBUFF DP-Reg
|
125
|
+
if options[:apacc_wait_states]
|
126
|
+
options[:apacc_wait_states].cycles
|
127
|
+
end
|
128
|
+
|
129
|
+
# Part 2 - Now read real data from RDBUFF (DP-Reg)
|
130
|
+
dr.reset
|
131
|
+
dr.overlay(nil)
|
132
|
+
dr[0].write(1)
|
133
|
+
dr[2..1].write(rdbuff.offset >> 2)
|
134
|
+
dr[34..3].copy_all(reg)
|
135
|
+
ir.write!(0b1010)
|
136
|
+
dut.jtag.read_dr(dr, options)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|