Files
openocd/tcl/target/stm32wlx.cfg
Niklas Gürtler 5479c58d23 tcl/target/stm32l4, tcl/target/stm32w*: Fix clock configuration
For stm32l4, stm32wbx, stm32wlx the target tcl scripts try to change the
MSI oscillator's speed to 24 MHz before boosting the interface
frequency, but don't clear the RCC_CR_MSIRANGE field correctly before.
This causes the register write access to fail and leaves the clock
frequency unchanged. For the stm32wlx, the script also neglects to set
the MSIRGSEL bit, such that the frequency setting is not actually
applied.

The issue appears to not cause a problem when using an ST-Link adapter.
When using an FT4232HP, communication to the target fails after the
reset-init event, possibly because this adapter actually supports the
higher interface frequency.

This commit fixes the register accesses to make sure the RCC_CR_MSIRANGE
is cleared to zero before OR-ing the new value. For the stm32wlx, also
set the MSIRGSEL bit. Just to be safe, also fix the write access to the
FLASH_ACR_LATENCY field to clear it before OR-ing, even though it should
be zero at reset anyways.

Change-Id: Ie8320fa6ee2086981c0b1f3c18f51e171709078d
Signed-off-by: Niklas Gürtler <profclonk@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/9282
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Tested-by: jenkins
2025-12-12 19:14:30 +00:00

186 lines
4.9 KiB
INI

# SPDX-License-Identifier: GPL-2.0-or-later
# script for stm32wlx family
#
# stm32wl 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 stm32wlx
}
if { [info exists DUAL_CORE] } {
set $_CHIPNAME.DUAL_CORE $DUAL_CORE
unset DUAL_CORE
} else {
set $_CHIPNAME.DUAL_CORE 0
}
if { [info exists WKUP_CM0P] } {
set $_CHIPNAME.WKUP_CM0P $WKUP_CM0P
unset WKUP_CM0P
} else {
set $_CHIPNAME.WKUP_CM0P 0
}
# Issue a warning when hla is used, and fallback to single core configuration
if { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {
echo "Warning : hla does not support multicore debugging"
set $_CHIPNAME.DUAL_CORE 0
set $_CHIPNAME.WKUP_CM0P 0
}
# setup the Work-area start address and size
# Work-area is a space in RAM used for flash programming
# Memory map for known devices:
# STM32WL x5JC x5JB x5J8
# FLASH 256 128 64
# SRAM1 32 16 0
# SRAM2 32 32 20
# By default use 8kB
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x2000
}
# Use SRAM2 as work area (some devices do not have SRAM1):
set WORKAREASTART_CM4 0x20008000
set WORKAREASTART_CM0P [expr {$WORKAREASTART_CM4 + $_WORKAREASIZE}]
#jtag scan chain
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
if { [using_jtag] } {
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
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
if {[using_jtag]} {
jtag newtap $_CHIPNAME bs -irlen 5
}
target create $_CHIPNAME.cpu0 cortex_m -endian little -dap $_CHIPNAME.dap
$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM4 -work-area-size $_WORKAREASIZE -work-area-backup 0
flash bank $_CHIPNAME.flash.cpu0 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu0
flash bank $_CHIPNAME.otp.cpu0 stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu0
if {![using_hla]} {
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq
}
$_CHIPNAME.cpu0 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 0x00000007 ;# FLASH_ACR |= PRFTEN | 2(Latency)
mmw 0x58000000 0x00000099 0x000000F0 ;# RCC_CR = MSI_ON | MSI Range 24 MHz | MSIRGSEL
# Boost JTAG frequency
adapter speed 4000
}
$_CHIPNAME.cpu0 configure -event reset-start {
# Reset clock is MSI (4 MHz)
adapter speed 500
}
$_CHIPNAME.cpu0 configure -event examine-end {
# Enable debug during low power modes (uses more power)
# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP
mmw 0xE0042004 0x00000007 0
# Stop watchdog counters during halt
# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP
mmw 0xE004203C 0x00001800 0
set _CHIPNAME [stm32wlx_get_chipname]
global $_CHIPNAME.WKUP_CM0P
if {[set $_CHIPNAME.WKUP_CM0P]} {
stm32wlx_wkup_cm0p
}
}
tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000
if {[set $_CHIPNAME.DUAL_CORE]} {
target create $_CHIPNAME.cpu1 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1
$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM0P -work-area-size $_WORKAREASIZE -work-area-backup 0
flash bank $_CHIPNAME.flash.cpu1 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu1
flash bank $_CHIPNAME.otp.cpu1 stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu1
if {![using_hla]} {
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq
}
proc stm32wlx_wkup_cm0p {} {
set _CHIPNAME [stm32wlx_get_chipname]
# enable CPU2 boot after reset and after wakeup from Stop or Standby mode
# PWR_CR4 |= C2BOOT
stm32wlx_mmw $_CHIPNAME.cpu0 0x5800040C 0x00008000 0
}
}
# get _CHIPNAME from current target
proc stm32wlx_get_chipname {} {
set t [target current]
set sep [string last "." $t]
if {$sep == -1} {
return $t
}
return [string range $t 0 [expr {$sep - 1}]]
}
# like mrw, but with target selection
proc stm32wlx_mrw {used_target reg} {
return [$used_target read_memory $reg 32 1]
}
# like mmw, but with target selection
proc stm32wlx_mmw {used_target reg setbits clearbits} {
set old [stm32wlx_mrw $used_target $reg]
set new [expr {($old & ~$clearbits) | $setbits}]
$used_target mww $reg $new
}
# Make sure that cpu0 is selected
targets $_CHIPNAME.cpu0
# Common knowledges tells JTAG speed should be <= F_CPU/6.
# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
# the safe side.
#
# Note that there is a pretty wide band where things are
# more or less stable, see http://openocd.zylin.com/#/c/3366/
adapter speed 500
adapter srst delay 100
if {[using_jtag]} {
jtag_ntrst_delay 100
}
reset_config srst_nogate