@@ -53,6 +53,33 @@ def read_segment(address, length)
53
53
resp [ 2 ..-1 ] . pack ( 'C*' )
54
54
end
55
55
56
+ # Erases the sector _containing_ address. Sectors are probably 4096/0x1000 bytes.
57
+ def erase_sector_containing ( address )
58
+ write_command ( [ CMD [ :ERASE_SECTOR ] , ( address >> 16 ) & 0xFF , ( address >> 8 ) & 0xFF , address & 0xFF ] )
59
+ resp = read_response ( 2 , timeout : 5 )
60
+ raise "mismatched reply" if resp [ 0 ] != CMD [ :ERASE_SECTOR ]
61
+ raise "res #{ resp [ 1 ] } " if resp [ 1 ] != RES [ :OK ]
62
+ nil
63
+ end
64
+
65
+ def write_data ( address , data )
66
+ if data . length > 256
67
+ raise "looks like i2c can only deal with 256 bytes at a time"
68
+ end
69
+
70
+ write_command ( [
71
+ CMD [ :WRITE ] ,
72
+ ( address >> 16 ) & 0xFF , ( address >> 8 ) & 0xFF , address & 0xFF ,
73
+ ( data . length >> 8 ) & 0xFF , data . length & 0xFF ,
74
+ *data . bytes ,
75
+ ] )
76
+
77
+ resp = read_response ( 2 , timeout : 1 )
78
+ raise "mismatched reply" if resp [ 0 ] != CMD [ :WRITE ]
79
+ raise "res #{ resp [ 1 ] } " if resp [ 1 ] != RES [ :OK ]
80
+ nil
81
+ end
82
+
56
83
private
57
84
58
85
def write_command ( cmd )
@@ -106,22 +133,73 @@ def read_response(len, timeout:)
106
133
107
134
puts "connected!"
108
135
109
- puts "dumping 4MiB of flash in 512 byte increments"
110
- f = File . open ( "flash-contents.bin" , "wb" )
111
- addr = 0
112
- top = 4 * 1024 * 1024
113
- start = Time . now
114
- while addr < top
136
+ cmd = ARGV . shift
137
+
138
+ def spinner ( addr , top , start , code : nil , length : 80 )
139
+ xs = addr * length / top
140
+ spaces = length - xs
115
141
print "["
116
- print ( "X" * ( addr * 80 / top ) )
117
- print ( " " * ( ( top - addr ) * 80 / top ) )
118
- print "] #{ "/-\\ |" [ ( Time . now - start ) . to_i % 4 ] } #{ addr . to_s . reverse . scan ( /\d {3}|.+/ ) . join ( "," ) . reverse . rjust ( 9 ) } \r "
142
+ print ( "X" * xs )
143
+ print ( " " * spaces )
144
+ print "] #{ code ? " #{ code } " : "" } #{ "/-\\ |" [ ( Time . now - start ) . to_i % 4 ] } #{ addr . to_s . reverse . scan ( /\d {3}|.+/ ) . join ( "," ) . reverse . rjust ( 9 ) } \r "
119
145
STDOUT . flush
120
-
121
- segment = arduino . read_segment ( addr , 512 )
122
- f . write ( segment )
123
- addr += 512
124
146
end
125
- f . close
126
- f . write ( segment )
127
147
148
+ if cmd == "dump"
149
+ puts "dumping 4MiB of flash in 512 byte increments"
150
+ f = File . open ( "flash-contents.bin" , "wb" )
151
+ addr = 0
152
+ top = 4 * 1024 * 1024
153
+ start = Time . now
154
+ while addr < top
155
+ spinner ( addr , top , start )
156
+ segment = arduino . read_segment ( addr , 512 )
157
+ f . write ( segment )
158
+ addr += 512
159
+ end
160
+ spinner ( addr , top , start )
161
+ print "\n "
162
+ f . close
163
+
164
+ elsif cmd == "write"
165
+ file = ARGV . shift
166
+ raise "specify a filename" unless file
167
+
168
+ content = File . open ( file , "rb" , &:read )
169
+ puts "writing #{ content . length } bytes to flash in 256 byte increments"
170
+
171
+ addr = 0
172
+ start = Time . now
173
+ while addr < content . length
174
+ if addr % 4096 == 0
175
+ spinner ( addr , content . length , start , code : 'E' )
176
+ arduino . erase_sector_containing ( addr )
177
+ end
178
+ spinner ( addr , content . length , start , code : 'W' )
179
+ arduino . write_data ( addr , content [ addr ...addr +256 ] )
180
+ addr += 256
181
+ end
182
+ spinner ( addr , content . length , start )
183
+ print "\n "
184
+
185
+ elsif cmd == "verify"
186
+ file = ARGV . shift
187
+ raise "specify a filename" unless file
188
+
189
+ content = File . open ( file , "rb" , &:read )
190
+ puts "verifying #{ content . length } bytes in flash in 512 byte"
191
+
192
+ addr = 0
193
+ start = Time . now
194
+ while addr < content . length
195
+ spinner ( addr , content . length , start )
196
+ segment = arduino . read_segment ( addr , 512 )
197
+ if segment != content [ addr ...addr +512 ]
198
+ print "\n "
199
+ puts "verify error in bytes #{ addr } ...#{ addr +512 } "
200
+ end
201
+ addr += 512
202
+ end
203
+ spinner ( addr , content . length , start )
204
+ print "\n "
205
+ end
0 commit comments