-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathopenocd_fe310_is25lp032d_flash_write.tcl
More file actions
149 lines (120 loc) · 4.3 KB
/
Copy pathopenocd_fe310_is25lp032d_flash_write.tcl
File metadata and controls
149 lines (120 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# ============================================================
# FE310 Flash Write — 256-byte pages
# ============================================================
echo off
source [find mem_helper.tcl]
reset_config srst_only srst_nogate
adapter srst delay 800
adapter srst pulse_width 800
init
reset halt
sleep 1000
# ------------------------------------------------------------
# Accept arguments
# ------------------------------------------------------------
if {![info exists write_addr]} { set write_addr 0 }
if {![info exists write_file]} {
puts "ERROR: write_file not specified"
shutdown
}
# ------------------------------------------------------------
# HARDWARE-DEPENDENT PARAMS
# ------------------------------------------------------------
set loader_addr 0x80000000
set flash_capacity 0x00400000
set PAGE_SIZE 256
# Control structure offsets
set off_STKOFF 0x00
set off_RMEMOFF 0x04
set off_CMDCTR 0x08
set off_STATUS 0x0C
set off_RQX 0x10
set off_ERR 0x14
set off_FMEMADDR 0x18
set off_FMEMSIZE 0x1C
set off_LOADER_MAJOR 0x20
set off_LOADER_MINOR 0x24
set RQX_FLASH_WRITE_PAGE 7
# ------------------------------------------------------------
# Load loader into RAM
# ------------------------------------------------------------
halt
load_image loader.bin $loader_addr
reg pc $loader_addr
set ctrl_addr [expr {$loader_addr + 8}]
# Let loader initialize
resume
wait_halt 10000
# ------------------------------------------------------------
# Determine buffer address
# ------------------------------------------------------------
set rmemoff [mrw [expr {$ctrl_addr + $off_RMEMOFF}]]
set buffer_addr [expr {$loader_addr + $rmemoff}]
puts [format "Buffer address = 0x%08X (%d)" $buffer_addr $buffer_addr]
puts [format "Write address = 0x%08X (%d)" $write_addr $write_addr]
puts "Input file = $write_file"
# ------------------------------------------------------------
# Helper: check loader error
# ------------------------------------------------------------
proc check_error {ctrl_addr} {
set err [mrw [expr {$ctrl_addr + 0x14}]]
if {$err != 0} {
puts "ERROR: Loader reported error $err"
shutdown
}
}
# ------------------------------------------------------------
# Read input file into Tcl binary string
# ------------------------------------------------------------
set fh [open $write_file "rb"]
fconfigure $fh -translation binary
set filedata [read $fh]
close $fh
set filelen [string length $filedata]
puts [format "File length = %d bytes" $filelen]
# ------------------------------------------------------------
# Compute number of pages
# ------------------------------------------------------------
set pages [expr { ($filelen + $PAGE_SIZE - 1) / $PAGE_SIZE }]
puts [format "Total pages = %d" $pages]
set cur_addr $write_addr
set offset 0
# ------------------------------------------------------------
# Main write loop
# ------------------------------------------------------------
for {set i 0} {$i < $pages} {incr i} {
puts [format "Writing page %d / %d at 0x%08X" $i $pages $cur_addr]
# Extract up to 256 bytes
set chunk [string range $filedata $offset [expr {$offset + $PAGE_SIZE - 1}]]
set chunk_len [string length $chunk]
# Pad with 0xFF if needed
if {$chunk_len < $PAGE_SIZE} {
set pad_len [expr {$PAGE_SIZE - $chunk_len}]
append chunk [binary format "c$pad_len" {*}[lrepeat $pad_len 0xFF]]
}
# Write chunk into RAM buffer
mww [expr {$ctrl_addr + $off_FMEMSIZE}] $PAGE_SIZE
mww [expr {$ctrl_addr + $off_FMEMADDR}] $cur_addr
# Write 256 bytes into RAM buffer, byte by byte
for {set j 0} {$j < $PAGE_SIZE} {incr j} {
set byte [scan [string index $chunk $j] %c]
#set byte 105
mwb [expr {$buffer_addr + $j}] $byte
}
# Issue write command
mww [expr {$ctrl_addr + $off_RQX}] $RQX_FLASH_WRITE_PAGE
# Skip ebreak
set pc_hex [lindex [reg pc] end]
reg pc [expr {$pc_hex + 4}]
sleep 4
resume
wait_halt 10000
check_error $ctrl_addr
# Advance
set offset [expr {$offset + $PAGE_SIZE}]
set cur_addr [expr {$cur_addr + $PAGE_SIZE}]
sleep 4
}
puts "Flash write complete."
sleep 10
shutdown