Skip to content

Commit ed5a14e

Browse files
committed
[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.
1 parent 715fc99 commit ed5a14e

File tree

2 files changed

+38
-21
lines changed

2 files changed

+38
-21
lines changed

cores/esp8266/Esp.cpp

+32-21
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,6 @@ uint32_t EspClass::getFlashChipId(void)
269269
static uint32_t flash_chip_id = 0;
270270
if (flash_chip_id == 0) {
271271
flash_chip_id = spi_flash_get_id();
272-
// Check for PUYA chip and allocate buffer as soon as possible.
273-
flashIsPuya();
274272
}
275273
return flash_chip_id;
276274
}
@@ -575,43 +573,56 @@ bool EspClass::flashEraseSector(uint32_t sector) {
575573
return rc == 0;
576574
}
577575

578-
// PUYA flash chips need to read entire sector, update in memory and write sector again.
576+
// PUYA flash chips need to read existing data, update in memory and write modified data again.
579577
static uint32_t *flash_write_puya_buf = 0;
580578

581579
bool EspClass::flashIsPuya(){
582580
if (flash_write_puya_buf != 0) {
583581
// Already detected PUYA and allocated buffer.
584582
return true;
585583
}
586-
bool isPuya = ((getFlashChipId() & 0x000000ff) == 0x85); // 0x146085 PUYA
587-
if (isPuya) {
588-
flash_write_puya_buf = (uint32_t*) malloc((SPI_FLASH_SEC_SIZE / 4) * sizeof(uint32_t));
589-
// No need to ever free this, since the flash chip will never change at runtime.
590-
}
591-
return isPuya;
584+
return ((getFlashChipId() & 0x000000ff) == 0x85); // 0x146085 PUYA
592585
}
593586

594587
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
595588
ets_isr_mask(FLASH_INT_MASK);
596-
int rc;
589+
int rc = 0;
597590
uint32_t* ptr = data;
598591

599592
if (flashIsPuya()) {
600593
if (flash_write_puya_buf == 0) {
601-
// Memory could not be allocated.
602-
return false;
603-
}
604-
rc = spi_flash_read(offset, flash_write_puya_buf, size);
605-
if (rc != 0) {
606-
ets_isr_unmask(FLASH_INT_MASK);
607-
return false;
594+
flash_write_puya_buf = (uint32_t*) malloc(PUYA_BUFFER_SIZE);
595+
// No need to ever free this, since the flash chip will never change at runtime.
596+
if (flash_write_puya_buf == 0) {
597+
// Memory could not be allocated.
598+
return false;
599+
}
608600
}
609-
for (size_t i = 0; i < size / 4; ++i) {
610-
flash_write_puya_buf[i] &= data[i];
601+
size_t bytesLeft = size;
602+
uint32_t pos = offset;
603+
while (bytesLeft > 0 && rc == 0) {
604+
size_t bytes_now = bytesLeft;
605+
if (bytes_now > PUYA_BUFFER_SIZE) {
606+
bytes_now = PUYA_BUFFER_SIZE;
607+
bytesLeft -= PUYA_BUFFER_SIZE;
608+
} else {
609+
bytesLeft = 0;
610+
}
611+
rc = spi_flash_read(pos, flash_write_puya_buf, bytes_now);
612+
if (rc != 0) {
613+
ets_isr_unmask(FLASH_INT_MASK);
614+
return false;
615+
}
616+
for (size_t i = 0; i < bytes_now / 4; ++i) {
617+
flash_write_puya_buf[i] &= *ptr;
618+
++ptr;
619+
}
620+
rc = spi_flash_write(pos, flash_write_puya_buf, bytes_now);
621+
pos += bytes_now;
611622
}
612-
ptr = flash_write_puya_buf;
623+
} else {
624+
rc = spi_flash_write(offset, ptr, size);
613625
}
614-
rc = spi_flash_write(offset, ptr, size);
615626
ets_isr_unmask(FLASH_INT_MASK);
616627
return rc == 0;
617628
}

cores/esp8266/Esp.h

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
#include <Arduino.h>
2525

2626
#define PUYASUPPORT
27+
#ifndef PUYA_BUFFER_SIZE
28+
// Good alternative for buffer size is: SPI_FLASH_SEC_SIZE
29+
// 512 bytes is a reasonable trade-off between memory use and write cycles.
30+
// Always use a multiple of flash page size (256 bytes)
31+
#define PUYA_BUFFER_SIZE 512
32+
#endif
2733

2834
/**
2935
* AVR macros for WDT managment

0 commit comments

Comments
 (0)