11# pyOCD debugger
2- # Copyright (c) 2015-2020 Arm Limited
2+ # Copyright (c) 2015-2020,2025 Arm Limited
33# Copyright (c) 2021-2023 Chris Reed
44# Copyright (c) 2022 Clay McClure
55# Copyright (c) 2022 Toshiba Electronic Devices & Storage Corporation
@@ -1016,6 +1016,9 @@ def _handle_error(self, error: Exception, num: int) -> None:
10161016 # This may put the AP that was aborted into an unpredictable state. Should consider
10171017 # attempting to reset debug logic.
10181018 self .write_reg (DP_ABORT , ABORT_DAPABORT )
1019+ elif isinstance (error , exceptions .TransferProtocolError ):
1020+ if self .probe .wire_protocol == DebugProbe .Protocol .SWD :
1021+ self ._swd_reset ()
10191022
10201023 def clear_sticky_err (self ) -> None :
10211024 self ._invalidate_cache ()
@@ -1028,6 +1031,28 @@ def clear_sticky_err(self) -> None:
10281031 else :
10291032 assert False
10301033
1034+ def _swd_reset (self ) -> None :
1035+ """@brief Reset the SWD interface.
1036+
1037+ This method is used to reset the SWD interface when a protocol error occurs. It is not
1038+ intended to be used for resetting the target.
1039+ """
1040+ self ._invalidate_cache ()
1041+ try :
1042+ self .lock ()
1043+ swj = SWJSequenceSender (self .probe , False )
1044+ for i in range (2 ):
1045+ try :
1046+ swj .line_reset () # > 50 cycles SWDIO/TMS High.
1047+ swj .idle_cycles (8 ) # At least 2 idle cycles (SWDIO/TMS Low).
1048+ self .probe .read_dp (DP_IDR , now = True ) # Read DP IDR to take connection out of reset state.
1049+ break # Success, so break out of the loop.
1050+ except exceptions .TargetError as error :
1051+ if i != 0 :
1052+ raise # Raise the error if this is the second attempt.
1053+ finally :
1054+ self .unlock ()
1055+
10311056class APAccessMemoryInterface (memory_interface .MemoryInterface ):
10321057 """@brief Memory interface for performing simple APACC transactions.
10331058
0 commit comments