Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions pyocd/probe/stlink/stlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
LOG = logging.getLogger(__name__)

class STLink(object):
"""@brief STLink V2 and V3 command-level interface.
"""@brief STLink V2, V3, and V4 command-level interface.
"""
class Protocol(Enum):
"""@brief Protocol options to pass to STLink.enter_debug() method.
Expand All @@ -56,17 +56,17 @@ class Protocol(Enum):
## Firmware version that adds DP bank support.
#
# Keys are the hardware version, value is the minimum JTAG version.
MIN_JTAG_VERSION_DPBANKSEL = {2: 32, 3: 2}
MIN_JTAG_VERSION_DPBANKSEL = {2: 32, 3: 2, 4: 2}

## Firmware version that supports JTAG_GET_BOARD_IDENTIFIERS.
#
# Keys are the hardware version, value is the minimum JTAG version.
MIN_JTAG_VERSION_GET_BOARD_IDS = {2: 36, 3: 6}
MIN_JTAG_VERSION_GET_BOARD_IDS = {2: 36, 3: 6, 4: 6}

## Firmware versions that support CSW settings on memory access commands.
#
# Keys are the hardware version, value is the minimum JTAG version.
MIN_JTAG_VERSION_MEM_CSW = {2: 32, 3: 2}
MIN_JTAG_VERSION_MEM_CSW = {2: 32, 3: 2, 4: 2}

## Port number to use to indicate DP registers.
DP_PORT = 0xffff
Expand Down Expand Up @@ -166,23 +166,39 @@ def get_version(self):
# TODO create version bitfield constants
self._hw_version = bfx(ver, 15, 12)
self._jtag_version = bfx(ver, 11, 6)
self._msc_version = bfx(ver, 5, 0)
msc_v = bfx(ver, 5, 0)

# For STLinkV3 we must use the extended get version command.
# For STLinkV3 and V4 we must use the extended get version command.
if self._hw_version >= 3:
# GET_VERSION_EXT response structure (byte offsets):
# 0: HW version
# 1: SWIM version
# 2: JTAG/SWD version
# 3: MSC/VCP version
# 4: Bridge version
# 5-7: reserved
# 5: Power interface version (for V4)
# 6-7: reserved
# 8-9: ST_VID
# 10-11: STLINK_PID
response = self._device.transfer([Commands.GET_VERSION_EXT], readSize=12)
hw_vers, _, self._jtag_version, self._msc_version = struct.unpack('<4B', response[0:4])

self._version_str = "V%dJ%dM%d" % (self._hw_version, self._jtag_version, self._msc_version)
_, swim_v, self._jtag_version, msc_v, bridge_v, power_v = struct.unpack('<6B', response[0:6])

# Build version string
if self._hw_version >= 3:
# V3/V4 extended format: (omit components if 0)
parts = [f"V{self._hw_version}", f"J{self._jtag_version}"]
if swim_v != 0:
parts.append(f"S{swim_v}")
if msc_v != 0:
parts.append(f"M{msc_v}")
if bridge_v != 0:
parts.append(f"B{bridge_v}")
if power_v != 0:
parts.append(f"P{power_v}")
self._version_str = "".join(parts)
else:
self._version_str = "V%dJ%dM%d" % (self._hw_version, self._jtag_version, msc_v)
LOG.debug("STLink probe %s firmware version: %s", self.serial_number, self._version_str)

# Check versions.
Expand Down Expand Up @@ -252,7 +268,7 @@ def enter_idle(self):
def set_prescaler(self, prescaler: int) -> None:
assert prescaler in (1, 2, 4)

# The SWITCH_STLINK_FREQ command is only supported on V3.
# The SWITCH_STLINK_FREQ command is only supported on V3 and V4.
if self._hw_version < 3:
return
with self._lock:
Expand Down
4 changes: 2 additions & 2 deletions pyocd/probe/stlink/usb.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# pyOCD debugger
# Copyright (c) 2018-2019 Arm Limited
# Copyright (c) 2018-2019,2025 Arm Limited
# Copyright (c) 2021 Chris Reed
# SPDX-License-Identifier: Apache-2.0
#
Expand Down Expand Up @@ -67,7 +67,7 @@ class STLinkUSBInterface:
0x3753: STLinkInfo('V3', 0x01, 0x81, 0x82), # 2VCP, No MSD
0x3754: STLinkInfo('V3', 0x01, 0x81, 0x82), # No MSD
0x3755: STLinkInfo('V3', 0x01, 0x81, 0x82),
0x3757: STLinkInfo('V3', 0x01, 0x81, 0x82),
0x3757: STLinkInfo('V3', 0x01, 0x81, 0x82), # Also for V4
}

## STLink devices only have one USB interface.
Expand Down
Loading