Skip to content

Commit 260ab63

Browse files
committed
Add flash read/write/erase APIs to ESPClass
1 parent aafacdc commit 260ab63

File tree

4 files changed

+67
-59
lines changed

4 files changed

+67
-59
lines changed

hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,3 +400,26 @@ bool EspClass::updateSketch(Stream& in, uint32_t size, bool restartOnFail, bool
400400
if(restartOnSuccess) ESP.restart();
401401
return true;
402402
}
403+
404+
static const int FLASH_INT_MASK = ((B10 << 8) | B00111010);
405+
406+
bool EspClass::flashEraseSector(uint32_t sector) {
407+
ets_isr_mask(FLASH_INT_MASK);
408+
int rc = spi_flash_erase_sector(sector);
409+
ets_isr_unmask(FLASH_INT_MASK);
410+
return rc == 0;
411+
}
412+
413+
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
414+
ets_isr_mask(FLASH_INT_MASK);
415+
int rc = spi_flash_write(offset, (uint32_t*) data, size);
416+
ets_isr_unmask(FLASH_INT_MASK);
417+
return rc == 0;
418+
}
419+
420+
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size) {
421+
ets_isr_mask(FLASH_INT_MASK);
422+
int rc = spi_flash_read(offset, (uint32_t*) data, size);
423+
ets_isr_unmask(FLASH_INT_MASK);
424+
return rc == 0;
425+
}

hardware/esp8266com/esp8266/cores/esp8266/Esp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ class EspClass {
117117
FlashMode_t getFlashChipMode();
118118
uint32_t getFlashChipSizeByChipId();
119119

120+
bool flashEraseSector(uint32_t sector);
121+
bool flashWrite(uint32_t offset, uint32_t *data, size_t size);
122+
bool flashRead(uint32_t offset, uint32_t *data, size_t size);
123+
120124
uint32_t getSketchSize();
121125
uint32_t getFreeSketchSpace();
122126
bool updateSketch(Stream& in, uint32_t size, bool restartOnFail = false, bool restartOnSuccess = true);

hardware/esp8266com/esp8266/cores/esp8266/Updater.cpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
#include "Updater.h"
22
#include "Arduino.h"
33
#include "eboot_command.h"
4-
54
//#define DEBUG_UPDATER Serial
65

6+
extern "C" {
7+
#include "c_types.h"
8+
#include "spi_flash.h"
9+
}
10+
711
extern "C" uint32_t _SPIFFS_start;
812

9-
UpdaterClass::UpdaterClass()
13+
UpdaterClass::UpdaterClass()
1014
: _error(0)
1115
, _buffer(0)
1216
, _bufferLen(0)
1317
, _size(0)
1418
, _startAddress(0)
15-
, _currentAddress(0)
19+
, _currentAddress(0)
1620
{
1721
}
1822

@@ -33,18 +37,18 @@ bool UpdaterClass::begin(size_t size){
3337
#endif
3438
return false;
3539
}
36-
40+
3741
if(size == 0){
3842
_error = UPDATE_ERROR_SIZE;
3943
#ifdef DEBUG_UPDATER
4044
printError(DEBUG_UPDATER);
4145
#endif
4246
return false;
4347
}
44-
48+
4549
_reset();
4650
_error = 0;
47-
51+
4852
//size of current sketch rounded to a sector
4953
uint32_t currentSketchSize = (ESP.getSketchSize() + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1));
5054
//address of the end of the space available for sketch and update
@@ -53,7 +57,7 @@ bool UpdaterClass::begin(size_t size){
5357
uint32_t roundedSize = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1));
5458
//address where we will start writing the update
5559
uint32_t updateStartAddress = updateEndAddress - roundedSize;
56-
60+
5761
//make sure that the size of both sketches is less than the total space (updateEndAddress)
5862
if(updateStartAddress < currentSketchSize){
5963
_error = UPDATE_ERROR_SPACE;
@@ -62,13 +66,13 @@ bool UpdaterClass::begin(size_t size){
6266
#endif
6367
return false;
6468
}
65-
69+
6670
//initialize
6771
_startAddress = updateStartAddress;
6872
_currentAddress = _startAddress;
6973
_size = size;
7074
_buffer = new uint8_t[FLASH_SECTOR_SIZE];
71-
75+
7276
return true;
7377
}
7478

