@@ -11,7 +11,7 @@ use crate::{
11
11
elf:: { ElfFirmwareImage , FirmwareImage , FlashFrequency , FlashMode , RomSegment } ,
12
12
error:: { ConnectionError , FlashDetectError , ResultExt } ,
13
13
image_format:: ImageFormatId ,
14
- Error , PartitionTable ,
14
+ Error , PartitionTable , stubs :: FlashStub ,
15
15
} ;
16
16
17
17
const DEFAULT_TIMEOUT : Duration = Duration :: from_secs ( 3 ) ;
@@ -192,6 +192,7 @@ impl Flasher {
192
192
serial : Box < dyn SerialPort > ,
193
193
port_info : UsbPortInfo ,
194
194
speed : Option < u32 > ,
195
+ use_stub : bool ,
195
196
) -> Result < Self , Error > {
196
197
// Establish a connection to the device using the default baud rate of 115,200
197
198
// and timeout of 3 seconds.
@@ -209,6 +210,13 @@ impl Flasher {
209
210
flash_size : FlashSize :: Flash4Mb ,
210
211
spi_params : SpiAttachParams :: default ( ) ,
211
212
} ;
213
+
214
+ // Load flash stub if enabled
215
+ if use_stub {
216
+ println ! ( "Using flash stub" ) ;
217
+ flasher. load_stub ( ) ?;
218
+ }
219
+
212
220
flasher. spi_autodetect ( ) ?;
213
221
214
222
// Now that we have established a connection and detected the chip and flash
@@ -228,11 +236,65 @@ impl Flasher {
228
236
Ok ( flasher)
229
237
}
230
238
239
+ /// Load flash stub
240
+ fn load_stub ( & mut self ) -> Result < ( ) , Error > {
241
+
242
+ println ! ( "Loading flash stub for chip: {:?}" , self . chip) ;
243
+
244
+ // Load flash stub
245
+ let stub = FlashStub :: get ( self . chip ) . unwrap ( ) ;
246
+
247
+ let mut ram_target = self . chip . ram_target ( Some ( stub. entry ( ) ) ) ;
248
+ ram_target. begin ( & mut self . connection ) . flashing ( ) ?;
249
+
250
+ let ( text_addr, text) = stub. text ( ) ;
251
+ println ! ( "Write {} byte stub text" , text. len( ) ) ;
252
+
253
+ ram_target. write_segment (
254
+ & mut self . connection ,
255
+ RomSegment {
256
+ addr : text_addr,
257
+ data : Cow :: Borrowed ( & text) ,
258
+ } ,
259
+ )
260
+ . flashing ( ) ?;
261
+
262
+
263
+ let ( data_addr, data) = stub. data ( ) ;
264
+ println ! ( "Write {} byte stub data" , data. len( ) ) ;
265
+
266
+ ram_target. write_segment (
267
+ & mut self . connection ,
268
+ RomSegment {
269
+ addr : data_addr,
270
+ data : Cow :: Borrowed ( & data) ,
271
+ } ,
272
+ )
273
+ . flashing ( ) ?;
274
+
275
+ println ! ( "Finish stub write" ) ;
276
+ ram_target. finish ( & mut self . connection , true ) . flashing ( ) ?;
277
+
278
+ println ! ( "Stub written..." ) ;
279
+
280
+ // Re-sync connection
281
+ self . connection . sync ( ) ?;
282
+
283
+ // Re-detect chip to check stub is up
284
+ let magic = self . connection . read_reg ( CHIP_DETECT_MAGIC_REG_ADDR ) ?;
285
+ let chip = Chip :: from_magic ( magic) ?;
286
+ println ! ( "Re-detected chip: {:?}" , chip) ;
287
+
288
+ Ok ( ( ) )
289
+ }
290
+
231
291
fn spi_autodetect ( & mut self ) -> Result < ( ) , Error > {
232
292
// Loop over all available SPI parameters until we find one that successfully
233
293
// reads the flash size.
234
294
for spi_params in TRY_SPI_PARAMS . iter ( ) . copied ( ) {
235
- self . enable_flash ( spi_params) ?;
295
+ if let Err ( _e) = self . enable_flash ( spi_params) {
296
+ continue ;
297
+ }
236
298
if let Some ( flash_size) = self . flash_detect ( ) ? {
237
299
// Flash detection was successful, so save the flash size and SPI parameters and
238
300
// return.
0 commit comments