@@ -204,12 +204,36 @@ bool UpdaterClass::end(bool evenIfRemaining){
204204}
205205
206206bool UpdaterClass::_writeBuffer (){
207+ #define FLASH_MODE_PAGE 0
208+ #define FLASH_MODE_OFFSET 2
207209
208210 bool eraseResult = true , writeResult = true ;
209211 if (_currentAddress % FLASH_SECTOR_SIZE == 0 ) {
210212 if (!_async) yield ();
211213 eraseResult = ESP.flashEraseSector (_currentAddress/FLASH_SECTOR_SIZE);
212214 }
215+
216+ // If the flash settings don't match what we already have, modify them.
217+ // But restore them after the modification, so the hash isn't affected.
218+ // This is analogous to what esptool.py does when it receives a --flash_mode argument.
219+ bool modifyFlashMode = false ;
220+ FlashMode_t flashMode = FM_QIO;
221+ FlashMode_t bufferFlashMode = FM_QIO;
222+ if (_currentAddress == _startAddress + FLASH_MODE_PAGE) {
223+ flashMode = ESP.getFlashChipMode ();
224+ #ifdef DEBUG_UPDATER
225+ DEBUG_UPDATER.printf (" Header: 0x%1X %1X %1X %1X\n " , _buffer[0 ], _buffer[1 ], _buffer[2 ], _buffer[3 ]);
226+ #endif
227+ bufferFlashMode = ESP.magicFlashChipMode (_buffer[FLASH_MODE_OFFSET]);
228+ if (bufferFlashMode != flashMode) {
229+ #ifdef DEBUG_UPDATER
230+ DEBUG_UPDATER.printf (" Set flash mode from 0x%1X to 0x%1X\n " , bufferFlashMode, flashMode);
231+ #endif
232+
233+ _buffer[FLASH_MODE_OFFSET] = flashMode;
234+ modifyFlashMode = true ;
235+ }
236+ }
213237
214238 if (eraseResult) {
215239 if (!_async) yield ();
@@ -220,6 +244,12 @@ bool UpdaterClass::_writeBuffer(){
220244 return false ;
221245 }
222246
247+ // Restore the old flash mode, if we modified it.
248+ // Ensures that the MD5 hash will still match what was sent.
249+ if (modifyFlashMode) {
250+ _buffer[FLASH_MODE_OFFSET] = bufferFlashMode;
251+ }
252+
223253 if (!writeResult) {
224254 _currentAddress = (_startAddress + _size);
225255 _setError (UPDATE_ERROR_WRITE);
0 commit comments