mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +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:
parent
d6c743027d
commit
4c04c63c2a
@ -132,18 +132,18 @@ uint64_t EspClass::deepSleepMax()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Layout of RTC Memory is as follows:
|
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)
|
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)--------------->|
|
|<------system data (256 bytes)------->|<-----------------user data (512 bytes)--------------->|
|
||||||
|
|
||||||
SDK function signature:
|
SDK function signature:
|
||||||
bool system_rtc_mem_read (
|
bool system_rtc_mem_read (
|
||||||
uint32 des_addr,
|
uint32 des_addr,
|
||||||
void * src_addr,
|
void * src_addr,
|
||||||
uint32 save_size
|
uint32 save_size
|
||||||
)
|
)
|
||||||
|
|
||||||
The system data section can't be used by the user, so:
|
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)
|
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
|
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
|
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.
|
retrieved by eboot on boot. That means that user data present there will be lost.
|
||||||
Ref:
|
Ref:
|
||||||
- discussion in PR #5330.
|
- discussion in PR #5330.
|
||||||
- https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map#memmory-mapped-io-registers
|
- https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map#memmory-mapped-io-registers
|
||||||
- Arduino/bootloaders/eboot/eboot_command.h RTC_MEM definition
|
- Arduino/bootloaders/eboot/eboot_command.h RTC_MEM definition
|
||||||
@ -266,7 +266,16 @@ uint8_t EspClass::getCpuFreqMHz(void)
|
|||||||
|
|
||||||
uint32_t EspClass::getFlashChipId(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)
|
uint32_t EspClass::getFlashChipRealSize(void)
|
||||||
@ -569,9 +578,61 @@ bool EspClass::flashEraseSector(uint32_t sector) {
|
|||||||
return rc == 0;
|
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) {
|
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
|
||||||
ets_isr_mask(FLASH_INT_MASK);
|
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);
|
ets_isr_unmask(FLASH_INT_MASK);
|
||||||
return rc == 0;
|
return rc == 0;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,52 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#ifndef PUYA_SUPPORT
|
||||||
|
#define PUYA_SUPPORT 0
|
||||||
|
#endif
|
||||||
|
#ifndef PUYA_BUFFER_SIZE
|
||||||
|
// Good alternative for buffer size is: SPI_FLASH_SEC_SIZE (= 4k)
|
||||||
|
// Always use a multiple of flash page size (256 bytes)
|
||||||
|
#define PUYA_BUFFER_SIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Vendor IDs taken from Flashrom project
|
||||||
|
// https://review.coreboot.org/cgit/flashrom.git/tree/flashchips.h?h=1.0.x
|
||||||
|
typedef enum {
|
||||||
|
SPI_FLASH_VENDOR_ALLIANCE = 0x52, /* Alliance Semiconductor */
|
||||||
|
SPI_FLASH_VENDOR_AMD = 0x01, /* AMD */
|
||||||
|
SPI_FLASH_VENDOR_AMIC = 0x37, /* AMIC */
|
||||||
|
SPI_FLASH_VENDOR_ATMEL = 0x1F, /* Atmel (now used by Adesto) */
|
||||||
|
SPI_FLASH_VENDOR_BRIGHT = 0xAD, /* Bright Microelectronics */
|
||||||
|
SPI_FLASH_VENDOR_CATALYST = 0x31, /* Catalyst */
|
||||||
|
SPI_FLASH_VENDOR_EON = 0x1C, /* EON Silicon Devices, missing 0x7F prefix */
|
||||||
|
SPI_FLASH_VENDOR_ESMT = 0x8C, /* Elite Semiconductor Memory Technology (ESMT) / EFST Elite Flash Storage */
|
||||||
|
SPI_FLASH_VENDOR_EXCEL = 0x4A, /* ESI, missing 0x7F prefix */
|
||||||
|
SPI_FLASH_VENDOR_FIDELIX = 0xF8, /* Fidelix */
|
||||||
|
SPI_FLASH_VENDOR_FUJITSU = 0x04, /* Fujitsu */
|
||||||
|
SPI_FLASH_VENDOR_GIGADEVICE = 0xC8, /* GigaDevice */
|
||||||
|
SPI_FLASH_VENDOR_HYUNDAI = 0xAD, /* Hyundai */
|
||||||
|
SPI_FLASH_VENDOR_INTEL = 0x89, /* Intel */
|
||||||
|
SPI_FLASH_VENDOR_ISSI = 0xD5, /* ISSI Integrated Silicon Solutions, see also PMC. */
|
||||||
|
SPI_FLASH_VENDOR_MACRONIX = 0xC2, /* Macronix (MX) */
|
||||||
|
SPI_FLASH_VENDOR_NANTRONICS = 0xD5, /* Nantronics, missing prefix */
|
||||||
|
SPI_FLASH_VENDOR_PMC = 0x9D, /* PMC, missing 0x7F prefix */
|
||||||
|
SPI_FLASH_VENDOR_PUYA = 0x85, /* Puya semiconductor (shanghai) co. ltd */
|
||||||
|
SPI_FLASH_VENDOR_SANYO = 0x62, /* Sanyo */
|
||||||
|
SPI_FLASH_VENDOR_SHARP = 0xB0, /* Sharp */
|
||||||
|
SPI_FLASH_VENDOR_SPANSION = 0x01, /* Spansion, same ID as AMD */
|
||||||
|
SPI_FLASH_VENDOR_SST = 0xBF, /* SST */
|
||||||
|
SPI_FLASH_VENDOR_ST = 0x20, /* ST / SGS/Thomson / Numonyx (later acquired by Micron) */
|
||||||
|
SPI_FLASH_VENDOR_SYNCMOS_MVC = 0x40, /* SyncMOS (SM) and Mosel Vitelic Corporation (MVC) */
|
||||||
|
SPI_FLASH_VENDOR_TENX = 0x5E, /* Tenx Technologies */
|
||||||
|
SPI_FLASH_VENDOR_TI = 0x97, /* Texas Instruments */
|
||||||
|
SPI_FLASH_VENDOR_TI_OLD = 0x01, /* TI chips from last century */
|
||||||
|
SPI_FLASH_VENDOR_WINBOND = 0xDA, /* Winbond */
|
||||||
|
SPI_FLASH_VENDOR_WINBOND_NEX = 0xEF, /* Winbond (ex Nexcom) serial flashes */
|
||||||
|
|
||||||
|
SPI_FLASH_VENDOR_UNKNOWN = 0xFF
|
||||||
|
} SPI_FLASH_VENDOR_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AVR macros for WDT managment
|
* AVR macros for WDT managment
|
||||||
*/
|
*/
|
||||||
@ -123,6 +169,8 @@ class EspClass {
|
|||||||
uint8_t getCpuFreqMHz();
|
uint8_t getCpuFreqMHz();
|
||||||
|
|
||||||
uint32_t getFlashChipId();
|
uint32_t getFlashChipId();
|
||||||
|
uint8_t getFlashChipVendorId();
|
||||||
|
|
||||||
//gets the actual chip size based on the flash id
|
//gets the actual chip size based on the flash id
|
||||||
uint32_t getFlashChipRealSize();
|
uint32_t getFlashChipRealSize();
|
||||||
//gets the size of the flash as set by the compiler
|
//gets the size of the flash as set by the compiler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user