diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index bdd5f0eb..1cd4b62d 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -315,12 +315,11 @@ static int jlink_execute_queue(void)
 static int jlink_speed(int speed)
 {
 	int ret;
-	uint32_t freq;
-	uint16_t divider;
+	struct jaylink_speed jSpeed;
 	int max_speed;
 
 	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
-		ret = jaylink_get_speeds(devh, &freq, &divider);
+		ret = jaylink_get_speeds(devh, &jSpeed);
 
 		if (ret != JAYLINK_OK) {
 			LOG_ERROR("jaylink_get_speeds() failed: %s.",
@@ -328,8 +327,8 @@ static int jlink_speed(int speed)
 			return ERROR_JTAG_DEVICE_ERROR;
 		}
 
-		freq = freq / 1000;
-		max_speed = freq / divider;
+		jSpeed.freq = jSpeed.freq / 1000;
+		max_speed = jSpeed.freq / jSpeed.div;
 	} else {
 		max_speed = JLINK_MAX_SPEED;
 	}
@@ -436,11 +435,12 @@ static int jlink_register(void)
 	int ret;
 	int i;
 	bool handle_found;
+	size_t count;
 
 	if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER))
 		return ERROR_OK;
 
-	ret = jaylink_register(devh, &conn, connlist, NULL, NULL);
+	ret = jaylink_register(devh, &conn, connlist, &count);
 
 	if (ret < 0) {
 		LOG_ERROR("jaylink_register() failed: %s.",
@@ -524,7 +524,7 @@ static int jlink_init(void)
 		return ERROR_JTAG_INIT_FAILED;
 	}
 
-	ret = jaylink_get_device_list(jayctx, &devs);
+	ret = jaylink_get_devices(jayctx, &devs, NULL);
 
 	if (ret < 0) {
 		LOG_ERROR("jaylink_get_device_list() failed: %s.",
@@ -577,7 +577,7 @@ static int jlink_init(void)
 		LOG_ERROR("Failed to open device: %s.", jaylink_strerror_name(ret));
 	}
 
-	jaylink_free_device_list(devs, 1);
+	jaylink_free_devices(devs, true);
 
 	if (!found_device) {
 		LOG_ERROR("No J-Link device found.");
@@ -627,7 +627,7 @@ static int jlink_init(void)
 		}
 	}
 
-	jtag_command_version = JAYLINK_JTAG_V2;
+	jtag_command_version = JAYLINK_JTAG_VERSION_2;
 
 	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) {
 		ret = jaylink_get_hardware_version(devh, &hwver);
@@ -643,7 +643,7 @@ static int jlink_init(void)
 		LOG_INFO("Hardware version: %u.%02u", hwver.major, hwver.minor);
 
 		if (hwver.major >= 5)
-			jtag_command_version = JAYLINK_JTAG_V3;
+			jtag_command_version = JAYLINK_JTAG_VERSION_3;
 	}
 
 	if (iface == JAYLINK_TIF_SWD) {
@@ -686,7 +686,7 @@ static int jlink_init(void)
 
 	conn.handle = 0;
 	conn.pid = 0;
-	conn.hid = 0;
+	memset(conn.hid, 0, INET_ADDRSTRLEN);
 	conn.iid = 0;
 	conn.cid = 0;
 
@@ -730,6 +730,7 @@ static int jlink_init(void)
 static int jlink_quit(void)
 {
 	int ret;
+	size_t count;
 
 	if (trace_enabled) {
 		ret = jaylink_swo_stop(devh);
@@ -740,7 +741,7 @@ static int jlink_quit(void)
 	}
 
 	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) {
-		ret = jaylink_unregister(devh, &conn, connlist, NULL, NULL);
+		ret = jaylink_unregister(devh, &conn, connlist, &count);
 
 		if (ret < 0)
 			LOG_ERROR("jaylink_unregister() failed: %s.",
@@ -952,10 +953,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
 
 	if (!CMD_ARGC) {
 		switch (jtag_command_version) {
-			case JAYLINK_JTAG_V2:
+			case JAYLINK_JTAG_VERSION_2:
 				version = 2;
 				break;
-			case JAYLINK_JTAG_V3:
+			case JAYLINK_JTAG_VERSION_3:
 				version = 3;
 				break;
 			default:
@@ -971,10 +972,10 @@ COMMAND_HANDLER(jlink_handle_jlink_jtag_command)
 
 		switch (tmp) {
 			case 2:
-				jtag_command_version = JAYLINK_JTAG_V2;
+				jtag_command_version = JAYLINK_JTAG_VERSION_2;
 				break;
 			case 3:
-				jtag_command_version = JAYLINK_JTAG_V3;
+				jtag_command_version = JAYLINK_JTAG_VERSION_3;
 				break;
 			default:
 				command_print(CMD_CTX, "Invalid argument: %s.", CMD_ARGV[0]);
diff --git a/tcl/target/stm32wbx.cfg b/tcl/target/stm32wbx.cfg
new file mode 100644
index 00000000..6e27f8ba
--- /dev/null
+++ b/tcl/target/stm32wbx.cfg
@@ -0,0 +1,143 @@
+# script for stm32wbx family
+
+#
+# stm32wb devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+source [find mem_helper.tcl]
+
+if { [info exists CHIPNAME] } {
+   set _CHIPNAME $CHIPNAME
+} else {
+   set _CHIPNAME stm32wb
+}
+
+set _ENDIAN little
+
+# Work-area is a space in RAM used for flash programming
+# By default use 64kB
+if { [info exists WORKAREASIZE] } {
+   set _WORKAREASIZE $WORKAREASIZE
+} else {
+   set _WORKAREASIZE 0x10000
+}
+
+#jtag scan chain
+if { [info exists CPUTAPID] } {
+   set _CPUTAPID $CPUTAPID
+} else {
+   if { [using_jtag] } {
+		# See @TODO
+      set _CPUTAPID 0x6ba00477
+   } else {
+      # SWD IDCODE (single drop, arm)
+	  set _CPUTAPID 0x6ba02477
+   }
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
+
+#if { [info exists BSTAPID] } {
+#   set _BSTAPID1 $BSTAPID
+#} else {
+#  # See STM Document RM0351
+#  # Section 44.6.3
+#  # STM32L47/L48xxG
+#  set _BSTAPID1 0x06415041
+#  # STM32L43/L44xxC
+#  set _BSTAPID2 0x06435041
+#}
+
+if {[using_jtag]} {
+  swj_newdap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID1 \
+      -expected-id $_BSTAPID2
+}
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME
+
+# JTAG speed should be <= F_CPU/6. F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz
+#
+# Since we may be running of an RC oscilator, we crank down the speed a
+# bit more to be on the safe side. Perhaps superstition, but if are
+# running off a crystal, we can run closer to the limit. Note
+# that there can be a pretty wide band where things are more or less stable.
+adapter_khz 500
+
+adapter_nsrst_delay 100
+if {[using_jtag]} {
+	jtag_ntrst_delay 100
+}
+
+# use hardware reset, connect under reset
+# connect_assert_srst needed if low power mode application running (WFI...)
+reset_config srst_only srst_nogate connect_assert_srst
+
+if {![using_hla]} {
+   # if srst is not fitted use SYSRESETREQ to
+   # perform a soft reset
+   cortex_m reset_config sysresetreq
+}
+
+$_TARGETNAME configure -event reset-init {
+	# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.
+	# Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.
+	# 2 WS compliant with VOS=Range1 and 24 MHz.
+	mmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTBE | 2(Latency)
+	mmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz
+	# Boost JTAG frequency
+	adapter_khz 4000
+}
+
+$_TARGETNAME configure -event examine-end {
+global _ENABLE_LOW_POWER
+global _STOP_WATCHDOG
+
+	if { [expr ($_ENABLE_LOW_POWER == 1)] } {
+		# Enable debug during low power modes (uses more power)
+		# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP
+		mmw 0xE0042004 0x00000007 0
+	}
+	if { [expr ($_ENABLE_LOW_POWER == 0)] } {
+		# Disable debug during low power modes
+		# DBGMCU_CR |= ~(DBG_STANDBY | DBG_STOP | DBG_SLEEP)
+		mmw 0xE0042004 0 0x00000007
+	}
+	if { [expr ($_STOP_WATCHDOG == 1)] } {
+		# Stop watchdog counters during halt
+		# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP
+		mmw 0xE004203C 0x00001800 0
+	}
+	if { [expr ($_STOP_WATCHDOG == 0)] } {
+		# Don't stop watchdog counters during halt
+		# DBGMCU_APB1_FZR1 |= ~(DBG_IWDG_STOP | DBG_WWDG_STOP)
+		mmw 0xE004203C 0 0x00001800
+	}
+}
+
+$_TARGETNAME configure -event trace-config {
+	# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync
+	# change this value accordingly to configure trace pins
+	# assignment
+	mmw 0xE0042004 0x00000020 0
+}
+
+$_TARGETNAME configure -event gdb-attach {
+global _CONNECT_UNDER_RESET
+
+	# Needed to be able to use the connect_assert_srst in reset_config
+	# otherwise, wrong value when reading device flash size register
+	if { [expr ($_CONNECT_UNDER_RESET == 1)] } {
+		reset init
+	}
+}
+
+$_TARGETNAME configure -event gdb-detach {
+	# to close connection if debug mode entered
+	shutdown
+}
