1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-06 05:21:22 +03:00

Add flash read/write/erase APIs to ESPClass

This commit is contained in:
Ivan Grokhotkov 2015-08-18 23:38:23 +03:00
parent fac840b6a8
commit c355f626f2
4 changed files with 67 additions and 59 deletions

View File

@ -400,3 +400,26 @@ bool EspClass::updateSketch(Stream& in, uint32_t size, bool restartOnFail, bool
if(restartOnSuccess) ESP.restart();
return true;
}
static const int FLASH_INT_MASK = ((B10 << 8) | B00111010);
bool EspClass::flashEraseSector(uint32_t sector) {
ets_isr_mask(FLASH_INT_MASK);
int rc = spi_flash_erase_sector(sector);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
ets_isr_mask(FLASH_INT_MASK);
int rc = spi_flash_write(offset, (uint32_t*) data, size);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size) {
ets_isr_mask(FLASH_INT_MASK);
int rc = spi_flash_read(offset, (uint32_t*) data, size);
ets_isr_unmask(FLASH_INT_MASK);
return rc == 0;
}

View File

@ -117,6 +117,10 @@ class EspClass {
FlashMode_t getFlashChipMode();
uint32_t getFlashChipSizeByChipId();
bool flashEraseSector(uint32_t sector);
bool flashWrite(uint32_t offset, uint32_t *data, size_t size);
bool flashRead(uint32_t offset, uint32_t *data, size_t size);
uint32_t getSketchSize();
uint32_t getFreeSketchSpace();
bool updateSketch(Stream& in, uint32_t size, bool restartOnFail = false, bool restartOnSuccess = true);

View File

@ -1,9 +1,13 @@
#include "Updater.h"
#include "Arduino.h"
#include "eboot_command.h"
//#define DEBUG_UPDATER Serial
extern "C" {
#include "c_types.h"
#include "spi_flash.h"
}
extern "C" uint32_t _SPIFFS_start;
UpdaterClass::UpdaterClass()
@ -112,17 +116,11 @@ bool UpdaterClass::end(bool evenIfRemaining){
}
bool UpdaterClass::_writeBuffer(){
noInterrupts();
int rc = SPIEraseSector(_currentAddress/FLASH_SECTOR_SIZE);
interrupts();
yield();
if(!rc){
noInterrupts();
rc = SPIWrite(_currentAddress, _buffer, _bufferLen);
interrupts();
}
interrupts();
if (rc) {
bool result = ESP.flashEraseSector(_currentAddress/FLASH_SECTOR_SIZE) &&
ESP.flashWrite(_currentAddress, (uint32_t*) _buffer, _bufferLen);
if (!result) {
_error = UPDATE_ERROR_WRITE;
_currentAddress = (_startAddress + _size);
#ifdef DEBUG_UPDATER

View File

@ -23,32 +23,11 @@
#include <algorithm>
#include "spiffs/spiffs.h"
#include "debug.h"
#include "interrupts.h"
extern "C" {
#include "c_types.h"
#include "spi_flash.h"
}
static int spi_flash_read_locked(uint32_t addr, uint32_t* dst, uint32_t size) {
optimistic_yield(10000);
AutoInterruptLock(5);
return spi_flash_read(addr, dst, size);
}
static int spi_flash_write_locked(uint32_t addr, const uint32_t* src, uint32_t size) {
optimistic_yield(10000);
AutoInterruptLock(5);
return spi_flash_write(addr, (uint32_t*) src, size);
}
static int spi_flash_erase_sector_locked(uint32_t sector) {
optimistic_yield(10000);
AutoInterruptLock(5);
return spi_flash_erase_sector(sector);
}
/*
spi_flash_read function requires flash address to be aligned on word boundary.
We take care of this by reading first and last words separately and memcpy
@ -64,6 +43,8 @@ alignedEnd: ^
*/
int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
optimistic_yield(10000);
uint32_t result = SPIFFS_OK;
uint32_t alignedBegin = (addr + 3) & (~3);
uint32_t alignedEnd = (addr + size) & (~3);
@ -71,7 +52,7 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
if (addr < alignedBegin) {
uint32_t nb = alignedBegin - addr;
uint32_t tmp;
if (spi_flash_read_locked(alignedBegin - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashRead(alignedBegin - 4, &tmp, 4)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -80,8 +61,8 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
}
if (alignedEnd != alignedBegin) {
if (spi_flash_read_locked(alignedBegin, (uint32_t*) (dst + alignedBegin - addr),
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashRead(alignedBegin, (uint32_t*) (dst + alignedBegin - addr),
alignedEnd - alignedBegin)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -91,7 +72,7 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
if (addr + size > alignedEnd) {
uint32_t nb = addr + size - alignedEnd;
uint32_t tmp;
if (spi_flash_read_locked(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashRead(alignedEnd, &tmp, 4)) {
DEBUGV("_spif_read(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -116,6 +97,8 @@ int32_t spiffs_hal_read(uint32_t addr, uint32_t size, uint8_t *dst) {
static const int UNALIGNED_WRITE_BUFFER_SIZE = 512;
int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
optimistic_yield(10000);
uint32_t alignedBegin = (addr + 3) & (~3);
uint32_t alignedEnd = (addr + size) & (~3);
@ -123,7 +106,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
uint32_t nb = alignedBegin - addr;
uint32_t tmp = 0xffffffff;
memcpy(((uint8_t* )&tmp) + 4 - nb, src, nb);
if (spi_flash_write_locked(alignedBegin - 4, &tmp, 4) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashWrite(alignedBegin - 4, &tmp, 4)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -134,8 +117,8 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
uint32_t* srcLeftover = (uint32_t*) (src + alignedBegin - addr);
uint32_t srcAlign = ((uint32_t) srcLeftover) & 3;
if (!srcAlign) {
if (spi_flash_write_locked(alignedBegin, (uint32_t*) srcLeftover,
alignedEnd - alignedBegin) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashWrite(alignedBegin, (uint32_t*) srcLeftover,
alignedEnd - alignedBegin)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -147,8 +130,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
size_t willCopy = std::min(sizeLeft, sizeof(buf));
memcpy(buf, srcLeftover, willCopy);
if (spi_flash_write_locked(alignedBegin, (uint32_t*) buf,
willCopy) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashWrite(alignedBegin, (uint32_t*) buf, willCopy)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -166,7 +148,7 @@ int32_t spiffs_hal_write(uint32_t addr, uint32_t size, uint8_t *src) {
uint32_t tmp = 0xffffffff;
memcpy(&tmp, src + size - nb, nb);
if (spi_flash_write_locked(alignedEnd, &tmp, 4) != SPI_FLASH_RESULT_OK) {
if (!ESP.flashWrite(alignedEnd, &tmp, 4)) {
DEBUGV("_spif_write(%d) addr=%x size=%x ab=%x ae=%x\r\n",
__LINE__, addr, size, alignedBegin, alignedEnd);
return SPIFFS_ERR_INTERNAL;
@ -185,7 +167,8 @@ int32_t spiffs_hal_erase(uint32_t addr, uint32_t size) {
const uint32_t sector = addr / SPI_FLASH_SEC_SIZE;
const uint32_t sectorCount = size / SPI_FLASH_SEC_SIZE;
for (uint32_t i = 0; i < sectorCount; ++i) {
if (spi_flash_erase_sector_locked(sector + i) != 0) {
optimistic_yield(10000);
if (!ESP.flashEraseSector(sector + i)) {
DEBUGV("_spif_erase addr=%x size=%d i=%d\r\n", addr, size, i);
return SPIFFS_ERR_INTERNAL;
}