@@ -126,6 +126,15 @@ def idr(self):
126126 """! @brief DPIDR instance containing values read from the DP IDR register."""
127127 return self ._idr
128128
129+ def _get_protocol (self , protocol ):
130+ # Convert protocol from setting if not passed as parameter.
131+ if protocol is None :
132+ protocol_name = self ._session .options .get ('dap_protocol' ).strip ().lower ()
133+ protocol = DebugProbe .PROTOCOL_NAME_MAP [protocol_name ]
134+ if protocol not in self ._probe .supported_wire_protocols :
135+ raise exceptions .DebugError ("requested wire protocol %s not supported by the debug probe" % protocol .name )
136+ return protocol
137+
129138 def connect (self , protocol = None ):
130139 """! @brief Establish a connection to the DP.
131140
@@ -138,27 +147,52 @@ def connect(self, protocol=None):
138147 @exception DebugError
139148 @exception TransferError
140149 """
141- protocol_name = self ._session .options .get ('dap_protocol' ).strip ().lower ()
142- send_swj = self ._session .options .get ('dap_swj_enable' ) \
143- and (DebugProbe .Capability .SWJ_SEQUENCE in self ._probe .capabilities )
144- use_dormant = self ._session .options .get ('dap_swj_use_dormant' )
150+ try :
151+ self ._probe .lock ()
145152
146- # Convert protocol from setting if not passed as parameter.
147- if protocol is None :
148- protocol = DebugProbe .PROTOCOL_NAME_MAP [protocol_name ]
149- if protocol not in self ._probe .supported_wire_protocols :
150- raise exceptions .DebugError ("requested wire protocol %s not supported by the debug probe" % protocol .name )
151- if protocol != DebugProbe .Protocol .DEFAULT :
153+ # Determine the requested wire protocol.
154+ protocol = self ._get_protocol (protocol )
155+
156+ # If this is not None then the probe is already connected.
157+ current_wire_protocol = self ._probe .wire_protocol
158+ already_connected = current_wire_protocol is not None
159+
160+ if already_connected :
161+ self ._check_protocol (current_wire_protocol , protocol )
162+ else :
163+ self ._connect_probe (protocol )
164+
165+ protocol = self ._probe .wire_protocol
166+ self ._connect_dp (protocol )
167+ finally :
168+ self ._probe .unlock ()
169+
170+ def _check_protocol (self , current_wire_protocol , protocol ):
171+ # Warn about mismatched current and requested wire protocols.
172+ if (protocol is not current_wire_protocol ) and (protocol is not DebugProbe .Protocol .DEFAULT ):
173+ LOG .warning ("Cannot use %s; already connected with %s" , protocol .name , current_wire_protocol .name )
174+ else :
175+ LOG .debug ("Already connected with %s" , current_wire_protocol .name )
176+
177+ def _connect_probe (self , protocol ):
178+ # Debug log with the selected protocol.
179+ if protocol is not DebugProbe .Protocol .DEFAULT :
152180 LOG .debug ("Using %s wire protocol" , protocol .name )
153-
181+
154182 # Connect using the selected protocol.
155183 self ._probe .connect (protocol )
156184
157185 # Log the actual protocol if selected was default.
158- if protocol == DebugProbe .Protocol .DEFAULT :
186+ if protocol is DebugProbe .Protocol .DEFAULT :
159187 protocol = self ._probe .wire_protocol
160188 LOG .debug ("Default wire protocol selected; using %s" , protocol .name )
161189
190+ def _connect_dp (self , protocol ):
191+ # Get SWJ settings.
192+ use_dormant = self ._session .options .get ('dap_swj_use_dormant' )
193+ send_swj = self ._session .options .get ('dap_swj_enable' ) \
194+ and (DebugProbe .Capability .SWJ_SEQUENCE in self ._probe .capabilities )
195+
162196 # Create object to send SWJ sequences.
163197 swj = SWJSequenceSender (self ._probe , use_dormant )
164198
@@ -207,6 +241,13 @@ class DebugPort(object):
207241 """! @brief Represents the Arm Debug Interface (ADI) Debug Port (DP)."""
208242
209243 def __init__ (self , probe , target ):
244+ """! @brief Constructor.
245+ @param self The DebugPort object.
246+ @param probe The @ref pyocd.probe.debug_probe.DebugProbe "DebugProbe" object. The probe is assumed to not
247+ have been opened yet.
248+ @param target An instance of @ref pyocd.core.soc_target.SoCTarget "SoCTarget". Assumed to not have been
249+ fully initialized.
250+ """
210251 self ._probe = probe
211252 self .target = target
212253 self ._session = target .session
@@ -219,6 +260,8 @@ def __init__(self, probe, target):
219260 self ._probe_managed_ap_select = False
220261 self ._probe_managed_dpbanksel = False
221262 self ._probe_supports_dpbanksel = False
263+ self ._have_probe_capabilities = False
264+ self ._did_check_version = False
222265
223266 # DPv3 attributes
224267 self ._is_dpv3 = False
@@ -268,24 +311,24 @@ def unlock(self):
268311 """! @brief Unlock the DP."""
269312 self .probe .unlock ()
270313
271- def init (self , protocol = None ):
314+ def connect (self , protocol = None ):
272315 """! @brief Connect to the target.
273316
274317 This method causes the debug probe to connect using the selected wire protocol. The probe
275318 must have already been opened prior to this call.
276319
277- Unlike init_sequence (), this method is intended to be used when manually constructing a
278- DebugPort instance. It simply calls init_sequence () and invokes the returned call sequence.
320+ Unlike create_connect_sequence (), this method is intended to be used when manually constructing a
321+ DebugPort instance. It simply calls create_connect_sequence () and invokes the returned call sequence.
279322
280323 @param self
281324 @param protocol One of the @ref pyocd.probe.debug_probe.DebugProbe.Protocol
282325 "DebugProbe.Protocol" enums. If not provided, will default to the `protocol` setting.
283326 """
284327 self ._protocol = protocol
285- self .init_sequence ().invoke ()
328+ self .create_connect_sequence ().invoke ()
286329
287- def init_sequence (self ):
288- """! @brief Init task to connect to the target.
330+ def create_connect_sequence (self ):
331+ """! @brief Returns call sequence to connect to the target.
289332
290333 Returns a @ref pyocd.utility.sequence.CallSequence CallSequence that will connect to the
291334 DP, power up debug and the system, check the DP version to identify whether the target uses
@@ -294,21 +337,36 @@ def init_sequence(self):
294337 The probe must have already been opened prior to this method being called.
295338
296339 @param self
340+ @return @ref pyocd.utility.sequence.CallSequence CallSequence
297341 """
298- return CallSequence (
299- ('get_probe_capabilities' , self ._get_probe_capabilities ),
342+ seq = [
343+ ('lock_probe' , self .probe .lock ),
344+ ]
345+ if not self ._have_probe_capabilities :
346+ seq += [
347+ ('get_probe_capabilities' , self ._get_probe_capabilities ),
348+ ]
349+ seq += [
300350 ('connect' , self ._connect ),
301351 ('clear_sticky_err' , self .clear_sticky_err ),
302352 ('power_up_debug' , self .power_up_debug ),
303- ('check_version' , self ._check_version ),
304- )
353+ ]
354+ if not self ._did_check_version :
355+ seq += [
356+ ('check_version' , self ._check_version ),
357+ ]
358+ seq += [
359+ ('unlock_probe' , self .probe .unlock ),
360+ ]
361+ return CallSequence (* seq )
305362
306363 def _get_probe_capabilities (self ):
307364 """! @brief Examine the probe's capabilities."""
308365 caps = self ._probe .capabilities
309366 self ._probe_managed_ap_select = (DebugProbe .Capability .MANAGED_AP_SELECTION in caps )
310367 self ._probe_managed_dpbanksel = (DebugProbe .Capability .MANAGED_DPBANKSEL in caps )
311368 self ._probe_supports_dpbanksel = (DebugProbe .Capability .BANKED_DP_REGISTERS in caps )
369+ self ._have_probe_capabilities = True
312370
313371 def _connect (self ):
314372 # Attempt to connect.
@@ -347,6 +405,8 @@ def _check_version(self):
347405 else :
348406 LOG .warning ("DPv3 has no valid base address" )
349407
408+ self ._did_check_version = True
409+
350410 def flush (self ):
351411 try :
352412 self .probe .flush ()
0 commit comments