origen_arm_debug 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/config/version.rb +1 -1
- metadata +1 -7
- data/lib/origen_arm_debug/abs_if_jtag.rb +0 -255
- data/lib/origen_arm_debug/abs_if_swd.rb +0 -269
- data/lib/origen_arm_debug/core_access_M4.rb +0 -0
- data/lib/origen_arm_debug/jtag_ap.rb +0 -0
- data/lib/origen_arm_debug/jtag_dp.rb +0 -0
- data/lib/origen_arm_debug/sw_dp.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc238d6a6c1968e247feaf3a6b57c4b6222246e8
|
4
|
+
data.tar.gz: 79ee7b36c4af7d4357fa541937b429a9b596525f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f13c97b08406af4d1748cea9ca1ce365cc910a14689f631aa9fc0156e4a454516978e5c4be3a1cc7579021b3df1c55624617ecc06fd9e59bba28fee0ea4a2707
|
7
|
+
data.tar.gz: b061fba3f3ccad2c04cc8b94b0ac8b633aea8a25ac3fc2183cec9f802e110c7829c2990edc71e4c298b8066afaec33872230080bf3c32db356e8f5212ef8d7e1
|
data/config/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: origen_arm_debug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ronnie Lajaunie
|
@@ -80,17 +80,11 @@ files:
|
|
80
80
|
- config/users.rb
|
81
81
|
- config/version.rb
|
82
82
|
- lib/origen_arm_debug.rb
|
83
|
-
- lib/origen_arm_debug/abs_if_jtag.rb
|
84
|
-
- lib/origen_arm_debug/abs_if_swd.rb
|
85
|
-
- lib/origen_arm_debug/core_access_M4.rb
|
86
83
|
- lib/origen_arm_debug/driver.rb
|
87
84
|
- lib/origen_arm_debug/dut.rb
|
88
85
|
- lib/origen_arm_debug/dut_jtag.rb
|
89
86
|
- lib/origen_arm_debug/dut_swd.rb
|
90
|
-
- lib/origen_arm_debug/jtag_ap.rb
|
91
|
-
- lib/origen_arm_debug/jtag_dp.rb
|
92
87
|
- lib/origen_arm_debug/mem_ap.rb
|
93
|
-
- lib/origen_arm_debug/sw_dp.rb
|
94
88
|
- lib/origen_arm_debug/swj_dp.rb
|
95
89
|
- pattern/read_write_reg.rb
|
96
90
|
- templates/web/index.md.erb
|
@@ -1,255 +0,0 @@
|
|
1
|
-
module OrigenARMDebug
|
2
|
-
class ABSIF_JTAG
|
3
|
-
JTAGC_ARM_ABORT = 0b1000
|
4
|
-
JTAGC_ARM_DPACC = 0b1010
|
5
|
-
JTAGC_ARM_APACC = 0b1011
|
6
|
-
JTAGC_ARM_IDCODE = 0b1110
|
7
|
-
JTAGC_ARM_BYPASS = 0b1111
|
8
|
-
|
9
|
-
attr_reader :owner
|
10
|
-
attr_accessor :write_ap_dly
|
11
|
-
attr_accessor :acc_access_dly
|
12
|
-
|
13
|
-
def initialize(owner, options = {})
|
14
|
-
@owner = owner
|
15
|
-
|
16
|
-
@write_ap_dly = 8
|
17
|
-
@acc_access_dly = 7
|
18
|
-
|
19
|
-
@current_apaddr = 0x00000000
|
20
|
-
end
|
21
|
-
|
22
|
-
#-------------------------------------
|
23
|
-
# Read tasks - high level
|
24
|
-
#-------------------------------------
|
25
|
-
def R_dp(name, rdata, options = {})
|
26
|
-
options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
|
27
|
-
read_dp(name, rdata, options)
|
28
|
-
end
|
29
|
-
|
30
|
-
def RE_dp(name, edata, options = {})
|
31
|
-
options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
|
32
|
-
actual = edata
|
33
|
-
R_dp(name, actual, options)
|
34
|
-
|
35
|
-
cc "ABS-IF: RE-DP: #{name} = 0x#{actual.to_s(16).rjust(8, '0')}, "\
|
36
|
-
"expected = 0x#{edata.to_s(16).rjust(8, '0')}, "\
|
37
|
-
"mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
|
38
|
-
end
|
39
|
-
|
40
|
-
def R_ap(addr, rdata, options = {})
|
41
|
-
options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
|
42
|
-
read_ap(addr, rdata, options)
|
43
|
-
end
|
44
|
-
|
45
|
-
def RE_ap(addr, edata, options = {})
|
46
|
-
options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
|
47
|
-
actual = edata
|
48
|
-
R_ap(addr, actual, options)
|
49
|
-
|
50
|
-
cc "ABS-IF: RE-AP: addr = 0x#{addr.to_s(16).rjust(8, '0')}, "\
|
51
|
-
"actual = 0x#{actual.to_s(16).rjust(8, '0')}, "\
|
52
|
-
"expected = 0x#{edata.to_s(16).rjust(8, '0')}, "\
|
53
|
-
"mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
|
54
|
-
end
|
55
|
-
|
56
|
-
def WAIT_RE_ap(addr, edata, options = {})
|
57
|
-
options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
|
58
|
-
actual = edata
|
59
|
-
R_ap(addr, actual, options)
|
60
|
-
|
61
|
-
cc "ABS-IF: WAIT_RE-AP: addr = 0x#{addr.to_s(16).rjust(8, '0')}, "\
|
62
|
-
"actual = 0x#{actual.to_s(16).rjust(8, '0')}, "\
|
63
|
-
"expected = 0x#{edata.to_s(16).rjust(8, '0')}, "\
|
64
|
-
"mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
|
65
|
-
end
|
66
|
-
|
67
|
-
#-------------------------------------
|
68
|
-
# Write tasks - high level
|
69
|
-
#-------------------------------------
|
70
|
-
def W_dp(name, wdata, options = {})
|
71
|
-
options = { w_attempts: 1 }.merge(options)
|
72
|
-
write_dp(name, wdata, options)
|
73
|
-
end
|
74
|
-
|
75
|
-
def WR_dp(name, wdata, options = {})
|
76
|
-
options = { edata: 0x00000000, mask: 0xffffffff, w_attempts: 1, r_attempts: 1 }.merge(options)
|
77
|
-
actual = options[:edata] & options[:mask]
|
78
|
-
|
79
|
-
W_dp(name, wdata, options)
|
80
|
-
R_dp(name, actual, options)
|
81
|
-
|
82
|
-
cc "ABS-IF: WR-DP: #{name} write = 0x#{wdata.to_s(16).rjust(8, '0')}, "\
|
83
|
-
"read = 0x#{actual.to_s(16).rjust(8, '0')}, "\
|
84
|
-
"expected = 0x#{options[:edata].to_s(16).rjust(8, '0')}, "\
|
85
|
-
"mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
|
86
|
-
end
|
87
|
-
|
88
|
-
def W_ap(addr, wdata, options = {})
|
89
|
-
options = { w_attempts: 1 }.merge(options)
|
90
|
-
write_ap(addr, wdata, options)
|
91
|
-
end
|
92
|
-
|
93
|
-
def WR_ap(addr, wdata, options = {})
|
94
|
-
options = { edata: 0x00000000, mask: 0xffffffff, w_attempts: 1, r_attempts: 1 }.merge(options)
|
95
|
-
actual = wdata & options[:mask]
|
96
|
-
|
97
|
-
W_ap(addr, wdata, options)
|
98
|
-
R_ap(addr, actual, options)
|
99
|
-
|
100
|
-
cc "ABS-IF: WR-AP: addr = 0x#{addr.to_s(16).rjust(8, '0')}, "\
|
101
|
-
"write = 0x#{wdata.to_s(16).rjust(8, '0')}, "\
|
102
|
-
"read = 0x#{actual.to_s(16).rjust(8, '0')}, "\
|
103
|
-
"expected = 0x#{options[:edata].to_s(16).rjust(8, '0')}, "\
|
104
|
-
"mask = 0x#{options[:mask].to_s(16).rjust(8, '0')}"
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
#-------------------------------------
|
110
|
-
# Implementation of virtual functions
|
111
|
-
#-------------------------------------
|
112
|
-
def read_dp(name, rdata, options = {})
|
113
|
-
options = { r_attempts: 1 }.merge(options)
|
114
|
-
|
115
|
-
set_ir(name) if name == 'IDCODE'
|
116
|
-
case name
|
117
|
-
when 'ABORT' then puts "#{name} JTAG-DP register is write-only"
|
118
|
-
when 'CTRL/STAT' then dpacc_access(name, 1, random, rdata, options)
|
119
|
-
when 'SELECT' then dpacc_access(name, 1, random, rdata, options)
|
120
|
-
when 'RDBUFF' then dpacc_access(name, 1, random, rdata, options)
|
121
|
-
when 'IDCODE' then owner.owner.jtag.write_dr(random, size: 32) # need to make parameterized!!!
|
122
|
-
else
|
123
|
-
puts "Unknown JTAG-DP register name #{name}"
|
124
|
-
end
|
125
|
-
if name != 'IDCODE' && name != 'RDBUFF'
|
126
|
-
read_dp('RDBUFF', rdata, options)
|
127
|
-
end
|
128
|
-
cc "ABS-IF: R-DP: #{name}=0x" + rdata.to_s(16).rjust(8, '0')
|
129
|
-
end
|
130
|
-
|
131
|
-
def write_dp(name, wdata, options = {})
|
132
|
-
options = { w_attempts: 1 }.merge(options)
|
133
|
-
|
134
|
-
if name == 'ABORT' && wdata != 0x00000001
|
135
|
-
puts "#{name} register must only ever be written with the value 0x00000001"
|
136
|
-
end
|
137
|
-
case name
|
138
|
-
when 'ABORT' then dpacc_access(name, 0, wdata, random, options)
|
139
|
-
when 'CTRL/STAT' then dpacc_access(name, 0, wdata, random, options)
|
140
|
-
when 'SELECT' then dpacc_access(name, 0, wdata, random, options)
|
141
|
-
when 'RDBUFF' then puts "#{name} JTAG-DP register is read-only"
|
142
|
-
when 'IDCODE' then puts "#{name} JTAG-DP register is read-only"
|
143
|
-
else; puts "Unknown JTAG-DP register name #{name}"
|
144
|
-
end
|
145
|
-
cc "ABS-IF: W-DP: #{name} = 0x#{wdata.to_s(16).rjust(8, '0')}"
|
146
|
-
end
|
147
|
-
|
148
|
-
def read_ap(addr, rdata, options = {});
|
149
|
-
options = { r_attempts: 1 }.merge(options)
|
150
|
-
|
151
|
-
apacc_access(addr, 1, random, rdata, options)
|
152
|
-
read_dp('RDBUFF', rdata, options)
|
153
|
-
|
154
|
-
cc "ABS-IF: R-AP: addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
155
|
-
"rdata=0x#{rdata.to_s(16).rjust(8, '0')}"
|
156
|
-
end
|
157
|
-
|
158
|
-
def write_ap(addr, wdata, options = {});
|
159
|
-
options = { w_attempts: 1 }.merge(options)
|
160
|
-
|
161
|
-
rdata = 0x00000000
|
162
|
-
apacc_access(addr, 0, wdata, rdata, options);
|
163
|
-
$tester.cycle(repeat: @write_ap_dly)
|
164
|
-
|
165
|
-
cc "ABS-IF: W-AP: addr=0x#{addr.to_s(16).rjust(8, '0')}, "\
|
166
|
-
"wdata=0x#{wdata.to_s(16).rjust(8, '0')}"
|
167
|
-
end
|
168
|
-
|
169
|
-
#-------------------------------------
|
170
|
-
# lower level helper tasks
|
171
|
-
#-------------------------------------
|
172
|
-
def set_ir(name)
|
173
|
-
new_ir = get_ir_code(name);
|
174
|
-
owner.owner.jtag.write_ir(new_ir, size: 4) # need to make parameterized!!!
|
175
|
-
end
|
176
|
-
|
177
|
-
def acc_access(name, addr, rwb, wdata, rdata, attempts, options = {});
|
178
|
-
set_ir(name);
|
179
|
-
concat_data = (wdata << 3) | (addr << 1) | rwb
|
180
|
-
attempts.times do
|
181
|
-
if name == 'RDBUFF'
|
182
|
-
r = $dut.reg(:dap)
|
183
|
-
if options[:r_mask] == 'store'
|
184
|
-
r.bits(3..34).store
|
185
|
-
elsif options.key?(:compare_data)
|
186
|
-
r.bits(3..34).data = options[:compare_data]
|
187
|
-
end
|
188
|
-
options = options.merge(size: r.size)
|
189
|
-
owner.owner.jtag.read_dr(r, options) # need to make parameterized!!!
|
190
|
-
else
|
191
|
-
options = options.merge(size: 35)
|
192
|
-
owner.owner.jtag.write_dr(concat_data, options) # need to make parameterized!!!
|
193
|
-
end
|
194
|
-
end
|
195
|
-
$tester.cycle(repeat: @acc_access_dly)
|
196
|
-
end
|
197
|
-
|
198
|
-
def dpacc_access(name, rwb, wdata, rdata, options = {});
|
199
|
-
attempts = options[:r_attempts].nil? ? (options[:w_attempts].nil? ? 1 : options[:w_attempts]) : options[:r_attempts]
|
200
|
-
addr = get_dp_addr(name);
|
201
|
-
addr_3_2 = (addr & 0x0C) >> 2
|
202
|
-
acc_access(name, addr_3_2, rwb, wdata, rdata, attempts, options);
|
203
|
-
end
|
204
|
-
|
205
|
-
def set_apselect(addr);
|
206
|
-
_random = random
|
207
|
-
addr = addr & 0xff0000f0;
|
208
|
-
concat_data = (addr & 0xff000000) | (_random & 0x00ffff00) | (addr & 0x000000f0) | (_random & 0x0000000f)
|
209
|
-
if (addr != @current_apaddr)
|
210
|
-
write_dp('SELECT', concat_data);
|
211
|
-
end
|
212
|
-
@current_apaddr = addr;
|
213
|
-
end
|
214
|
-
|
215
|
-
def apacc_access(addr, rwb, wdata, rdata, options = {});
|
216
|
-
attempts = options[:r_attempts].nil? ? (options[:w_attempts].nil? ? 1 : options[:w_attempts]) : options[:r_attempts]
|
217
|
-
set_apselect(addr);
|
218
|
-
addr_3_2 = (addr & 0x0000000C) >> 2
|
219
|
-
acc_access('APACC', addr_3_2, rwb, wdata, rdata, attempts, options);
|
220
|
-
end
|
221
|
-
|
222
|
-
def get_dp_addr(name);
|
223
|
-
case name
|
224
|
-
when 'IDCODE' then return 0xF
|
225
|
-
when 'CTRL/STAT' then return 0x4
|
226
|
-
when 'SELECT' then return 0x8
|
227
|
-
when 'RDBUFF' then return 0xC
|
228
|
-
when 'ABORT' then return 0x0
|
229
|
-
when 'WCR' then puts "#{name} is a SW-DP only register"
|
230
|
-
when 'RESEND' then puts "#{name} is a SW-DP only register"
|
231
|
-
else; puts "Unknown JTAG-DP register name: #{name}"
|
232
|
-
end
|
233
|
-
0
|
234
|
-
end
|
235
|
-
|
236
|
-
def get_ir_code(name);
|
237
|
-
case name
|
238
|
-
when 'ABORT' then return JTAGC_ARM_ABORT
|
239
|
-
when 'CTRL/STAT' then return JTAGC_ARM_DPACC
|
240
|
-
when 'SELECT' then return JTAGC_ARM_DPACC
|
241
|
-
when 'RDBUFF' then return JTAGC_ARM_DPACC
|
242
|
-
when 'APACC' then return JTAGC_ARM_APACC
|
243
|
-
when 'IDCODE' then return JTAGC_ARM_IDCODE
|
244
|
-
when 'RESEND' then puts "#{name} is a SW-DP only register"
|
245
|
-
else; puts "Unknown JTAG-DP register name: #{name}"
|
246
|
-
end
|
247
|
-
0
|
248
|
-
end
|
249
|
-
|
250
|
-
def random
|
251
|
-
# rand(4294967295) # random 32-bit integer
|
252
|
-
0x01234567
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
@@ -1,269 +0,0 @@
|
|
1
|
-
# To use this driver the $soc model must define the following pins (an alias is fine):
|
2
|
-
# :swd_clk
|
3
|
-
# :swd_dio
|
4
|
-
#
|
5
|
-
# API methods:
|
6
|
-
# R_dp - debug register read - just a dummy function in origen
|
7
|
-
# RE_dp - debug register read/expect - expect compares not implemented
|
8
|
-
# R_ap - read a specific address - just a dummy function in origen
|
9
|
-
# W_dp - debug register write
|
10
|
-
# W_ap - write a specific address
|
11
|
-
# WR_ap - write a specific address, then read back
|
12
|
-
|
13
|
-
module OrigenARMDebug
|
14
|
-
class ABSIF_SWD
|
15
|
-
attr_reader :owner
|
16
|
-
include Origen::Registers
|
17
|
-
|
18
|
-
def initialize(owner, options = {})
|
19
|
-
@current_apaddr = 0
|
20
|
-
@orundetect = 0
|
21
|
-
@owner = owner
|
22
|
-
end
|
23
|
-
|
24
|
-
# Highest level implementation of API - abstracted from 'read' and 'write' for future merging with JTAG debug
|
25
|
-
def R_dp(name, rdata, options = {})
|
26
|
-
cc 'Reading ' + name
|
27
|
-
read_dp(name, options)
|
28
|
-
end
|
29
|
-
|
30
|
-
def RE_dp(name, edata, options = {})
|
31
|
-
R_dp(name, edata, options)
|
32
|
-
end
|
33
|
-
|
34
|
-
def R_ap(addr, rdata, options = {})
|
35
|
-
cc 'Reading address ' + addr.to_s(16)
|
36
|
-
read_ap(addr, options)
|
37
|
-
end
|
38
|
-
|
39
|
-
def WAIT_RE_ap(addr, edata, options = {})
|
40
|
-
options = { mask: 0xffffffff, r_attempts: 1 }.merge(options)
|
41
|
-
|
42
|
-
# just assume that it always passes
|
43
|
-
actual = edata
|
44
|
-
|
45
|
-
R_ap(addr, actual, options)
|
46
|
-
|
47
|
-
cc "ABS-IF: WAIT_RE-AP: addr = 0x#{addr.to_s(16)}, "\
|
48
|
-
"actual = 0x#{actual.to_s(16)}, "\
|
49
|
-
"expected = 0x#{edata.to_s(16)}, "\
|
50
|
-
"mask = 0x#{options[:mask].to_s(16)}"
|
51
|
-
end
|
52
|
-
|
53
|
-
def W_dp(name, wdata, options = {})
|
54
|
-
cc 'Writing 0x' + wdata.to_s(16) + ' to ' + name
|
55
|
-
write_dp(name, wdata, options)
|
56
|
-
end
|
57
|
-
|
58
|
-
def WR_dp(name, wdata, options = {})
|
59
|
-
options = { edata: 0x00000000, mask: 0xffffffff,
|
60
|
-
w_attempts: 1, r_attempts: 1
|
61
|
-
}.merge(options)
|
62
|
-
|
63
|
-
# just assume that it always passes
|
64
|
-
actual = options[:edata] & options[:mask]
|
65
|
-
|
66
|
-
W_dp(name, wdata, options)
|
67
|
-
R_dp(name, actual, options)
|
68
|
-
|
69
|
-
cc "ABS-IF: WR-DP: #{name} write = 0x#{wdata.to_s(16)}, "\
|
70
|
-
"read = 0x#{actual.to_s(16)}, "\
|
71
|
-
"expected = 0x#{options[:edata].to_s(16)}, "\
|
72
|
-
"mask = 0x#{options[:mask].to_s(16)}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def W_ap(addr, wdata, options = {})
|
76
|
-
options = { w_attempts: 1 }.merge(options)
|
77
|
-
cc 'Writing 0x' + wdata.to_s(16) + ' to address 0x' + addr.to_s(16)
|
78
|
-
write_ap(addr, wdata, options)
|
79
|
-
end
|
80
|
-
|
81
|
-
def WR_ap(addr, wdata, options = {})
|
82
|
-
options = { edata: 0x00000000, mask: 0xffffffff,
|
83
|
-
w_attempts: 1, r_attempts: 1
|
84
|
-
}.merge(options)
|
85
|
-
|
86
|
-
# just assume that it always passes
|
87
|
-
actual = wdata & options[:mask]
|
88
|
-
W_ap(addr, wdata, options)
|
89
|
-
options.delete(:w_delay) if options.key?(:w_delay)
|
90
|
-
R_ap(addr, actual, options)
|
91
|
-
|
92
|
-
cc "ABS-IF: WR-AP: addr = 0x#{addr.to_s(16)}, "\
|
93
|
-
"write = 0x#{wdata.to_s(16)}, "\
|
94
|
-
"read = 0x#{actual.to_s(16)}, "\
|
95
|
-
"expected = 0x#{options[:edata].to_s(16)}, "\
|
96
|
-
"mask = 0x#{options[:mask].to_s(16)}"
|
97
|
-
end
|
98
|
-
|
99
|
-
# SWD-specific functions
|
100
|
-
def read_dp(name, options = {})
|
101
|
-
case name
|
102
|
-
when 'IDCODE' then dpacc_access(name, 1, 0x55555555, options)
|
103
|
-
when 'ABORT' then cc 'Write only register!'
|
104
|
-
when 'CTRL/STAT' then dpacc_access(name, 1, 0x55555555, options)
|
105
|
-
when 'SELECT' then cc 'Write only register!'
|
106
|
-
when 'RDBUFF' then dpacc_access(name, 1, 0x55555555, options)
|
107
|
-
when 'WCR' then dpacc_access(name, 1, 0x55555555, options)
|
108
|
-
when 'RESEND' then dpacc_access(name, 1, 0x55555555, options)
|
109
|
-
else cc 'Unknown SW-DP register name'
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def write_dp(name, wdata, options = {})
|
114
|
-
case name
|
115
|
-
when 'IDCODE' then cc 'SW-DP register is read-only'
|
116
|
-
when 'ABORT' then dpacc_access(name, 0, wdata, options)
|
117
|
-
when 'CTRL/STAT' then dpacc_access(name, 0, wdata, options)
|
118
|
-
when 'SELECT' then dpacc_access(name, 0, wdata, options)
|
119
|
-
when 'RDBUFF' then cc 'SW-DP register is read-only'
|
120
|
-
when 'WCR' then dpacc_access(name, 0, wdata, options)
|
121
|
-
when 'RESEND' then cc 'SW-DP register is read-only'
|
122
|
-
else cc 'Unknown SW-DP register name'
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def write_ap(addr, wdata, options = {})
|
127
|
-
apacc_access(addr, 0, wdata, options)
|
128
|
-
end
|
129
|
-
|
130
|
-
def read_ap(addr, options = {})
|
131
|
-
# Create another copy of options with select keys removed. This first read is junk so we do not want to
|
132
|
-
# store it or compare it.
|
133
|
-
junk_options = options.clone.delete_if do |key, val|
|
134
|
-
(key.eql?(:r_mask) && val.eql?('store')) || key.eql?(:compare_data)
|
135
|
-
end
|
136
|
-
# pass junk options onto the first apacc access
|
137
|
-
apacc_access(addr, 1, 0x55555555, junk_options)
|
138
|
-
read_dp('RDBUFF', options) # This is the real data
|
139
|
-
end
|
140
|
-
|
141
|
-
# Low-level access functions
|
142
|
-
def dpacc_access(name, rwb, wdata, options = {})
|
143
|
-
addr = get_dp_addr(name)
|
144
|
-
if (name == 'CTRL/STAT')
|
145
|
-
cc 'CTRL/STAT'
|
146
|
-
set_apselect(@current_apaddr & 0xFFFFFFFE, options)
|
147
|
-
end
|
148
|
-
if (name == 'WCR')
|
149
|
-
cc 'NOT IMPLEMENTED'
|
150
|
-
end
|
151
|
-
|
152
|
-
acc_access(addr, rwb, 0, wdata, options)
|
153
|
-
|
154
|
-
if (name == 'WCR')
|
155
|
-
cc 'NOT IMPLEMENTED'
|
156
|
-
end
|
157
|
-
if (name == 'CTRL/STAT')
|
158
|
-
@orundetect = wdata & 0x1
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def apacc_access(addr, rwb, wdata, options = {})
|
163
|
-
set_apselect((addr & 0xFFFFFFFE) | (@current_apaddr & 1), options)
|
164
|
-
options.delete(:w_delay) if options.key?(:w_delay)
|
165
|
-
acc_access((addr & 0xC), rwb, 1, wdata, options)
|
166
|
-
end
|
167
|
-
|
168
|
-
def get_dp_addr(name)
|
169
|
-
case name
|
170
|
-
when 'IDCODE' then return 0x0
|
171
|
-
when 'ABORT' then return 0x0
|
172
|
-
when 'CTRL/STAT' then return 0x4
|
173
|
-
when 'WCR' then return 0x4
|
174
|
-
when 'RESEND' then return 0x8
|
175
|
-
when 'SELECT' then return 0x8
|
176
|
-
when 'RDBUFF' then return 0xC
|
177
|
-
else cc 'Unknown SW-DP register name'
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
def acc_access(address, rwb, ap_dp, wdata, options = {})
|
182
|
-
start = 1
|
183
|
-
apndp = ap_dp
|
184
|
-
rnw = rwb
|
185
|
-
addr = address >> 2
|
186
|
-
parity_pr = ap_dp ^ rwb ^ (addr >> 3) ^ (addr >> 2) & (0x01) ^ (addr >> 1) & (0x01) ^ addr & 0x01
|
187
|
-
trn = 0
|
188
|
-
data = wdata
|
189
|
-
require_dp = @orundetect
|
190
|
-
line_reset = 0
|
191
|
-
stop = 0
|
192
|
-
park = 1
|
193
|
-
|
194
|
-
cc 'SWD transaction'
|
195
|
-
cc 'Packet Request Phase'
|
196
|
-
|
197
|
-
annotate 'Send Start Bit'
|
198
|
-
owner.owner.swd.send_data(start, 1)
|
199
|
-
cc('Send APnDP Bit (DP or AP Access Register Bit)', prefix: true)
|
200
|
-
owner.owner.swd.send_data(apndp, 1)
|
201
|
-
c2 'Send RnW Bit (read or write bit)'
|
202
|
-
owner.owner.swd.send_data(rnw, 1)
|
203
|
-
c2 'Send Address Bits (2 bits)'
|
204
|
-
owner.owner.swd.send_data(addr, 2)
|
205
|
-
c2 'Send Parity Bit'
|
206
|
-
owner.owner.swd.send_data(parity_pr, 1)
|
207
|
-
c2 'Send Stop Bit'
|
208
|
-
owner.owner.swd.send_data(stop, 1)
|
209
|
-
c2 'Send Park Bit'
|
210
|
-
owner.owner.swd.send_data(park, 1)
|
211
|
-
|
212
|
-
cc 'Acknowledge Response phase'
|
213
|
-
owner.owner.swd.send_data(0xf, trn + 1)
|
214
|
-
owner.owner.swd.get_data (3)
|
215
|
-
cc 'Read/Write Data Phase'
|
216
|
-
if (rwb == 1)
|
217
|
-
cc 'Read'
|
218
|
-
if options[:r_mask] == 'store'
|
219
|
-
owner.owner.pin(:swd_dio).store
|
220
|
-
end
|
221
|
-
cc 'SWD 32-Bit Read Data Start'
|
222
|
-
owner.owner.swd.get_data(32, options)
|
223
|
-
cc 'SWD 32-Bit Read Data End'
|
224
|
-
cc 'Get Read Parity Bit'
|
225
|
-
owner.owner.swd.get_data(1)
|
226
|
-
cc 'Send Read ACK bits'
|
227
|
-
owner.owner.swd.send_data(0xf, trn + 1)
|
228
|
-
else
|
229
|
-
cc 'Write'
|
230
|
-
cc 'Send ACK Bits'
|
231
|
-
owner.owner.swd.send_data(0xf, trn + 1)
|
232
|
-
cc 'SWD 32-Bit Write Start'
|
233
|
-
owner.owner.swd.send_data(data, 32, options)
|
234
|
-
cc 'SWD 32-Bit Write End'
|
235
|
-
cc 'Send Write Parity Bit'
|
236
|
-
owner.owner.swd.send_data(swd_xor_calc(32, data), 1)
|
237
|
-
end
|
238
|
-
|
239
|
-
if options.key?(:w_delay)
|
240
|
-
cc "SWD DIO to 0 for #{options[:w_delay]} cycles"
|
241
|
-
owner.owner.swd.swd_dio_to_0(options[:w_delay])
|
242
|
-
else
|
243
|
-
cc 'SWD DIO to 0 for 10 cycles'
|
244
|
-
owner.owner.swd.swd_dio_to_0(10)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
def set_apselect(addr, options = {})
|
249
|
-
addr &= 0xff0000f1
|
250
|
-
cc "SET_APSelect: addr = 0x#{addr.to_s(16)} "
|
251
|
-
|
252
|
-
if (addr != @current_apaddr)
|
253
|
-
cc 'SET_APSelect: write_dp SELECT'
|
254
|
-
write_dp('SELECT', addr & 0xff0000ff, options)
|
255
|
-
end
|
256
|
-
|
257
|
-
@current_apaddr = addr
|
258
|
-
end
|
259
|
-
|
260
|
-
# Calculate exclusive OR
|
261
|
-
def swd_xor_calc(size, number)
|
262
|
-
xor = 0
|
263
|
-
size.times do |bit|
|
264
|
-
xor ^= (number >> bit) & 0x01
|
265
|
-
end
|
266
|
-
xor
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|