@@ -79,30 +83,30 @@ bool UpdaterClass::end(bool evenIfRemaining){
7983
#endif
8084
return false;
8185
}
82-
86+
8387
if(hasError() || (!isFinished() && !evenIfRemaining)){
8488
#ifdef DEBUG_UPDATER
8589
DEBUG_UPDATER.printf("premature end: res:%u, pos:%u/%u\n", getError(), progress(), _size);
8690
#endif
87-
91+
8892
_reset();
8993
return false;
9094
}
91-
95+
9296
if(evenIfRemaining){
9397
if(_bufferLen > 0){
9498
_writeBuffer();
9599
}
96100
_size = progress();
97101
}
98-
102+
99103
eboot_command ebcmd;
100104
ebcmd.action = ACTION_COPY_RAW;
101105
ebcmd.args[0] = _startAddress;
102106
ebcmd.args[1] = 0x00000;
103107
ebcmd.args[2] = _size;
104108
eboot_command_write(&ebcmd);
105-
109+
106110
#ifdef DEBUG_UPDATER
107111
DEBUG_UPDATER.printf("Staged: address:0x%08X, size:0x%08X\n", _startAddress, _size);
108112
#endif
@@ -112,17 +116,11 @@ bool UpdaterClass::end(bool evenIfRemaining){
112116
}
113117

