mirror of
https://github.com/MikronMIK32/mik32-uploader.git
synced 2026-01-01 13:37:03 +03:00
277 lines
8.4 KiB
Tcl
277 lines
8.4 KiB
Tcl
set EEPROM_REGS_BASE_ADDRESS 0x00070400
|
|
|
|
set EEPROM_REGS_EEDAT [expr {($EEPROM_REGS_BASE_ADDRESS + 0x00)}]
|
|
set EEPROM_REGS_EEA [expr {($EEPROM_REGS_BASE_ADDRESS + 0x04)}]
|
|
set EEPROM_REGS_EECON [expr {($EEPROM_REGS_BASE_ADDRESS + 0x08)}]
|
|
set EEPROM_REGS_EESTA [expr {($EEPROM_REGS_BASE_ADDRESS + 0x0C)}]
|
|
set EEPROM_REGS_EERB [expr {($EEPROM_REGS_BASE_ADDRESS + 0x10)}]
|
|
set EEPROM_REGS_EEADJ [expr {($EEPROM_REGS_BASE_ADDRESS + 0x14)}]
|
|
set EEPROM_REGS_NCYCRL [expr {($EEPROM_REGS_BASE_ADDRESS + 0x18)}]
|
|
set EEPROM_REGS_NCYCEP1 [expr {($EEPROM_REGS_BASE_ADDRESS + 0x1C)}]
|
|
set EEPROM_REGS_NCYCEP2 [expr {($EEPROM_REGS_BASE_ADDRESS + 0x20)}]
|
|
|
|
#--------------------------
|
|
# EEPROM register fields
|
|
#--------------------------
|
|
#EECON
|
|
set EEPROM_EX_S 0
|
|
set EEPROM_OP_S 1
|
|
set EEPROM_WRBEH_S 3
|
|
set EEPROM_APBNWS_S 5
|
|
set EEPROM_DISECC_S 6
|
|
set EEPROM_BWE_S 7
|
|
set EEPROM_IESERR_S 8
|
|
#EESTA
|
|
set EEPROM_BSY_S 0
|
|
set EEPROM_SERR_S 1
|
|
#NCYCRL
|
|
set EEPROM_N_LD_S 0
|
|
set EEPROM_N_R_1_S 8
|
|
set EEPROM_N_R_2_S 16
|
|
#--------------------------
|
|
# EEPROM codes
|
|
#--------------------------
|
|
set EEPROM_OP_RD 0
|
|
set EEPROM_OP_ER 1
|
|
set EEPROM_OP_PR 2
|
|
set EEPROM_BEH_EVEN 1
|
|
set EEPROM_BEH_ODD 2
|
|
set EEPROM_BEH_GLOB 3
|
|
|
|
set EEPROM_PAGE_MASK 0x1F80
|
|
|
|
#set NO_CH [expr (0<<1)]
|
|
|
|
proc eeprom_print_error {a_text} {
|
|
puts -nonewline "\033\[1;31m"; #RED
|
|
puts "ERROR: $a_text"
|
|
puts -nonewline "\033\[0m";# Reset
|
|
}
|
|
|
|
proc eeprom_sysinit {} {
|
|
puts "MCU clock init..."
|
|
mww 0x00060010 0x202
|
|
mww 0x0005001C 0xffffffff
|
|
mww 0x00050014 0xffffffff
|
|
mww 0x0005000C 0xffffffff
|
|
}
|
|
|
|
proc eeprom_global_erase {} {
|
|
puts "EEPROM global erase..."
|
|
mww $::EEPROM_REGS_NCYCRL [expr {(1<<$::EEPROM_N_LD_S | 3<<$::EEPROM_N_R_1_S | 1 << $::EEPROM_N_R_2_S)}];
|
|
mww $::EEPROM_REGS_NCYCEP1 100000;
|
|
mww $::EEPROM_REGS_NCYCEP2 1000;
|
|
sleep 100;
|
|
mww $::EEPROM_REGS_EECON [expr {(1 << $::EEPROM_BWE_S) | ($::EEPROM_BEH_GLOB << $::EEPROM_WRBEH_S)}]; #prepare to buffer load
|
|
mww $::EEPROM_REGS_EEA 0x00000000;
|
|
#buffer load
|
|
for {set i 0} {$i < 32} {incr i} {
|
|
mww $::EEPROM_REGS_EEDAT 0x00000000;
|
|
}
|
|
#start operation
|
|
mww $::EEPROM_REGS_EECON [expr {(1 << $::EEPROM_EX_S) | (1 << $::EEPROM_BWE_S) | ($::EEPROM_OP_ER << $::EEPROM_OP_S) | ($::EEPROM_BEH_GLOB << $::EEPROM_WRBEH_S)}];
|
|
#eeprom_global_erase_check;
|
|
}
|
|
|
|
proc eeprom_global_erase_check {} {
|
|
puts "EEPROM global erase check through APB...";
|
|
puts " Read Data at ..."
|
|
set ex_value 0x00000000;
|
|
mww $::EEPROM_REGS_EEA 0x00000000;
|
|
for {set i 0} {$i < 64} {incr i} {
|
|
puts " Row=$i...";
|
|
for {set j 0} {$j < 32} {incr j} {
|
|
set value {};
|
|
mem2array value 32 $::EEPROM_REGS_EEDAT 1;
|
|
if {$ex_value != $value(0)} {
|
|
eeprom_print_error "Unexpect value at Row $i, Word $j, expect $ex_value, get $value"
|
|
return 1
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
proc eeprom_write_word {a_addr a_data} {
|
|
mww $::EEPROM_REGS_EECON [expr {(1 << $::EEPROM_BWE_S)}]; #prepare to buffer load
|
|
mww $::EEPROM_REGS_EEA $a_addr;
|
|
#buffer load
|
|
mww $::EEPROM_REGS_EEDAT $a_data;
|
|
#puts "[format "%#.4x" $a_addr]: $a_data";
|
|
#for {set i 0} {$i < 32} {incr i} {
|
|
# mww $::EEPROM_REGS_EEDAT 0x00000000;
|
|
#}
|
|
#start operation
|
|
mww $::EEPROM_REGS_EECON [expr {(1 << $::EEPROM_EX_S) | (1 << $::EEPROM_BWE_S) | ($::EEPROM_OP_PR << $::EEPROM_OP_S)}]
|
|
sleep 1
|
|
}
|
|
|
|
proc eeprom_write_page {a_addr a_data} {
|
|
mww $::EEPROM_REGS_EECON [expr {(1 << $::EEPROM_BWE_S)}]; #prepare to buffer load
|
|
mww $::EEPROM_REGS_EEA $a_addr;
|
|
set page_address [expr {$a_addr & $::EEPROM_PAGE_MASK}]
|
|
set n 0
|
|
# buffer load
|
|
foreach word $a_data {
|
|
if {[expr {($a_addr + $n) & $::EEPROM_PAGE_MASK}] != $page_address} {
|
|
eeprom_print_error "word outside page! page_address=$page_address"
|
|
return 1
|
|
}
|
|
mww $::EEPROM_REGS_EEDAT $word;
|
|
}
|
|
mww $::EEPROM_REGS_EECON [expr {(1 << $::EEPROM_EX_S) | (1 << $::EEPROM_BWE_S) | ($::EEPROM_OP_PR << $::EEPROM_OP_S)}]
|
|
sleep 1
|
|
}
|
|
|
|
proc eeprom_hex_reverse_bytes {str} {
|
|
if {[string length $str] != 8} {
|
|
eeprom_print_error "eeprom_hex_reverse_bytes string length != 8";
|
|
return 1;
|
|
}
|
|
return "[string range $str 6 7][string range $str 4 5][string range $str 2 3][string range $str 0 1]";
|
|
}
|
|
|
|
proc eeprom_hex_parse_file {a_filename} {
|
|
puts "EEPROM reading $a_filename..."
|
|
set fp [open $a_filename r];
|
|
set list {};
|
|
while {[gets $fp s1] > 0} {
|
|
if {[string range $s1 1 2] == "10"} {
|
|
lappend list [eeprom_hex_reverse_bytes [string range $s1 9 16]];
|
|
lappend list [eeprom_hex_reverse_bytes [string range $s1 17 24]];
|
|
lappend list [eeprom_hex_reverse_bytes [string range $s1 25 32]];
|
|
lappend list [eeprom_hex_reverse_bytes [string range $s1 33 40]];
|
|
}
|
|
}
|
|
close $fp;
|
|
return $list;
|
|
}
|
|
|
|
proc eeprom_check_data_apb {data} {
|
|
puts "EEPROM check through APB...";
|
|
mww $::EEPROM_REGS_EEA 0x00000000;
|
|
set list_size [llength $data]
|
|
set ll 0
|
|
set progress 2
|
|
puts -nonewline "\["
|
|
set value {}
|
|
foreach byte $data {
|
|
mem2array value 32 $::EEPROM_REGS_EEDAT 1
|
|
#mem2array value 32 $::EEPROM_REGS_EEDAT 1;
|
|
scan $byte %x decimal
|
|
if {$decimal != [lindex $value 1]} {
|
|
eeprom_print_error "Unexpect value at $ll word, expect $decimal $byte, get $value"
|
|
return 1
|
|
};
|
|
incr ll;
|
|
if {[expr {($ll * 100) / $list_size}] > $progress} {
|
|
puts -nonewline "#"
|
|
set progress [expr {$progress + 2}]
|
|
}
|
|
}
|
|
puts "\]";
|
|
puts "EEPROM check through APB done!"
|
|
}
|
|
|
|
proc eeprom_check_data_ahb_lite {a_words} {
|
|
puts "EEPROM check through AHB-Lite..."
|
|
set len_words [llength $a_words]
|
|
# set mem_array [read_memory 0x01000000 32 $len_words]
|
|
mem2array mem_array 32 0x01000000 $len_words
|
|
if {$len_words != [expr {[llength $mem_array] / 2}]} {
|
|
eeprom_print_error "Wrong number of words in read_memory output!"
|
|
return 1
|
|
}
|
|
set progress 0
|
|
puts -nonewline "\[";
|
|
for {set word_num 0} {$word_num < $len_words} {incr word_num} {
|
|
if {"0x[lindex $a_words $word_num]" != [dict get $mem_array $word_num]} {
|
|
eeprom_print_error "Unexpect value at $word_num word, expect 0x[lindex $a_words $word_num], get [lindex $mem_array $word_num]"
|
|
return 1
|
|
}
|
|
set curr_progress [expr {($word_num * 50) / $len_words}]
|
|
if {$curr_progress > $progress} {
|
|
for {set i 0} {$i < [expr {$curr_progress - $progress}]} {incr i} {
|
|
puts -nonewline "#";
|
|
}
|
|
set progress $curr_progress;
|
|
}
|
|
}
|
|
puts "\]";
|
|
puts "EEPROM check through APB done!";
|
|
}
|
|
|
|
proc eeprom_write_file {a_filename} {
|
|
eeprom_sysinit;
|
|
eeprom_global_erase;
|
|
mww $::EEPROM_REGS_NCYCRL [expr {(1<<$::EEPROM_N_LD_S | 3<<$::EEPROM_N_R_1_S | 1 << $::EEPROM_N_R_2_S)}];
|
|
mww $::EEPROM_REGS_NCYCEP1 100000;
|
|
mww $::EEPROM_REGS_NCYCEP2 1000;
|
|
sleep 100;
|
|
set words [eeprom_hex_parse_file $a_filename];
|
|
set list_size [llength $words];
|
|
set word_num 0
|
|
set progress 0
|
|
puts "EEPROM writing $a_filename...";
|
|
puts -nonewline "\[";
|
|
|
|
set page {}
|
|
set page_num 0
|
|
set page_size 32
|
|
while {$word_num < $list_size} {
|
|
if {$word_num < [expr {$page_size*($page_num+1)}]} {
|
|
lappend page "0x[lindex $words $word_num]"
|
|
incr word_num;
|
|
} else {
|
|
# print(list(map(lambda word: f"{word:#0x}", page)))
|
|
eeprom_write_page [expr {$page_num*$page_size*4}] $page;
|
|
incr page_num;
|
|
set page {}; # page.clear()
|
|
}
|
|
set curr_progress [expr {($word_num * 50) / $list_size}]
|
|
if {$curr_progress > $progress} {
|
|
for {set i 0} {$i < [expr {$curr_progress - $progress}]} {incr i} {
|
|
puts -nonewline "#";
|
|
}
|
|
set progress $curr_progress;
|
|
}
|
|
|
|
|
|
# eeprom_write_word [expr {$ll*4}] 0x$byte;
|
|
# incr ll;
|
|
# if {[expr {($ll * 100) / $list_size}] > $progress} {
|
|
# puts -nonewline "#";
|
|
# set progress [expr {$progress + 2}];
|
|
# }
|
|
}
|
|
eeprom_write_page [expr {$page_num*$page_size*4}] $page;
|
|
puts "\]";
|
|
puts "EEPROM write file done!";
|
|
eeprom_check_data_ahb_lite $words;
|
|
}
|
|
|
|
proc eeprom_write_file_by_word {a_filename} {
|
|
eeprom_sysinit;
|
|
eeprom_global_erase;
|
|
mww $::EEPROM_REGS_NCYCRL [expr {(1<<$::EEPROM_N_LD_S | 3<<$::EEPROM_N_R_1_S | 1 << $::EEPROM_N_R_2_S)}];
|
|
mww $::EEPROM_REGS_NCYCEP1 100000;
|
|
mww $::EEPROM_REGS_NCYCEP2 1000;
|
|
sleep 100;
|
|
set bytes [eeprom_hex_parse_file $a_filename];
|
|
set list_size [llength $bytes];
|
|
set ll 0;
|
|
set progress 2;
|
|
puts "EEPROM writing a_filename..."
|
|
puts -nonewline "\[";
|
|
foreach byte $bytes {
|
|
eeprom_write_word [expr {$ll*4}] 0x$byte;
|
|
incr ll;
|
|
if {[expr {($ll * 100) / $list_size}] > $progress} {
|
|
puts -nonewline "#";
|
|
set progress [expr {$progress + 2}];
|
|
}
|
|
}
|
|
puts "\]";
|
|
puts "EEPROM write file done!";
|
|
eeprom_check_data_apb $bytes;
|
|
}
|