3131LOG = logging .getLogger (__name__ )
3232
3333class STLink (object ):
34- """@brief STLink V2 and V3 command-level interface.
34+ """@brief STLink V2, V3, and V4 command-level interface.
3535 """
3636 class Protocol (Enum ):
3737 """@brief Protocol options to pass to STLink.enter_debug() method.
@@ -56,17 +56,17 @@ class Protocol(Enum):
5656 ## Firmware version that adds DP bank support.
5757 #
5858 # Keys are the hardware version, value is the minimum JTAG version.
59- MIN_JTAG_VERSION_DPBANKSEL = {2 : 32 , 3 : 2 }
59+ MIN_JTAG_VERSION_DPBANKSEL = {2 : 32 , 3 : 2 , 4 : 2 }
6060
6161 ## Firmware version that supports JTAG_GET_BOARD_IDENTIFIERS.
6262 #
6363 # Keys are the hardware version, value is the minimum JTAG version.
64- MIN_JTAG_VERSION_GET_BOARD_IDS = {2 : 36 , 3 : 6 }
64+ MIN_JTAG_VERSION_GET_BOARD_IDS = {2 : 36 , 3 : 6 , 4 : 6 }
6565
6666 ## Firmware versions that support CSW settings on memory access commands.
6767 #
6868 # Keys are the hardware version, value is the minimum JTAG version.
69- MIN_JTAG_VERSION_MEM_CSW = {2 : 32 , 3 : 2 }
69+ MIN_JTAG_VERSION_MEM_CSW = {2 : 32 , 3 : 2 , 4 : 2 }
7070
7171 ## Port number to use to indicate DP registers.
7272 DP_PORT = 0xffff
@@ -166,23 +166,39 @@ def get_version(self):
166166 # TODO create version bitfield constants
167167 self ._hw_version = bfx (ver , 15 , 12 )
168168 self ._jtag_version = bfx (ver , 11 , 6 )
169- self . _msc_version = bfx (ver , 5 , 0 )
169+ msc_v = bfx (ver , 5 , 0 )
170170
171- # For STLinkV3 we must use the extended get version command.
171+ # For STLinkV3 and V4 we must use the extended get version command.
172172 if self ._hw_version >= 3 :
173173 # GET_VERSION_EXT response structure (byte offsets):
174174 # 0: HW version
175175 # 1: SWIM version
176176 # 2: JTAG/SWD version
177177 # 3: MSC/VCP version
178178 # 4: Bridge version
179- # 5-7: reserved
179+ # 5: Power interface version (for V4)
180+ # 6-7: reserved
180181 # 8-9: ST_VID
181182 # 10-11: STLINK_PID
182183 response = self ._device .transfer ([Commands .GET_VERSION_EXT ], readSize = 12 )
183- hw_vers , _ , self ._jtag_version , self ._msc_version = struct .unpack ('<4B' , response [0 :4 ])
184184
185- self ._version_str = "V%dJ%dM%d" % (self ._hw_version , self ._jtag_version , self ._msc_version )
185+ _ , swim_v , self ._jtag_version , msc_v , bridge_v , power_v = struct .unpack ('<6B' , response [0 :6 ])
186+
187+ # Build version string
188+ if self ._hw_version >= 3 :
189+ # V3/V4 extended format: (omit components if 0)
190+ parts = [f"V{ self ._hw_version } " , f"J{ self ._jtag_version } " ]
191+ if swim_v != 0 :
192+ parts .append (f"S{ swim_v } " )
193+ if msc_v != 0 :
194+ parts .append (f"M{ msc_v } " )
195+ if bridge_v != 0 :
196+ parts .append (f"B{ bridge_v } " )
197+ if power_v != 0 :
198+ parts .append (f"P{ power_v } " )
199+ self ._version_str = "" .join (parts )
200+ else :
201+ self ._version_str = "V%dJ%dM%d" % (self ._hw_version , self ._jtag_version , msc_v )
186202 LOG .debug ("STLink probe %s firmware version: %s" , self .serial_number , self ._version_str )
187203
188204 # Check versions.
@@ -252,7 +268,7 @@ def enter_idle(self):
252268 def set_prescaler (self , prescaler : int ) -> None :
253269 assert prescaler in (1 , 2 , 4 )
254270
255- # The SWITCH_STLINK_FREQ command is only supported on V3.
271+ # The SWITCH_STLINK_FREQ command is only supported on V3 and V4 .
256272 if self ._hw_version < 3 :
257273 return
258274 with self ._lock :
0 commit comments