Merge pull request #12685 from s-hadinger/psram_disable_unsupported

Disable PSRAM on unsupported hardware
This commit is contained in:
s-hadinger 2021-07-18 21:25:35 +02:00 committed by GitHub
commit c64f6c326f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 58 additions and 12 deletions

View File

@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added
- Command ``SetSensor1..127 0|1`` to globally disable individual sensor driver
- Support for CAN bus and Freedom Won Battery Management System by Marius Bezuidenhout (#12651)
- Disable PSRAM on unsupported hardware
## [9.5.0.2] 20210714
### Added

View File

@ -380,6 +380,7 @@ uDisplay::uDisplay(char *lp) : Renderer(800, 600) {
Renderer *uDisplay::Init(void) {
extern bool UsePSRAM(void);
// for any bpp below native 16 bits, we allocate a local framebuffer to copy into
if (ep_mode || bpp < 16) {
@ -387,7 +388,7 @@ Renderer *uDisplay::Init(void) {
#ifdef ESP8266
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);
#else
if (psramFound()) {
if (UsePSRAM()) {
framebuffer = (uint8_t*)heap_caps_malloc((gxs * gys * bpp) / 8, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {
framebuffer = (uint8_t*)calloc((gxs * gys * bpp) / 8, 1);

View File

@ -464,22 +464,28 @@ uint8_t* FlashDirectAccess(void) {
return data;
}
// new function to check whether PSRAM is present and supported (i.e. required pacthes are present)
bool UsePSRAM(void) {
static bool can_use_psram = CanUsePSRAM();
return psramFound() && can_use_psram;
}
void *special_malloc(uint32_t size) {
if (psramFound()) {
if (UsePSRAM()) {
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {
return malloc(size);
}
}
void *special_realloc(void *ptr, size_t size) {
if (psramFound()) {
if (UsePSRAM()) {
return heap_caps_realloc(ptr, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {
return realloc(ptr, size);
}
}
void *special_calloc(size_t num, size_t size) {
if (psramFound()) {
if (UsePSRAM()) {
return heap_caps_calloc(num, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {
return calloc(num, size);
@ -675,6 +681,36 @@ typedef struct {
return F("ESP32");
}
/*
* ESP32 v1 and v2 needs some special patches to use PSRAM.
* Standard Tasmota 32 do not include those patches.
* If using ESP32 v1, please add: `-mfix-esp32-psram-cache-issue -lc-psram-workaround -lm-psram-workaround`
*
* This function returns true if the chip supports PSRAM natively (v3) or if the
* patches are present.
*/
bool CanUsePSRAM(void) {
#ifdef HAS_PSRAM_FIX
return true;
#endif
#ifdef CONFIG_IDF_TARGET_ESP32
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
if ((CHIP_ESP32 == chip_info.model) && (chip_info.revision < 3)) {
return false;
}
#if ESP_IDF_VERSION_MAJOR < 4
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_version = chip_ver & 0x7;
if ((CHIP_ESP32 == chip_info.model) && (pkg_version >= 6)) {
return false; // support for embedded PSRAM of ESP32-PICO-V3-02 requires esp-idf 4.4
}
#endif // ESP_IDF_VERSION_MAJOR < 4
#endif // CONFIG_IDF_TARGET_ESP32
return true;
}
#endif // ESP32
/*********************************************************************************************\

View File

@ -276,6 +276,14 @@ void setup(void) {
// AddLog(LOG_LEVEL_INFO, PSTR("ADR: Settings %p, Log %p"), Settings, TasmotaGlobal.log_buffer);
AddLog(LOG_LEVEL_INFO, PSTR("HDW: %s"), GetDeviceHardware().c_str());
#ifdef ESP32
AddLog(LOG_LEVEL_DEBUG, PSTR("HDW: psramFound=%i CanUsePSRAM=%i"), psramFound(), CanUsePSRAM());
#endif // ESP32
#if defined(ESP32) && !defined(HAS_PSRAM_FIX)
if (psramFound() && !CanUsePSRAM()) {
AddLog(LOG_LEVEL_INFO, PSTR("HDW: PSRAM is disabled, requires specific compilation on this hardware (see doc)"));
}
#endif // ESP32
#ifdef USE_UFILESYS
UfsInit(); // xdrv_50_filesystem.ino

View File

@ -2372,7 +2372,7 @@ void HandleInformation(void)
#ifdef ESP32
int32_t freeMaxMem = 100 - (int32_t)(ESP_getMaxAllocHeap() * 100 / ESP_getFreeHeap());
WSContentSend_PD(PSTR("}1" D_FREE_MEMORY "}2%1_f kB (" D_FRAGMENTATION " %d%%)"), &freemem, freeMaxMem);
if (psramFound()) {
if (UsePSRAM()) {
WSContentSend_P(PSTR("}1" D_PSR_MAX_MEMORY "}2%d kB"), ESP.getPsramSize() / 1024);
WSContentSend_P(PSTR("}1" D_PSR_FREE_MEMORY "}2%d kB"), ESP.getFreePsram() / 1024);
}

View File

@ -280,12 +280,12 @@ void I2S_Init(void) {
mp3ram = nullptr;
#ifdef ESP32
if (psramFound()) {
if (UsePSRAM()) {
mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}
#ifdef USE_I2S_WEBRADIO
if (psramFound()) {
if (UsePSRAM()) {
preallocateBuffer = heap_caps_malloc(preallocateBufferSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
preallocateCodec = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
} else {

View File

@ -181,7 +181,7 @@ extern "C" {
map_insert_int(vm, "heap_free", ESP_getFreeHeap() / 1024);
int32_t freeMaxMem = 100 - (int32_t)(ESP_getMaxAllocHeap() * 100 / ESP_getFreeHeap());
map_insert_int(vm, "frag", freeMaxMem);
if (psramFound()) {
if (UsePSRAM()) {
map_insert_int(vm, "psram", ESP.getPsramSize() / 1024);
map_insert_int(vm, "psram_free", ESP.getFreePsram() / 1024);
}

View File

@ -442,13 +442,13 @@ void start_lvgl(const char * uconfig) {
// initialize the FreeType renderer
lv_freetype_init(USE_LVGL_FREETYPE_MAX_FACES,
USE_LVGL_FREETYPE_MAX_SIZES,
psramFound() ? USE_LVGL_FREETYPE_MAX_BYTES_PSRAM : USE_LVGL_FREETYPE_MAX_BYTES);
UsePSRAM() ? USE_LVGL_FREETYPE_MAX_BYTES_PSRAM : USE_LVGL_FREETYPE_MAX_BYTES);
#endif
#ifdef USE_LVGL_PNG_DECODER
lv_png_init();
#endif // USE_LVGL_PNG_DECODER
if (psramFound()) {
if (UsePSRAM()) {
lv_img_cache_set_size(LV_IMG_CACHE_DEF_SIZE_PSRAM);
}

View File

@ -252,7 +252,7 @@ uint32_t WcSetup(int32_t fsiz) {
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
bool psram = psramFound();
bool psram = UsePSRAM();
if (psram) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;

View File

@ -125,7 +125,7 @@ void HandleMetrics(void) {
int32_t freeMaxMem = 100 - (int32_t)(ESP_getMaxAllocHeap() * 100 / ESP_getFreeHeap());
WSContentSend_PD(PSTR("# TYPE tasmota_memory_bytes gauge\ntasmota_memory_bytes{memory=\"Ram\"} %d\n"), ESP_getFreeHeap());
WSContentSend_PD(PSTR("# TYPE tasmota_memory_ratio gauge\ntasmota_memory_ratio{memory=\"Fragmentation\"} %d)"), freeMaxMem / 100);
if (psramFound()) {
if (UsePSRAM()) {
WSContentSend_P(PSTR("# TYPE tasmota_memory_bytes gauge\ntasmota_memory_bytes{memory=\"Psram\"} %d\n"), ESP.getFreePsram() );
}
#else // ESP32