mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Refactor hardware specific code
This commit is contained in:
parent
7febc11b8c
commit
ede5e398a6
@ -1,218 +1,15 @@
|
||||
/*
|
||||
support_esp.ino - ESP specific code for Tasmota
|
||||
support_esp32.ino - ESP32 specific support for Tasmota
|
||||
|
||||
Copyright (C) 2021 Theo Arends / Jörg Schüler-Maroldt
|
||||
SPDX-FileCopyrightText: 2023 Theo Arends
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP8266 and ESP32 specific code
|
||||
*
|
||||
* At the end the common Tasmota calls are provided
|
||||
\*********************************************************************************************/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP8266 Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef ESP8266
|
||||
|
||||
extern "C" {
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Core overrides executed by core
|
||||
\*********************************************************************************************/
|
||||
|
||||
// Add below line to tasmota_globals.h
|
||||
// extern "C" void resetPins();
|
||||
//
|
||||
// This function overrules __resetPins() which is executed by core init() as initPins() in core_esp8266_wiring.cpp
|
||||
//
|
||||
// 20221229 - (v12.3.1.2) Enabled with additional check to execute on power on only to fix relay clicks on power on
|
||||
// 20200321 - (v8.2.0.1) Disable core functionality to fix relay clicks on restart after OTA - make function return without setting pinMode
|
||||
void resetPins() {
|
||||
if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) {
|
||||
// Only perform at power on
|
||||
for (int i = 0; i <= 5; ++i) {
|
||||
pinMode(i, INPUT);
|
||||
}
|
||||
// pins 6-11 are used for the SPI flash interface ESP8266
|
||||
for (int i = 12; i <= 16; ++i) {
|
||||
pinMode(i, INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Hardware related
|
||||
\*********************************************************************************************/
|
||||
|
||||
void HwWdtDisable(void) {
|
||||
*((volatile uint32_t*) 0x60000900) &= ~(1); // Hardware WDT OFF
|
||||
}
|
||||
|
||||
void HwWdtEnable(void) {
|
||||
*((volatile uint32_t*) 0x60000900) |= 1; // Hardware WDT ON
|
||||
}
|
||||
|
||||
void WdtDisable(void) {
|
||||
ESP.wdtDisable();
|
||||
HwWdtDisable();
|
||||
}
|
||||
|
||||
void WdtEnable(void) {
|
||||
HwWdtEnable();
|
||||
ESP.wdtEnable(0);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP8266 specifics
|
||||
\*********************************************************************************************/
|
||||
|
||||
uint32_t ESP_ResetInfoReason(void) {
|
||||
return resetInfo.reason;
|
||||
}
|
||||
|
||||
String ESP_getResetReason(void) {
|
||||
return ESP.getResetReason();
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipId(void) {
|
||||
return ESP.getChipId();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeSketchSpace(void) {
|
||||
return ESP.getFreeSketchSpace();
|
||||
}
|
||||
|
||||
uint32_t ESP_getSketchSize(void) {
|
||||
return ESP.getSketchSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeHeap(void) {
|
||||
return ESP.getFreeHeap();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipId(void) {
|
||||
return ESP.getFlashChipId();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipRealSize(void) {
|
||||
return ESP.getFlashChipRealSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipSize(void) {
|
||||
return ESP.getFlashChipSize();
|
||||
}
|
||||
|
||||
void ESP_Restart(void) {
|
||||
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
|
||||
ESP.reset();
|
||||
}
|
||||
|
||||
uint32_t FlashWriteStartSector(void) {
|
||||
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
|
||||
}
|
||||
|
||||
uint32_t FlashWriteMaxSector(void) {
|
||||
return (((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE) - 2;
|
||||
}
|
||||
|
||||
uint8_t* FlashDirectAccess(void) {
|
||||
return (uint8_t*)(0x40200000 + (FlashWriteStartSector() * SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
void *special_malloc(uint32_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *special_realloc(void *ptr, size_t size) {
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void *special_calloc(size_t num, size_t size) {
|
||||
return calloc(num, size);
|
||||
}
|
||||
|
||||
String GetDeviceHardware(void) {
|
||||
/*
|
||||
ESP8266 SoCs
|
||||
- 32-bit MCU & 2.4 GHz Wi-Fi
|
||||
- High-performance 160 MHz single-core CPU
|
||||
- +19.5 dBm output power ensures a good physical range
|
||||
- Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
|
||||
- Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
|
||||
*/
|
||||
// esptool.py get_efuses
|
||||
uint32_t efuse0 = *(uint32_t*)(0x3FF00050);
|
||||
// uint32_t efuse1 = *(uint32_t*)(0x3FF00054);
|
||||
uint32_t efuse2 = *(uint32_t*)(0x3FF00058);
|
||||
uint32_t efuse3 = *(uint32_t*)(0x3FF0005C);
|
||||
|
||||
bool r0_4 = efuse0 & (1 << 4); // ESP8285
|
||||
bool r2_16 = efuse2 & (1 << 16); // ESP8285
|
||||
if (r0_4 || r2_16) { // ESP8285
|
||||
// 1M 2M 2M 4M flash size
|
||||
// r0_4 1 1 0 0
|
||||
bool r3_25 = efuse3 & (1 << 25); // flash matrix 0 0 1 1
|
||||
bool r3_26 = efuse3 & (1 << 26); // flash matrix 0 1 0 1
|
||||
bool r3_27 = efuse3 & (1 << 27); // flash matrix 0 0 0 0
|
||||
uint32_t pkg_version = 0;
|
||||
if (!r3_27) {
|
||||
if (r0_4 && !r3_25) {
|
||||
pkg_version = (r3_26) ? 2 : 1;
|
||||
}
|
||||
else if (!r0_4 && r3_25) {
|
||||
pkg_version = (r3_26) ? 4 : 2;
|
||||
}
|
||||
}
|
||||
bool max_temp = efuse0 & (1 << 5); // Max flash temperature (0 = 85C, 1 = 105C)
|
||||
switch (pkg_version) {
|
||||
case 1:
|
||||
if (max_temp) { return F("ESP8285H08"); } // 1M flash
|
||||
else { return F("ESP8285N08"); }
|
||||
case 2:
|
||||
if (max_temp) { return F("ESP8285H16"); } // 2M flash
|
||||
else { return F("ESP8285N16"); }
|
||||
case 4:
|
||||
if (max_temp) { return F("ESP8285H32"); } // 4M flash
|
||||
else { return F("ESP8285N32"); }
|
||||
}
|
||||
return F("ESP8285");
|
||||
}
|
||||
return F("ESP8266EX");
|
||||
}
|
||||
|
||||
String GetDeviceHardwareRevision(void) {
|
||||
// No known revisions for ESP8266/85
|
||||
return GetDeviceHardware();
|
||||
}
|
||||
|
||||
String GetCodeCores(void) {
|
||||
return F("");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP32 Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef ESP32
|
||||
/*********************************************************************************************\
|
||||
* ESP32, ESP32-S2, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C6 and ESP32-H2 Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/spi_reg.h"
|
||||
@ -233,6 +30,8 @@ String GetCodeCores(void) {
|
||||
#define ESP32_ARCH "esp32c3"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
#define ESP32_ARCH "esp32c6"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#define ESP32_ARCH "esp32h2"
|
||||
#else
|
||||
#define ESP32_ARCH ""
|
||||
#endif
|
||||
@ -256,6 +55,8 @@ String GetCodeCores(void) {
|
||||
#include "esp32c3/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 // ESP32-C6
|
||||
#include "esp32c6/rom/rtc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2 // ESP32-H2
|
||||
#include "esp32h2/rom/rtc.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
@ -440,6 +241,9 @@ extern "C" {
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6 // ESP32-C6
|
||||
#include "esp32c6/rom/spi_flash.h"
|
||||
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32c6 is located at 0x0000
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2 // ESP32-H2
|
||||
#include "esp32h2/rom/spi_flash.h"
|
||||
#define ESP_FLASH_IMAGE_BASE 0x0000 // Esp32h2 is located at 0x0000
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
@ -707,6 +511,15 @@ uint32_t ESP_getFreeHeap(void) {
|
||||
return heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeHeap1024(void) {
|
||||
return ESP_getFreeHeap() / 1024;
|
||||
}
|
||||
/*
|
||||
float ESP_getFreeHeap1024(void) {
|
||||
return ((float)ESP_getFreeHeap()) / 1024;
|
||||
}
|
||||
*/
|
||||
|
||||
uint32_t ESP_getMaxAllocHeap(void) {
|
||||
// arduino returns IRAM but we want only DRAM
|
||||
#ifdef USE_GT911 // GT911 IRQ crashes with heap_caps_get_largest_free_block
|
||||
@ -1140,21 +953,6 @@ bool CanUsePSRAM(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // ESP32
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
uint32_t ESP_getFreeHeap1024(void) {
|
||||
return ESP_getFreeHeap() / 1024;
|
||||
}
|
||||
/*
|
||||
float ESP_getFreeHeap1024(void) {
|
||||
return ((float)ESP_getFreeHeap()) / 1024;
|
||||
}
|
||||
*/
|
||||
|
||||
/*********************************************************************************************\
|
||||
* High entropy hardware random generator
|
||||
* Thanks to DigitalAlchemist
|
||||
@ -1166,18 +964,12 @@ float ESP_getFreeHeap1024(void) {
|
||||
|
||||
// Based on code from https://raw.githubusercontent.com/espressif/esp-idf/master/components/esp32/hw_random.c
|
||||
uint32_t HwRandom(void) {
|
||||
#if ESP8266
|
||||
// https://web.archive.org/web/20160922031242/http://esp8266-re.foogod.com/wiki/Random_Number_Generator
|
||||
#define _RAND_ADDR 0x3FF20E44UL
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
// See for more info on the HW RNG:
|
||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/random.html
|
||||
return esp_random();
|
||||
#endif
|
||||
#else
|
||||
#define _RAND_ADDR 0x3FF75144UL
|
||||
#endif // ESP32
|
||||
static uint32_t last_ccount = 0;
|
||||
uint32_t ccount;
|
||||
uint32_t result = 0;
|
||||
@ -1187,5 +979,8 @@ uint32_t HwRandom(void) {
|
||||
} while (ccount - last_ccount < 64);
|
||||
last_ccount = ccount;
|
||||
return result ^ *(volatile uint32_t *)_RAND_ADDR;
|
||||
#undef _RAND_ADDR
|
||||
#undef _RAND_ADDR
|
||||
#endif // ESP_IDF_VERSION_MAJOR >= 5
|
||||
}
|
||||
|
||||
#endif // ESP32
|
221
tasmota/tasmota_support/support_esp8266.ino
Normal file
221
tasmota/tasmota_support/support_esp8266.ino
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
support_esp8266.ino - ESP8266 specific support for Tasmota
|
||||
|
||||
SPDX-FileCopyrightText: 2023 Theo Arends
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
#ifdef ESP8266
|
||||
/*********************************************************************************************\
|
||||
* ESP8266 and ESP8285 Support
|
||||
\*********************************************************************************************/
|
||||
|
||||
extern "C" {
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Core overrides executed by core
|
||||
\*********************************************************************************************/
|
||||
|
||||
// Add below line to tasmota_globals.h
|
||||
// extern "C" void resetPins();
|
||||
//
|
||||
// This function overrules __resetPins() which is executed by core init() as initPins() in core_esp8266_wiring.cpp
|
||||
//
|
||||
// 20221229 - (v12.3.1.2) Enabled with additional check to execute on power on only to fix relay clicks on power on
|
||||
// 20200321 - (v8.2.0.1) Disable core functionality to fix relay clicks on restart after OTA - make function return without setting pinMode
|
||||
void resetPins() {
|
||||
if ((resetInfo.reason == REASON_DEFAULT_RST) || (resetInfo.reason == REASON_EXT_SYS_RST)) {
|
||||
// Only perform at power on
|
||||
for (int i = 0; i <= 5; ++i) {
|
||||
pinMode(i, INPUT);
|
||||
}
|
||||
// pins 6-11 are used for the SPI flash interface ESP8266
|
||||
for (int i = 12; i <= 16; ++i) {
|
||||
pinMode(i, INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Hardware related
|
||||
\*********************************************************************************************/
|
||||
|
||||
void HwWdtDisable(void) {
|
||||
*((volatile uint32_t*) 0x60000900) &= ~(1); // Hardware WDT OFF
|
||||
}
|
||||
|
||||
void HwWdtEnable(void) {
|
||||
*((volatile uint32_t*) 0x60000900) |= 1; // Hardware WDT ON
|
||||
}
|
||||
|
||||
void WdtDisable(void) {
|
||||
ESP.wdtDisable();
|
||||
HwWdtDisable();
|
||||
}
|
||||
|
||||
void WdtEnable(void) {
|
||||
HwWdtEnable();
|
||||
ESP.wdtEnable(0);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ESP8266 specifics
|
||||
\*********************************************************************************************/
|
||||
|
||||
uint32_t ESP_ResetInfoReason(void) {
|
||||
return resetInfo.reason;
|
||||
}
|
||||
|
||||
String ESP_getResetReason(void) {
|
||||
return ESP.getResetReason();
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipId(void) {
|
||||
return ESP.getChipId();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeSketchSpace(void) {
|
||||
return ESP.getFreeSketchSpace();
|
||||
}
|
||||
|
||||
uint32_t ESP_getSketchSize(void) {
|
||||
return ESP.getSketchSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeHeap(void) {
|
||||
return ESP.getFreeHeap();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeHeap1024(void) {
|
||||
return ESP_getFreeHeap() / 1024;
|
||||
}
|
||||
/*
|
||||
float ESP_getFreeHeap1024(void) {
|
||||
return ((float)ESP_getFreeHeap()) / 1024;
|
||||
}
|
||||
*/
|
||||
|
||||
uint32_t ESP_getFlashChipId(void) {
|
||||
return ESP.getFlashChipId();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipRealSize(void) {
|
||||
return ESP.getFlashChipRealSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipSize(void) {
|
||||
return ESP.getFlashChipSize();
|
||||
}
|
||||
|
||||
void ESP_Restart(void) {
|
||||
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
|
||||
ESP.reset();
|
||||
}
|
||||
|
||||
uint32_t FlashWriteStartSector(void) {
|
||||
return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side
|
||||
}
|
||||
|
||||
uint32_t FlashWriteMaxSector(void) {
|
||||
return (((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE) - 2;
|
||||
}
|
||||
|
||||
uint8_t* FlashDirectAccess(void) {
|
||||
return (uint8_t*)(0x40200000 + (FlashWriteStartSector() * SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
void *special_malloc(uint32_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *special_realloc(void *ptr, size_t size) {
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void *special_calloc(size_t num, size_t size) {
|
||||
return calloc(num, size);
|
||||
}
|
||||
|
||||
String GetDeviceHardware(void) {
|
||||
/*
|
||||
ESP8266 SoCs
|
||||
- 32-bit MCU & 2.4 GHz Wi-Fi
|
||||
- High-performance 160 MHz single-core CPU
|
||||
- +19.5 dBm output power ensures a good physical range
|
||||
- Sleep current is less than 20 μA, making it suitable for battery-powered and wearable-electronics applications
|
||||
- Peripherals include UART, GPIO, I2C, I2S, SDIO, PWM, ADC and SPI
|
||||
*/
|
||||
// esptool.py get_efuses
|
||||
uint32_t efuse0 = *(uint32_t*)(0x3FF00050);
|
||||
// uint32_t efuse1 = *(uint32_t*)(0x3FF00054);
|
||||
uint32_t efuse2 = *(uint32_t*)(0x3FF00058);
|
||||
uint32_t efuse3 = *(uint32_t*)(0x3FF0005C);
|
||||
|
||||
bool r0_4 = efuse0 & (1 << 4); // ESP8285
|
||||
bool r2_16 = efuse2 & (1 << 16); // ESP8285
|
||||
if (r0_4 || r2_16) { // ESP8285
|
||||
// 1M 2M 2M 4M flash size
|
||||
// r0_4 1 1 0 0
|
||||
bool r3_25 = efuse3 & (1 << 25); // flash matrix 0 0 1 1
|
||||
bool r3_26 = efuse3 & (1 << 26); // flash matrix 0 1 0 1
|
||||
bool r3_27 = efuse3 & (1 << 27); // flash matrix 0 0 0 0
|
||||
uint32_t pkg_version = 0;
|
||||
if (!r3_27) {
|
||||
if (r0_4 && !r3_25) {
|
||||
pkg_version = (r3_26) ? 2 : 1;
|
||||
}
|
||||
else if (!r0_4 && r3_25) {
|
||||
pkg_version = (r3_26) ? 4 : 2;
|
||||
}
|
||||
}
|
||||
bool max_temp = efuse0 & (1 << 5); // Max flash temperature (0 = 85C, 1 = 105C)
|
||||
switch (pkg_version) {
|
||||
case 1:
|
||||
if (max_temp) { return F("ESP8285H08"); } // 1M flash
|
||||
else { return F("ESP8285N08"); }
|
||||
case 2:
|
||||
if (max_temp) { return F("ESP8285H16"); } // 2M flash
|
||||
else { return F("ESP8285N16"); }
|
||||
case 4:
|
||||
if (max_temp) { return F("ESP8285H32"); } // 4M flash
|
||||
else { return F("ESP8285N32"); }
|
||||
}
|
||||
return F("ESP8285");
|
||||
}
|
||||
return F("ESP8266EX");
|
||||
}
|
||||
|
||||
String GetDeviceHardwareRevision(void) {
|
||||
// No known revisions for ESP8266/85
|
||||
return GetDeviceHardware();
|
||||
}
|
||||
|
||||
String GetCodeCores(void) {
|
||||
return F("");
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* High entropy hardware random generator
|
||||
* Thanks to DigitalAlchemist
|
||||
\*********************************************************************************************/
|
||||
|
||||
// Based on code from https://raw.githubusercontent.com/espressif/esp-idf/master/components/esp32/hw_random.c
|
||||
uint32_t HwRandom(void) {
|
||||
// https://web.archive.org/web/20160922031242/http://esp8266-re.foogod.com/wiki/Random_Number_Generator
|
||||
#define _RAND_ADDR 0x3FF20E44UL
|
||||
static uint32_t last_ccount = 0;
|
||||
uint32_t ccount;
|
||||
uint32_t result = 0;
|
||||
do {
|
||||
ccount = ESP.getCycleCount();
|
||||
result ^= *(volatile uint32_t *)_RAND_ADDR;
|
||||
} while (ccount - last_ccount < 64);
|
||||
last_ccount = ccount;
|
||||
return result ^ *(volatile uint32_t *)_RAND_ADDR;
|
||||
#undef _RAND_ADDR
|
||||
}
|
||||
|
||||
#endif // ESP8266
|
Loading…
x
Reference in New Issue
Block a user