Skip to content

Commit

Permalink
Simpler "Always PSRAM"
Browse files Browse the repository at this point in the history
  • Loading branch information
troyhacks committed Nov 26, 2024
1 parent 2328a66 commit 4204abe
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 107 deletions.
29 changes: 2 additions & 27 deletions tools/ESP32-Chip_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,6 @@ void my_verbose_print_reset_reason(int reason)

void show_psram_info_part1(void)
{
#if defined(BOARD_HAS_PSRAM)
//if (esp_spiram_is_initialized() == false) esp_spiram_init();
Serial.println(psramFound() ? "ESP32 PSRAM: found.": "ESP32 PSRAM: not found!");
if (!psramFound()) return;
Expand All @@ -495,12 +494,10 @@ void show_psram_info_part1(void)
}
#endif
#endif
#endif
}

void show_psram_info_part2(void)
{
#if defined(BOARD_HAS_PSRAM)
if (!psramFound()) return;

// usually the next part won't work ...
Expand All @@ -518,27 +515,6 @@ void show_psram_info_part2(void)
case PSRAM_CACHE_F80M_S80M: Serial.println("* PSRAM speed = PSRAM_CACHE_F80M_S80M -> speed=80 esptool_flash=80 (by config)"); break;
}
#endif

#if 0 // this test makes the "max used PSRAM" info unusable
// try to allocate PSRAM (one 640KB chunk so we can be sure it will not fit into DRAM)
void * buff2 = ps_malloc(640 * 1024);
uint8_t * buf = (uint8_t*)malloc(620 * 1024);
Serial.print("* PSRAM free after malloc / ps_malloc : "); Serial.print(ESP.getFreePsram() / 1024.0, 2); Serial.println(" KB (1.2MB allocated)");
if (buff2 == NULL)
Serial.println("* can't allocate big memory with ps_malloc()");
else {
Serial.println("* Can allocate big memory with ps_malloc()");
free(buff2);
}
if (buf == NULL)
Serial.println("* can't allocate big memory with malloc()");
else {
free(buf);
Serial.println("* Can allocate big memory with malloc()");
}
#endif

#endif
}

