Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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
- scan [string index $data 0] %c b0
- scan [string index $data 1] %c b1
- scan [string index $data 2] %c b2
- scan [string index $data 3] %c b3
- set i_data [expr {($b0 & 0xFF) | (($b1 & 0xFF) << 8) | (($b2 & 0xFF) << 16) | (($b3 & 0xFF) << 24)}]
- 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
Advertisement
Add Comment
Please, Sign In to add comment