@@ -387,7 +387,7 @@ <h2>Browser support</h2>
387387 </ div >
388388 < footer >
389389 Product of < a href ="https://github.com/C5Lab/projectZero/ "> C5Lab/projectZero</ a > -
390- < span id ="pageVersion " class ="mono "> Web flasher v1.0.7 </ span > .
390+ < span id ="pageVersion " class ="mono "> Web flasher v1.0.8 </ span > .
391391 </ footer >
392392
393393 < script type ="module ">
@@ -438,7 +438,7 @@ <h2>Browser support</h2>
438438 monitorConnected : false ,
439439 } ;
440440
441- const PAGE_VERSION = "1.0.7 " ;
441+ const PAGE_VERSION = "1.0.8 " ;
442442 const FLASH_BAUD = 115200 ;
443443 const monitorEncoder = new TextEncoder ( ) ;
444444
@@ -662,6 +662,58 @@ <h2>Browser support</h2>
662662 }
663663 } ;
664664
665+ const applyEspToolWorkarounds = ( loader ) => {
666+ if ( ! loader || loader . __projectZeroPatched ) return ;
667+ loader . __projectZeroPatched = true ;
668+
669+ const originalRunStub = loader . runStub . bind ( loader ) ;
670+ loader . runStub = async ( ) => {
671+ const chipName = loader ?. chip ?. CHIP_NAME || "" ;
672+ if ( chipName === "ESP32-C5" ) {
673+ state . usingStub = false ;
674+ log ( "Skipping flasher stub for ESP32-C5. Using ROM bootloader path due to known C5 ECO2 stub flash-write failures." ) ;
675+ return loader . chip ;
676+ }
677+ state . usingStub = true ;
678+ return originalRunStub ( ) ;
679+ } ;
680+
681+ const originalFlashDeflBegin = loader . flashDeflBegin . bind ( loader ) ;
682+ loader . flashDeflBegin = async ( size , compsize , offset ) => {
683+ const chipName = loader ?. chip ?. CHIP_NAME || "" ;
684+ if ( loader . IS_STUB || chipName === "ESP32" || chipName === "ESP8266" ) {
685+ return originalFlashDeflBegin ( size , compsize , offset ) ;
686+ }
687+
688+ const numBlocks = Math . floor ( ( compsize + loader . FLASH_WRITE_SIZE - 1 ) / loader . FLASH_WRITE_SIZE ) ;
689+ const eraseBlocks = Math . floor ( ( size + loader . FLASH_WRITE_SIZE - 1 ) / loader . FLASH_WRITE_SIZE ) ;
690+ const t1 = Date . now ( ) ;
691+ const writeSize = eraseBlocks * loader . FLASH_WRITE_SIZE ;
692+ const timeout = loader . timeoutPerMb ( loader . ERASE_REGION_TIMEOUT_PER_MB , writeSize ) ;
693+
694+ loader . info ( "Compressed " + size + " bytes to " + compsize + "..." ) ;
695+ let pkt = loader . _appendArray ( loader . _intToByteArray ( writeSize ) , loader . _intToByteArray ( numBlocks ) ) ;
696+ pkt = loader . _appendArray ( pkt , loader . _intToByteArray ( loader . FLASH_WRITE_SIZE ) ) ;
697+ pkt = loader . _appendArray ( pkt , loader . _intToByteArray ( offset ) ) ;
698+ pkt = loader . _appendArray ( pkt , loader . _intToByteArray ( 0 ) ) ;
699+
700+ await loader . checkCommand (
701+ "enter compressed flash mode" ,
702+ loader . ESP_FLASH_DEFL_BEGIN ,
703+ pkt ,
704+ undefined ,
705+ undefined ,
706+ timeout ,
707+ ) ;
708+
709+ if ( size !== 0 ) {
710+ const elapsed = Date . now ( ) - t1 ;
711+ loader . info ( "Took " + elapsed / 1000 + "." + ( elapsed % 1000 ) + "s to erase flash block" ) ;
712+ }
713+ return numBlocks ;
714+ } ;
715+ } ;
716+
665717 const connect = async ( ) => {
666718 ensureSupport ( ) ;
667719 if ( state . connected ) {
@@ -712,17 +764,7 @@ <h2>Browser support</h2>
712764 try {
713765 state . esploader = new ESPLoader ( loaderOptions ) ;
714766 state . usingStub = null ;
715- const originalRunStub = state . esploader . runStub . bind ( state . esploader ) ;
716- state . esploader . runStub = async ( ) => {
717- const chipName = state . esploader ?. chip ?. CHIP_NAME || "" ;
718- if ( chipName === "ESP32-C5" ) {
719- state . usingStub = false ;
720- log ( "Skipping flasher stub for ESP32-C5. Using ROM bootloader path due to known C5 ECO2 stub flash-write failures." ) ;
721- return state . esploader . chip ;
722- }
723- state . usingStub = true ;
724- return originalRunStub ( ) ;
725- } ;
767+ applyEspToolWorkarounds ( state . esploader ) ;
726768 log ( "Connecting..." ) ;
727769 state . chip = await state . esploader . main ( ) ;
728770 lastErr = null ;
0 commit comments