mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +00:00
34 files changed
+603
No files matched your search
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,119 @@
|
||||
# Unbricking the UV-K5 V1
|
||||
|
||||
<img width="2016" height="1512" alt="pcbite" src="https://github.com/user-attachments/assets/b3086bf2-c14c-47da-b68b-a6867268ae78" />
|
||||
|
||||
Restoring a UV-K5 V1 accidentally flashed with the F4HWN 4.3 Fusion 🔥 Edition firmware, using OpenOCD and a ST-LINK programmer.
|
||||
|
||||
## Introduction
|
||||
|
||||
Some users have accidentally flashed a UV-K5 V1 with the F4HWN 4.3 Fusion 🔥 Edition firmware. This edition **is only** compatible with:
|
||||
|
||||
- UV-K5 V3
|
||||
- UV-K1
|
||||
|
||||
When flashed onto a UV-K5 V1, it causes a complete brick, such as:
|
||||
|
||||
- The radio does not power on anymore
|
||||
- DFU mode is unavailable
|
||||
- No LED activity
|
||||
- Flashing tools cannot detect the device
|
||||
|
||||
Fortunately, the UV-K5 V1 can be fully restored by using OpenOCD and a ST-LINK programmer.
|
||||
|
||||
## Requirements
|
||||
|
||||
You will need:
|
||||
|
||||
- A ST-LINK V2 programmer (original or clone)
|
||||
- Four Dupont jumper wires
|
||||
- A small screwdriver to open the radio
|
||||
- A computer with OpenOCD installed (Windows / macOS / Linux).
|
||||
|
||||
## SWD connection points on the UV-K5 V1
|
||||
|
||||
The radio must be opened to access the front side of the PCB.
|
||||
The UV-K5 V1 exposes a 4-pin SWD (Serial Wire Debug) interface:
|
||||
|
||||
|Signal| UV-K5 V1 Pad| ST-LINK Pin|
|
||||
|:-------- |:--------:| --------:|
|
||||
|GND |GND pad | GND |
|
||||
|SWCLK |SWCLK pad | SWCLK
|
||||
|SWDIO |SWDIO pad | SWDIO
|
||||
|3.3V | VCC pad | 3.3V |
|
||||
|
||||
<img width="750" height="500" alt="bottom" src="https://github.com/user-attachments/assets/381a9bc5-daac-4547-820e-a5c96c0bd2e1" />
|
||||
|
||||
> [!WARNING]
|
||||
> Do not connect the battery while using the ST-LINK.
|
||||
The ST-LINK provides 3.3V to the board.
|
||||
|
||||
## Installing OpenOCD
|
||||
|
||||
### macOS (Homebrew)
|
||||
|
||||
`brew install openocd`
|
||||
|
||||
### Windows
|
||||
|
||||
Download the official build from:
|
||||
|
||||
- [Website](https://openocd.org/pages/getting-openocd.html)
|
||||
- [GitHub](https://github.com/openocd-org/openocd/releases)
|
||||
|
||||
### Linux (Ubuntu / Debian)
|
||||
|
||||
`sudo apt install openocd`
|
||||
|
||||
### Verify installation
|
||||
|
||||
`openocd --version`
|
||||
|
||||
## Download unbrick toolkit
|
||||
|
||||
Download the [unbrick toolkit archive](https://github.com/user-attachments/files/24002834/unbrick_k5_v1.zip) and extract it on your PC.
|
||||
|
||||
## Unbrick procedure
|
||||
|
||||
### Connect the ST-LINK
|
||||
|
||||
1. Connect the ST-LINK pins to the SWD pads:
|
||||
|
||||
* 3.3V → 3.3V
|
||||
* SWDIO → SWDIO
|
||||
* SWCLK → SWCLK
|
||||
* GND → GND
|
||||
|
||||
2. Plug the ST-LINK into your computer.
|
||||
3. Power on your UV-K5 V1 (normal mode).
|
||||
|
||||
### Flash the bootloader
|
||||
|
||||
From the `unbrick_k5_v1` directory:
|
||||
|
||||
#### Option A — Use the helper script
|
||||
|
||||
`
|
||||
./unbrick_k5_v1.sh
|
||||
`
|
||||
|
||||
#### Option B — Run the OpenOCD command manually
|
||||
|
||||
`
|
||||
openocd -f ./interface/stlink.cfg -f ./target/dp32g030.cfg -c "init; reset halt; uv_flash_bl bootloader.bin; shutdown"
|
||||
`
|
||||
|
||||
|
||||
https://github.com/user-attachments/assets/a511fdb3-a3a3-4fe1-91cc-31e765221b22
|
||||
|
||||
|
||||
If no errors appear, the bootloader has been successfully restored.
|
||||
|
||||
- Disconnect and remove the ST-LINK from your UV-K5 V1 SWD port
|
||||
- Reinstall the battery
|
||||
- Power on the radio on DFU mode
|
||||
|
||||
The device should now start correctly on DFU mode again. You can then flash stock firmware, or the [F4HWN firmware for UV-K5 V1](https://github.com/armel/uv-k5-firmware-custom) (not the Fusion 🔥 Edition).
|
||||
|
||||
# Disclaimer
|
||||
|
||||
This procedure requires opening the device and directly manipulating its microcontroller over SWD. Incorrect use may permanently damage the radio. Proceed at your own risk.
|
||||
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
# 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"
|
||||
@@ -0,0 +1,4 @@
|
||||
# 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]
|
||||
@@ -0,0 +1,4 @@
|
||||
# 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]
|
||||
@@ -0,0 +1,4 @@
|
||||
# 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]
|
||||
@@ -0,0 +1,18 @@
|
||||
# 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.
|
After Width: | Height: | Size: 685 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 696 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.4 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.3 MiB |
Binary file not shown.
@@ -0,0 +1,359 @@
|
||||
#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 binary_to_int {data} {
|
||||
# Complète la chaîne à 4 octets si nécessaire
|
||||
set data $data[string repeat \xFF [expr {4 - [string length $data]}]]
|
||||
|
||||
# Initialise le résultat à 0
|
||||
set result 0
|
||||
|
||||
# Parcourt les octets et assemble l'entier
|
||||
for {set i 0} {$i < 4} {incr i} {
|
||||
# Récupère l'octet à la position $i
|
||||
set byte [scan [string index $data $i] %c]
|
||||
# Décale l'octet en fonction de l'ordre Little Endian
|
||||
set result [expr {$result | ($byte & 0xFF) << (8 * $i)}]
|
||||
}
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
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
|
||||
set i_data [binary_to_int $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
|
||||
@@ -0,0 +1,34 @@
|
||||
# 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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# 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
|
||||
}
|
||||
}
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
openocd -f ./interface/stlink.cfg -f ./target/dp32g030.cfg -c "init; reset halt; uv_flash_bl bootloader.bin; shutdown"
|
||||
Reference in new issue
Block a user