11use crate :: connection:: Connection ;
22use crate :: elf:: { FirmwareImage , RomSegment } ;
33use crate :: error:: Error ;
4- use crate :: flasher:: { get_erase_size , Command , SpiAttachParams , FLASH_WRITE_SIZE } ;
5- use crate :: flashtarget:: { begin_command, block_command , FlashTarget } ;
4+ use crate :: flasher:: { Command , SpiAttachParams , FLASH_SECTOR_SIZE , FLASH_WRITE_SIZE } ;
5+ use crate :: flashtarget:: { begin_command, block_command_with_timeout , FlashTarget } ;
66use crate :: Chip ;
7+ use flate2:: write:: { ZlibDecoder , ZlibEncoder } ;
8+ use flate2:: Compression ;
79use indicatif:: { ProgressBar , ProgressStyle } ;
10+ use std:: io:: Write ;
811
912pub struct Esp32Target {
1013 chip : Chip ,
@@ -35,21 +38,26 @@ impl FlashTarget for Esp32Target {
3538 segment : RomSegment ,
3639 ) -> Result < ( ) , Error > {
3740 let addr = segment. addr ;
38- let block_count = ( segment. data . len ( ) + FLASH_WRITE_SIZE - 1 ) / FLASH_WRITE_SIZE ;
41+ let mut encoder = ZlibEncoder :: new ( Vec :: new ( ) , Compression :: best ( ) ) ;
42+ encoder. write_all ( & segment. data ) ?;
43+ let compressed = encoder. finish ( ) ?;
44+ let block_count = ( compressed. len ( ) + FLASH_WRITE_SIZE - 1 ) / FLASH_WRITE_SIZE ;
45+ let erase_count = ( segment. data . len ( ) + FLASH_SECTOR_SIZE - 1 ) / FLASH_SECTOR_SIZE ;
3946
40- let erase_size = segment. data . len ( ) as u32 ;
47+ // round up to sector size
48+ let erase_size = ( erase_count * FLASH_SECTOR_SIZE ) as u32 ;
4149
4250 begin_command (
4351 connection,
44- Command :: FlashBegin ,
52+ Command :: FlashDeflateBegin ,
4553 erase_size,
4654 block_count as u32 ,
4755 FLASH_WRITE_SIZE as u32 ,
4856 addr,
4957 self . chip != Chip :: Esp32 ,
5058 ) ?;
5159
52- let chunks = segment . data . chunks ( FLASH_WRITE_SIZE ) ;
60+ let chunks = compressed . chunks ( FLASH_WRITE_SIZE ) ;
5361
5462 let ( _, chunk_size) = chunks. size_hint ( ) ;
5563 let chunk_size = chunk_size. unwrap_or ( 0 ) as u64 ;
@@ -60,16 +68,25 @@ impl FlashTarget for Esp32Target {
6068 . progress_chars ( "#>-" ) ,
6169 ) ;
6270
71+ // decode the chunks to see how much data the device will have to save
72+ let mut decoder = ZlibDecoder :: new ( Vec :: new ( ) ) ;
73+ let mut decoded_size = 0 ;
74+
6375 for ( i, block) in chunks. enumerate ( ) {
76+ decoder. write_all ( block) ?;
77+ decoder. flush ( ) ?;
78+ let size = decoder. get_ref ( ) . len ( ) - decoded_size;
79+ decoded_size = decoder. get_ref ( ) . len ( ) ;
80+
6481 pb_chunk. set_message ( format ! ( "segment 0x{:X} writing chunks" , addr) ) ;
65- let block_padding = FLASH_WRITE_SIZE - block. len ( ) ;
66- block_command (
82+ block_command_with_timeout (
6783 connection,
68- Command :: FlashData ,
84+ Command :: FlashDeflateData ,
6985 block,
70- block_padding ,
86+ 0 ,
7187 0xff ,
7288 i as u32 ,
89+ Command :: FlashDeflateData . timeout_for_size ( size as u32 ) ,
7390 ) ?;
7491 pb_chunk. inc ( 1 ) ;
7592 }
@@ -80,8 +97,8 @@ impl FlashTarget for Esp32Target {
8097 }
8198
8299 fn finish ( & mut self , connection : & mut Connection , reboot : bool ) -> Result < ( ) , Error > {
83- connection. with_timeout ( Command :: FlashEnd . timeout ( ) , |connection| {
84- connection. write_command ( Command :: FlashEnd as u8 , & [ 1 ] [ ..] , 0 )
100+ connection. with_timeout ( Command :: FlashDeflateEnd . timeout ( ) , |connection| {
101+ connection. write_command ( Command :: FlashDeflateEnd as u8 , & [ 1 ] [ ..] , 0 )
85102 } ) ?;
86103 if reboot {
87104 connection. reset ( )
0 commit comments