origen_arm_debug 0.4.0 → 0.4.1
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.
- 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
|