Skip to content

Rewrite PUYA patch to be more universal and mem friendly. #5504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 66 additions & 8 deletions cores/esp8266/Esp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -569,9 +578,58 @@ 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) {
// PUYA flash chips need to read existing data, update in memory and write modified data again.
static uint32_t *flash_write_puya_buf = 0;
int rc = 0;
uint32_t* ptr = data;

if (flash_write_puya_buf == 0) {
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 == 0) {
// 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;
}
Expand Down
44 changes: 44 additions & 0 deletions cores/esp8266/Esp.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,48 @@

#include <Arduino.h>

#ifndef PUYA_SUPPORT
#define PUYA_SUPPORT 1
#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
#define SPI_FLASH_VENDOR_ALLIANCE 0x52 /* Alliance Semiconductor */
#define SPI_FLASH_VENDOR_AMD 0x01 /* AMD */
#define SPI_FLASH_VENDOR_AMIC 0x37 /* AMIC */
#define SPI_FLASH_VENDOR_ATMEL 0x1F /* Atmel (now used by Adesto) */
#define SPI_FLASH_VENDOR_BRIGHT 0xAD /* Bright Microelectronics */
#define SPI_FLASH_VENDOR_CATALYST 0x31 /* Catalyst */
#define SPI_FLASH_VENDOR_EON 0x1C /* EON Silicon Devices, missing 0x7F prefix */
#define SPI_FLASH_VENDOR_ESMT 0x8C /* Elite Semiconductor Memory Technology (ESMT) / EFST Elite Flash Storage */
#define SPI_FLASH_VENDOR_EXCEL 0x4A /* ESI, missing 0x7F prefix */
#define SPI_FLASH_VENDOR_FIDELIX 0xF8 /* Fidelix */
#define SPI_FLASH_VENDOR_FUJITSU 0x04 /* Fujitsu */
#define SPI_FLASH_VENDOR_GIGADEVICE 0xC8 /* GigaDevice */
#define SPI_FLASH_VENDOR_HYUNDAI 0xAD /* Hyundai */
#define SPI_FLASH_VENDOR_INTEL 0x89 /* Intel */
#define SPI_FLASH_VENDOR_ISSI 0xD5 /* ISSI Integrated Silicon Solutions, see also PMC. */
#define SPI_FLASH_VENDOR_MACRONIX 0xC2 /* Macronix (MX) */
#define SPI_FLASH_VENDOR_NANTRONICS 0xD5 /* Nantronics, missing prefix */
#define SPI_FLASH_VENDOR_PMC 0x9D /* PMC, missing 0x7F prefix */
#define SPI_FLASH_VENDOR_PUYA 0x85 /* Puya semiconductor (shanghai) co. ltd */
#define SPI_FLASH_VENDOR_SANYO 0x62 /* Sanyo */
#define SPI_FLASH_VENDOR_SHARP 0xB0 /* Sharp */
#define SPI_FLASH_VENDOR_SPANSION 0x01 /* Spansion, same ID as AMD */
#define SPI_FLASH_VENDOR_SST 0xBF /* SST */
#define SPI_FLASH_VENDOR_ST 0x20 /* ST / SGS/Thomson / Numonyx (later acquired by Micron) */
#define SPI_FLASH_VENDOR_SYNCMOS_MVC 0x40 /* SyncMOS (SM) and Mosel Vitelic Corporation (MVC) */
#define SPI_FLASH_VENDOR_TENX 0x5E /* Tenx Technologies */
#define SPI_FLASH_VENDOR_TI 0x97 /* Texas Instruments */
#define SPI_FLASH_VENDOR_TI_OLD 0x01 /* TI chips from last century */
#define SPI_FLASH_VENDOR_WINBOND 0xDA /* Winbond */
#define SPI_FLASH_VENDOR_WINBOND_NEX 0xEF /* Winbond (ex Nexcom) serial flashes */

/**
* AVR macros for WDT managment
*/
Expand Down Expand Up @@ -123,6 +165,8 @@ class EspClass {
uint8_t getCpuFreqMHz();

uint32_t getFlashChipId();
uint8_t getFlashChipVendorId();

//gets the actual chip size based on the flash id
uint32_t getFlashChipRealSize();
//gets the size of the flash as set by the compiler
Expand Down