RTL8710 Flasher

https://bitbucket.org/rebane/rtl8710_openocd/

rtl8710_openocd / script / rtl8710.ocd

#
# OpenOCD script for RTL8710
# Copyright (C) Rebane, rebane@alkohol.ee
# source [find target/swj-dp.tcl] if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME rtl8710
} if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
} if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x800
} if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x2ba01477
} swj_newdap $_CHIPNAME cpu -irlen -expected-id $_CPUTAPID set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME $_TARGETNAME configure -work-area-phys 0x10001000 -work-area-size $_WORKAREASIZE -work-area-backup adapter_khz
adapter_nsrst_delay if {![using_hla]} {
cortex_m reset_config sysresetreq
} set rtl8710_flasher_firmware_ptr 0x10001000
set rtl8710_flasher_buffer 0x10008000
set rtl8710_flasher_buffer_size
set rtl8710_flasher_sector_size array set rtl8710_flasher_code {
0xB671B57F 0x25FF4B58 0x6B196B1A 0x7040F042 0x69D96318 0xF4414E55
0x69D97480 0xF8D361DC 0xF8C32120 0xF8D35120 0xF8C31124 0x47B05124
0x47B04E4F 0x47984B4F 0x60104A4F 0x484F47B0 0x60012100 0x2C006804
0x4D4DD0FC 0xB93E682E 0x60264C49 0x47B04E46 0x47984B46 0xE7ED6020
0x2B01682B 0x4E42D109 0x4C4647B0 0x47A02006 0x47904A45 0x47A020C7
0x682AE00D 0xD10E2A02 0x47B04E3B 0x20064C3F 0x483F47A0 0x493F4780
0x68084D3F 0x47B047A8 0x47A02004 0x6828E7CE 0xD1132803 0x47A04C32
0x24004838 0x4E396805 0x68311960 0xD206428C 0x4B384A37 0x221018A1
0x34104798 0x4D2AE7F3 0xE7B847A8 0x29046829 0x2400D11B 0x6806482F
0xD2B042B4 0x47A84D24 0x20064E28 0x4B2847B0 0x49284798 0x680A4B2A
0x18A018E1 0xF44F4B2A 0x47987280 0x200447A8 0xF50447B0 0x47A87480
0x682CE7E4 0xD1232C05 0x47984B17 0x4D1F2400 0x4294682A 0x481BD28F
0x68012210 0x18604E1D 0x47B04669 0x1B19682B 0xBF282910 0x23002110
0xD011428B 0xF81D4A16 0x18A05003 0x42B55CC6 0x3301D101 0x4A15E7F4
0x60112101 0xE7726054 0x25014E12 0xE76E6035 0x47A84D03 0xE7D63410
0x40000200 0x100011BD 0x100013DD 0x10001289 0x1000800C 0x10008000
0x10008004 0x1000130D 0x100013ED 0x10008010 0x10001335 0x10008014
0x10008020 0x10001221 0x10001375 0x10008008 0x6A5A4B03 0xD0FB0512
0x0060F893 0xBF004770 0x40006000 0x6B194B17 0xF4416B1A 0x63187040
0x69186919 0x0110F041 0xF8D36119 0x220000C0 0x0106F020 0x00C0F8D3
0x10C0F8C3 0x00C0F8D3 0x0101F040 0x00C0F8D3 0x10C0F8C3 0x43BCF503
0x609A6899 0x20016AD9 0x691962DA 0x69596118 0x61592102 0x619A6999
0x61DA69D9 0x64DA6CD9 0xBF004770 0x40000200 0x460EB570 0xB34A4614
0xF3C04B15 0x681A4507 0x7240F44F 0x685A601A 0xF3C02103 0x2C102207
0x2410BF28 0x605CB2C0 0x1060F883 0x5060F883 0xF8832101 0xF8832060
0x689A0060 0x60992500 0x47984B08 0x35015570 0x42A2B2AA 0x4804D3F8
0xF0116A81 0xD1FA0301 0x60836881 0xBD704620 0x40006000 0x100011A9
0x4C10B5F8 0x68232003 0x7340F44F 0x68636023 0x60602101 0x68A3229F
0x60A14D0B 0x2060F884 0x460647A8 0x460747A8 0x040347A8 0x2707EA43
0x0006EA47 0x4B036AA1 0x0201F011 0x6899D1FA 0xBDF8609A 0x40006000
0x100011A9 0x4C0BB510 0x68232001 0x7340F44F 0x68636023 0x60602105
0x60A068A2 0xF8844A06 0x47901060 0x4B036AA1 0x0201F011 0x6899D1FA
0xBD10609A 0x40006000 0x100011A9 0x21014B08 0xF44F681A 0x601A7280
0x6099689A 0x0060F883 0x48036A9A 0x0101F012 0x6883D1FA 0x47706081
0x40006000 0x21014B0E 0xF44F681A 0x601A7280 0x2220689A 0xF8836099
0xF3C02060 0xF3C04107 0xB2C02207 0x1060F883 0x2060F883 0x0060F883
0x4A036A99 0x0001F011 0x6893D1FA 0x47706090 0x40006000 0xB36AB530
0x25014B17 0xF44F681C 0x601C7480 0x2402689C 0xF883609D 0xF3C04060
0xF3C04507 0xB2C02407 0x5060F883 0x7F80F5B2 0xF44FBF28 0xF8837280
0xF8834060 0x20000060 0x4C095C0D 0xF8843001 0xB2855060 0xD3F74295
0x07496A99 0x6AA0D5FC 0xF0104B03 0xD1FA0101 0x60996898 0xBD304610
0x40006000 0x4B02B508 0x07C04798 0xBD08D4FB 0x100012D5 0x4B04B508
0xF0004798 0xB2C10002 0xD0F82900 0xBF00BD08 0x100012D5
} set rtl8710_flasher_command_read_id
set rtl8710_flasher_command_mass_erase
set rtl8710_flasher_command_sector_erase
set rtl8710_flasher_command_read
set rtl8710_flasher_command_write
set rtl8710_flasher_command_verify set rtl8710_flasher_mac_address_offset 0xA088 set rtl8710_flasher_ready
set rtl8710_flasher_capacity
set rtl8710_flasher_auto_erase
set rtl8710_flasher_auto_verify
set rtl8710_flasher_auto_erase_sector 0xFFFFFFFF proc rtl8710_flasher_init {} {
global rtl8710_flasher_firmware_ptr
global rtl8710_flasher_buffer
global rtl8710_flasher_capacity
global rtl8710_flasher_ready
global rtl8710_flasher_code if {[expr {$rtl8710_flasher_ready == }]} {
echo "initializing RTL8710 flasher"
halt
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
array2mem rtl8710_flasher_code $rtl8710_flasher_firmware_ptr [array size rtl8710_flasher_code]
reg faultmask 0x01
reg sp 0x20000000
reg pc $rtl8710_flasher_firmware_ptr
resume
rtl8710_flasher_wait
set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]]
set rtl8710_flasher_capacity [expr { ** [expr {($id >> ) & 0xFF}]}]
set rtl8710_flasher_ready
echo "RTL8710 flasher initialized"
}
return ""
} proc rtl8710_flasher_mrw {reg} {
set value ""
mem2array value $reg
return $value()
} proc rtl8710_flasher_wait {} {
global rtl8710_flasher_buffer
while {[rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x00}]]} { }
} proc rtl8710_flasher_load_block {local_filename offset len} {
global rtl8710_flasher_buffer
load_image $local_filename [expr {$rtl8710_flasher_buffer + 0x20 - $offset}] bin [expr {$rtl8710_flasher_buffer + 0x20}] $len
} proc rtl8710_flasher_read_block {offset len} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_read
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x14}] $len
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]]
if {[expr {$status > }]} {
error "read error, offset $offset"
}
} proc rtl8710_flasher_write_block {offset len} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_write
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_write
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x14}] $len
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]]
if {[expr {$status > }]} {
error "write error, offset $offset"
}
} proc rtl8710_flasher_verify_block {offset len} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_verify
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_verify
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x14}] $len
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]]
if {[expr {$status > }]} {
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]]
set status [expr {$status + $offset}]
error "verify error, offset $status"
}
} proc rtl8710_flash_read_id {} {
global rtl8710_flasher_buffer
global rtl8710_flasher_capacity
global rtl8710_flasher_command_read_id
rtl8710_flasher_init
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read_id
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]]
set manufacturer_id [format "0x%02X" [expr {$id & 0xFF}]]
set memory_type [format "0x%02X" [expr {($id >> ) & 0xFF}]]
set memory_capacity [expr { ** [expr {($id >> ) & 0xFF}]}]
echo "manufacturer ID: $manufacturer_id, memory type: $memory_type, memory capacity: $memory_capacity bytes"
} proc rtl8710_flash_mass_erase {} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_mass_erase
rtl8710_flasher_init
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_mass_erase
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
} proc rtl8710_flash_sector_erase {offset} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_sector_erase
rtl8710_flasher_init
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_sector_erase
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
} proc rtl8710_flash_read {local_filename loc size} {
global rtl8710_flasher_buffer
global rtl8710_flasher_buffer_size
rtl8710_flasher_init
for {set offset } {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} {
set len [expr {$size - $offset}]
if {[expr {$len > $rtl8710_flasher_buffer_size}]} {
set len $rtl8710_flasher_buffer_size
}
set flash_offset [expr {$loc + $offset}]
echo "read offset $flash_offset"
rtl8710_flasher_read_block $flash_offset $len
dump_image /tmp/_rtl8710_flasher.bin [expr {$rtl8710_flasher_buffer + 0x20}] $len
exec dd conv=notrunc if=/tmp/_rtl8710_flasher.bin "of=$local_filename" bs= "seek=$offset"
echo "read $len bytes"
}
} proc rtl8710_flash_write {local_filename loc} {
global rtl8710_flasher_buffer_size
global rtl8710_flasher_sector_size
global rtl8710_flasher_auto_erase
global rtl8710_flasher_auto_verify
global rtl8710_flasher_auto_erase_sector
rtl8710_flasher_init
set sector
set size [file size $local_filename]
for {set offset } {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} {
set len [expr {$size - $offset}]
if {[expr {$len > $rtl8710_flasher_buffer_size}]} {
set len $rtl8710_flasher_buffer_size
}
set flash_offset [expr {$loc + $offset}]
echo "write offset $flash_offset"
rtl8710_flasher_load_block $local_filename $offset $len
if {[expr {$rtl8710_flasher_auto_erase != }]} {
for {set i $flash_offset} {$i < [expr {$flash_offset + $len}]} {incr i} {
set sector [expr {$i / $rtl8710_flasher_sector_size}]
if {[expr {$rtl8710_flasher_auto_erase_sector != $sector}]} {
echo "erase sector $sector"
rtl8710_flash_sector_erase [expr {$sector * $rtl8710_flasher_sector_size}]
set rtl8710_flasher_auto_erase_sector $sector
}
}
}
rtl8710_flasher_write_block $flash_offset $len
echo "wrote $len bytes"
if {[expr {$rtl8710_flasher_auto_verify != }]} {
echo "verify offset $flash_offset"
rtl8710_flasher_verify_block $flash_offset $len
}
}
} proc rtl8710_flash_verify {local_filename loc} {
global rtl8710_flasher_buffer_size
rtl8710_flasher_init
set size [file size $local_filename]
for {set offset } {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} {
set len [expr {$size - $offset}]
if {[expr {$len > $rtl8710_flasher_buffer_size}]} {
set len $rtl8710_flasher_buffer_size
}
set flash_offset [expr {$loc + $offset}]
echo "read offset $flash_offset"
rtl8710_flasher_load_block $local_filename $offset $len
echo "verify offset $flash_offset"
rtl8710_flasher_verify_block $flash_offset $len
}
} proc rtl8710_flash_read_mac {} {
global rtl8710_flasher_mac_address_offset
global rtl8710_flasher_buffer
rtl8710_flasher_init
rtl8710_flasher_read_block $rtl8710_flasher_mac_address_offset
set mac ""
mem2array mac [expr {$rtl8710_flasher_buffer + 0x20}]
set res "MAC address: "
append res [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
echo $res
} proc rtl8710_flash_auto_erase {on} {
global rtl8710_flasher_auto_erase
if {[expr {$on != }]} {
set rtl8710_flasher_auto_erase
echo "auto erase on"
} else {
set rtl8710_flasher_auto_erase
echo "auto erase off"
}
} proc rtl8710_flash_auto_verify {on} {
global rtl8710_flasher_auto_verify
if {[expr {$on != }]} {
set rtl8710_flasher_auto_verify
echo "auto verify on"
} else {
set rtl8710_flasher_auto_verify
echo "auto verify off"
}
} proc rtl8710_reboot {} {
mww 0xE000ED0C 0x05FA0007
}

rtl8710_openocd / rtl8710_flasher.tcl

set rtl8710_flasher_command_read_id
set rtl8710_flasher_command_mass_erase
set rtl8710_flasher_command_sector_erase
set rtl8710_flasher_command_read
set rtl8710_flasher_command_write
set rtl8710_flasher_command_verify set rtl8710_flasher_mac_address_offset 0xA088 set rtl8710_flasher_ready
set rtl8710_flasher_capacity
set rtl8710_flasher_auto_erase
set rtl8710_flasher_auto_verify
set rtl8710_flasher_auto_erase_sector 0xFFFFFFFF proc rtl8710_flasher_init {} {
global rtl8710_flasher_firmware_ptr
global rtl8710_flasher_buffer
global rtl8710_flasher_capacity
global rtl8710_flasher_ready
global rtl8710_flasher_code if {[expr {$rtl8710_flasher_ready == }]} {
echo "initializing RTL8710 flasher"
halt
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
array2mem rtl8710_flasher_code $rtl8710_flasher_firmware_ptr [array size rtl8710_flasher_code]
reg faultmask 0x01
reg sp 0x20000000
reg pc $rtl8710_flasher_firmware_ptr
resume
rtl8710_flasher_wait
set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]]
set rtl8710_flasher_capacity [expr { ** [expr {($id >> ) & 0xFF}]}]
set rtl8710_flasher_ready
echo "RTL8710 flasher initialized"
}
return ""
} proc rtl8710_flasher_mrw {reg} {
set value ""
mem2array value $reg
return $value()
} proc rtl8710_flasher_wait {} {
global rtl8710_flasher_buffer
while {[rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x00}]]} { }
} proc rtl8710_flasher_load_block {local_filename offset len} {
global rtl8710_flasher_buffer
load_image $local_filename [expr {$rtl8710_flasher_buffer + 0x20 - $offset}] bin [expr {$rtl8710_flasher_buffer + 0x20}] $len
} proc rtl8710_flasher_read_block {offset len} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_read
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x14}] $len
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]]
if {[expr {$status > }]} {
error "read error, offset $offset"
}
} proc rtl8710_flasher_write_block {offset len} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_write
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_write
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x14}] $len
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]]
if {[expr {$status > }]} {
error "write error, offset $offset"
}
} proc rtl8710_flasher_verify_block {offset len} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_verify
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_verify
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x14}] $len
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]]
if {[expr {$status > }]} {
set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]]
set status [expr {$status + $offset}]
error "verify error, offset $status"
}
} proc rtl8710_flash_read_id {} {
global rtl8710_flasher_buffer
global rtl8710_flasher_capacity
global rtl8710_flasher_command_read_id
rtl8710_flasher_init
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read_id
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]]
set manufacturer_id [format "0x%02X" [expr {$id & 0xFF}]]
set memory_type [format "0x%02X" [expr {($id >> ) & 0xFF}]]
set memory_capacity [expr { ** [expr {($id >> ) & 0xFF}]}]
echo "manufacturer ID: $manufacturer_id, memory type: $memory_type, memory capacity: $memory_capacity bytes"
} proc rtl8710_flash_mass_erase {} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_mass_erase
rtl8710_flasher_init
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_mass_erase
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
} proc rtl8710_flash_sector_erase {offset} {
global rtl8710_flasher_buffer
global rtl8710_flasher_command_sector_erase
rtl8710_flasher_init
mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_sector_erase
mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000
mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset
mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001
rtl8710_flasher_wait
} proc rtl8710_flash_read {local_filename loc size} {
global rtl8710_flasher_buffer
global rtl8710_flasher_buffer_size
rtl8710_flasher_init
for {set offset } {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} {
set len [expr {$size - $offset}]
if {[expr {$len > $rtl8710_flasher_buffer_size}]} {
set len $rtl8710_flasher_buffer_size
}
set flash_offset [expr {$loc + $offset}]
echo "read offset $flash_offset"
rtl8710_flasher_read_block $flash_offset $len
dump_image /tmp/_rtl8710_flasher.bin [expr {$rtl8710_flasher_buffer + 0x20}] $len
exec dd conv=notrunc if=/tmp/_rtl8710_flasher.bin "of=$local_filename" bs= "seek=$offset"
echo "read $len bytes"
}
} proc rtl8710_flash_write {local_filename loc} {
global rtl8710_flasher_buffer_size
global rtl8710_flasher_sector_size
global rtl8710_flasher_auto_erase
global rtl8710_flasher_auto_verify
global rtl8710_flasher_auto_erase_sector
rtl8710_flasher_init
set sector
set size [file size $local_filename]
for {set offset } {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} {
set len [expr {$size - $offset}]
if {[expr {$len > $rtl8710_flasher_buffer_size}]} {
set len $rtl8710_flasher_buffer_size
}
set flash_offset [expr {$loc + $offset}]
echo "write offset $flash_offset"
rtl8710_flasher_load_block $local_filename $offset $len
if {[expr {$rtl8710_flasher_auto_erase != }]} {
for {set i $flash_offset} {$i < [expr {$flash_offset + $len}]} {incr i} {
set sector [expr {$i / $rtl8710_flasher_sector_size}]
if {[expr {$rtl8710_flasher_auto_erase_sector != $sector}]} {
echo "erase sector $sector"
rtl8710_flash_sector_erase [expr {$sector * $rtl8710_flasher_sector_size}]
set rtl8710_flasher_auto_erase_sector $sector
}
}
}
rtl8710_flasher_write_block $flash_offset $len
echo "wrote $len bytes"
if {[expr {$rtl8710_flasher_auto_verify != }]} {
echo "verify offset $flash_offset"
rtl8710_flasher_verify_block $flash_offset $len
}
}
} proc rtl8710_flash_verify {local_filename loc} {
global rtl8710_flasher_buffer_size
rtl8710_flasher_init
set size [file size $local_filename]
for {set offset } {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} {
set len [expr {$size - $offset}]
if {[expr {$len > $rtl8710_flasher_buffer_size}]} {
set len $rtl8710_flasher_buffer_size
}
set flash_offset [expr {$loc + $offset}]
echo "read offset $flash_offset"
rtl8710_flasher_load_block $local_filename $offset $len
echo "verify offset $flash_offset"
rtl8710_flasher_verify_block $flash_offset $len
}
} proc rtl8710_flash_read_mac {} {
global rtl8710_flasher_mac_address_offset
global rtl8710_flasher_buffer
rtl8710_flasher_init
rtl8710_flasher_read_block $rtl8710_flasher_mac_address_offset
set mac ""
mem2array mac [expr {$rtl8710_flasher_buffer + 0x20}]
set res "MAC address: "
append res [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
append res ":" [format %02X $mac()]
echo $res
} proc rtl8710_flash_auto_erase {on} {
global rtl8710_flasher_auto_erase
if {[expr {$on != }]} {
set rtl8710_flasher_auto_erase
echo "auto erase on"
} else {
set rtl8710_flasher_auto_erase
echo "auto erase off"
}
} proc rtl8710_flash_auto_verify {on} {
global rtl8710_flasher_auto_verify
if {[expr {$on != }]} {
set rtl8710_flasher_auto_verify
echo "auto verify on"
} else {
set rtl8710_flasher_auto_verify
echo "auto verify off"
}
} proc rtl8710_reboot {} {
mww 0xE000ED0C 0x05FA0007
}

tl8710_openocd / rtl8710_flasher.c

/*
*
* Copyright (C) 2016 Rebane, rebane@alkohol.ee
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
* Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/ #include "rtl8710.h"
#include <stdio.h>
#include "spi_flash.h" #define MEM_START (*(volatile uint32_t *)(BUFFER_ADDRESS + 0x00))
#define MEM_COMMAND (*(volatile uint32_t *)(BUFFER_ADDRESS + 0x04))
#define MEM_STATUS (*(volatile uint32_t *)(BUFFER_ADDRESS + 0x08))
#define MEM_PARAM (*(volatile uint32_t *)(BUFFER_ADDRESS + 0x0C))
#define MEM_OFFSET (*(volatile uint32_t *)(BUFFER_ADDRESS + 0x10))
#define MEM_LEN (*(volatile uint32_t *)(BUFFER_ADDRESS + 0x14))
#define MEM_DATA ((volatile uint8_t *)(BUFFER_ADDRESS + 0x20)) #define COMMAND_READ_ID 0
#define COMMAND_MASS_ERASE 1
#define COMMAND_SECTOR_ERASE 2
#define COMMAND_READ 3
#define COMMAND_WRITE 4
#define COMMAND_VERIFY 5 int __attribute__((section(".vectors"))) main(){
uint32_t p, i, l;
uint8_t read_buffer[]; __asm__("cpsid f"); PERI_ON->PESOC_CLK_CTRL |= PERI_ON_CLK_CTRL_ACTCK_GPIO_EN | PERI_ON_CLK_CTRL_SLPCK_GPIO_EN; // enable gpio peripheral clock
PERI_ON->SOC_PERI_FUNC1_EN |= PERI_ON_SOC_PERI_FUNC1_EN_GPIO; // enable gpio peripheral PERI_ON->GPIO_SHTDN_CTRL = 0xFF;
PERI_ON->GPIO_DRIVING_CTRL = 0xFF; spi_flash_init(); // read jedec info
spi_flash_wait_busy();
MEM_PARAM = spi_flash_jedec_id();
spi_flash_wait_busy(); while(){
MEM_START = 0x00000000;
while(MEM_START == 0x00000000);
if(MEM_COMMAND == COMMAND_READ_ID){
MEM_PARAM = 0x00000000;
spi_flash_wait_busy();
MEM_PARAM = spi_flash_jedec_id();
spi_flash_wait_busy();
}else if(MEM_COMMAND == COMMAND_MASS_ERASE){
spi_flash_wait_busy();
spi_flash_cmd(0x06);
spi_flash_wait_wel();
spi_flash_cmd(0xC7);
spi_flash_wait_busy();
spi_flash_cmd(0x04);
spi_flash_wait_busy();
}else if(MEM_COMMAND == COMMAND_SECTOR_ERASE){
spi_flash_wait_busy();
spi_flash_cmd(0x06);
spi_flash_wait_wel();
spi_flash_sector_erase(MEM_OFFSET);
spi_flash_wait_busy();
spi_flash_cmd(0x04);
spi_flash_wait_busy();
}else if(MEM_COMMAND == COMMAND_READ){
spi_flash_wait_busy();
p = MEM_OFFSET;
for(i = ; i < MEM_LEN; i += , p += ){
spi_flash_read(p, (void *)&MEM_DATA[i], );
}
spi_flash_wait_busy();
}else if(MEM_COMMAND == COMMAND_WRITE){
for(p = ; p < MEM_LEN; p += ){
spi_flash_wait_busy();
spi_flash_cmd(0x06);
spi_flash_wait_wel();
spi_flash_write((MEM_OFFSET + p), (void *)&MEM_DATA[p], );
spi_flash_wait_busy();
spi_flash_cmd(0x04);
spi_flash_wait_busy();
}
}else if(MEM_COMMAND == COMMAND_VERIFY){
spi_flash_wait_busy();
for(p = ; p < MEM_LEN; p += ){
spi_flash_read((MEM_OFFSET + p), read_buffer, );
l = MEM_LEN - p;
if(l > )l = ;
for(i = ; i < l; i++){
if(read_buffer[i] != MEM_DATA[p + i]){
break;
}
}
if(i < l){
MEM_STATUS = 0x00000001;
MEM_PARAM = p;
break;
}
spi_flash_wait_busy();
}
}else{
MEM_STATUS = 0x00000001;
}
}
}

rtl8710_openocd / spi_flash.h

/*
*
* Copyright (C) 2016 Rebane, rebane@alkohol.ee
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
* Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/ #ifndef _SPI_FLASH_H_
#define _SPI_FLASH_H_ #include <stdint.h> void spi_flash_init();
uint16_t spi_flash_read(uint32_t address, void *buf, uint16_t count);
uint16_t spi_flash_write(uint32_t address, const void *buf, uint16_t count);
uint32_t spi_flash_jedec_id();
uint8_t spi_flash_status();
void spi_flash_cmd(uint8_t cmd);
void spi_flash_sector_erase(uint32_t address);
void spi_flash_wait_busy();
void spi_flash_wait_wel(); #endif

rtl8710_openocd / spi_flash.c

/*
*
* Copyright (C) 2016 Rebane, rebane@alkohol.ee
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
* Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/ #include "spi_flash.h"
#include "rtl8710.h"
#include "mask.h" static void spi_flash_send(uint8_t byte){
// while(!(SPI_FLASH->SR & SPI_SR_TFNF));
SPI_FLASH->DR = byte;
} static uint8_t spi_flash_recv(){
while(!(SPI_FLASH->RXFLR & 0x0FFF));
return(SPI_FLASH->DR);
} void spi_flash_init(){
PERI_ON->PESOC_CLK_CTRL |= PERI_ON_CLK_CTRL_ACTCK_FLASH_EN | PERI_ON_CLK_CTRL_SLPCK_FLASH_EN; // enable spi flash peripheral clock
PERI_ON->SOC_FUNC_EN |= PERI_ON_SOC_FUNC_EN_FLASH; // enable spi flash peripheral
mask32_set(PERI_ON->CPU_PERIPHERAL_CTRL, PERI_ON_CPU_PERIPHERAL_CTRL_SPI_FLASH_PIN_SEL, ); // select spi flash pinout (0 - internal)
PERI_ON->CPU_PERIPHERAL_CTRL |= PERI_ON_CPU_PERIPHERAL_CTRL_SPI_FLASH_PIN_EN; // enable spi flash pins SPI_FLASH->SSIENR = ; // disable SPI FLASH operation
SPI_FLASH->IMR = ; // disable all interrupts
SPI_FLASH->SER = SPI_SER_SS0; // use first "slave select" pin
SPI_FLASH->BAUDR = ; // baud rate, default value
SPI_FLASH->TXFTLR = ; // tx fifo threshold
SPI_FLASH->RXFTLR = ; // rx fifo threshold
SPI_FLASH->DMACR = ; // disable DMA
} uint16_t spi_flash_read(uint32_t address, void *buf, uint16_t count){
uint16_t i;
if(!count)return();
if(count > )count = ;
SPI_FLASH->CTRLR0 = mask32(SPI_CTRLR0_TMOD, ) | mask32(SPI_CTRLR0_CMD_CH, ) | mask32(SPI_CTRLR0_ADDR_CH, ) | mask32(SPI_CTRLR0_DATA_CH, );
SPI_FLASH->CTRLR1 = count; spi_flash_send(0x03); // flash command "read"
spi_flash_send((address >> ) & 0xFF); // address * 3
spi_flash_send((address >> ) & 0xFF);
spi_flash_send((address >> ) & 0xFF); SPI_FLASH->SSIENR = ; for(i = ; i < count; i++){
((uint8_t *)buf)[i] = spi_flash_recv();
}
while(SPI_FLASH->SR & SPI_SR_SSI);
SPI_FLASH->SSIENR = ;
return(count);
} uint32_t spi_flash_jedec_id(){
uint32_t id;
SPI_FLASH->CTRLR0 = mask32(SPI_CTRLR0_TMOD, ) | mask32(SPI_CTRLR0_CMD_CH, ) | mask32(SPI_CTRLR0_ADDR_CH, ) | mask32(SPI_CTRLR0_DATA_CH, );
SPI_FLASH->CTRLR1 = ; SPI_FLASH->SSIENR = ;
spi_flash_send(0x9F); // jedec id
id = spi_flash_recv();
id |= ((uint32_t)spi_flash_recv() << );
id |= ((uint32_t)spi_flash_recv() << );
while(SPI_FLASH->SR & SPI_SR_SSI);
SPI_FLASH->SSIENR = ;
return(id);
} uint8_t spi_flash_status(){
uint8_t status;
SPI_FLASH->CTRLR0 = mask32(SPI_CTRLR0_TMOD, ) | mask32(SPI_CTRLR0_CMD_CH, ) | mask32(SPI_CTRLR0_ADDR_CH, ) | mask32(SPI_CTRLR0_DATA_CH, );
SPI_FLASH->CTRLR1 = ; SPI_FLASH->SSIENR = ;
spi_flash_send(0x05); // read status
status = spi_flash_recv();
while(SPI_FLASH->SR & SPI_SR_SSI);
SPI_FLASH->SSIENR = ;
return(status);
} void spi_flash_cmd(uint8_t cmd){
SPI_FLASH->CTRLR0 = mask32(SPI_CTRLR0_TMOD, ) | mask32(SPI_CTRLR0_CMD_CH, ) | mask32(SPI_CTRLR0_ADDR_CH, ) | mask32(SPI_CTRLR0_DATA_CH, ); SPI_FLASH->SSIENR = ;
spi_flash_send(cmd);
while(SPI_FLASH->SR & SPI_SR_SSI);
SPI_FLASH->SSIENR = ;
} void spi_flash_sector_erase(uint32_t address){
SPI_FLASH->CTRLR0 = mask32(SPI_CTRLR0_TMOD, ) | mask32(SPI_CTRLR0_CMD_CH, ) | mask32(SPI_CTRLR0_ADDR_CH, ) | mask32(SPI_CTRLR0_DATA_CH, ); SPI_FLASH->SSIENR = ;
spi_flash_send(0x20); // sector erase
spi_flash_send((address >> ) & 0xFF);
spi_flash_send((address >> ) & 0xFF);
spi_flash_send((address >> ) & 0xFF);
while(SPI_FLASH->SR & SPI_SR_SSI);
SPI_FLASH->SSIENR = ;
} uint16_t spi_flash_write(uint32_t address, const void *buf, uint16_t count){
uint16_t i;
if(!count)return();
if(count > )count = ;
SPI_FLASH->CTRLR0 = mask32(SPI_CTRLR0_TMOD, ) | mask32(SPI_CTRLR0_CMD_CH, ) | mask32(SPI_CTRLR0_ADDR_CH, ) | mask32(SPI_CTRLR0_DATA_CH, ); SPI_FLASH->SSIENR = ;
spi_flash_send(0x02); // write
spi_flash_send((address >> ) & 0xFF);
spi_flash_send((address >> ) & 0xFF);
spi_flash_send((address >> ) & 0xFF);
for(i = ; i < count; i++){
spi_flash_send(((uint8_t *)buf)[i]);
}
while(!(SPI_FLASH->SR & SPI_SR_TFE));
while(SPI_FLASH->SR & SPI_SR_SSI);
SPI_FLASH->SSIENR = ;
return(count);
} void spi_flash_wait_busy(){
while(spi_flash_status() & 0x01);
} void spi_flash_wait_wel(){
while(!(spi_flash_status() & 0x02));
}

rtl8710_openocd / make_array.c

#include <stdio.h>
#include <stdint.h>
#include <unistd.h> int main(){
ssize_t i, l;
uint32_t value, index;
uint8_t buffer[];
index = ;
while(){
l = read(, buffer, );
if(l < )break;
printf("\t");
for(i = ; i < l; i += ){
value = ((uint32_t)buffer[i + ] << ) | ((uint32_t)buffer[i + ] << ) | ((uint32_t)buffer[i + ] << ) | ((uint32_t)buffer[i + ] << );
if(i)printf(" ");
printf("%d 0x%08X", index++, (unsigned int)value);
}
printf("\n");
}
}

RTL-8710 openocd support

OpenOCD support for RTL8710 and integrated flash.

pins:

SWD

  • SWDIO: GE3
  • SWCLK: GE4

JTAG

  • TRST: GE0
  • TDI: GE1
  • TDO: GE2
  • TMS: GE3
  • TCK: GE4

building:

make

available OpenOCD commands:

rtl8710_flash_read_id

read and parse the jedec id bytes from flash

rtl8710_flash_read_mac

read MAC address from flash memory at 0xA088

rtl8710_flash_mass_erase

erase whole flash

rtl8710_flash_read [filename] [offset] [size]

dump (size) bytes from flash offset (offset) to file (filename)

rtl8710_flash_write [filename] [offset]

write file (filename) to flash offset (offset)

rtl8710_flash_verify [filename] [offset]

compare file (filename) with flash offset (offset)

rtl8710_flash_auto_erase [1/0]

set auto_erase option on/off. flash sectors will be autoerased when writing

rtl8710_flash_auto_verify [1/0]

set auto_verify option on/off. each block of data will be auto verified when writing

examples:

openocd -f interface/stlink-v2-1.cfg -f rtl8710.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "rtl8710_flash_read dump.bin 0 1048576" -c "shutdown"
openocd -f interface/stlink-v2-1.cfg -f rtl8710.ocd -c "init" -c "reset halt" -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" -c "rtl8710_flash_write dump.bin 0" -c "shutdown"

About

RTL8710 OpenOCD support is created by Rebane (rebane@alkohol.ee)

This document and the attached source code is released under GPLv2.

上一篇:高危预警|RDP漏洞或引发大规模蠕虫爆发,用户可用阿里云免费检测服务自检,建议尽快修复


下一篇:【转】测试LibreOffice SDK 开发环境配置(Windows)