mirror of
https://github.com/silenty4ng/uv-k5-firmware-chinese-lts
synced 2025-01-15 14:54:40 +00:00
删除多余的openocd
This commit is contained in:
parent
b00251a300
commit
e7caf187c4
21 changed files with 0 additions and 1155 deletions
|
@ -1,61 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#----------------------------------------
|
|
||||||
# Purpose - Create some $BIT variables
|
|
||||||
# Create $K and $M variables
|
|
||||||
# and some bit field extraction variables.
|
|
||||||
# Create helper variables ...
|
|
||||||
# BIT0.. BIT31
|
|
||||||
|
|
||||||
for { set x 0 } { $x < 32 } { set x [expr {$x + 1}]} {
|
|
||||||
set vn [format "BIT%d" $x]
|
|
||||||
global $vn
|
|
||||||
set $vn [expr {1 << $x}]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create K bytes values
|
|
||||||
# __1K ... to __2048K
|
|
||||||
for { set x 1 } { $x < 2048 } { set x [expr {$x * 2}]} {
|
|
||||||
set vn [format "__%dK" $x]
|
|
||||||
global $vn
|
|
||||||
set $vn [expr {1024 * $x}]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create M bytes values
|
|
||||||
# __1M ... to __2048K
|
|
||||||
for { set x 1 } { $x < 2048 } { set x [expr {$x * 2}]} {
|
|
||||||
set vn [format "__%dM" $x]
|
|
||||||
global $vn
|
|
||||||
set $vn [expr {1024 * 1024 * $x}]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc create_mask { MSB LSB } {
|
|
||||||
return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cut Bits $MSB to $LSB out of this value.
|
|
||||||
# Example: % format "0x%08x" [extract_bitfield 0x12345678 27 16]
|
|
||||||
# Result: 0x02340000
|
|
||||||
|
|
||||||
proc extract_bitfield { VALUE MSB LSB } {
|
|
||||||
return [expr {[create_mask $MSB $LSB] & $VALUE}]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Cut bits $MSB to $LSB out of this value
|
|
||||||
# and shift (normalize) them down to bit 0.
|
|
||||||
#
|
|
||||||
# Example: % format "0x%08x" [normalize_bitfield 0x12345678 27 16]
|
|
||||||
# Result: 0x00000234
|
|
||||||
#
|
|
||||||
proc normalize_bitfield { VALUE MSB LSB } {
|
|
||||||
return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc show_normalize_bitfield { VALUE MSB LSB } {
|
|
||||||
set m [create_mask $MSB $LSB]
|
|
||||||
set mr [expr {$VALUE & $m}]
|
|
||||||
set sr [expr {$mr >> $LSB}]
|
|
||||||
echo [format "((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d " $VALUE $m $mr $LSB $sr $sr]
|
|
||||||
return $sr
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,22 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#
|
|
||||||
# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit
|
|
||||||
# debugger/programmer
|
|
||||||
#
|
|
||||||
# This new interface driver creates a ST-Link wrapper for ARM-DAP named "dapdirect"
|
|
||||||
# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support "dapdirect"
|
|
||||||
#
|
|
||||||
# SWIM transport is natively supported
|
|
||||||
#
|
|
||||||
|
|
||||||
adapter driver st-link
|
|
||||||
st-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757
|
|
||||||
|
|
||||||
# transport select dapdirect_jtag
|
|
||||||
# transport select dapdirect_swd
|
|
||||||
# transport select swim
|
|
||||||
|
|
||||||
# Optionally specify the serial number of usb device
|
|
||||||
# e.g.
|
|
||||||
# adapter serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f"
|
|
|
@ -1,4 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
echo "WARNING: interface/stlink-v1.cfg is deprecated, please switch to interface/stlink.cfg"
|
|
||||||
source [find interface/stlink.cfg]
|
|
|
@ -1,4 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
echo "WARNING: interface/stlink-v2-1.cfg is deprecated, please switch to interface/stlink.cfg"
|
|
||||||
source [find interface/stlink.cfg]
|
|
|
@ -1,4 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
echo "WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg"
|
|
||||||
source [find interface/stlink.cfg]
|
|
|
@ -1,18 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#
|
|
||||||
# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit
|
|
||||||
# debugger/programmer
|
|
||||||
#
|
|
||||||
|
|
||||||
adapter driver hla
|
|
||||||
hla_layout stlink
|
|
||||||
hla_device_desc "ST-LINK"
|
|
||||||
hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757
|
|
||||||
|
|
||||||
# Optionally specify the serial number of ST-LINK/V2 usb device. ST-LINK/V2
|
|
||||||
# devices seem to have serial numbers with unreadable characters. ST-LINK/V2
|
|
||||||
# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial
|
|
||||||
# number reset issues.
|
|
||||||
# eg.
|
|
||||||
# adapter serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f"
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,38 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
# Helper for common memory read/modify/write procedures
|
|
||||||
|
|
||||||
# mrw: "memory read word", returns value of $reg
|
|
||||||
proc mrw {reg} {
|
|
||||||
return [read_memory $reg 32 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
add_usage_text mrw "address"
|
|
||||||
add_help_text mrw "Returns value of word in memory."
|
|
||||||
|
|
||||||
# mrh: "memory read halfword", returns value of $reg
|
|
||||||
proc mrh {reg} {
|
|
||||||
return [read_memory $reg 16 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
add_usage_text mrh "address"
|
|
||||||
add_help_text mrh "Returns value of halfword in memory."
|
|
||||||
|
|
||||||
# mrb: "memory read byte", returns value of $reg
|
|
||||||
proc mrb {reg} {
|
|
||||||
return [read_memory $reg 8 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
add_usage_text mrb "address"
|
|
||||||
add_help_text mrb "Returns value of byte in memory."
|
|
||||||
|
|
||||||
# mmw: "memory modify word", updates value of $reg
|
|
||||||
# $reg <== ((value & ~$clearbits) | $setbits)
|
|
||||||
proc mmw {reg setbits clearbits} {
|
|
||||||
set old [mrw $reg]
|
|
||||||
set new [expr {($old & ~$clearbits) | $setbits}]
|
|
||||||
mww $reg $new
|
|
||||||
}
|
|
||||||
|
|
||||||
add_usage_text mmw "address setbits clearbits"
|
|
||||||
add_help_text mmw "Modify word in memory. new_val = (old_val & ~clearbits) | setbits;"
|
|
|
@ -1,177 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
# MEMORY
|
|
||||||
#
|
|
||||||
# All Memory regions have two components.
|
|
||||||
# (1) A count of regions, in the form N_NAME
|
|
||||||
# (2) An array within info about each region.
|
|
||||||
#
|
|
||||||
# The ARRAY
|
|
||||||
#
|
|
||||||
# <NAME>( RegionNumber , ATTRIBUTE )
|
|
||||||
#
|
|
||||||
# Where <NAME> is one of:
|
|
||||||
#
|
|
||||||
# N_FLASH & FLASH (internal memory)
|
|
||||||
# N_RAM & RAM (internal memory)
|
|
||||||
# N_MMREGS & MMREGS (for memory mapped registers)
|
|
||||||
# N_XMEM & XMEM (off chip memory, ie: flash on cs0, sdram on cs2)
|
|
||||||
# or N_UNKNOWN & UNKNOWN for things that do not exist.
|
|
||||||
#
|
|
||||||
# We have 1 unknown region.
|
|
||||||
set N_UNKNOWN 1
|
|
||||||
# All MEMORY regions must have these attributes
|
|
||||||
# CS - chip select (if internal, use -1)
|
|
||||||
set UNKNOWN(0,CHIPSELECT) -1
|
|
||||||
# BASE - base address in memory
|
|
||||||
set UNKNOWN(0,BASE) 0
|
|
||||||
# LEN - length in bytes
|
|
||||||
set UNKNOWN(0,LEN) $CPU_MAX_ADDRESS
|
|
||||||
# HUMAN - human name of the region
|
|
||||||
set UNKNOWN(0,HUMAN) "unknown"
|
|
||||||
# TYPE - one of:
|
|
||||||
# flash, ram, mmr, unknown
|
|
||||||
# For harvard arch:
|
|
||||||
# iflash, dflash, iram, dram
|
|
||||||
set UNKNOWN(0,TYPE) "unknown"
|
|
||||||
# RWX - access ablity
|
|
||||||
# unix style chmod bits
|
|
||||||
# 0 - no access
|
|
||||||
# 1 - execute
|
|
||||||
# 2 - write
|
|
||||||
# 4 - read
|
|
||||||
# hence: 7 - readwrite execute
|
|
||||||
set RWX_NO_ACCESS 0
|
|
||||||
set RWX_X_ONLY $BIT0
|
|
||||||
set RWX_W_ONLY $BIT1
|
|
||||||
set RWX_R_ONLY $BIT2
|
|
||||||
set RWX_RW [expr {$RWX_R_ONLY + $RWX_W_ONLY}]
|
|
||||||
set RWX_R_X [expr {$RWX_R_ONLY + $RWX_X_ONLY}]
|
|
||||||
set RWX_RWX [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}]
|
|
||||||
set UNKNOWN(0,RWX) $RWX_NO_ACCESS
|
|
||||||
|
|
||||||
# WIDTH - access width
|
|
||||||
# 8,16,32 [0 means ANY]
|
|
||||||
set ACCESS_WIDTH_NONE 0
|
|
||||||
set ACCESS_WIDTH_8 $BIT0
|
|
||||||
set ACCESS_WIDTH_16 $BIT1
|
|
||||||
set ACCESS_WIDTH_32 $BIT2
|
|
||||||
set ACCESS_WIDTH_ANY [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}]
|
|
||||||
set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE
|
|
||||||
|
|
||||||
proc iswithin { ADDRESS BASE LEN } {
|
|
||||||
return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc address_info { ADDRESS } {
|
|
||||||
|
|
||||||
foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {
|
|
||||||
if { info exists $WHERE } {
|
|
||||||
set lmt [set N_[set WHERE]]
|
|
||||||
for { set region 0 } { $region < $lmt } { incr region } {
|
|
||||||
if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {
|
|
||||||
return "$WHERE $region";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Return the 'unknown'
|
|
||||||
return "UNKNOWN 0"
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memread32 {ADDR} {
|
|
||||||
if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {
|
|
||||||
return $foo
|
|
||||||
} else {
|
|
||||||
error "memread32: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memread16 {ADDR} {
|
|
||||||
if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {
|
|
||||||
return $foo
|
|
||||||
} else {
|
|
||||||
error "memread16: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memread8 {ADDR} {
|
|
||||||
if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {
|
|
||||||
return $foo
|
|
||||||
} else {
|
|
||||||
error "memread8: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memwrite32 {ADDR DATA} {
|
|
||||||
if ![ catch { write_memory $ADDR 32 $DATA } msg ] {
|
|
||||||
return $DATA
|
|
||||||
} else {
|
|
||||||
error "memwrite32: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memwrite16 {ADDR DATA} {
|
|
||||||
if ![ catch { write_memory $ADDR 16 $DATA } msg ] {
|
|
||||||
return $DATA
|
|
||||||
} else {
|
|
||||||
error "memwrite16: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memwrite8 {ADDR DATA} {
|
|
||||||
if ![ catch { write_memory $ADDR 8 $DATA } msg ] {
|
|
||||||
return $DATA
|
|
||||||
} else {
|
|
||||||
error "memwrite8: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memread32_phys {ADDR} {
|
|
||||||
if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {
|
|
||||||
return $foo
|
|
||||||
} else {
|
|
||||||
error "memread32: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memread16_phys {ADDR} {
|
|
||||||
if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {
|
|
||||||
return $foo
|
|
||||||
} else {
|
|
||||||
error "memread16: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memread8_phys {ADDR} {
|
|
||||||
if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {
|
|
||||||
return $foo
|
|
||||||
} else {
|
|
||||||
error "memread8: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memwrite32_phys {ADDR DATA} {
|
|
||||||
if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {
|
|
||||||
return $DATA
|
|
||||||
} else {
|
|
||||||
error "memwrite32: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memwrite16_phys {ADDR DATA} {
|
|
||||||
if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {
|
|
||||||
return $DATA
|
|
||||||
} else {
|
|
||||||
error "memwrite16: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc memwrite8_phys {ADDR DATA} {
|
|
||||||
if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {
|
|
||||||
return $DATA
|
|
||||||
} else {
|
|
||||||
error "memwrite8: $msg"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
proc proc_exists { NAME } {
|
|
||||||
set n [info commands $NAME]
|
|
||||||
set l [string length $n]
|
|
||||||
return [expr {$l != 0}]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Give: REGISTER name - must be a global variable.
|
|
||||||
proc show_mmr32_reg { NAME } {
|
|
||||||
|
|
||||||
global $NAME
|
|
||||||
# we want $($NAME)
|
|
||||||
set a [set [set NAME]]
|
|
||||||
|
|
||||||
if ![catch { set v [memread32 $a] } msg ] {
|
|
||||||
echo [format "%15s: (0x%08x): 0x%08x" $NAME $a $v]
|
|
||||||
|
|
||||||
# Was a helper defined?
|
|
||||||
set fn show_${NAME}_helper
|
|
||||||
if [ proc_exists $fn ] {
|
|
||||||
# Then call it
|
|
||||||
$fn $NAME $a $v
|
|
||||||
}
|
|
||||||
return $v;
|
|
||||||
} else {
|
|
||||||
error [format "%s (%s)" $msg $NAME ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Give: NAMES - an array of names accessible
|
|
||||||
# in the callers symbol-scope.
|
|
||||||
# VAL - the bits to display.
|
|
||||||
|
|
||||||
proc show_mmr32_bits { NAMES VAL } {
|
|
||||||
|
|
||||||
upvar $NAMES MYNAMES
|
|
||||||
|
|
||||||
set w 5
|
|
||||||
foreach {IDX N} $MYNAMES {
|
|
||||||
set l [string length $N]
|
|
||||||
if { $l > $w } { set w $l }
|
|
||||||
}
|
|
||||||
|
|
||||||
for { set x 24 } { $x >= 0 } { incr x -8 } {
|
|
||||||
echo -n " "
|
|
||||||
for { set y 7 } { $y >= 0 } { incr y -1 } {
|
|
||||||
set s $MYNAMES([expr {$x + $y}])
|
|
||||||
echo -n [format "%2d: %-*s | " [expr {$x + $y}] $w $s ]
|
|
||||||
}
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -n " "
|
|
||||||
for { set y 7 } { $y >= 0 } { incr y -1 } {
|
|
||||||
echo -n [format " %d%*s | " [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] ""]
|
|
||||||
}
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } {
|
|
||||||
set width [expr {(($MSB - $LSB + 1) + 7) / 4}]
|
|
||||||
set nval [show_normalize_bitfield $VAL $MSB $LSB ]
|
|
||||||
set name0 [lindex $FIELDVALUES 0 ]
|
|
||||||
if [ string compare $name0 _NUMBER_ ] {
|
|
||||||
set sval [lindex $FIELDVALUES $nval]
|
|
||||||
} else {
|
|
||||||
set sval ""
|
|
||||||
}
|
|
||||||
echo [format "%-15s: %d (0x%0*x) %s" $FIELDNAME $nval $width $nval $sval ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Give: ADDR - address of the register.
|
|
||||||
# BIT - bit's number.
|
|
||||||
|
|
||||||
proc get_mmr_bit { ADDR BIT } {
|
|
||||||
set val [memread32 $ADDR]
|
|
||||||
set bit_val [expr {$val & [expr {1 << $BIT}]}]
|
|
||||||
return $bit_val
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Give: ADDR - address of the register.
|
|
||||||
# MSB - MSB bit's number.
|
|
||||||
# LSB - LSB bit's number.
|
|
||||||
|
|
||||||
proc get_mmr_bitfield { ADDR MSB LSB } {
|
|
||||||
set rval [memread32 $ADDR]
|
|
||||||
return normalize_bitfield $rval $MSB $LSB
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,340 +0,0 @@
|
||||||
#OpenOCD script for Action Dynamic DP32G030 ARM Cortex M0 CPU (UV-5R, UV-k5 Ham HTs)
|
|
||||||
#For use with cheap ST-Link USB debug probe
|
|
||||||
source target/swj-dp.tcl
|
|
||||||
|
|
||||||
set _CHIP_NAME DP32G0xx
|
|
||||||
set _ENDIAN little
|
|
||||||
set _WORKAREASIZE 0x1000
|
|
||||||
set _FLASH_SIZE 0x10000
|
|
||||||
set _CPUTAPID 0x0BB11477
|
|
||||||
set _TARGETNAME $_CHIP_NAME.cpu
|
|
||||||
set _FLASHNAME $_CHIP_NAME.flash
|
|
||||||
set _SECTOR_SIZE 512
|
|
||||||
set _MASKING_CFG 2 ;#1:2kB, 2:4kB, 3:8kB
|
|
||||||
|
|
||||||
adapter speed 960
|
|
||||||
adapter srst delay 100
|
|
||||||
reset_config srst_nogate
|
|
||||||
|
|
||||||
# Create a new dap, with name chip and role CPU, -enable let's OpenOCD to know to add it to the scan
|
|
||||||
swj_newdap $_CHIP_NAME cpu -expected-id $_CPUTAPID -enable
|
|
||||||
|
|
||||||
# Create the DAP instance, this must be explicitly created according to the OpenOCD docs
|
|
||||||
dap create $_CHIP_NAME.dap -chain-position $_CHIP_NAME.cpu
|
|
||||||
|
|
||||||
# Set up the GDB target for the CPU
|
|
||||||
target create $_CHIP_NAME.cpu cortex_m -endian $_ENDIAN -dap $_CHIP_NAME.dap
|
|
||||||
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
|
|
||||||
|
|
||||||
# Declare internal bank
|
|
||||||
flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME
|
|
||||||
|
|
||||||
proc check_readiness {} {
|
|
||||||
while {[read_memory 0x4006F014 32 1] & 0x2} {}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc rom_mask_off {} {
|
|
||||||
echo "\nChecking ROM masking"
|
|
||||||
check_readiness
|
|
||||||
set status [read_memory 0x4006F020 32 1]
|
|
||||||
if {($status & 0x3) != 0} {
|
|
||||||
echo [format "\nROM masking is set to 0b%03b. Unsetting..." $status]
|
|
||||||
write_memory 0x4006F020 32 [expr {[read_memory 0x4006F020 32 1] & 0x3}]
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F020 32 0
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F020 32 4
|
|
||||||
}
|
|
||||||
return [read_memory 0x4006F020 32 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc rom_mask_on {} {
|
|
||||||
global _MASKING_CFG
|
|
||||||
echo "\nChecking ROM masking"
|
|
||||||
check_readiness
|
|
||||||
set status [read_memory 0x4006F020 32 1]
|
|
||||||
if {($status & 0x3) != $_MASKING_CFG} {
|
|
||||||
echo [format "\nROM masking is set to 0b%03b. Setting ON..." $status]
|
|
||||||
write_memory 0x4006F020 32 [expr {[read_memory 0x4006F020 32 1] & 0x3}]
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F020 32 $_MASKING_CFG
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F020 32 [expr {4 | $_MASKING_CFG}]
|
|
||||||
}
|
|
||||||
return [read_memory 0x4006F020 32 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc unlock_rom {} {
|
|
||||||
write_memory 0x4006F01c 32 0xAA
|
|
||||||
check_readiness
|
|
||||||
}
|
|
||||||
|
|
||||||
proc lock_rom {} {
|
|
||||||
write_memory 0x4006F018 32 0x55
|
|
||||||
check_readiness
|
|
||||||
}
|
|
||||||
|
|
||||||
proc select_region {target_r} {
|
|
||||||
#Region 0 is main user ROM area, 1 is NVRAM area
|
|
||||||
write_memory 0x4006F000 32 [expr {(0x31 & [read_memory 0x4006F000 32 1]) | (($target_r & 0x1) << 1)}]
|
|
||||||
check_readiness
|
|
||||||
}
|
|
||||||
|
|
||||||
proc wipe_sector_range {st_sec sec_count} {
|
|
||||||
set last [expr {$st_sec + $sec_count}]
|
|
||||||
set reg [expr {[read_memory 0x4006F000 32 1] & 0x7FFFFFFF}]
|
|
||||||
write_memory 0x4006F000 32 [expr {$reg | 0x8}] ;#set writing mode ERASE
|
|
||||||
|
|
||||||
for {set i $st_sec} {$i < $last} {incr i} {
|
|
||||||
check_readiness
|
|
||||||
echo -n [format "\rErasing sector 0x%02x = offset 0x%04x" [expr {$i}] [expr {$i*512}] ]
|
|
||||||
write_memory 0x4006F004 32 [expr {$i << 7}] ;#set address in flash
|
|
||||||
write_memory 0x4006F010 32 0x01 ;#do it
|
|
||||||
}
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F000 32 $reg
|
|
||||||
}
|
|
||||||
|
|
||||||
proc wipe_rom {} {
|
|
||||||
#This will wipe everything including bootloader
|
|
||||||
global _SECTOR_SIZE
|
|
||||||
global _FLASH_SIZE
|
|
||||||
unlock_rom
|
|
||||||
select_region 0
|
|
||||||
if {[rom_mask_off] != 4} {
|
|
||||||
echo "\nROM Masking failed to disable!"
|
|
||||||
close $fd
|
|
||||||
return
|
|
||||||
}
|
|
||||||
wipe_sector_range 0 [expr {$_FLASH_SIZE / $_SECTOR_SIZE}]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc write_image {filename offset} {
|
|
||||||
global _SECTOR_SIZE
|
|
||||||
global _FLASH_SIZE
|
|
||||||
set fs [file size $filename]
|
|
||||||
set fd [open $filename "rb"]
|
|
||||||
set reg [expr {[read_memory 0x4006F000 32 1] & 0x7FFFFFFF}]
|
|
||||||
write_memory 0x4006F000 32 [expr {$reg | 0x4}] ;#set writing mode PROGRAM
|
|
||||||
while {![eof $fd]} {
|
|
||||||
if {($offset+4) > $_FLASH_SIZE} {
|
|
||||||
echo "\nData exceeds main storage capacity!"
|
|
||||||
write_memory 0x4006F000 32 $reg
|
|
||||||
lock_rom
|
|
||||||
close $fd
|
|
||||||
return
|
|
||||||
}
|
|
||||||
check_readiness
|
|
||||||
set data [read $fd 4]
|
|
||||||
set data $data[string repeat \xFF [expr {4-[string length $data]}]] ;#padding
|
|
||||||
binary scan $data i i_data
|
|
||||||
write_memory 0x4006F004 32 [expr {($offset>>2)+0xC000}] ;#set destination offset
|
|
||||||
write_memory 0x4006F008 32 $i_data ;#set word
|
|
||||||
write_memory 0x4006F010 32 0x01 ;#set OPSTART=1
|
|
||||||
while {([read_memory 0x4006F014 32 1] & 4) == 0} {}
|
|
||||||
echo -n [format "\rProgrammed up to 0x%04x (FLASH_ADDR=0x%04x)" $offset [expr {($offset>>2)+0xC000}]]
|
|
||||||
incr offset 4
|
|
||||||
}
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F000 32 $reg ;#reset writing mode to OFF
|
|
||||||
}
|
|
||||||
|
|
||||||
proc flash_blocks {filename address nblocks offset} {
|
|
||||||
#Intended for speed. Due to tight timings, sometimes it works, sometimes it does not. Needs clocks adjusting there.
|
|
||||||
global _SECTOR_SIZE
|
|
||||||
global _FLASH_SIZE
|
|
||||||
|
|
||||||
if {($nblocks != 0) & [expr {$nblocks & 1}]} {
|
|
||||||
set nblocks [expr {$nblocks + 1}]
|
|
||||||
}
|
|
||||||
set addr [expr {$_SECTOR_SIZE * ($address >> 9)}]
|
|
||||||
set fs [expr {((($_SECTOR_SIZE*$nblocks)/2 + $_SECTOR_SIZE-1)&(0x10000000-$_SECTOR_SIZE))}]
|
|
||||||
set fd [open $filename "rb"]
|
|
||||||
|
|
||||||
read $fd $addr
|
|
||||||
set addr [expr {$addr + $offset}] ;#apply ROM offset
|
|
||||||
set reg [expr {[read_memory 0x4006F000 32 1] & 0x7FFFFFFF}]
|
|
||||||
|
|
||||||
echo -n [format "\tWiping %02d sectors, starting at %02d " [expr {$nblocks / 2}] [expr {$addr >> 9}]]
|
|
||||||
|
|
||||||
wipe_sector_range [expr {$addr >> 9}] [expr {$nblocks / 2}] ;#wipe related sectors
|
|
||||||
echo "\nRegion cleared OK"
|
|
||||||
|
|
||||||
echo [format "%02d bytes to push" $fs]; ##DEBUG
|
|
||||||
write_memory 0x4006F000 32 [expr {$reg | 0x4}] ;#set writing mode PROGRAM
|
|
||||||
|
|
||||||
while {$fs > 0} {
|
|
||||||
write_memory 0x4006F004 32 [expr {0xC000+(($addr)>>2)}] ;#set block starting offset
|
|
||||||
set i_buffer {}
|
|
||||||
for {set blk 0} {$blk < $_SECTOR_SIZE/2} {incr blk 4} {
|
|
||||||
set data [read $fd 4]
|
|
||||||
set data $data[string repeat \xFF [expr {4-[string length $data]}]] ;#padding to desired ending block
|
|
||||||
if {($addr+$_SECTOR_SIZE/2) >= $_FLASH_SIZE} {
|
|
||||||
echo [format "\nMain firmware image upper boundary reached (%d)!" $addr]
|
|
||||||
write_memory 0x4006F000 32 $reg ;#reset writing mode to OFF
|
|
||||||
close $fd
|
|
||||||
return
|
|
||||||
}
|
|
||||||
binary scan $data i i_data
|
|
||||||
lappend i_buffer [expr {$i_data & 0xFFFFFFFF}]
|
|
||||||
incr fs -4
|
|
||||||
}
|
|
||||||
echo [format "\nWriting at offset 0x%04x" [expr {$addr}]]
|
|
||||||
##for {set bi 0} {$bi < 64} {incr bi} {echo -n [format "%08x" [lindex $i_buffer $bi]]}; #DEBUG
|
|
||||||
write_memory 0x4006F008 32 [lindex $i_buffer 0] ;#prepare 1st word: we need to be quick beyond this point
|
|
||||||
check_readiness
|
|
||||||
write_memory 0x4006F010 32 0x01
|
|
||||||
for {set bi 1} {$bi < 64} {incr bi} {while {([read_memory 0x4006F014 32 1] & 0x4) == 4} {write_memory 0x4006F008 32 [lindex $i_buffer $bi]}}
|
|
||||||
check_readiness
|
|
||||||
incr addr $_SECTOR_SIZE/2 ;# Next block
|
|
||||||
}
|
|
||||||
write_memory 0x4006F000 32 $reg ;#reset writing mode to OFF
|
|
||||||
echo [format "\nLast write was 0x%08x " [lindex $i_buffer 63]]
|
|
||||||
close $fd
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
proc toggle_pin_gpioa {pin} {
|
|
||||||
write_memory 0x40060000 16 [expr {[read_memory 0x40060000 16 1] ^(1<<$pin) }]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc toggle_pin_gpiob {pin} {
|
|
||||||
write_memory 0x40060800 16 [expr {[read_memory 0x40060800 16 1] ^(1<<$pin) }]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc toggle_pin_gpioc {pin} {
|
|
||||||
write_memory 0x40061000 16 [expr {[read_memory 0x40061000 16 1] ^(1<<$pin) }]
|
|
||||||
}
|
|
||||||
|
|
||||||
proc set_pin_gpioa {pin value} {
|
|
||||||
if {$value == 0} {
|
|
||||||
write_memory 0x40060000 16 [expr {[read_memory 0x40060000 16 1] &~(1<<$pin) }]
|
|
||||||
} else {
|
|
||||||
write_memory 0x40060000 16 [expr {[read_memory 0x40060000 16 1] |(1<<$pin) }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc set_pin_gpiob {pin value} {
|
|
||||||
if {$value == 0} {
|
|
||||||
write_memory 0x40060800 16 [expr {[read_memory 0x40060800 16 1] &~(1<<$pin) }]
|
|
||||||
} else {
|
|
||||||
write_memory 0x40060800 16 [expr {[read_memory 0x40060800 16 1] |(1<<$pin) }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc set_pin_gpioc {pin value} {
|
|
||||||
if {$value == 0} {
|
|
||||||
write_memory 0x40061000 16 [expr {[read_memory 0x40061000 16 1] &~(1<<$pin) }]
|
|
||||||
} else {
|
|
||||||
write_memory 0x40061000 16 [expr {[read_memory 0x40061000 16 1] |(1<<$pin) }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##Quansheng UVK5-specific snippets
|
|
||||||
|
|
||||||
proc uv_fastflash_bl {filename} {
|
|
||||||
write_memory 0x4006F024 32 0x4E02A300 ;#force stock timings, just in case
|
|
||||||
write_memory 0x4006F028 32 0x210360
|
|
||||||
write_memory 0x4006F000 32 0x1
|
|
||||||
check_readiness
|
|
||||||
select_region 0
|
|
||||||
if {[rom_mask_off] != 4} {
|
|
||||||
echo "\nROM Masking failed to disable!"
|
|
||||||
close $fd
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reset halt
|
|
||||||
unlock_rom
|
|
||||||
|
|
||||||
flash_blocks $filename 0 16 0
|
|
||||||
|
|
||||||
#just relock flashROM
|
|
||||||
lock_rom
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_fastflash_fw {filename} {
|
|
||||||
#Make sure bootloader is hidden
|
|
||||||
if {[rom_mask_on] != 6} {
|
|
||||||
echo "\nROM Masking failed to enable!"
|
|
||||||
close $fd
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reset halt
|
|
||||||
unlock_rom
|
|
||||||
|
|
||||||
flash_blocks $filename 0 [expr {[file size $filename] >> 8}] 0
|
|
||||||
reset
|
|
||||||
echo "\nCPU reset: Transceiver should boot now."
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_flash_bl {filename} {
|
|
||||||
#Securely rewrites bootloader (slowly)
|
|
||||||
|
|
||||||
if {[file size $filename] > 0x1000} {
|
|
||||||
echo [format "Bootloader image is too large to fit!]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
select_region 0
|
|
||||||
if {[rom_mask_off] != 4} {
|
|
||||||
echo "\nROM Masking failed to disable!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reset halt
|
|
||||||
unlock_rom
|
|
||||||
|
|
||||||
wipe_sector_range 0 8
|
|
||||||
echo "\nRegion cleared OK"
|
|
||||||
|
|
||||||
write_image $filename 0
|
|
||||||
|
|
||||||
if {[rom_mask_on] != 6} {
|
|
||||||
echo "\nROM Masking failed to enable!"
|
|
||||||
lock_rom
|
|
||||||
return
|
|
||||||
}
|
|
||||||
#relock flashROM, in case conventional method for fw is preferred
|
|
||||||
lock_rom
|
|
||||||
echo "\nBootloader code programmed.\nYou can use uv_flash_fw to program main firmware, or just use stock tool to do it."
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_flash_fw {filename} {
|
|
||||||
#Securely rewrites main firmware (slowly)
|
|
||||||
|
|
||||||
select_region 0
|
|
||||||
#Make sure bootloader is hidden
|
|
||||||
if {[rom_mask_on] != 6} {
|
|
||||||
echo "\nROM Masking failed to enable!"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reset halt
|
|
||||||
unlock_rom
|
|
||||||
|
|
||||||
wipe_sector_range 0 120
|
|
||||||
echo "\nRegion cleared OK"
|
|
||||||
|
|
||||||
write_image $filename 0
|
|
||||||
|
|
||||||
#relock flashROM, then reset CPU
|
|
||||||
lock_rom
|
|
||||||
reset
|
|
||||||
echo "\nCPU reset: Transceiver should boot now."
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_flashlight_toggle {} {
|
|
||||||
toggle_pin_gpioc 3 ;# toggles PORTC.3
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_flashlight_on {} {
|
|
||||||
set_pin_gpioc 3 1 ;# set PORTC.3 high
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_flashlight_off {} {
|
|
||||||
set_pin_gpioc 3 0 ;# set PORTC.3 to low
|
|
||||||
}
|
|
||||||
|
|
||||||
proc uv_backlight_toggle {} {
|
|
||||||
toggle_pin_gpiob 6 ;# toggles PORTB.6
|
|
||||||
}
|
|
||||||
|
|
||||||
init
|
|
||||||
#reset halt
|
|
|
@ -1,34 +0,0 @@
|
||||||
# ARM Debug Interface V5 (ADI_V5) utility
|
|
||||||
# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since
|
|
||||||
# SW-DP and JTAG-DP targets don't need to switch based
|
|
||||||
# on which transport is active.
|
|
||||||
#
|
|
||||||
# declare a JTAG or SWD Debug Access Point (DAP)
|
|
||||||
# based on the transport in use with this session.
|
|
||||||
# You can't access JTAG ops when SWD is active, etc.
|
|
||||||
|
|
||||||
# params are currently what "jtag newtap" uses
|
|
||||||
# because OpenOCD internals are still strongly biased
|
|
||||||
# to JTAG .... but for SWD, "irlen" etc are ignored,
|
|
||||||
# and the internals work differently
|
|
||||||
|
|
||||||
# for now, ignore non-JTAG and non-SWD transports
|
|
||||||
# (e.g. initial flash programming via SPI or UART)
|
|
||||||
|
|
||||||
# split out "chip" and "tag" so we can someday handle
|
|
||||||
# them more uniformly irlen too...)
|
|
||||||
|
|
||||||
if [catch {transport select}] {
|
|
||||||
echo "Error: unable to select a session transport. Can't continue."
|
|
||||||
shutdown
|
|
||||||
}
|
|
||||||
|
|
||||||
proc swj_newdap {chip tag args} {
|
|
||||||
if [using_hla] {
|
|
||||||
eval hla newtap $chip $tag $args
|
|
||||||
} elseif [using_jtag] {
|
|
||||||
eval jtag newtap $chip $tag $args
|
|
||||||
} elseif [using_swd] {
|
|
||||||
eval swd newdap $chip $tag $args
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
# ARM Debug Interface V5 (ADI_V5) utility
|
|
||||||
# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since
|
|
||||||
# SW-DP and JTAG-DP targets don't need to switch based
|
|
||||||
# on which transport is active.
|
|
||||||
#
|
|
||||||
# declare a JTAG or SWD Debug Access Point (DAP)
|
|
||||||
# based on the transport in use with this session.
|
|
||||||
# You can't access JTAG ops when SWD is active, etc.
|
|
||||||
|
|
||||||
# params are currently what "jtag newtap" uses
|
|
||||||
# because OpenOCD internals are still strongly biased
|
|
||||||
# to JTAG .... but for SWD, "irlen" etc are ignored,
|
|
||||||
# and the internals work differently
|
|
||||||
|
|
||||||
# for now, ignore non-JTAG and non-SWD transports
|
|
||||||
# (e.g. initial flash programming via SPI or UART)
|
|
||||||
|
|
||||||
# split out "chip" and "tag" so we can someday handle
|
|
||||||
# them more uniformly irlen too...)
|
|
||||||
|
|
||||||
if [catch {transport select}] {
|
|
||||||
echo "Error: unable to select a session transport. Can't continue."
|
|
||||||
shutdown
|
|
||||||
}
|
|
||||||
|
|
||||||
proc swj_newdap {chip tag args} {
|
|
||||||
if [using_jtag] {
|
|
||||||
eval jtag newtap $chip $tag $args
|
|
||||||
} elseif [using_swd] {
|
|
||||||
eval swd newdap $chip $tag $args
|
|
||||||
} else {
|
|
||||||
echo "Error: transport '[ transport select ]' not supported by swj_newdap"
|
|
||||||
shutdown
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,191 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
# Algorithms by Michael Barr, released into public domain
|
|
||||||
# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser
|
|
||||||
|
|
||||||
set CPU_MAX_ADDRESS 0xFFFFFFFF
|
|
||||||
source [find bitsbytes.tcl]
|
|
||||||
source [find memory.tcl]
|
|
||||||
|
|
||||||
proc runAllMemTests { baseAddress nBytes } {
|
|
||||||
memTestDataBus $baseAddress
|
|
||||||
memTestAddressBus $baseAddress $nBytes
|
|
||||||
memTestDevice $baseAddress $nBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
#***********************************************************************************
|
|
||||||
# *
|
|
||||||
# * Function: memTestDataBus()
|
|
||||||
# *
|
|
||||||
# * Description: Test the data bus wiring in a memory region by
|
|
||||||
# * performing a walking 1's test at a fixed address
|
|
||||||
# * within that region. The address (and hence the
|
|
||||||
# * memory region) is selected by the caller.
|
|
||||||
# * Ported from:
|
|
||||||
# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
|
|
||||||
# * Notes:
|
|
||||||
# *
|
|
||||||
# * Returns: Empty string if the test succeeds.
|
|
||||||
# * A non-zero result is the first pattern that failed.
|
|
||||||
# *
|
|
||||||
#***********************************************************************************
|
|
||||||
proc memTestDataBus { address } {
|
|
||||||
echo "Running memTestDataBus"
|
|
||||||
|
|
||||||
for {set i 0} {$i < 32} {incr i} {
|
|
||||||
# Shift bit
|
|
||||||
set pattern [expr {1 << $i}]
|
|
||||||
|
|
||||||
# Write pattern to memory
|
|
||||||
memwrite32 $address $pattern
|
|
||||||
|
|
||||||
# Read pattern from memory
|
|
||||||
set data [memread32 $address]
|
|
||||||
|
|
||||||
if {$data != $pattern} {
|
|
||||||
echo "FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data"
|
|
||||||
return $pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#***********************************************************************************
|
|
||||||
# *
|
|
||||||
# * Function: memTestAddressBus()
|
|
||||||
# *
|
|
||||||
# * Description: Perform a walking 1's test on the relevant bits
|
|
||||||
# * of the address and check for aliasing. This test
|
|
||||||
# * will find single-bit address failures such as stuck
|
|
||||||
# * -high, stuck-low, and shorted pins. The base address
|
|
||||||
# * and size of the region are selected by the caller.
|
|
||||||
# * Ported from:
|
|
||||||
# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
|
|
||||||
# *
|
|
||||||
# * Notes: For best results, the selected base address should
|
|
||||||
# * have enough LSB 0's to guarantee single address bit
|
|
||||||
# * changes. For example, to test a 64-Kbyte region,
|
|
||||||
# * select a base address on a 64-Kbyte boundary. Also,
|
|
||||||
# * select the region size as a power-of-two--if at all
|
|
||||||
# * possible.
|
|
||||||
# *
|
|
||||||
# * Returns: Empty string if the test succeeds.
|
|
||||||
# * A non-zero result is the first address at which an
|
|
||||||
# * aliasing problem was uncovered. By examining the
|
|
||||||
# * contents of memory, it may be possible to gather
|
|
||||||
# * additional information about the problem.
|
|
||||||
# *
|
|
||||||
#***********************************************************************************
|
|
||||||
proc memTestAddressBus { baseAddress nBytes } {
|
|
||||||
set addressMask [expr {$nBytes - 1}]
|
|
||||||
set pattern 0xAAAAAAAA
|
|
||||||
set antipattern 0x55555555
|
|
||||||
|
|
||||||
echo "Running memTestAddressBus"
|
|
||||||
|
|
||||||
echo "addressMask: [convertToHex $addressMask]"
|
|
||||||
|
|
||||||
echo "memTestAddressBus: Writing the default pattern at each of the power-of-two offsets..."
|
|
||||||
for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}] } {
|
|
||||||
set addr [expr {$baseAddress + $offset}]
|
|
||||||
memwrite32 $addr $pattern
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "memTestAddressBus: Checking for address bits stuck high..."
|
|
||||||
memwrite32 $baseAddress $antipattern
|
|
||||||
|
|
||||||
for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {
|
|
||||||
set addr [expr {$baseAddress + $offset}]
|
|
||||||
set data [memread32 $addr]
|
|
||||||
|
|
||||||
if {$data != $pattern} {
|
|
||||||
echo "FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]"
|
|
||||||
return $pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "memTestAddressBus: Checking for address bits stuck low or shorted..."
|
|
||||||
memwrite32 $baseAddress $pattern
|
|
||||||
for {set testOffset 32} {[expr {$testOffset & $addressMask}] != 0} {set testOffset [expr {$testOffset << 1}] } {
|
|
||||||
set addr [expr {$baseAddress + $testOffset}]
|
|
||||||
memwrite32 $addr $antipattern
|
|
||||||
|
|
||||||
set data [memread32 $baseAddress]
|
|
||||||
if {$data != $pattern} {
|
|
||||||
echo "FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]"
|
|
||||||
return $pattern
|
|
||||||
}
|
|
||||||
|
|
||||||
for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {
|
|
||||||
set addr [expr {$baseAddress + $offset}]
|
|
||||||
set data [memread32 $baseAddress]
|
|
||||||
|
|
||||||
if {(($data != $pattern) && ($offset != $testOffset))} {
|
|
||||||
echo "FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]"
|
|
||||||
return $pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set addr [expr {$baseAddress + $testOffset}]
|
|
||||||
memwrite32 $addr $pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#***********************************************************************************
|
|
||||||
# *
|
|
||||||
# * Function: memTestDevice()
|
|
||||||
# *
|
|
||||||
# * Description: Test the integrity of a physical memory device by
|
|
||||||
# * performing an increment/decrement test over the
|
|
||||||
# * entire region. In the process every storage bit
|
|
||||||
# * in the device is tested as zero and as one. The
|
|
||||||
# * base address and the size of the region are
|
|
||||||
# * selected by the caller.
|
|
||||||
# * Ported from:
|
|
||||||
# * http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C
|
|
||||||
# * Notes:
|
|
||||||
# *
|
|
||||||
# * Returns: Empty string if the test succeeds.
|
|
||||||
# * A non-zero result is the first address at which an
|
|
||||||
# * incorrect value was read back. By examining the
|
|
||||||
# * contents of memory, it may be possible to gather
|
|
||||||
# * additional information about the problem.
|
|
||||||
# *
|
|
||||||
#***********************************************************************************
|
|
||||||
proc memTestDevice { baseAddress nBytes } {
|
|
||||||
echo "Running memTestDevice"
|
|
||||||
|
|
||||||
echo "memTestDevice: Filling memory with a known pattern..."
|
|
||||||
for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
|
|
||||||
memwrite32 [expr {$baseAddress + $offset}] $pattern
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "memTestDevice: Checking each location and inverting it for the second pass..."
|
|
||||||
for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
|
|
||||||
set addr [expr {$baseAddress + $offset}]
|
|
||||||
set data [memread32 $addr]
|
|
||||||
|
|
||||||
if {$data != $pattern} {
|
|
||||||
echo "FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]"
|
|
||||||
return $pattern
|
|
||||||
}
|
|
||||||
|
|
||||||
set antiPattern [expr {~$pattern}]
|
|
||||||
memwrite32 [expr {$baseAddress + $offset}] $antiPattern
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "memTestDevice: Checking each location for the inverted pattern and zeroing it..."
|
|
||||||
for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {
|
|
||||||
set antiPattern [expr {~$pattern & ((1<<32) - 1)}]
|
|
||||||
set addr [expr {$baseAddress + $offset}]
|
|
||||||
set data [memread32 $addr]
|
|
||||||
set dataHex [convertToHex $data]
|
|
||||||
set antiPatternHex [convertToHex $antiPattern]
|
|
||||||
if {$dataHex != $antiPatternHex} {
|
|
||||||
echo "FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset"
|
|
||||||
return $pattern
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc convertToHex { value } {
|
|
||||||
format 0x%08x $value
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
# Description:
|
|
||||||
# Measure the CPU clock frequency of an ARM Cortex-M based device.
|
|
||||||
#
|
|
||||||
# Return:
|
|
||||||
# The CPU clock frequency in Hz. A negative value indicates that the loop
|
|
||||||
# counter was saturated.
|
|
||||||
#
|
|
||||||
# Note:
|
|
||||||
# You may need to adapt the number of cycles for your device.
|
|
||||||
#
|
|
||||||
add_help_text cortex_m_test_cpu_speed "Measure the CPU clock frequency of an ARM Cortex-M based device"
|
|
||||||
add_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}
|
|
||||||
proc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {
|
|
||||||
set loop_counter_start 0xffffffff
|
|
||||||
|
|
||||||
halt
|
|
||||||
|
|
||||||
# Backup registers and memory.
|
|
||||||
set backup_regs [get_reg -force {pc r0 xpsr}]
|
|
||||||
set backup_mem [read_memory $address 16 3]
|
|
||||||
|
|
||||||
# We place the following code at the given address to measure the
|
|
||||||
# CPU clock frequency:
|
|
||||||
#
|
|
||||||
# 3801: subs r0, #1
|
|
||||||
# d1fd: bne #-2
|
|
||||||
# e7fe: b #-4
|
|
||||||
write_memory $address 16 {0x3801 0xd1fd 0xe7fe}
|
|
||||||
|
|
||||||
set_reg "pc $address r0 $loop_counter_start"
|
|
||||||
resume
|
|
||||||
sleep $timeout
|
|
||||||
halt
|
|
||||||
|
|
||||||
# Get the loop counter value from register r0.
|
|
||||||
set loop_counter_end [dict values [get_reg r0]]
|
|
||||||
set loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]
|
|
||||||
|
|
||||||
# Restore registers and memory.
|
|
||||||
set_reg $backup_regs
|
|
||||||
write_memory $address 16 $backup_mem
|
|
||||||
|
|
||||||
if { [expr {$loop_counter_end == 0}] } {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
return [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
UNBRICK SESSION:
|
|
||||||
---------------
|
|
||||||
|
|
||||||
> openocd -f interface/stlink.cfg -f target/dp32g030.cfg -c "reset halt" -c "uv_flash_bl boot3.bin" -c "uv_flash_fw TEST.bin" -c "shutdown"
|
|
||||||
|
|
||||||
Open On-Chip Debugger 0.12.0 (2023-10-02) [https://github.com/sysprogs/openocd]
|
|
||||||
Licensed under GNU GPL v2
|
|
||||||
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
|
|
||||||
For bug reports, read
|
|
||||||
http://openocd.org/doc/doxygen/bugs.html
|
|
||||||
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
|
|
||||||
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
|
|
||||||
Info : clock speed 960 kHz
|
|
||||||
Info : STLINK V2J32S1 (API v2) VID:PID 0483:3748
|
|
||||||
Info : Target voltage: 3.262151
|
|
||||||
Info : [DP32G0xx.cpu] Cortex-M0 r0p0 processor detected
|
|
||||||
Info : [DP32G0xx.cpu] target has 4 breakpoints, 2 watchpoints
|
|
||||||
Info : starting gdb server for DP32G0xx.cpu on 3333
|
|
||||||
Info : Listening on port 3333 for gdb connections
|
|
||||||
[DP32G0xx.cpu] halted due to debug-request, current mode: Thread
|
|
||||||
xPSR: 0xc1000000 pc: 0x000000d4 msp: 0x200015d8
|
|
||||||
|
|
||||||
Checking ROM masking
|
|
||||||
Erasing sector 0x0f = offset 0x0f00
|
|
||||||
Region cleared OK
|
|
||||||
Erasing sector 0x1f = offset 0x1f00R=0xc3ff), Remaining 00 %
|
|
||||||
Region cleared OK
|
|
||||||
Writing at offset 0x1ffc (FLASH_ADDR=0xc7ff), Remaining 00 %
|
|
||||||
Checking ROM masking
|
|
||||||
|
|
||||||
ROM masking is set to 0b100. Setting ON...
|
|
||||||
shutdown command invoked
|
|
||||||
|
|
||||||
CPU reset: Transceiver should boot now.
|
|
||||||
|
|
||||||
>
|
|
||||||
|
|
||||||
___________________
|
|
||||||
DUMP SESSION:
|
|
||||||
------------
|
|
||||||
|
|
||||||
>openocd -f interface/stlink.cfg -f target/dp32g030.cfg -c "reset halt" -c "uv_unmask_rom" -c "dump_image testFFFF.bin 0 0x10000" -c "shutdown"
|
|
||||||
|
|
||||||
Open On-Chip Debugger 0.12.0 (2023-10-02) [https://github.com/sysprogs/openocd]
|
|
||||||
Licensed under GNU GPL v2
|
|
||||||
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
|
|
||||||
For bug reports, read
|
|
||||||
http://openocd.org/doc/doxygen/bugs.html
|
|
||||||
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
|
|
||||||
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
|
|
||||||
Info : clock speed 960 kHz
|
|
||||||
Info : STLINK V2J32S1 (API v2) VID:PID 0483:3748
|
|
||||||
Info : Target voltage: 3.263745
|
|
||||||
Info : [DP32G0xx.cpu] Cortex-M0 r0p0 processor detected
|
|
||||||
Info : [DP32G0xx.cpu] target has 4 breakpoints, 2 watchpoints
|
|
||||||
Info : starting gdb server for DP32G0xx.cpu on 3333
|
|
||||||
Info : Listening on port 3333 for gdb connections
|
|
||||||
[DP32G0xx.cpu] halted due to debug-request, current mode: Thread
|
|
||||||
xPSR: 0xc0000000 pc: 0xaaaaaaaa msp: 0xaaaaaaa8
|
|
||||||
|
|
||||||
Checking ROM masking
|
|
||||||
|
|
||||||
ROM masking is set to 0b110. Unsetting...
|
|
||||||
0x4
|
|
||||||
dumped 65536 bytes in 1.074061s (59.587 KiB/s)
|
|
||||||
shutdown command invoked
|
|
||||||
|
|
||||||
>
|
|
||||||
|
|
||||||
_________________
|
|
||||||
FIRMWARE ONLY:
|
|
||||||
-------------
|
|
||||||
|
|
||||||
>openocd -f interface/stlink.cfg -f target/dp32g030.cfg -c "reset halt" -c "rom_mask_off" -c "reset halt" -c "uv_flash_fw fw.dec.bin" -c "shutdown"
|
|
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
|
@ -1,9 +0,0 @@
|
||||||
@REM Fires 1-handed unbricking command using cheap ST-Link v2 "baite" debug probe
|
|
||||||
@REM No need to solder. Just press the right wires on the right pads with your fingers.
|
|
||||||
@REM Restores bootloader 2.00.06 with factory firmware 2.01.27
|
|
||||||
@ECHO ******** Launching 1 shot unbricking process with OpenOCD (STLink v2)...
|
|
||||||
@ECHO .
|
|
||||||
@CD OpenOCD
|
|
||||||
@openocd -f interface/stlink.cfg -f target/dp32g030.cfg -c "reset halt" -c "uv_flash_bl bootloader.bin" -c "uv_flash_fw k5_v2.01.27_fw.bin" -c "shutdown"
|
|
||||||
@PAUSE
|
|
||||||
|
|
Loading…
Reference in a new issue