mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-23 08:45:22 +03:00
Rewrite PUYA patch to be more universal and mem friendly. (#5504)
* [PUYA] Applied ESPeasy puya_v3.patch Applied the patch to get the starting point as described in https://github.com/esp8266/Arduino/issues/5493 * [PUYA] Only allocate memory when PUYA detected core 2.5.0 PUYA patch, no puya: Description Function #calls call/sec min (ms) Avg (ms) max (ms) Save File 4 0.25 34.755 45.264 67.620 Free Mem: 16168 core 2.5.0 PUYA patch, Faked Puya detect: Description Function #calls call/sec min (ms) Avg (ms) max (ms) Save File 2 0.04 41.332 57.544 73.756 Free Mem: 11560 * [PUYA] Check for PUYA chip as soon as possible at boot Check for PUYA chip in call for `getFlashChipId()` This will only be done once and the result of the get function is also cached. * [PUYA] Use limited buffer (512 byte) allocated at first write No need to allocate a buffer when not writing to flash. The default buffer size is 512 bytes, which is 2 pages in the flash chip. * [PUYA] Lower PUYA flash buffer to 1 page (256 B) As discussed here: https://github.com/esp8266/Arduino/issues/5493#issuecomment-447543279 * [PUYA] Fix indents naming and return conditions * [PUYA] Move Puya write code to spi_flash_write_puya * [PUYA] Make spi_flash_write_puya static and define PUYA_SUPPORT * [PUYA] Add some SPI flash vendor IDs As requested by @igrr https://github.com/esp8266/Arduino/pull/5504#discussion_r242016184 * [PUYA] All suggested changes. See: https://github.com/esp8266/Arduino/pull/5504#pullrequestreview-186145820
This commit is contained in:
@ -132,18 +132,18 @@ uint64_t EspClass::deepSleepMax()
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
Layout of RTC Memory is as follows:
|
||||
Ref: Espressif doc 2C-ESP8266_Non_OS_SDK_API_Reference, section 3.3.23 (system_rtc_mem_write)
|
||||
|
||||
|<------system data (256 bytes)------->|<-----------------user data (512 bytes)--------------->|
|
||||
|
||||
SDK function signature:
|
||||
SDK function signature:
|
||||
bool system_rtc_mem_read (
|
||||
uint32 des_addr,
|
||||
void * src_addr,
|
||||
uint32 des_addr,
|
||||
void * src_addr,
|
||||
uint32 save_size
|
||||
)
|
||||
)
|
||||
|
||||
The system data section can't be used by the user, so:
|
||||
des_addr must be >=64 (i.e.: 256/4) and <192 (i.e.: 768/4)
|
||||
@ -160,7 +160,7 @@ Same for write
|
||||
Note: If the Updater class is in play, e.g.: the application uses OTA, the eboot
|
||||
command will be stored into the first 128 bytes of user data, then it will be
|
||||
retrieved by eboot on boot. That means that user data present there will be lost.
|
||||
Ref:
|
||||
Ref:
|
||||
- discussion in PR #5330.
|
||||
- https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map#memmory-mapped-io-registers
|
||||
- Arduino/bootloaders/eboot/eboot_command.h RTC_MEM definition
|
||||
@ -266,7 +266,16 @@ uint8_t EspClass::getCpuFreqMHz(void)
|
||||
|
||||
uint32_t EspClass::getFlashChipId(void)
|
||||
{
|
||||
return spi_flash_get_id();
|
||||
static uint32_t flash_chip_id = 0;
|
||||
if (flash_chip_id == 0) {
|
||||
flash_chip_id = spi_flash_get_id();
|
||||
}
|
||||
return flash_chip_id;
|
||||
}
|
||||
|
||||
uint8_t EspClass::getFlashChipVendorId(void)
|
||||
{
|
||||
return (getFlashChipId() & 0x000000ff);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipRealSize(void)
|
||||
@ -569,9 +578,61 @@ bool EspClass::flashEraseSector(uint32_t sector) {
|
||||
return rc == 0;
|
||||
}
|
||||
|
||||
#if PUYA_SUPPORT
|
||||
static int spi_flash_write_puya(uint32_t offset, uint32_t *data, size_t size) {
|
||||
if (data == nullptr) {
|
||||
return 1; // SPI_FLASH_RESULT_ERR
|
||||
}
|
||||
// PUYA flash chips need to read existing data, update in memory and write modified data again.
|
||||
static uint32_t *flash_write_puya_buf = nullptr;
|
||||
int rc = 0;
|
||||
uint32_t* ptr = data;
|
||||
|
||||
if (flash_write_puya_buf == nullptr) {
|
||||
flash_write_puya_buf = (uint32_t*) malloc(PUYA_BUFFER_SIZE);
|
||||
// No need to ever free this, since the flash chip will never change at runtime.
|
||||
if (flash_write_puya_buf == nullptr) {
|
||||
// Memory could not be allocated.
|
||||
return 1; // SPI_FLASH_RESULT_ERR
|
||||
}
|
||||
}
|
||||
size_t bytesLeft = size;
|
||||
uint32_t pos = offset;
|
||||
while (bytesLeft > 0 && rc == 0) {
|
||||
size_t bytesNow = bytesLeft;
|
||||
if (bytesNow > PUYA_BUFFER_SIZE) {
|
||||
bytesNow = PUYA_BUFFER_SIZE;
|
||||
bytesLeft -= PUYA_BUFFER_SIZE;
|
||||
} else {
|
||||
bytesLeft = 0;
|
||||
}
|
||||
rc = spi_flash_read(pos, flash_write_puya_buf, bytesNow);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
for (size_t i = 0; i < bytesNow / 4; ++i) {
|
||||
flash_write_puya_buf[i] &= *ptr;
|
||||
++ptr;
|
||||
}
|
||||
rc = spi_flash_write(pos, flash_write_puya_buf, bytesNow);
|
||||
pos += bytesNow;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
int rc = 0;
|
||||
#if PUYA_SUPPORT
|
||||
if (getFlashChipVendorId() == SPI_FLASH_VENDOR_PUYA) {
|
||||
rc = spi_flash_write_puya(offset, data, size);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
rc = spi_flash_write(offset, data, size);
|
||||
}
|
||||
ets_isr_unmask(FLASH_INT_MASK);
|
||||
return rc == 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user