mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 02:36:35 +00:00
Fix ESP32C3 relay toggle on restart
Fix ESP32C3 relay toggle on restart (#20030)
This commit is contained in:
parent
040e25a92c
commit
b02a66a1b6
@ -1442,30 +1442,16 @@ void SetPin(uint32_t lpin, uint32_t gpio) {
|
||||
TasmotaGlobal.gpio_pin[lpin] = gpio;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "driver/gpio.h" // Include needed for Arduino 3
|
||||
#endif
|
||||
|
||||
void DigitalWrite(uint32_t gpio_pin, uint32_t index, uint32_t state) {
|
||||
static uint32_t pinmode_init[2] = { 0 }; // Pins 0 to 63 !!!
|
||||
|
||||
if (PinUsed(gpio_pin, index)) {
|
||||
uint32_t pin = Pin(gpio_pin, index) & 0x3F; // Fix possible overflow over 63 gpios
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
// if (GPIO_REL1 == gpio_pin) {
|
||||
gpio_hold_dis((gpio_num_t)pin); // Allow state change
|
||||
// }
|
||||
#endif
|
||||
if (!bitRead(pinmode_init[pin / 32], pin % 32)) {
|
||||
bitSet(pinmode_init[pin / 32], pin % 32);
|
||||
pinMode(pin, OUTPUT);
|
||||
}
|
||||
digitalWrite(pin, state &1);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
if (GPIO_REL1 == gpio_pin) {
|
||||
gpio_hold_en((gpio_num_t)pin); // Retain the state when the chip or system is reset, for example, when watchdog time-out or Deep-sleep
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -978,4 +978,42 @@ uint32_t HwRandom(void) {
|
||||
#endif // ESP_IDF_VERSION_MAJOR >= 5
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
// Since ESP-IDF 4.4, GPIO matrix or I/O is not reset during a restart
|
||||
// and GPIO configuration can get stuck because of leftovers
|
||||
//
|
||||
// This patched version of pinMode forces a full GPIO reset before setting new mode
|
||||
//
|
||||
#include "driver/gpio.h"
|
||||
|
||||
extern "C" void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode);
|
||||
|
||||
extern "C" void ARDUINO_ISR_ATTR pinMode(uint8_t pin, uint8_t mode) {
|
||||
gpio_reset_pin((gpio_num_t)pin);
|
||||
__pinMode(pin, mode);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
// See GpioForceHoldRelay() below
|
||||
gpio_hold_dis((gpio_num_t)pin); // Allow state change
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
void GpioForceHoldRelay(void) {
|
||||
// Only ESP32-C3 toggles outputs on restart unless gpio_hold_en() is called before restart
|
||||
// Retain the state when the chip or system is reset, for example, when watchdog time-out or Deep-sleep
|
||||
|
||||
// gpio_force_hold_all(); // This will hold flash/serial too so do not use
|
||||
|
||||
uint16_t real_gpio = GPIO_REL1 << 5;
|
||||
uint16_t mask = 0xFFE0;
|
||||
for (uint32_t i = 0; i < nitems(TasmotaGlobal.gpio_pin); i++) {
|
||||
if ((TasmotaGlobal.gpio_pin[i] & mask) == real_gpio) {
|
||||
gpio_hold_en((gpio_num_t)i); // Retain the state when the chip or system is reset, for example, when watchdog time-out or Deep-sleep
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
#endif // ESP32
|
@ -1916,24 +1916,6 @@ void TasConsoleInput(void) {
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
#ifdef ESP32
|
||||
// Since ESP-IDF 4.4, GPIO matrix or I/O is not reset during a restart
|
||||
// and GPIO configuration can get stuck because of leftovers
|
||||
//
|
||||
// This patched version of pinMode forces a full GPIO reset before setting new mode
|
||||
//
|
||||
#include "driver/gpio.h"
|
||||
|
||||
extern "C" void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode);
|
||||
|
||||
extern "C" void ARDUINO_ISR_ATTR pinMode(uint8_t pin, uint8_t mode) {
|
||||
gpio_reset_pin((gpio_num_t)pin);
|
||||
__pinMode(pin, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void GpioInit(void)
|
||||
{
|
||||
if (!ValidModule(Settings->module)) {
|
||||
|
@ -1149,12 +1149,15 @@ void WifiDisable(void) {
|
||||
TasmotaGlobal.global_state.wifi_down = 1;
|
||||
}
|
||||
|
||||
void EspRestart(void)
|
||||
{
|
||||
void EspRestart(void) {
|
||||
ResetPwm();
|
||||
WifiShutdown(true);
|
||||
CrashDumpClear(); // Clear the stack dump in RTC
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
||||
GpioForceHoldRelay(); // Retain the state when the chip or system is reset, for example, when watchdog time-out or Deep-sleep
|
||||
#endif // CONFIG_IDF_TARGET_ESP32C3
|
||||
|
||||
if (TasmotaGlobal.restart_halt) { // Restart 2
|
||||
while (1) {
|
||||
OsWatchLoop(); // Feed OsWatch timer to prevent restart
|
||||
|
Loading…
x
Reference in New Issue
Block a user