114118
bool UpdaterClass::_writeBuffer(){
115-
noInterrupts();
116-
int rc = SPIEraseSector(_currentAddress/FLASH_SECTOR_SIZE);
117-
interrupts();
118119
yield();
119-
if(!rc){
120-
noInterrupts();
121-
rc = SPIWrite(_currentAddress, _buffer, _bufferLen);
122-
interrupts();
123-
}
124-
interrupts();
125-
if (rc) {
120+
bool result = ESP.flashEraseSector(_currentAddress/FLASH_SECTOR_SIZE) &&
121+
ESP.flashWrite(_currentAddress, (uint32_t*) _buffer, _bufferLen);
122+
123+
if (!result) {
126124
_error = UPDATE_ERROR_WRITE;
127125
_currentAddress = (_startAddress + _size);
128126
#ifdef DEBUG_UPDATER
@@ -139,10 +137,10 @@ size_t UpdaterClass::write(uint8_t *data, size_t len) {
139137
size_t left = len;
140138
if(hasError() || !isRunning())
141139
return 0;
142-
140+
143141
if(len > remaining())
144142
len = remaining();
145-
143+
146144
while((_bufferLen + left) > FLASH_SECTOR_SIZE) {
147145
size_t toBuff = FLASH_SECTOR_SIZE - _bufferLen;
148146
memcpy(_buffer + _bufferLen, data + (len - left), toBuff);
@@ -170,7 +168,7 @@ size_t UpdaterClass::writeStream(Stream &data) {
170168
size_t toRead = 0;
171169
if(hasError() || !isRunning())
172170
return 0;
173-
171+
174172
while(remaining()) {
175173
toRead = FLASH_SECTOR_SIZE - _bufferLen;
176174
toRead = data.readBytes(_buffer + _bufferLen, toRead);

hardware/esp8266com/esp8266/cores/esp8266/spiffs_hal.cpp

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,11 @@
2323
#include <algorithm>
2424
#include "spiffs/spiffs.h"
2525
#include "debug.h"
26-
#include "interrupts.h"
2726

2827
extern "C" {
2928
#include "c_types.h"
3029
#include "spi_flash.h"
3130
}
32-
33-
static int spi_flash_read_locked(uint32_t addr, uint32_t* dst, uint32_t size) {
34-
optimistic_yield(10000);
35-
AutoInterruptLock(5);
36-
return spi_flash_read(addr, dst, size);
37-
}
38-
39-
static int spi_flash_write_locked(uint32_t addr, const uint32_t* src, uint32_t size) {
40-
optimistic_yield(10000);
41-
AutoInterruptLock(5);
42-
return spi_flash_write(addr, (uint32_t*) src, size);
43-
}
44-
45-
static int spi_flash_erase_sector_locked(uint32_t sector) {
46-
optimistic_yield(10000);
47-
AutoInterruptLock(5);
48-
return spi_flash_erase_sector(sector);
49-
}
50-
51-
5231
/*
5332
spi_flash_read function requires flash address to be aligned on word boundary.
5433
We take care of this by reading first and last words separately and memcpy
@@ -64,14 +43,16 @@ alignedEnd: ^
6443
*/
6544

6645
int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
46+
optimistic_yield(10000);
47+
6748
uint32_t result = SPIFFS_OK;
6849
uint32_t alignedBegin = (addr + 3) & (~3);
6950
uint32_t alignedEnd = (addr + size) & (~3);
7051

7152
if (addr < alignedBegin) {
7253
uint32_t nb = alignedBegin - addr;
7354
uint32_t tmp;
74-
if (spi_flash_read_locked(alignedBegin - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) {
55+
if (!ESP.flashRead(alignedBegin - 4, &tmp, 4)) {
7556
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
7657
__LINE__, addr, size, alignedBegin, alignedEnd);
7758
return SPIFFS_ERR_INTERNAL;
@@ -80,8 +61,8 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
8061
}
8162

8263
if (alignedEnd != alignedBegin) {
83-
if (spi_flash_read_locked(alignedBegin, (uint32_t*) (dst + alignedBegin - addr),
84-
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) {
64+
if (!ESP.flashRead(alignedBegin, (uint32_t*) (dst + alignedBegin - addr),
65+
alignedEnd - alignedBegin)) {
8566
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
8667
__LINE__, addr, size, alignedBegin, alignedEnd);
8768
return SPIFFS_ERR_INTERNAL;
@@ -91,7 +72,7 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
9172
if (addr + size > alignedEnd) {
9273
uint32_t nb = addr + size - alignedEnd;
9374
uint32_t tmp;
94-
if (spi_flash_read_locked(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) {
75+
if (!ESP.flashRead(alignedEnd, &tmp, 4)) {
9576
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
9677
__LINE__, addr, size, alignedBegin, alignedEnd);
9778
return SPIFFS_ERR_INTERNAL;
@@ -116,14 +97,16 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
11697
static const int UNALIGNED_WRITE_BUFFER_SIZE = 512;
11798

11899
int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
100+
optimistic_yield(10000);
101+
119102
uint32_t alignedBegin = (addr + 3) & (~3);
120103
uint32_t alignedEnd = (addr + size) & (~3);
121104

122105
if (addr < alignedBegin) {
123106
uint32_t nb = alignedBegin - addr;
124107
uint32_t tmp = 0xffffffff;
125108
memcpy(((uint8_t* )&tmp) + 4 - nb, src, nb);
126-
if (spi_flash_write_locked(alignedBegin - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) {
109+
if (!ESP.flashWrite(alignedBegin - 4, &tmp, 4)) {
127110
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
128111
__LINE__, addr, size, alignedBegin, alignedEnd);
129112
return SPIFFS_ERR_INTERNAL;
@@ -134,8 +117,8 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
134117
uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr);
135118
uint32_t srcAlign = ((uint32_t) srcLeftover) & 3;
136119
if (!srcAlign) {
137-
if (spi_flash_write_locked(alignedBegin, (uint32_t*) srcLeftover,
138-
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) {
120+
if (!ESP.flashWrite(alignedBegin, (uint32_t*) srcLeftover,
121+
alignedEnd - alignedBegin)) {
139122
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
140123
__LINE__, addr, size, alignedBegin, alignedEnd);
141124
return SPIFFS_ERR_INTERNAL;
@@ -147,8 +130,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
147130
size_t willCopy = std::min(sizeLeft, sizeof(buf));
148131
memcpy(buf, srcLeftover, willCopy);
149132

150-
if (spi_flash_write_locked(alignedBegin, (uint32_t*) buf,
151-
willCopy) != SPI_FLASH_RESULT_OK) {
133+
if (!ESP.flashWrite(alignedBegin, (uint32_t*) buf, willCopy)) {
152134
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
153135
__LINE__, addr, size, alignedBegin, alignedEnd);
154136
return SPIFFS_ERR_INTERNAL;
@@ -166,7 +148,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
166148
uint32_t tmp = 0xffffffff;
167149
memcpy(&tmp, src + size - nb, nb);
168150

169-
if (spi_flash_write_locked(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) {
151+
if (!ESP.flashWrite(alignedEnd, &tmp, 4)) {
170152
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
171153
__LINE__, addr, size, alignedBegin, alignedEnd);
172154
return SPIFFS_ERR_INTERNAL;
@@ -185,7 +167,8 @@ int32_t spiffs_hal_erase(uint32_t addr, uint32_t size) {
185167
const uint32_t sector = addr / SPI_FLASH_SEC_SIZE;
186168
const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE;
187169
for (uint32_t i = 0; i < sectorCount; ++i) {
188-
if (spi_flash_erase_sector_locked(sector + i) != 0) {
170+
optimistic_yield(10000);
171+
if (!ESP.flashEraseSector(sector + i)) {
189172
DEBUGV("_spif_erase addr=%x size=%d i=%d\r\n", addr, size, i);
190173
return SPIFFS_ERR_INTERNAL;
191174
}

0 commit comments

Comments
 (0)