void showRealSpeed() {
Expand Down Expand Up @@ -582,10 +558,10 @@ void showRealSpeed() {
Serial.print( " FREE RAM: "); Serial.print(ESP.getFreeHeap() / 1024.0, 2); Serial.println(" KB");
Serial.print( " MAX RAM alloc: "); Serial.print(ESP.getMaxAllocHeap() / 1024.0, 2); Serial.println(" KB");

#if defined(BOARD_HAS_PSRAM)
Serial.println();
show_psram_info_part1();

if (psramFound()) {
show_psram_info_part1();
Serial.print(" total PSRAM: "); Serial.print(ESP.getPsramSize() / 1024.0, 0); Serial.println(" KB");
Serial.print(" FREE PSRAM: "); Serial.print(ESP.getFreePsram() / 1024.0, 2); Serial.println(" KB");
Serial.print(" MAX PSRAM alloc:"); Serial.print(ESP.getMaxAllocPsram() / 1024.0, 2); Serial.println(" KB");
Expand All @@ -594,7 +570,6 @@ void showRealSpeed() {
show_psram_info_part2();
}
Serial.flush();
#endif

#if 0 // duplicate - this info is also printed by getCoreResetReason()
Serial.println();
Expand Down
12 changes: 6 additions & 6 deletions wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,13 @@ bool Segment::allocateData(size_t len) {
//DEBUG_PRINTF("allocateData(%u) start %d, stop %d, vlen %d\n", len, start, stop, virtualLength());
deallocateData();
if (len == 0) return false; // nothing to do
#if defined(ARDUINO_ARCH_ESP32) && !defined(BOARD_HAS_PSRAM)
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) {
//USER_PRINTF("Segment::allocateData: Segment data quota exceeded! used:%u request:%u max:%d\n", Segment::getUsedSegmentData(), len, MAX_SEGMENT_DATA);
if (len > 0) errorFlag = ERR_LOW_SEG_MEM; // WLEDMM raise errorflag
return false; //not enough memory
if (!psramFound()) {
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) {
//USER_PRINTF("Segment::allocateData: Segment data quota exceeded! used:%u request:%u max:%d\n", Segment::getUsedSegmentData(), len, MAX_SEGMENT_DATA);
if (len > 0) errorFlag = ERR_LOW_SEG_MEM; // WLEDMM raise errorflag
return false; //not enough memory
}
}
#endif
#ifdef ESP32
data = (byte*) heap_caps_calloc_prefer(len, 1, 2, MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT);
#else
Expand Down
46 changes: 22 additions & 24 deletions wled00/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,21 +411,20 @@ static String getContentType(AsyncWebServerRequest* request, String filename){
return "text/plain";
}

#if defined(BOARD_HAS_PSRAM)
// caching presets in PSRAM may prevent occasional flashes seen when HomeAssistant polls WLED
// original idea by @akaricchi (https://github.com/Akaricchi)
// returns a pointer to the PSRAM buffer, updates size parameter
static const uint8_t *getPresetCache(size_t &size) {
static unsigned long presetsCachedTime = 0;
static uint8_t *presetsCached = nullptr;
static size_t presetsCachedSize = 0;
static byte presetsCachedValidate = 0;

if (!psramFound()) {
size = 0;
return nullptr;
}

static unsigned long presetsCachedTime = 0;
static uint8_t *presetsCached = nullptr;
static size_t presetsCachedSize = 0;
static byte presetsCachedValidate = 0;

//if (presetsModifiedTime != presetsCachedTime) DEBUG_PRINTLN(F("getPresetCache(): presetsModifiedTime changed."));
//if (presetsCachedValidate != cacheInvalidate) DEBUG_PRINTLN(F("getPresetCache(): cacheInvalidate changed."));

Expand Down Expand Up @@ -458,7 +457,6 @@ static const uint8_t *getPresetCache(size_t &size) {
size = presetsCachedSize;
return presetsCached;
}
#endif

// WLEDMM
static bool haveLedmapFile = true;
Expand All @@ -473,14 +471,14 @@ void invalidateFileNameCache() { // reset "file not found" cache
haveICOFile = true;
haveCpalFile = true;

#if defined(BOARD_HAS_PSRAM)
// WLEDMM hack to clear presets.json cache
size_t dummy;
unsigned long realpresetsTime = presetsModifiedTime;
presetsModifiedTime = toki.second(); // pretend we have changes
(void) getPresetCache(dummy); // clear presets.json cache
presetsModifiedTime = realpresetsTime; // restore correct value
#endif
if (psramFound()) {
// WLEDMM hack to clear presets.json cache
size_t dummy;
unsigned long realpresetsTime = presetsModifiedTime;
presetsModifiedTime = toki.second(); // pretend we have changes
(void) getPresetCache(dummy); // clear presets.json cache
presetsModifiedTime = realpresetsTime; // restore correct value
}
//USER_PRINTLN("WS FileRead cache cleared");
}

Expand All @@ -504,17 +502,17 @@ bool handleFileRead(AsyncWebServerRequest* request, String path){
return true;
}*/

#if defined(BOARD_HAS_PSRAM)
if (path.endsWith("/presets.json")) {
size_t psize;
const uint8_t *presets = getPresetCache(psize);
if (presets) {
AsyncWebServerResponse *response = request->beginResponse_P(200, contentType, presets, psize);
request->send(response);
return true;
if (psramFound()) {
if (path.endsWith("/presets.json")) {
size_t psize;
const uint8_t *presets = getPresetCache(psize);
if (presets) {
AsyncWebServerResponse *response = request->beginResponse_P(200, contentType, presets, psize);
request->send(response);
return true;
}
}
}
#endif

if(WLED_FS.exists(path) || WLED_FS.exists(path + ".gz")) {
request->send(WLED_FS, path, String(), request->hasArg(F("download")));
Expand Down
3 changes: 0 additions & 3 deletions wled00/json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,6 @@ void serializeInfo(JsonObject root)
root[F("freestack")] = uxTaskGetStackHighWaterMark(NULL); //WLEDMM
root[F("minfreeheap")] = ESP.getMinFreeHeap();
#endif
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
if (psramFound()) {
root[F("tpram")] = ESP.getPsramSize(); //WLEDMM
root[F("psram")] = ESP.getFreePsram();
Expand All @@ -1088,12 +1087,10 @@ void serializeInfo(JsonObject root)
#endif
#endif
}
#else
// for testing
// root[F("tpram")] = 4194304; //WLEDMM
// root[F("psram")] = 4193000;
// root[F("psusedram")] = 3083000;
#endif

// begin WLEDMM
#ifdef ARDUINO_ARCH_ESP32
Expand Down
22 changes: 11 additions & 11 deletions wled00/pin_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,10 @@ String PinManagerClass::getPinSpecialText(int gpio) { // special purpose PIN in
#if defined(CONFIG_IDF_TARGET_ESP32S3)
// ESP32-S3
if (gpio > 18 && gpio < 21) return (F("USB (CDC) or JTAG"));
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI || (CONFIG_SPIRAM_MODE_OCT && defined(BOARD_HAS_PSRAM))
if (gpio > 32 && gpio < 38) return (F("(reserved) Octal PSRAM or Octal Flash"));
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI || CONFIG_SPIRAM_MODE_OCT
if (psramFound()) {
if (gpio > 32 && gpio < 38) return (F("(reserved) Octal PSRAM or Octal Flash"));
}
#endif
//if (gpio == 0 || gpio == 3 || gpio == 45 || gpio == 46) return (F("(strapping pin)"));
#ifdef ARDUINO_TTGO_T7_S3
Expand Down Expand Up @@ -143,15 +145,17 @@ String PinManagerClass::getPinSpecialText(int gpio) { // special purpose PIN in
//if (gpio == 12) return (F("(strapping pin - MTDI)"));
//if (gpio == 15) return (F("(strapping pin - MTDO)"));
//if (gpio > 11 && gpio < 16) return (F("(optional) JTAG debug probe"));
#if defined(BOARD_HAS_PSRAM)
if (psramFound()) {
if (gpio == 16 || gpio == 17) return (F("(reserved) PSRAM"));
#endif
}
#if defined(ARDUINO_TTGO_T7_V14_Mini32) || defined(ARDUINO_LOLIN_D32_PRO) || defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
if (gpio == 35) return (F("(reserved) _VBAT voltage monitoring")); // WLEDMM experimental
#endif
#if (defined(ARDUINO_TTGO_T7_V14_Mini32) || defined(ARDUINO_TTGO_T7_V15_Mini32)) && defined(BOARD_HAS_PSRAM)
if (gpio == 25) return (F("cross-connected to pin 16")); // WLEDMM experimental
if (gpio == 27) return (F("Cross-connected to pin 17")); // WLEDMM experimental
#if (defined(ARDUINO_TTGO_T7_V14_Mini32) || defined(ARDUINO_TTGO_T7_V15_Mini32))
if (psramFound()) {
if (gpio == 25) return (F("cross-connected to pin 16")); // WLEDMM experimental
if (gpio == 27) return (F("Cross-connected to pin 17")); // WLEDMM experimental
}
#endif
#endif
#else
Expand Down Expand Up @@ -744,10 +748,6 @@ bool PinManagerClass::isPinOk(byte gpio, bool output) const
if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses.
#endif
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
// #if CONFIG_SPIRAM_MODE_OCT && defined(BOARD_HAS_PSRAM)
// if (gpio > 32 && gpio < 38) return !psramFound(); // 33 to 37: not available if using _octal_ SPI Flash or _octal_ PSRAM
// #endif
// 38 to 48 are for general use. Be careful about straping pins GPIO45 and GPIO46 - these may be pull-up or pulled-down on your board.
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
// strapping pins: 0, 45 & 46
if (gpio > 18 && gpio < 21) return false; // WLEDMM: 19 + 20 = USB HWCDC. Not recommended for other uses.
Expand Down
30 changes: 12 additions & 18 deletions wled00/wled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,17 +344,14 @@ void WLED::loop()
DEBUG_PRINT(F("Avail heap: ")); DEBUG_PRINTLN(ESP.getMaxAllocHeap());
DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM
#endif
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
if (psramFound()) {
//DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
DEBUG_PRINT(F("Avail PSRAM: ")); DEBUG_PRINT(ESP.getMaxAllocPsram()/1024); DEBUG_PRINTLN("kB");
DEBUG_PRINT(F("PSRAM in use:")); DEBUG_PRINT(int(ESP.getPsramSize() - ESP.getFreePsram())); DEBUG_PRINTLN(F(" Bytes"));

} else {
//DEBUG_PRINTLN(F("No PSRAM"));
}
#endif
DEBUG_PRINTLN(F("No PSRAM"));
}
DEBUG_PRINT(F("Wifi state: ")); DEBUG_PRINTLN(WiFi.status());

if (WiFi.status() != lastWifiState) {
Expand Down Expand Up @@ -599,13 +596,14 @@ void WLED::setup()
DEBUG_PRINTF("%s min free stack %d\n", pcTaskGetTaskName(NULL), uxTaskGetStackHighWaterMark(NULL)); //WLEDMM
#endif

#if defined(ARDUINO_ARCH_ESP32) && (defined(BOARD_HAS_PSRAM) || defined(CONFIG_ESPTOOLPY_FLASHMODE_OPI))
//psramInit(); //WLEDMM?? softhack007: not sure if explicit init is really needed ... lets disable it here and see if that works
#if defined(CONFIG_IDF_TARGET_ESP32S3)
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI || (CONFIG_SPIRAM_MODE_OCT && defined(BOARD_HAS_PSRAM))
// S3: reserve GPIO 33-37 for "octal" PSRAM
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
#if CONFIG_ESPTOOLPY_FLASHMODE_OPI || CONFIG_SPIRAM_MODE_OCT
DEBUG_PRINTF("**** PSRAM WAS %s *****",psramFound()?"Found!":"NOT FOUND!"); // TroyHacks: Figure out why it's finding PSRAM when there isn't any. FIXME
if (psramFound()) {
// S3: reserve GPIO 33-37 for "octal" PSRAM
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
}
#endif
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
// S2: reserve GPIO 26-32 for PSRAM (may fail due to isPinOk() but that will also prevent other allocation)
Expand All @@ -620,15 +618,13 @@ void WLED::setup()
managed_pin_type pins[] = { {16, true}, {17, true} };
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
#endif
#if defined(BOARD_HAS_PSRAM)
if (psramFound()) {
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
}
#else
} else {
DEBUG_PRINTLN(F("PSRAM not used."));
#endif
#endif
}

#if defined(ARDUINO_ARCH_ESP32)
if (strncmp("ESP32-PICO", ESP.getChipModel(), 10) == 0) { // WLEDMM detect pico board at runtime
// special handling for PICO-D4: gpio16+17 are in use for onboard SPI FLASH (not PSRAM)
Expand All @@ -647,15 +643,13 @@ void WLED::setup()
pinManager.allocatePin(2, true, PinOwner::DMX);
#endif

#if defined(BOARD_HAS_PSRAM)
if (psramFound()) {
DEBUG_PRINT(F("\nfree heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
USER_PRINTLN(F("JSON gabage collection (initial)."));
doc.garbageCollect(); // WLEDMM experimental - this seems to move the complete doc[] into PSRAM
USER_PRINT(F("PSRAM in use:")); USER_PRINT(int(ESP.getPsramSize() - ESP.getFreePsram())); USER_PRINTLN(F(" Bytes."));
DEBUG_PRINT(F("free heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
}
#endif

// WLEDMM experimental: support for single neoPixel on Adafruit boards
#if 0
Expand Down
22 changes: 9 additions & 13 deletions wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -816,21 +816,17 @@ WLED_GLOBAL int8_t spi_sclk _INIT(HW_PIN_CLOCKSPI);
#endif

// global ArduinoJson buffer
#if defined(BOARD_HAS_PSRAM)
// WLEDMM experimental : always use dynamic JSON
#ifndef WLED_DEFINE_GLOBAL_VARS
WLED_GLOBAL PSRAMDynamicJsonDocument doc;
#else
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
WLED_GLOBAL PSRAMDynamicJsonDocument doc(JSON_BUFFER_SIZE); // S2 has very small RAM - lets not push our luck too far
#else
WLED_GLOBAL PSRAMDynamicJsonDocument doc(JSON_BUFFER_SIZE * 2 ); // initially "doc" is allocated in RAM, and later pushed into PSRAM when the drivers is ready
#endif
//#warning trying to always use dynamic JSON in PSRAM
#endif
#ifndef WLED_DEFINE_GLOBAL_VARS
WLED_GLOBAL PSRAMDynamicJsonDocument doc;
#else
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
WLED_GLOBAL PSRAMDynamicJsonDocument doc(JSON_BUFFER_SIZE); // S2 has very small RAM - lets not push our luck too far
#else
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> doc;
#endif // WLEDMM end
WLED_GLOBAL PSRAMDynamicJsonDocument doc(JSON_BUFFER_SIZE * 2 ); // initially "doc" is allocated in RAM, and later pushed into PSRAM when the drivers is ready
#endif
//#warning trying to always use dynamic JSON in PSRAM
#endif
WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);

// enable additional debug output
Expand Down
6 changes: 1 addition & 5 deletions wled00/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,7 @@ void appendGPIOinfo() {
size_t roLen = strlen(ro_gpio);
char pinString[10];
for(int pinNr = 0; pinNr < WLED_NUM_PINS; pinNr++) { // 49 = highest PIN on ESP32-S3
#if defined(ARDUINO_ARCH_ESP32) && !defined(BOARD_HAS_PSRAM)
if ((!pinManager.isPinOk(pinNr, false)) || (pinManager.getPinOwner(pinNr) == PinOwner::SPI_RAM)) { // WLEDMM add SPIRAM pins as "reserved" (pico boards)
#else
if (!pinManager.isPinOk(pinNr, false)) {
#endif
sprintf(pinString, "%s%d", strlen(rsvd)==rsLen?"":",", pinNr);
strcat(rsvd, pinString);
}
Expand Down Expand Up @@ -231,7 +227,7 @@ void appendGPIOinfo() {

//Note: Using pin 3 (RX) disables Adalight / Serial JSON

#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
#if defined(ARDUINO_ARCH_ESP32)
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32C3)
if (psramFound()) oappend(SET_F(",16,17")); // GPIO16 & GPIO17 reserved for SPI RAM on ESP32 (not on S2, S3 or C3)
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
Expand Down

0 comments on commit 4204abe

Please sign in to comment.