diff --git a/openocd-scripts/include_eeprom.tcl b/openocd-scripts/include_eeprom.tcl new file mode 100644 index 0000000..9de8fc3 --- /dev/null +++ b/openocd-scripts/include_eeprom.tcl @@ -0,0 +1,276 @@ +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; +} diff --git a/openocd-scripts/interface/ftdi/mikron-link.cfg b/openocd-scripts/interface/ftdi/mikron-link.cfg new file mode 100644 index 0000000..8882295 --- /dev/null +++ b/openocd-scripts/interface/ftdi/mikron-link.cfg @@ -0,0 +1,19 @@ +# +# FT2232HL for openOCD Device +# +# According to the sch file, it uses BDBUS. +# + +interface ftdi +# ftdi_device_desc "Dual RS232-HS (Interface 1)" +ftdi_vid_pid 0x0403 0x6010 + +# ftdi_channel 0 is port ADBUS, ftdi_channel 1 is port BDBUS. +ftdi_channel 1 + +transport select jtag +# adapter_khz 500 + +ftdi_layout_init 0x00f8 0x00fb +ftdi_layout_signal nSRST -noe 0x0040 +ftdi_layout_signal nTRST -data 0x0010 diff --git a/openocd-scripts/target/mik32.cfg b/openocd-scripts/target/mik32.cfg new file mode 100644 index 0000000..5a1534c --- /dev/null +++ b/openocd-scripts/target/mik32.cfg @@ -0,0 +1,24 @@ + + +proc init_targets {} { + + adapter speed 500 + reset_config trst_and_srst + + set _CHIPNAME riscv + set _CPUTAPID 0xdeb11001 + + jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID + + jtag newtap $_CHIPNAME sys -irlen 4 -ircapture 0x05 -irmask 0x0F -enable + + set _TARGETNAME $_CHIPNAME.cpu + + target create $_TARGETNAME riscv -endian little -chain-position $_TARGETNAME -coreid 0 +} + +poll_period 200 + +init +puts "init done" +