mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-15 22:48:14 +08:00
357 lines
12 KiB
Tcl
357 lines
12 KiB
Tcl
#
|
|
# sflash_write.tcl
|
|
#
|
|
# This TCL OpenOCD script runs on a PC and communicates with the embedded
|
|
# sflash_write app to allow the PC to write data into a serial flash chip
|
|
# attached to the target processor
|
|
#
|
|
# Usage example:
|
|
#
|
|
# source [find mfg_spi_flash/write_sflash.tcl]
|
|
# sflash_init "MK3165@debug"
|
|
# sflash_write_file "example.bin" 0x10 "MK3165@debug" 1
|
|
# shutdown
|
|
#
|
|
###############################################################################
|
|
|
|
# CHIP_RAM_START must be supplied by target specific TCL script
|
|
set MemoryStart $CHIP_RAM_START
|
|
|
|
###############################################################################
|
|
#
|
|
# These variables must match the ones in Apps/waf/sflash_write/sflash_write.c
|
|
#
|
|
# They rely on the linker script placing the data_config_area_t and
|
|
# data_transfer_area_t structures at the start of RAM
|
|
#
|
|
###############################################################################
|
|
|
|
# This must match data_config_area_t
|
|
set entry_address_loc [expr $MemoryStart + 0x00 ]
|
|
set stack_address_loc [expr $MemoryStart + 0x04 ]
|
|
set buffer_size_loc [expr $MemoryStart + 0x08 ]
|
|
|
|
# This must match data_transfer_area_t
|
|
set data_size_loc [expr $MemoryStart + 0x0C ]
|
|
set dest_partition_loc [expr $MemoryStart + 0x10 ]
|
|
set dest_address_loc [expr $MemoryStart + 0x14 ]
|
|
set command_loc [expr $MemoryStart + 0x18 ]
|
|
set result_loc [expr $MemoryStart + 0x1C ]
|
|
set data_loc [expr $MemoryStart + 0x20 ]
|
|
|
|
|
|
# These must match the MFG_SPI_FLASH_COMMAND defines
|
|
set COMMAND_INITIAL_VERIFY (0x01)
|
|
set COMMAND_ERASE (0x02)
|
|
set COMMAND_WRITE (0x04)
|
|
set COMMAND_POST_WRITE_VERIFY (0x08)
|
|
set COMMAND_VERIFY_CHIP_ERASURE (0x10)
|
|
set COMMAND_WRITE_DCT (0x20)
|
|
set COMMAND_READ (0x40)
|
|
set COMMAND_WRITE_ERASE_IF_NEEDED (0x80)
|
|
set COMMAND_WRITE_DONE (0x100)
|
|
|
|
# These must match the mfg_spi_flash_result_t enum
|
|
set RESULT(0xffffffff) "In Progress"
|
|
set RESULT(4294967295) "In Progress"
|
|
set RESULT(0) "OK"
|
|
set RESULT(1) "Erase Failed"
|
|
set RESULT(2) "Verify after write failed"
|
|
set RESULT(3) "Size too big for buffer"
|
|
set RESULT(4) "Size too big for chip"
|
|
set RESULT(5) "DCT location not found - has factory reset app been written?"
|
|
set RESULT(6) "Error during Write"
|
|
set RESULT(7) "Error during Read"
|
|
|
|
|
|
###############################################################################
|
|
# memread32
|
|
#
|
|
# Helper function that reads a 32 bit value from RAM and returns it
|
|
#
|
|
# address - the RAM address to read from
|
|
###############################################################################
|
|
proc memread32 {address resume_required} {
|
|
if { $resume_required == 1 } {
|
|
halt
|
|
}
|
|
mem2array memar 32 $address 1
|
|
if { $resume_required == 1} {
|
|
resume
|
|
}
|
|
return $memar(0)
|
|
}
|
|
|
|
###############################################################################
|
|
# load_image_bin
|
|
#
|
|
# Loads part of a binary file into RAM
|
|
#
|
|
# fname - filename of binary image file
|
|
# foffset - offset from the start of the binary file where data will be read
|
|
# address - the destination RAM address
|
|
# length - number of bytes to transfer
|
|
###############################################################################
|
|
proc load_image_bin {fname foffset address length } {
|
|
# Load data from fname filename at foffset offset to
|
|
# target at address. Load at most length bytes.
|
|
puts "loadimage address $address foffset $foffset $length"
|
|
load_image $fname [expr $address - $foffset] bin $address $length
|
|
}
|
|
|
|
|
|
|
|
###############################################################################
|
|
# sflash_init
|
|
#
|
|
# Prepares for writing to serial flashby loading the sflash_write app into
|
|
# memory and setting it running.
|
|
# This function assumes the following target has already been built:
|
|
# waf.sflash_write-NoOS-<PlatBusDebug>
|
|
#
|
|
# PlatBusDebug - The platform, bus and debug part of the build target
|
|
# init4390 - run initialisation for the 4390
|
|
###############################################################################
|
|
proc sflash_init { PlatBusDebug } {
|
|
global entry_address_loc
|
|
global stack_address_loc
|
|
global buffer_size_loc
|
|
global entry_address
|
|
global stack_address
|
|
global buffer_size
|
|
|
|
init
|
|
reset init
|
|
reset halt
|
|
|
|
#load_image build/sub_build.spi_flash_write@NoRTOS@$PlatBusDebug/binary/sub_build.spi_flash_write@NoRTOS@$PlatBusDebug.elf
|
|
if {[file exists mico-os/board/$PlatBusDebug/flash_prog.elf]} {
|
|
load_image mico-os/board/$PlatBusDebug/flash_prog.elf
|
|
} else {
|
|
if {[file exists board/$PlatBusDebug/flash_prog.elf]} {
|
|
load_image board/$PlatBusDebug/flash_prog.elf
|
|
} else {
|
|
error "Error: Cann't find flash_prog.elf in $PlatBusDebug directory"
|
|
exit -1;
|
|
}
|
|
}
|
|
|
|
#mdw 0x000D0000 100
|
|
#mdw $entry_address_loc 100
|
|
|
|
set entry_address [memread32 $entry_address_loc 0]
|
|
set stack_address [memread32 $stack_address_loc 0]
|
|
set buffer_size [memread32 $buffer_size_loc 0]
|
|
|
|
puts "entry_address= $entry_address"
|
|
puts "stack_address= $stack_address"
|
|
puts "buffer_size= $buffer_size"
|
|
if { $buffer_size == 0 } {
|
|
error "Error: Buffer size read from address $buffer_size_loc on target is zero"
|
|
exit -1;
|
|
}
|
|
|
|
|
|
|
|
# Setup start address
|
|
reg pc $entry_address
|
|
reg sp $stack_address
|
|
|
|
resume
|
|
sleep 500
|
|
}
|
|
|
|
|
|
###############################################################################
|
|
# program_sflash
|
|
#
|
|
# Executes a serial command by communicating to the sflash_write app
|
|
#
|
|
# fname - filename of binary image file (if command requires it)
|
|
# foffset - offset from the start of the binary file where data will be read (if command requires it)
|
|
# dataSize - number of bytes to transfer (if command requires it)
|
|
# partition- the destination flash partition (if command requires it)
|
|
# destaddr - the destination offset address on a partition (if command requires it)
|
|
# cmd - The commmand to execute (see list above)
|
|
###############################################################################
|
|
proc program_sflash { filename foffset dataSize partition destaddr cmd } {
|
|
global PlatBusDebug MemoryStart data_size_loc dest_partition_loc data_loc dest_address_loc command_loc result_loc entry_address RESULT entry_address_loc
|
|
|
|
halt
|
|
# Load the binary data into the RAM
|
|
if { ( $dataSize != 0 ) && ( $filename != "" ) } {
|
|
load_image_bin $filename $foffset $data_loc $dataSize
|
|
}
|
|
|
|
# Write the details of the data
|
|
|
|
mww $data_size_loc $dataSize
|
|
mww $dest_partition_loc $partition
|
|
mww $dest_address_loc $destaddr
|
|
mww $result_loc 0xffffffff
|
|
|
|
puts "========================dest_address_loc= $destaddr"
|
|
#mdw $entry_address_loc 100
|
|
|
|
# Write the command - This causes the writing to start
|
|
mww $command_loc $cmd
|
|
resume
|
|
|
|
set resultval 0xffffffff
|
|
set loops 0
|
|
while { ($resultval == 0xffffffff) && ( $loops < 100 ) } {
|
|
sleep 100
|
|
set resultval [memread32 $result_loc 1]
|
|
incr loops
|
|
}
|
|
|
|
puts "****************** Result: $RESULT($resultval)"
|
|
|
|
if { $resultval != 0 } {
|
|
halt
|
|
reg
|
|
error "program_sflash error, Result: $RESULT($resultval)"
|
|
exit -1;
|
|
}
|
|
|
|
}
|
|
|
|
###############################################################################
|
|
# program_sflash_done
|
|
#
|
|
# Notice flash write is finished, perfor some post actions
|
|
#
|
|
###############################################################################
|
|
proc program_sflash_done { partition } {
|
|
global RESULT dest_partition_loc result_loc command_loc COMMAND_WRITE_DONE
|
|
|
|
halt
|
|
|
|
mww $dest_partition_loc $partition
|
|
mww $command_loc [expr $COMMAND_WRITE_DONE]
|
|
resume
|
|
|
|
set resultval 0xffffffff
|
|
set loops 0
|
|
while { ($resultval == 0xffffffff) && ( $loops < 100 ) } {
|
|
sleep 100
|
|
set resultval [memread32 $result_loc 1]
|
|
incr loops
|
|
}
|
|
|
|
puts "****************** Result: $RESULT($resultval)"
|
|
|
|
if { $resultval != 0 } {
|
|
halt
|
|
reg
|
|
error "program_sflash_done error, Result: $RESULT($resultval)"
|
|
exit -1;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
###############################################################################
|
|
# sflash_write_file
|
|
#
|
|
# Writes an entire binary image file to a serial flash address
|
|
# This function assumes the following target has already been built:
|
|
# waf.sflash_write-NoOS-<PlatBusDebug>
|
|
#
|
|
# filename - filename of binary image file
|
|
# partition - the destination flash partition
|
|
# destAddress - the destination flash partition offset address
|
|
# PlatBusDebug - The platform, bus and debug part of the build target
|
|
# erasechip - If 1, Erase the partition before writing.
|
|
# init4390 - run initialisation for the 4390
|
|
###############################################################################
|
|
proc sflash_write_file { filename partition destAddress PlatBusDebug erasechip } {
|
|
global COMMAND_ERASE COMMAND_INITIAL_VERIFY COMMAND_WRITE COMMAND_POST_WRITE_VERIFY buffer_size COMMAND_WRITE_ERASE_IF_NEEDED
|
|
|
|
sflash_init $PlatBusDebug
|
|
|
|
set binDataSize [file size $filename]
|
|
# set erase_command_val [expr $COMMAND_ERASE ]
|
|
set write_command_val [expr $COMMAND_WRITE_ERASE_IF_NEEDED | $COMMAND_POST_WRITE_VERIFY ]
|
|
set pos 0
|
|
|
|
# if { $erasechip } {
|
|
# puts "Erasing partition $partition"
|
|
# program_sflash $filename $pos 0 $partition $destAddress $erase_command_val
|
|
# puts "Chip Erase Done"
|
|
# }
|
|
|
|
puts "Total write size is $binDataSize to partition $partition"
|
|
while { $pos < $binDataSize } {
|
|
if { ($binDataSize - $pos) < $buffer_size } {
|
|
set writesize [expr ($binDataSize - $pos)]
|
|
} else {
|
|
set writesize $buffer_size
|
|
}
|
|
puts "writing $writesize bytes at [expr $destAddress + $pos]"
|
|
program_sflash $filename $pos $writesize $partition [expr $destAddress + $pos] $write_command_val
|
|
set pos [expr $pos + $writesize]
|
|
}
|
|
|
|
program_sflash_done $partition
|
|
}
|
|
|
|
|
|
|
|
###############################################################################
|
|
# sflash_read_file
|
|
#
|
|
# Reads data from a serial flash address
|
|
# This function assumes the following target has already been built:
|
|
# waf.sflash_write-NoOS-<PlatBusDebug>
|
|
#
|
|
# filename - output filename for binary image file
|
|
# srcAddress - the destination serial flash address
|
|
# PlatBusDebug - The platform, bus and debug part of the build target
|
|
# length - number of bytes to read
|
|
# init4390 - run initialisation for the 4390
|
|
###############################################################################
|
|
proc sflash_read_file { filename srcAddress PlatBusDebug length } {
|
|
global COMMAND_ERASE COMMAND_INITIAL_VERIFY COMMAND_WRITE COMMAND_POST_WRITE_VERIFY buffer_size COMMAND_READ data_loc
|
|
|
|
sflash_init $PlatBusDebug
|
|
set temp_file "temp.bin"
|
|
exec tools/common/Win32/echo -n > $filename
|
|
|
|
set read_command_val [expr $COMMAND_READ ]
|
|
set pos 0
|
|
|
|
puts "Total read size is $length"
|
|
while { $pos < $length } {
|
|
if { ($length - $pos) < $buffer_size } {
|
|
set readsize [expr ($length - $pos)]
|
|
} else {
|
|
set readsize $buffer_size
|
|
}
|
|
puts "reading $readsize bytes from [expr $srcAddress + $pos]"
|
|
program_sflash "" $pos $readsize [expr $srcAddress + $pos] $read_command_val
|
|
# mem2array memar 8 [expr $data_loc-8] 1024
|
|
# puts "$memar(0) $memar(1) $memar(2) $memar(3) $memar(4) $memar(5) $memar(6) $memar(7) $memar(8)"
|
|
puts "dumping image from $data_loc $readsize"
|
|
halt
|
|
dump_image $temp_file $data_loc $readsize
|
|
|
|
exec cat $temp_file >> $filename
|
|
set pos [expr $pos + $readsize]
|
|
}
|
|
}
|
|
|
|
|
|
|
|
proc sflash_erase { PlatBusDebug } {
|
|
global COMMAND_ERASE COMMAND_INITIAL_VERIFY COMMAND_WRITE COMMAND_POST_WRITE_VERIFY buffer_size COMMAND_WRITE_ERASE_IF_NEEDED
|
|
|
|
sflash_init $PlatBusDebug
|
|
|
|
set erase_command_val [expr $COMMAND_ERASE ]
|
|
|
|
puts "Erasing Chip"
|
|
program_sflash "" 0 0 0 $erase_command_val
|
|
puts "Chip Erase Done"
|
|
}
|