@@ -204,12 +204,36 @@ bool UpdaterClass::end(bool evenIfRemaining){
204
204
}
205
205
206
206
bool UpdaterClass::_writeBuffer (){
207
+ #define FLASH_MODE_PAGE 0
208
+ #define FLASH_MODE_OFFSET 2
207
209
208
210
bool eraseResult = true , writeResult = true ;
209
211
if (_currentAddress % FLASH_SECTOR_SIZE == 0 ) {
210
212
if (!_async) yield ();
211
213
eraseResult = ESP.flashEraseSector (_currentAddress/FLASH_SECTOR_SIZE);
212
214
}
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
+ }
213
237
214
238
if (eraseResult) {
215
239
if (!_async) yield ();
@@ -220,6 +244,12 @@ bool UpdaterClass::_writeBuffer(){
220
244
return false ;
221
245
}
222
246
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
+
223
253
if (!writeResult) {
224
254
_currentAddress = (_startAddress + _size);
225
255
_setError (UPDATE_ERROR_WRITE);
0 commit comments