Add experimental minimal support for ESP32

Add experimental minimal support for ESP32 (#8110)
This commit is contained in:
Theo Arends 2020-04-10 18:24:08 +02:00
parent 13d7943b58
commit 93fd5dd618
54 changed files with 1469 additions and 61 deletions

46
ESP32README.md Normal file
View File

@ -0,0 +1,46 @@
![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg)
## ESP32 port with minimal changes
## Description:
This is my esp32 port, i try to make only minimal changes to the original source code
from Theo Arends, now again for development branch.
## Checklist:
- [x] The pull request is done against the latest dev branch
- [x] Only relevant files were touched
- [x] Only one feature/fix was added per PR.
- [x] The code change is tested and works on core Tasmota_core_stage
- [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass**
- [x] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
- [x] i checked binary "tasmota.bin" to be the same in development and development_esp32 branch
Here are the main things i have done
- in "lib_extra_dirs" i have libesp32 directory for things missing in ESP32 framework
my "ESP32-to-ESP8266-compat" has all files that are not available in ESP32
so you dont have to change the source code and i write code to get the informations from ESP32
- all librarys that are not compatibel i add to lib_ignore
- all code that is not for ESP32 i put in "#ifdef ESP8266" the define is from espessif platform
- all code for ESP32 is in "#ifdef ESP32"
- SerConfu8 type uint8_t for SerialConfig list
- changed "HTTP_HEADER" to "HTTP_HEADER1", in ESP32 its an enum
- for ip adress 0 i used IPAddress(0,0,0,0)
- Special ESP.xxx call i change to ESP_xxx (ESP_rtcUserMemoryWrite, ...) and write macros for ESP8266
- because ESP32 has only WEMOS 32 modul, i exclude all code like this:
"if (SONOFF_xxx == Settings.module)" in "#ifdef ESP8266"
- variable "sleep" i changed to "ssleep" because of standard library sleep(..) function
- all esp32 stuff is in support_esp32.ino
- in tasmota.ino i include "tasmota_compat.h"
- in tasmota_template.h i use ifdef and tasmota_templESP32.h
- defines for sensors that currently don't work, i undef in tasmota_templESP32.h
- comment fo "no warnig" in "xdrv_20_hue.ino" thats the only warning i had
Build info
Copy platformio_override_esp32.ini to platformio_override.ini an select your imagetype.
You can build tasmota and tasmota32 Version with one build.
If you need other versions change platformio_override.ini
stay at home, have fun and keep good
Jörg

View File

@ -24,6 +24,8 @@ SOFTWARE.
#include <twi.h>
#include <FrogmoreScd30.h>
#ifdef ESP8266
#define COMMAND_SCD30_CONTINUOUS_MEASUREMENT 0x0010
#define COMMAND_SCD30_MEASUREMENT_INTERVAL 0x4600
#define COMMAND_SCD30_GET_DATA_READY 0x0202
@ -253,7 +255,7 @@ int FrogmoreScd30::get16BitRegCheckCRC(void* pInput, uint16_t *pData)
}
// gets 32 bits, (2) 16-bit chunks, and validates the CRCs
//
//
int FrogmoreScd30::get32BitRegCheckCRC(void *pInput, float *pData)
{
uint16_t tempU16High;
@ -458,7 +460,7 @@ int FrogmoreScd30::setTemperatureOffset(float offset_degC)
{
return (ERROR_SCD30_INVALID_VALUE);
}
}
int FrogmoreScd30::setTemperatureOffset(uint16_t offset_centiDegC)
@ -568,7 +570,7 @@ int FrogmoreScd30::readMeasurement(
return (error);
}
error = get32BitRegCheckCRC(&bytes[12], &tempHumidity);
error = get32BitRegCheckCRC(&bytes[12], &tempHumidity);
if (error)
{
#ifdef SCD30_DEBUG
@ -651,3 +653,4 @@ int FrogmoreScd30::stopMeasuring(void)
return (sendCommand(COMMAND_SCD30_STOP_MEASUREMENT));
}
#endif // ESP8266

View File

@ -150,9 +150,11 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
} else {
Serial.begin(speed, SERIAL_8N1);
}
#ifdef ESP8266
if (m_hardswap) {
Serial.swap();
}
#endif // ESP8266
} else {
// Use getCycleCount() loop to get as exact timing as possible
m_bit_time = ESP.getCpuFreqMHz() * 1000000 / speed;

View File

@ -2584,6 +2584,9 @@ br_cpuid(uint32_t mask_eax, uint32_t mask_ebx,
#define optimistic_yield(ignored)
#endif
#ifdef ESP32
#define memcpy_P memcpy
#endif
/* ==================================================================== */

View File

@ -68,8 +68,8 @@ public:
int16_t width;
int16_t height;
Epd();
~Epd();
// Epd();
// ~Epd();
int Init(const unsigned char* lut);
void Init(int8_t p);
void SendCommand(unsigned char command);

View File

@ -0,0 +1,19 @@
Library for ESP32 with Tasmota
This Class is for compatibility with esp8266 code
== License ==
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

View File

@ -0,0 +1,24 @@
#######################################
# Syntax Coloring Map For Test
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
A4988_ESP32Compat KEYWORD1 A4988_ESP32Compat
#######################################
# Methods and Functions (KEYWORD2)
#######################################
doMove KEYWORD2
doRotate KEYWORD2
setRPM KEYWORD2
setSPR KEYWORD2
setMIS KEYWORD2
version KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,9 @@
name=ESP32-to-ESP8266-compat
version=0.0.2
author=Jörg Schüler-Maroldt
maintainer=Jörg Schüler-Maroldt <schueler-maoldt@arcor.de>
sentence=Allows Tasmota to compile for esp32
paragraph=Allows Tasmota to compile for esp32
category=ESP32
url=
architectures=*

View File

@ -0,0 +1,233 @@
/*
AddrList.h - cycle through lwIP netif's ip addresses like a c++ list
Copyright (c) 2018 david gauchard. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
This class allows to explore all configured IP addresses
in lwIP netifs, with that kind of c++ loop:
for (auto a: addrList)
out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n",
a.iface().c_str(),
a.ifnumber(),
a.addr().isLegacy(),
a.addr().isV4(),
a.addr().isLocal(),
a.hostname().c_str(),
a.addr().toString().c_str());
This loop:
while (WiFi.status() != WL_CONNECTED()) {
Serial.print('.');
delay(500);
}
can be replaced by:
for (bool configured = false; !configured; ) {
for (auto iface: addrList)
if ((configured = !iface.addr().isLocal())
break;
Serial.print('.');
delay(500);
}
waiting for an IPv6 global address:
for (bool configured = false; !configured; ) {
for (auto iface: addrList)
if ((configured = ( !iface.addr().isV4()
&& !iface.addr().isLocal())))
break;
Serial.print('.');
delay(500);
}
waiting for an IPv6 global address, on a specific interface:
for (bool configured = false; !configured; ) {
for (auto iface: addrList)
if ((configured = ( !iface.addr().isV4()
&& !iface.addr().isLocal()
&& iface.ifnumber() == STATION_IF)))
break;
Serial.print('.');
delay(500);
}
*/
#ifndef __ADDRLIST_H
#define __ADDRLIST_H
#include <IPAddress.h>
#include <lwip/netif.h>
#if LWIP_IPV6
#define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES)
#else
#define IF_NUM_ADDRESSES (1)
#endif
namespace esp8266
{
namespace AddressListImplementation
{
struct netifWrapper
{
netifWrapper (netif* netif) : _netif(netif), _num(-1) {}
netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {}
netifWrapper& operator= (const netifWrapper& o)
{
_netif = o._netif;
_num = o._num;
return *this;
}
bool equal(const netifWrapper& o)
{
return _netif == o._netif && (!_netif || _num == o._num);
}
// address properties
class IPAddress4 : public IPAddress
{
public:
bool isV6() const
{
return false;
}
bool isLocal() const
{
return false;
}
};
IPAddress4 addr () const { return ipFromNetifNum(); }
bool isLegacy () const { return _num == 0; }
//bool isLocal () const { return addr().isLocal(); }
bool isV4 () const { return addr().isV4(); }
bool isV6 () const { return !addr().isV4(); }
String toString() const { return addr().toString(); }
// related to legacy address (_num=0, ipv4)
IPAddress ipv4 () const { return _netif->ip_addr; }
IPAddress netmask () const { return _netif->netmask; }
IPAddress gw () const { return _netif->gw; }
// common to all addresses of this interface
String ifname () const { return String(_netif->name[0]) + _netif->name[1]; }
const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); }
const char* ifmac () const { return (const char*)_netif->hwaddr; }
int ifnumber () const { return _netif->num; }
bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); }
const netif* interface () const { return _netif; }
const ip_addr_t* ipFromNetifNum () const
{
#if LWIP_IPV6
return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr;
#else
return &_netif->ip_addr;
#endif
}
// lwIP interface
netif* _netif;
// address index within interface
// 0: legacy address (IPv4)
// n>0: (_num-1) is IPv6 index for netif->ip6_addr[]
int _num;
};
class AddressListIterator
{
public:
AddressListIterator (const netifWrapper& o) : netIf(o) {}
AddressListIterator (netif* netif) : netIf(netif)
{
// This constructor is called with lwIP's global netif_list, or
// nullptr. operator++() is designed to loop through _configured_
// addresses. That's why netIf's _num is initialized to -1 to allow
// returning the first usable address to AddressList::begin().
(void)operator++();
}
const netifWrapper& operator* () const { return netIf; }
const netifWrapper* operator-> () const { return &netIf; }
bool operator== (AddressListIterator& o) { return netIf.equal(*o); }
bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); }
AddressListIterator operator++ (int)
{
AddressListIterator ret = *this;
(void)operator++();
return ret;
}
AddressListIterator& operator++ ()
{
while (netIf._netif)
{
if (++netIf._num == IF_NUM_ADDRESSES)
{
// all addresses from current interface were iterated,
// switching to next interface
netIf = netifWrapper(netIf._netif->next);
continue;
}
if (!ip_addr_isany(netIf.ipFromNetifNum()))
// found an initialized address
break;
}
return *this;
}
netifWrapper netIf;
};
class AddressList
{
public:
using const_iterator = const AddressListIterator;
const_iterator begin () const { return const_iterator(netif_list); }
const_iterator end () const { return const_iterator(nullptr); }
};
inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); }
inline AddressList::const_iterator end (const AddressList& a) { return a.end(); }
} // AddressListImplementation
} // esp8266
extern AddressList addrList;
#endif

View File

@ -0,0 +1,93 @@
/*
WiFi compat with ESP32
Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt
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/>.
*/
//
#include "Arduino.h"
#include <ESP8266WiFi.h>
//
// Wifi
//
#ifdef WiFi
#undef WiFi
#endif
void WiFiClass32::setSleepMode(int iSleepMode)
{
// WIFI_MODEM_SLEEP
WiFi.setSleep(iSleepMode != WIFI_MODEM_SLEEP);
}
int WiFiClass32::getPhyMode()
{
return 0; // " BGN"
}
void WiFiClass32::wps_disable()
{
}
void WiFiClass32::setOutputPower(int n)
{
wifi_power_t p = WIFI_POWER_2dBm;
if (n > 19)
p = WIFI_POWER_19_5dBm;
else if (n > 18)
p = WIFI_POWER_18_5dBm;
else if (n >= 17)
p = WIFI_POWER_17dBm;
else if (n >= 15)
p = WIFI_POWER_15dBm;
else if (n >= 13)
p = WIFI_POWER_13dBm;
else if (n >= 11)
p = WIFI_POWER_11dBm;
else if (n >= 8)
p = WIFI_POWER_8_5dBm;
else if (n >= 7)
p = WIFI_POWER_7dBm;
else if (n >= 5)
p = WIFI_POWER_5dBm;
WiFi.setTxPower(p);
}
void WiFiClass32::forceSleepBegin()
{
}
void WiFiClass32::forceSleepWake()
{
}
bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan)
{
hidden_scan = false;
return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel);
}
void wifi_station_disconnect()
{
// erase ap: empty ssid, ...
WiFi.disconnect(true, true);
}
void wifi_station_dhcpc_start()
{
}
WiFiClass32 WiFi32;

View File

@ -0,0 +1,5 @@
//
// Compat with ESP32
//
#include <HTTPClient.h>

View File

@ -0,0 +1,19 @@
//
// Compat with ESP32
//
#pragma once
#include <WebServer.h>
//#define ESP8266WebServer WebServer
class ESP8266WebServer : public WebServer
{
public:
ESP8266WebServer(int port)
:WebServer(port)
{
}
};
//#define ENC_TYPE_AUTO 0

View File

@ -0,0 +1,85 @@
/*
WiFi compat with ESP32
Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt
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/>.
*/
#pragma once
#include <WiFi.h>
// sorry, no <AddrList.h>
#undef LWIP_IPV6
#define ENC_TYPE_NONE WIFI_AUTH_OPEN
#define ENC_TYPE_WEP WIFI_AUTH_WEP
#define ENC_TYPE_CCMP WIFI_AUTH_WPA2_PSK
#define ENC_TYPE_TKIP WIFI_AUTH_WPA_WPA2_PSK
#define ENC_TYPE_AUTO WIFI_AUTH_MAX + 1
#define WIFI_LIGHT_SLEEP 1
#define WIFI_MODEM_SLEEP 2
class WiFiClass32 : public WiFiClass
{
public:
static void hostname(const char* aHostname)
{
WiFi.setHostname(aHostname);
}
static void setSleepMode(int iSleepMode);
static int getPhyMode();
static void wps_disable();
static void setOutputPower(int n);
static void forceSleepBegin();
static void forceSleepWake();
static bool getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan);
};
void wifi_station_disconnect();
void wifi_station_dhcpc_start();
extern WiFiClass32 WiFi32;
#define WiFi WiFi32
class WiFiUDP32 : public WiFiUDP
{
public:
size_t write(const char*s)
{
return WiFiUDP::write((const uint8_t *)s, strlen(s));
}
size_t write(const uint8_t *buf, size_t n)
{
return WiFiUDP::write(buf, n);
}
static void stopAll()
{
}
static void forceSleepWake()
{
}
uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port)
{
return WiFiUDP::beginMulticast(multicast, port);
}
void beginPacketMulticast(IPAddress multicast, uint16_t port, IPAddress interfaceAddr)
{
}
};
#define WiFiUDP WiFiUDP32

View File

@ -0,0 +1,10 @@
//
// Compat with ESP32
//
#include <httpUpdate.h>
#define ESPhttpUpdate httpUpdate
inline HTTPUpdateResult ESPhttpUpdate_update(const String& url, const String& currentVersion = "")
{
return HTTP_UPDATE_OK;
}

View File

@ -0,0 +1,4 @@
//
// Compat with ESP32
//
#include <mDNS.h>

View File

@ -0,0 +1,6 @@
#pragma once
/**/
#include <stdint.h>
#ifndef ICACHE_FLASH_ATTR
#define ICACHE_FLASH_ATTR
#endif

View File

@ -0,0 +1,3 @@
//
// Compat with ESP32
//

View File

@ -0,0 +1,73 @@
/*
This library 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 library 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/>.
*/
//
#include "Arduino.h"
#include "lwip/apps/sntp.h"
#include <nvs.h>
#include <rom/rtc.h>
#include <ESP8266WiFi.h>
#include "esp8266toEsp32.h"
// ESP Stuff
struct rst_info resetInfo;
String ESP_getResetReason(void)
{
// CPU 0
return String(rtc_get_reset_reason(0));
}
String ESP_getResetInfo(void)
{
return String(PSTR("0"));
}
String ESP_getBootVersion(void)
{
return String(PSTR("Unknown"));
}
bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size)
{
return false;
}
bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size)
{
return false;
}
void ESP_reset()
{
ESP.restart();
}
uint32_t ESP_getFlashChipId()
{
return 0;
}
String String_ESP_getChipId()
{
uint64_t mac = ESP.getEfuseMac();
return String(uint32_t(mac >> 32)) + String(uint32_t(mac));
}
/*
uint64_t ESP_getChipId()
{
return ESP.getEfuseMac();
}
*/

View File

@ -0,0 +1,115 @@
/*
This library 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 library 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/>.
*/
#pragma once
#ifdef ESP32
// my debug Stuff
#define Serial_Debug1(p) Serial.printf p
#define Serial_DebugX(p)
//
// basics
//
// dummy defines
#define SPIFFS_END (SPI_FLASH_SEC_SIZE * 200)
#define SETTINGS_LOCATION SPIFFS_END
#include <Esp.h>
//
// ESP32
//
#define ESP_flashReadHeader(offset, data, size) ESP32_flashRead(offset, data, size)
#define ESP_flashRead(offset, data, size) ESP32_flashRead(offset, data, size)
String ESP_getResetReason(void);
String ESP_getBootVersion(void);
bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size);
bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size);
void ESP_reset();
String ESP_getResetInfo(void);
uint32_t ESP_getFlashChipId();
String String_ESP_getChipId();
// Analog
inline void analogWrite(uint8_t pin, int val)
{
}
inline void analogWriteFreq(uint32_t freq)
{
}
inline void analogWriteRange(uint32_t range)
{
}
#define INPUT_PULLDOWN_16 INPUT_PULLUP
typedef double real64_t;
//
// Time and Timer
//
#define ETS_UART_INTR_DISABLE()
#define ETS_UART_INTR_ENABLE()
#define getChipId() getEfuseMac()
#define ESPhttpUpdate httpUpdate
#define getFlashChipRealSize() getFlashChipSize()
#define os_delay_us ets_delay_us
// Serial minimal type to hold the config
typedef int SerConfu8;
typedef int SerialConfig;
#define analogWrite(a, b)
//
// WS2812
//
#define NeoEsp8266BitBang800KbpsMethod NeoEsp32BitBang800KbpsMethod
//
// UDP
//
//#define PortUdp_writestr(log_data) PortUdp.write((const uint8_t *)(log_data), strlen(log_data))
#define PortUdp_write(log_data, n) PortUdp.write((const uint8_t *)(log_data), n)
//
#define wifi_forceSleepBegin()
#undef LWIP_IPV6
struct rst_info
{
int reason;
};
#define REASON_DEFAULT_RST 1
#define REASON_EXT_SYS_RST 2
#define REASON_DEEP_SLEEP_AWAKE 3
// memmove ...
#define memcpy_P memcpy
#define memmove_P memmove
#define strncpy_P strncpy
#define strcmp_P strcmp
#define memccpy_P memccpy
#define snprintf_P snprintf
#define sprintf_P sprintf
#define strncmp_P strncmp
// LWIP STuff
#define STATION_IF 0
#endif

View File

@ -0,0 +1,3 @@
#pragma once
#define timercallback void*
#define ets_printf(...)

View File

@ -0,0 +1,2 @@
#pragma once
#define GPIO_STATUS_W1TC_ADDRESS 0x24

View File

@ -0,0 +1,6 @@
#pragma once
#include "esp8266-compat.h"
#include <stdbool.h>
#include <stdint.h>
typedef uint16 uint16_t;
typedef double real64_t;

View File

@ -0,0 +1,8 @@
#pragma once
/**/
#include <lwip/ip_addr.h>
/*
#ifndef ICACHE_FLASH_ATTR
#define ICACHE_FLASH_ATTR
#endif
*/

View File

@ -0,0 +1,7 @@
#pragma once
#define sntp_get_current_timestamp() SntpGetCurrentTimestamp()
#define sntp_init() SntpInit()
#define sntp_set_timezone(tz)
#define sntp_setservername(idx, name)
#define sntp_stop()

View File

@ -0,0 +1,4 @@
//
// Compat with ESP32
//
// TODO: Port it to ESP32

View File

@ -0,0 +1,2 @@
#pragma once
/**/

View File

@ -0,0 +1,24 @@
/*
This library 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 library 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/>.
*/
#ifndef user_interface_h
#define user_interface_h
enum wps_cb_status {
WPS_CB_ST_SUCCESS = 0,
WPS_CB_ST_FAILED,
WPS_CB_ST_TIMEOUT,
WPS_CB_ST_WEP,
WPS_CB_ST_UNK,
};
#endif

View File

@ -0,0 +1,109 @@
;
; Example PlatformIO Project Configuration Override for ESP32 ***
; Changes done here override settings in platformio.ini ***
;
; to build Tasmota ESP32 copy to platformio_override.ini ***
;
; Please visit documentation for the options and examples
; http://docs.platformio.org/en/stable/projectconf.html
;
[platformio]
; *** Build/upload environment
;monitor_port = COM5
default_envs =
; *** Uncomment the line(s) below to select version(s)
tasmota
tasmota32
; tasmota32-minimal
; tasmota32-lite
; tasmota32-knx
; tasmota32-sensors
; tasmota32-display
; tasmota32-ir
; tasmota32-ircustom
; tasmota32-DE
; tasmota32-NL
[env32]
; uncomment this for all other tasmota32 builds
[env:tasmota32]
framework = ${common.framework}
platform = ${common32.platform}
platform_packages = ${common32.platform_packages}
board = ${common32.board}
board_build.ldscript = ${common32.board_build.ldscript}
board_build.flash_mode = ${common32.board_build.flash_mode}
board_build.f_cpu = ${common32.board_build.f_cpu}
build_unflags = ${common32.build_unflags}
build_flags = ${common32.build_flags}
monitor_speed = ${common32.monitor_speed}
upload_port = ${common32.upload_port}
upload_resetmethod = ${common32.upload_resetmethod}
upload_speed = ${common32.upload_speed}
extra_scripts = ${common32.extra_scripts}
lib_extra_dirs = ${common32.lib_extra_dirs}
lib_ignore = ${common32.lib_ignore}
; uncomment this for all other tasmota32 builds
;[env:tasmota32]
[env:tasmota32-minimal]
build_flags = ${common.build_flags} -DFIRMWARE_MINIMAL
[env:tasmota32-lite]
build_flags = ${common.build_flags} -DFIRMWARE_LITE
[env:tasmota32-knx]
build_flags = ${common.build_flags} -DFIRMWARE_KNX_NO_EMULATION
[env:tasmota32-sensors]
build_flags = ${common.build_flags} -DFIRMWARE_SENSORS
[env:tasmota32-display]
build_flags = ${common.build_flags} -DFIRMWARE_DISPLAYS
[env:tasmota32-ir]
build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags} -DFIRMWARE_IR
[env:tasmota32-ircustom]
build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags}
[env:tasmota32-DE]
build_flags = ${common.build_flags} -DMY_LANGUAGE=de-DE
[env:tasmota32-NL]
build_flags = ${common.build_flags} -DMY_LANGUAGE=nl-NL
[common32]
platform = espressif32@1.12.0
platform_packages =
board = wemos_d1_mini32
board_build.ldscript = esp32_out.ld
board_build.flash_mode = ${common.board_build.flash_mode}
board_build.f_cpu = ${common.board_build.f_cpu}
build_unflags = ${common.build_unflags}
monitor_speed = ${common.monitor_speed}
upload_port = ${common.upload_port}
upload_resetmethod = ${common.upload_resetmethod}
upload_speed = 921600
extra_scripts = ${common.extra_scripts}
build_flags =
-D BUFFER_LENGTH=128
-D MQTT_MAX_PACKET_SIZE=1000
-D uint32=uint32_t
-D uint16=uint16_t
-D uint8=uint8_t
-D sint8_t=int8_t
-D sint32_t=int32_t
-D sint16_t=int16_t
-D memcpy_P=memcpy
-D memcmp_P=memcmp
; -D USE_CONFIG_OVERRIDE
lib_extra_dirs =
libesp32
lib_ignore =
ESP MQTT
TasmotaMqtt
ILI9488
RA8876
SSD3115
cc1101
FrogmoreScd30
ArduinoNTPd

View File

@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef ESP8266
// Use PWM from core 2.4.0 as all versions below 2.5.0-beta3 produce LED flickering when settings are saved to flash
#include <core_version.h>
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
@ -109,3 +111,5 @@ void ICACHE_RAM_ATTR timer0_detachInterrupt(void) {
}
#endif // ARDUINO_ESP8266_RELEASE
#endif // ESP8266

View File

@ -37,6 +37,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef ESP8266
#include <core_version.h>
#if defined(ARDUINO_ESP8266_RELEASE_2_6_1) || defined(ARDUINO_ESP8266_RELEASE_2_6_2) || defined(ARDUINO_ESP8266_RELEASE_2_6_3) || !defined(ARDUINO_ESP8266_RELEASE)
#warning **** Tasmota is using a patched PWM Arduino version as planned ****
@ -341,4 +343,6 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
};
#endif // ARDUINO_ESP8266_RELEASE
#endif // ARDUINO_ESP8266_RELEASE
#endif // ESP8266

View File

@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef ESP8266
// Use PWM from core 2.4.0 as all versions below 2.5.0-beta3 produce LED flickering when settings are saved to flash
#include <core_version.h>
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
@ -217,3 +219,5 @@ extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attrib
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
#endif // ARDUINO_ESP8266_RELEASE
#endif // ESP8266

View File

@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef ESP8266
// Use PWM from core 2.4.0 as all versions below 2.5.0-beta3 produce LED flickering when settings are saved to flash
#include <core_version.h>
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
@ -232,3 +234,5 @@ extern void analogWriteFreq(uint32_t freq) __attribute__ ((weak, alias("__analog
extern void analogWriteRange(uint32_t range) __attribute__ ((weak, alias("__analogWriteRange")));
#endif // ARDUINO_ESP8266_RELEASE
#endif // ESP8266

View File

@ -221,7 +221,7 @@ typedef struct {
} EnergyUsage;
typedef struct {
typedef struct PACKED {
uint8_t fnid = 0;
uint8_t dpid = 0;
} TuyaFnidDpidMap;
@ -229,7 +229,7 @@ typedef struct {
const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017)
const uint8_t MAX_TUYA_FUNCTIONS = 16;
struct SYSCFG {
struct PACKED SYSCFG {
uint16_t cfg_holder; // 000 v6 header
uint16_t cfg_size; // 002
unsigned long save_flag; // 004

View File

@ -40,14 +40,14 @@ void RtcSettingsSave(void)
{
if (GetRtcSettingsCrc() != rtc_settings_crc) {
RtcSettings.valid = RTC_MEM_VALID;
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
ESP_rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
rtc_settings_crc = GetRtcSettingsCrc();
}
}
void RtcSettingsLoad(void)
{
ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290
ESP_rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290
if (RtcSettings.valid != RTC_MEM_VALID) {
memset(&RtcSettings, 0, sizeof(RTCMEM));
RtcSettings.valid = RTC_MEM_VALID;
@ -87,7 +87,7 @@ void RtcRebootSave(void)
{
if (GetRtcRebootCrc() != rtc_reboot_crc) {
RtcReboot.valid = RTC_MEM_VALID;
ESP.rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
ESP_rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
rtc_reboot_crc = GetRtcRebootCrc();
}
}
@ -100,7 +100,7 @@ void RtcRebootReset(void)
void RtcRebootLoad(void)
{
ESP.rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); // 0x280
ESP_rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); // 0x280
if (RtcReboot.valid != RTC_MEM_VALID) {
memset(&RtcReboot, 0, sizeof(RTCRBT));
RtcReboot.valid = RTC_MEM_VALID;
@ -141,6 +141,8 @@ extern "C" {
}
#include "eboot_command.h"
#ifdef ESP8266
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2)
extern "C" uint32_t _SPIFFS_end;
@ -168,6 +170,9 @@ const uint32_t SPIFFS_END = ((uint32_t)&_FS_end - 0x40200000) / SPI_FLASH_SEC_SI
// Version 4.2 config = eeprom area
const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses EEPROM area
#endif // ESP8266
// Version 5.2 allow for more flash space
const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads)
@ -181,6 +186,7 @@ uint8_t *settings_buffer = nullptr;
*/
void SetFlashModeDout(void)
{
#ifdef ESP8266
uint8_t *_buffer;
uint32_t address;
@ -198,10 +204,13 @@ void SetFlashModeDout(void)
}
}
delete[] _buffer;
#endif // ESP8266
}
bool VersionCompatible(void)
{
#ifdef ESP8266
if (Settings.flag3.compatibility_check) {
return true;
}
@ -244,6 +253,8 @@ bool VersionCompatible(void)
return false;
}
#endif // ESP8266
return true;
}
@ -478,6 +489,7 @@ void SettingsSave(uint8_t rotate)
Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade
Settings.cfg_crc32 = GetSettingsCrc32();
#ifdef ESP8266
if (ESP.flashEraseSector(settings_location)) {
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
}
@ -488,6 +500,9 @@ void SettingsSave(uint8_t rotate)
delay(1);
}
}
#else // ESP32
SettingsSaveMain(&Settings, sizeof(SYSCFG));
#endif // ESP8266
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG));
@ -512,8 +527,7 @@ void SettingsLoad(void)
uint16_t cfg_holder = 0;
for (uint32_t i = 0; i < CFG_ROTATES; i++) {
flash_location--;
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
ESP_flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
bool valid = false;
if (Settings.version > 0x06000000) {
bool almost_valid = (Settings.cfg_crc32 == GetSettingsCrc32());
@ -524,7 +538,7 @@ void SettingsLoad(void)
if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder
valid = (cfg_holder == Settings.cfg_holder);
} else {
ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
ESP_flashReadHeader((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
valid = (Settings.cfg_holder == _SettingsH.cfg_holder);
}
if (valid) {
@ -540,7 +554,7 @@ void SettingsLoad(void)
delay(1);
}
if (settings_location > 0) {
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
ESP_flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
}
@ -579,6 +593,7 @@ void EspErase(uint32_t start_sector, uint32_t end_sector)
void SettingsErase(uint8_t type)
{
#ifdef ESP8266
/*
For Arduino core and SDK:
Erase only works from flash start address to SDK recognized flash end address (flashchip->chip_size = ESP.getFlashChipSize).
@ -630,6 +645,7 @@ void SettingsErase(uint8_t type)
// EspErase(_sectorStart, _sectorEnd); // Arduino core and SDK - erases flash as seen by SDK
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
#endif // FIRMWARE_MINIMAL
#endif // ESP8266
}
void SettingsSdkErase(void)
@ -1028,6 +1044,8 @@ void SettingsEnableAllI2cDrivers(void)
void SettingsDelta(void)
{
if (Settings.version != VERSION) { // Fix version dependent changes
#ifdef ESP8266
if (Settings.version < 0x06000000) {
Settings.cfg_size = sizeof(SYSCFG);
Settings.cfg_crc = GetSettingsCrc();
@ -1315,6 +1333,7 @@ void SettingsDelta(void)
if (Settings.version < 0x08020003) {
SettingsUpdateText(SET_TEMPLATE_NAME, Settings.user_template_name);
}
#endif // ESP8266
Settings.version = VERSION;
SettingsSave(1);

View File

@ -109,7 +109,7 @@ String GetResetReason(void)
strncpy_P(buff, PSTR(D_JSON_BLOCKED_LOOP), sizeof(buff));
return String(buff);
} else {
return ESP.getResetReason();
return ESP_getResetReason();
}
}
@ -1660,7 +1660,7 @@ void Syslog(void)
memmove(log_data + strlen(syslog_preamble), log_data, sizeof(log_data) - strlen(syslog_preamble));
log_data[sizeof(log_data) -1] = '\0';
memcpy(log_data, syslog_preamble, strlen(syslog_preamble));
PortUdp.write(log_data, strlen(log_data));
PortUdp_write(log_data, strlen(log_data));
PortUdp.endPacket();
delay(1); // Add time for UDP handling (#5512)
} else {

View File

@ -119,6 +119,7 @@ void ButtonHandler(void)
uint8_t button = NOT_PRESSED;
uint8_t button_present = 0;
#ifdef ESP8266
if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type))) {
button_present = 1;
if (Button.dual_code) {
@ -131,7 +132,9 @@ void ButtonHandler(void)
Button.dual_code = 0;
}
}
else if (pin[GPIO_KEY1 +button_index] < 99) {
else
#endif // ESP8266
if (pin[GPIO_KEY1 +button_index] < 99) {
button_present = 1;
button = (digitalRead(pin[GPIO_KEY1 +button_index]) != bitRead(Button.inverted_mask, button_index));
}
@ -153,6 +156,7 @@ void ButtonHandler(void)
if (XdrvCall(FUNC_BUTTON_PRESSED)) {
// Serviced
}
#ifdef ESP8266
else if (SONOFF_4CHPRO == my_module_type) {
if (Button.hold_timer[button_index]) { Button.hold_timer[button_index]--; }
@ -172,6 +176,7 @@ void ButtonHandler(void)
}
}
}
#endif // ESP8266
else {
if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) {
if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action
@ -227,9 +232,12 @@ void ButtonHandler(void)
if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS +3)) {
bool single_press = false;
if (Button.press_counter[button_index] < 3) { // Single or Double press
#ifdef ESP8266
if ((SONOFF_DUAL_R2 == my_module_type) || (SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
single_press = true;
} else {
} else
#endif // ESP8266
{
single_press = (Settings.flag.button_swap +1 == Button.press_counter[button_index]); // SetOption11 (0)
if ((1 == Button.present) && (2 == devices_present)) { // Single Button with two devices only
if (Settings.flag.button_swap) { // SetOption11 (0)

View File

@ -426,7 +426,7 @@ void CmndStatus(void)
"\"Hardware\":\"%s\""
"%s}}"),
my_version, my_image, GetBuildDateAndTime().c_str(),
ESP.getBootVersion(), ESP.getSdkVersion(),
ESP_getBootVersion(), ESP.getSdkVersion(),
GetDeviceHardware().c_str(),
GetStatistics().c_str());
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2"));
@ -448,7 +448,7 @@ void CmndStatus(void)
D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d,\"" D_JSON_FLASHCHIPID "\":\"%06X\",\"" D_JSON_FLASHMODE "\":%d,\""
D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"),
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024,
ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipId(), ESP.getFlashChipMode(),
ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP_getFlashChipId(), ESP.getFlashChipMode(),
LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6);
XsnsDriverState();
ResponseAppend_P(PSTR(",\"Sensors\":"));
@ -580,10 +580,10 @@ void CmndSleep(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) {
Settings.sleep = XdrvMailbox.payload;
sleep = XdrvMailbox.payload;
ssleep = XdrvMailbox.payload;
WiFiSetSleepMode();
}
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, sleep);
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, ssleep);
}
@ -646,7 +646,10 @@ void CmndRestart(void)
void CmndPowerOnState(void)
{
if (my_module_type != MOTOR) {
#ifdef ESP8266
if (my_module_type != MOTOR)
#endif // ESP8266
{
/* 0 = Keep relays off after power on
* 1 = Turn relays on after power on, if PulseTime set wait for PulseTime seconds, and turn relays off
* 2 = Toggle relays after power on

View File

@ -17,6 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ESP8266
const uint32_t crash_magic = 0x53415400; // Stack trace magic number (TASx)
const uint32_t crash_rtc_offset = 32; // Offset in RTC memory skipping OTA used block
const uint32_t crash_dump_max_len = 31; // Dump only 31 call addresses to satisfy max JSON length of about 600 characters
@ -109,3 +111,5 @@ void CrashDump(void)
ResponseJsonEnd();
}
#endif // ESP8266

View File

@ -20,6 +20,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_DEVICE_GROUPS
//#define DEVICE_GROUPS_DEBUG
@ -163,7 +164,7 @@ void SendDeviceGroupPacket(IPAddress ip, char * packet, int len, const char * la
if (!ip) ip = IPAddress(239,255,255,250);
for (int attempt = 1; attempt <= 5; attempt++) {
if (PortUdp.beginPacket(ip, 1900)) {
PortUdp.write(packet, len);
PortUdp_write(packet, len);
if (PortUdp.endPacket()) return;
}
delay(10);
@ -552,7 +553,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
#ifdef DEVICE_GROUPS_DEBUG
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8);
#endif // DEVICE_GROUPS_DEBUG
SendDeviceGroupPacket(0, device_group->message, device_group->message_length, PSTR("Multicast"));
SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Multicast"));
uint32_t now = millis();
if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) {
@ -857,7 +858,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
#ifdef DEVICE_GROUPS_DEBUG
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending initial status request for group %s"), device_group->group_name);
#endif // DEVICE_GROUPS_DEBUG
SendDeviceGroupPacket(0, device_group->message, device_group->message_length, PSTR("Initial"));
SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Initial"));
device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now
device_group->next_ack_check_time = now + 200;
}
@ -941,7 +942,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
#ifdef DEVICE_GROUPS_DEBUG
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending device group %s announcement"), device_group->group_name);
#endif // DEVICE_GROUPS_DEBUG
SendDeviceGroupPacket(0, device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement"));
SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement"));
device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL + random(10000);
}
if (device_group->next_announcement_time < next_check_time) next_check_time = device_group->next_announcement_time;

177
tasmota/support_esp32.ino Normal file
View File

@ -0,0 +1,177 @@
/*
support_esp32.ino - ESP32 specific code for Tasmota
Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt
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/>.
*/
#ifdef ESP32
#include <nvs.h>
#include <rom/rtc.h>
void SettingsErase(uint8_t type)
{
if (1 == type) // SDK parameter area
{
}
else if (2 == type) // Tasmota parameter area (0x0F3xxx - 0x0FBFFF)
{
}
else if (3 == type) // Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
{
}
noInterrupts();
nvs_handle handle;
nvs_open("main", NVS_READWRITE, &handle);
nvs_erase_all(handle);
nvs_commit(handle);
nvs_close(handle);
interrupts();
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " t=%d"), type);
}
void SettingsLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen)
{
noInterrupts();
nvs_handle handle;
size_t size;
nvs_open(sNvsName, NVS_READONLY, &handle);
size = nSettingsLen;
nvs_get_blob(handle, sName, pSettings, &size);
nvs_close(handle);
interrupts();
}
void SettingsSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen)
{
nvs_handle handle;
noInterrupts();
nvs_open(sNvsName, NVS_READWRITE, &handle);
nvs_set_blob(handle, sName, pSettings, nSettingsLen);
nvs_commit(handle);
nvs_close(handle);
interrupts();
}
void ESP32_flashRead(uint32_t offset, uint32_t *data, size_t size)
{
SettingsLoad("main", "Settings", data, size);
}
void ESP32_flashReadHeader(uint32_t offset, uint32_t *data, size_t size)
{
SettingsLoad("main", "SettingsH", data, size);
}
void SettingsSaveMain(const void *pSettings, unsigned nSettingsLen)
{
SettingsSave("main", "Settings", pSettings, nSettingsLen);
}
/*
void SettingsLoadMain(void *pSettings, unsigned nSettingsLen)
{
SettingsLoad("main", "Settings", pSettings, nSettingsLen);
}
void SettingsLoadMainH(void *pSettingsH, unsigned nSettingsLenH)
{
SettingsLoad("main", "SettingsH", pSettingsH, nSettingsLenH);
}
*/
void SettingsLoadUpg(void *pSettings, unsigned nSettingsLen)
{
SettingsLoad("upg", "Settings", pSettings, nSettingsLen);
}
void SettingsLoadUpgH(void *pSettings, unsigned nSettingsLen)
{
SettingsLoad("upg", "SettingsH", pSettings, nSettingsLen);
}
//
// sntp emulation
//
static bool bNetIsTimeSync = false;
//
void SntpInit()
{
bNetIsTimeSync = true;
}
uint32_t SntpGetCurrentTimestamp(void)
{
time_t now = 0;
if (bNetIsTimeSync || ntp_force_sync)
{
//Serial_DebugX(("timesync configTime %d\n", ntp_force_sync, bNetIsTimeSync));
// init to UTC Time
configTime(0, 0, SettingsText(SET_NTPSERVER1), SettingsText(SET_NTPSERVER2), SettingsText(SET_NTPSERVER3));
bNetIsTimeSync = false;
ntp_force_sync = false;
}
time(&now);
return now;
}
//
// Crash stuff
//
void CrashDump(void)
{
}
bool CrashFlag(void)
{
return false;
}
void CrashDumpClear(void)
{
}
void CmndCrash(void)
{
/*
volatile uint32_t dummy;
dummy = *((uint32_t*) 0x00000000);
*/
}
// Do an infinite loop to trigger WDT watchdog
void CmndWDT(void)
{
/*
volatile uint32_t dummy = 0;
while (1) {
dummy++;
}
*/
}
// This will trigger the os watch after OSWATCH_RESET_TIME (=120) seconds
void CmndBlockedLoop(void)
{
/*
while (1) {
delay(1000);
}
*/
}
#endif // ESP32

View File

@ -17,7 +17,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ESP8266
#define USE_ESPTOOL
#endif // ESP8266
#ifdef USE_ESPTOOL
/*********************************************************************************************\
* EspTool Erase function based on Version 2.8

View File

@ -210,6 +210,7 @@ void SetDevicePower(power_t rpower, uint32_t source)
if (XdrvCall(FUNC_SET_DEVICE_POWER)) { // Set power state and stop if serviced
// Serviced
}
#ifdef ESP8266
else if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
Serial.write(0xA0);
Serial.write(0x04);
@ -221,7 +222,9 @@ void SetDevicePower(power_t rpower, uint32_t source)
else if (EXS_RELAY == my_module_type) {
SetLatchingRelay(rpower, 1);
}
else {
else
#endif // ESP8266
{
for (uint32_t i = 0; i < devices_present; i++) {
power_t state = rpower &1;
if (i < MAX_RELAYS) {
@ -279,9 +282,11 @@ void SetAllPower(uint32_t state, uint32_t source)
void SetPowerOnState(void)
{
#ifdef ESP8266
if (MOTOR == my_module_type) {
Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo!
}
#endif // ESP8266
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
SetDevicePower(1, SRC_RESTART);
} else {
@ -625,7 +630,7 @@ void MqttShowState(void)
ResponseAppend_P(PSTR(",\"" D_JSON_HEAPSIZE "\":%d,\"SleepMode\":\"%s\",\"Sleep\":%u,\"LoadAvg\":%u,\"MqttCount\":%u"),
ESP.getFreeHeap()/1024, GetTextIndexed(stemp1, sizeof(stemp1), Settings.flag3.sleep_normal, kSleepMode), // SetOption60 - Enable normal sleep instead of dynamic sleep
sleep, loop_load_avg, MqttConnectCount());
ssleep, loop_load_avg, MqttConnectCount());
for (uint32_t i = 1; i <= devices_present; i++) {
#ifdef USE_LIGHT
@ -903,9 +908,11 @@ void Every250mSeconds(void)
}
if (Settings.ledstate &1 && (pin[GPIO_LEDLNK] < 99 || !(blinks || restart_flag || ota_state_flag)) ) {
bool tstate = power & Settings.ledmask;
#ifdef ESP8266
if ((SONOFF_TOUCH == my_module_type) || (SONOFF_T11 == my_module_type) || (SONOFF_T12 == my_module_type) || (SONOFF_T13 == my_module_type)) {
tstate = (!power) ? 1 : 0; // As requested invert signal for Touch devices to find them in the dark
}
#endif // ESP8266
SetLedPower(tstate);
}
@ -1213,13 +1220,14 @@ void SerialInput(void)
delay(0);
serial_in_byte = Serial.read();
#ifdef ESP8266
/*-------------------------------------------------------------------------------------------*\
* Sonoff dual and ch4 19200 baud serial interface
\*-------------------------------------------------------------------------------------------*/
if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
serial_in_byte = ButtonSerial(serial_in_byte);
}
#endif // ESP8266
/*-------------------------------------------------------------------------------------------*/
if (XdrvCall(FUNC_SERIAL)) {
@ -1320,7 +1328,15 @@ void GpioInit(void)
if (!ValidModule(Settings.module)) {
uint32_t module = MODULE;
if (!ValidModule(MODULE)) { module = SONOFF_BASIC; }
if (!ValidModule(MODULE)) {
#ifdef ESP8266
module = SONOFF_BASIC;
#endif // ESP8266
#ifdef ESP32
module = WEMOS;
#endif // ESP32
}
Settings.module = module;
Settings.last_module = module;
}
@ -1417,7 +1433,9 @@ void GpioInit(void)
if (mpin) pin[mpin] = i;
}
#ifdef ESP8266
if ((2 == pin[GPIO_TXD]) || (H801 == my_module_type)) { Serial.set_tx(2); }
#endif // ESP8266
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
@ -1462,6 +1480,7 @@ void GpioInit(void)
if (XdrvCall(FUNC_MODULE_INIT)) {
// Serviced
}
#ifdef ESP8266
else if (YTF_IR_BRIDGE == my_module_type) {
ClaimSerial(); // Stop serial loopback mode
// devices_present = 1;
@ -1479,6 +1498,7 @@ void GpioInit(void)
SetSerial(19200, TS_SERIAL_8N1);
}
#endif // USE_SONOFF_SC
#endif // ESP8266
for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only
if (pin[GPIO_PWM1 +i] < 99) {
@ -1497,10 +1517,12 @@ void GpioInit(void)
if (pin[GPIO_REL1 +i] < 99) {
pinMode(pin[GPIO_REL1 +i], OUTPUT);
devices_present++;
#ifdef ESP8266
if (EXS_RELAY == my_module_type) {
digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? 1 : 0);
if (i &1) { devices_present--; }
}
#endif // ESP8266
}
}

View File

@ -156,10 +156,10 @@ void WiFiSetSleepMode(void)
// Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255
#if defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
#else // Enabled in 2.3.0, 2.4.0 and stage
if (sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
if (ssleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
} else {
WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default)
WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default)
}
#endif
WifiSetOutputPower();
@ -709,7 +709,7 @@ void EspRestart(void)
WifiShutdown(true);
CrashDumpClear(); // Clear the stack dump in RTC
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
ESP.reset();
ESP_reset();
}
#ifndef ARDUINO_ESP8266_RELEASE_2_3_0

View File

@ -41,8 +41,14 @@
* Power Type
\*********************************************************************************************/
#ifdef ESP8266
typedef unsigned long power_t; // Power (Relay) type
const uint32_t POWER_MASK = 0xffffffffUL; // Power (Relay) full mask
#endif // ESP8266
#ifdef ESP32
typedef uint64_t power_t; // Power (Relay) type
const uint64_t POWER_MASK = 0xffffffffffffffffull; // Power (Relay) full mask
#endif // ESP32
/*********************************************************************************************\
* Constants
@ -331,7 +337,7 @@ enum TasmotaSerialConfig {
TS_SERIAL_5O1, TS_SERIAL_6O1, TS_SERIAL_7O1, TS_SERIAL_8O1,
TS_SERIAL_5O2, TS_SERIAL_6O2, TS_SERIAL_7O2, TS_SERIAL_8O2 };
const uint8_t kTasmotaSerialConfig[] PROGMEM = {
const SerConfu8 kTasmotaSerialConfig[] PROGMEM = {
SERIAL_5N1, SERIAL_6N1, SERIAL_7N1, SERIAL_8N1,
SERIAL_5N2, SERIAL_6N2, SERIAL_7N2, SERIAL_8N2,
SERIAL_5E1, SERIAL_6E1, SERIAL_7E1, SERIAL_8E1,

View File

@ -32,6 +32,7 @@
// Location specific includes
#include <core_version.h> // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
#include "tasmota_compat.h"
#include "tasmota_version.h" // Tasmota version information
#include "tasmota.h" // Enumeration used in my_user_config.h
#include "my_user_config.h" // Fixed user configurable options
@ -123,7 +124,7 @@ uint8_t mqtt_cmnd_blocked = 0; // Ignore flag for publish command
uint8_t mqtt_cmnd_blocked_reset = 0; // Count down to reset if needed
uint8_t state_250mS = 0; // State 250msecond per second flag
uint8_t latching_relay_pulse = 0; // Latching relay pulse timer
uint8_t sleep; // Current copy of Settings.sleep
uint8_t ssleep; // Current copy of Settings.sleep
uint8_t blinkspeed = 1; // LED blink rate
uint8_t pin[GPIO_MAX]; // Possible pin configurations
uint8_t active_device = 1; // Active device in ExecuteCommandPower
@ -226,7 +227,7 @@ void setup(void)
syslog_level = Settings.syslog_level;
stop_flash_rotate = Settings.flag.stop_flash_rotate; // SetOption12 - Switch between dynamic or fixed slot flash save location
save_data_counter = Settings.save_data;
sleep = Settings.sleep;
ssleep = Settings.sleep;
#ifndef USE_EMULATION
Settings.flag2.emulation = 0;
#else
@ -259,8 +260,13 @@ void setup(void)
Settings.my_adc0 = ADC0_NONE; // Reset user defined ADC0 disabling sensors
}
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times
#ifdef ESP8266
Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic
// Settings.last_module = SONOFF_BASIC;
#endif // ESP8266
#ifdef ESP32
Settings.module = WEMOS; // Reset module to Wemos
#endif // ESP32
}
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count);
}
@ -374,10 +380,10 @@ void loop(void)
if (Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
// yield(); // yield == delay(0), delay contains yield, auto yield in loop
delay(sleep); // https://github.com/esp8266/Arduino/issues/2021
delay(ssleep); // https://github.com/esp8266/Arduino/issues/2021
} else {
if (my_activity < (uint32_t)sleep) {
delay((uint32_t)sleep - my_activity); // Provide time for background tasks like wifi
if (my_activity < (uint32_t)ssleep) {
delay((uint32_t)ssleep - my_activity); // Provide time for background tasks like wifi
} else {
if (global_state.wifi_down) {
delay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period
@ -386,7 +392,7 @@ void loop(void)
}
if (!my_activity) { my_activity++; } // We cannot divide by 0
uint32_t loop_delay = sleep;
uint32_t loop_delay = ssleep;
if (!loop_delay) { loop_delay++; } // We cannot divide by 0
uint32_t loops_per_second = 1000 / loop_delay; // We need to keep track of this many loops per second
uint32_t this_cycle_ratio = 100 * my_activity / loop_delay;

31
tasmota/tasmota_compat.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#ifdef ESP32
#include <esp8266toEsp32.h>
#define PACKED __attribute((__packed__))
// Modul
#undef MODULE
#define MODULE WEMOS // [Module] Select default model
#endif
#ifdef ESP8266
// ESP8266
#define PACKED
#define ESP_rtcUserMemoryWrite(offset, data, size) ESP.rtcUserMemoryWrite(offset, data, size)
#define ESP_rtcUserMemoryRead(offset, data, size) ESP.rtcUserMemoryRead(offset, data, size)
#define ESP_getResetReason() ESP.getResetReason()
#define ESP_reset() ESP.reset()
#define ESP_getBootVersion() ESP.getBootVersion()
#define ESP_getFlashChipId() ESP.getFlashChipId()
//
// we need different ESP_flashRead for ESP32
//
#define ESP_flashReadHeader(offset, data, size) ESP.flashRead(offset, data, size)
#define ESP_flashRead(offset, data, size) ESP.flashRead(offset, data, size)
//
// UDP
#define PortUdp_write(p,n) PortUdp.write(p, n)
//
// Serial minimal type to hold the config
#define SerConfu8 uint8_t
#endif // ESP32

View File

@ -692,11 +692,26 @@ const char kAdc0Names[] PROGMEM =
/********************************************************************************************/
#ifdef ESP8266
#define MAX_GPIO_PIN 17 // Number of supported GPIO
#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11)
const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0";
#else // ESP32
// esp32 has more pins
#define USER_MODULE 255
#define MAX_GPIO_PIN 44 // Number of supported GPIO
#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11)
const char PINS_WEMOS[] PROGMEM = "00010203040506070809101112131415161718192021222324252627282930313233343536373839";
#endif // ESP8266
/********************************************************************************************/
typedef struct MYIO {
uint8_t io[MAX_GPIO_PIN];
} myio;
@ -730,6 +745,8 @@ typedef struct MYTMPLT {
/********************************************************************************************/
#ifdef ESP8266
// Supported hardware modules
enum SupportedModules {
SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH,
@ -2221,4 +2238,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
}
};
#endif // ESP8266
#ifdef ESP32
#include "tasmota_template_ESP32.h"
#endif // ESP32
#endif // _TASMOTA_TEMPLATE_H_

View File

@ -0,0 +1,155 @@
/*
tasmota_template_ESP32.h - template settings for Tasmota
Copyright (C) 2020 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/>.
*/
#ifndef _TASMOTA_TEMPLATE_ESP32_H_
#define _TASMOTA_TEMPLATE_ESP32_H_
#ifdef ESP32
// mqtt
#undef MQTT_LIBRARY_TYPE
#define MQTT_LIBRARY_TYPE MQTT_PUBSUBCLIENT
// Hardware has no ESP32
#undef USE_TUYA_DIMMER
#undef USE_PWM_DIMMER
#undef USE_EXS_DIMMER
#undef USE_ARMTRONIX_DIMMERS
#undef USE_SONOFF_RF
#undef USE_SONOFF_SC
#undef USE_SONOFF_IFAN
#undef USE_SONOFF_L1
#undef USE_SONOFF_D1
#undef USE_RF_FLASH
// not ported
#undef USE_DISCOVERY
#undef USE_ADC_VCC // Needs to be ported
#undef USE_DEEPSLEEP
#undef USE_MY92X1
#undef USE_TUYA_MCU
#undef USE_I2C
#undef USE_PS_16_DZ
/********************************************************************************************/
// Supported hardware modules
enum SupportedModules {
WEMOS,
ESP32_CAM,
MAXMODULE
};
const char kModuleNames[] PROGMEM =
"WeMos D1 ESP32|ESP32 CAM|"
;
// Default module settings
const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
WEMOS,
ESP32_CAM
};
const mytmplt kModules[MAXMODULE] PROGMEM = {
{ // "WeMos D1 ESP32", // Any ESP32 device like WeMos and NodeMCU hardware (ESP32)
GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
0, //6
0, //7
0, //8
0, //9
0, //10
0, //11
GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
0, //20
0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
0, //24
GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
0, //28
0, //29
0, //30
0, //31
GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
0, //37 NO PULLUP
0, //38 NO PULLUP
GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
},
{ //"ESP32 CAM",
GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
0, //6
0, //7
0, //8
0, //9
0, //10
0, //11
GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
0, //20
0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
0, //24
GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
0, //28
0, //29
0, //30
0, //31
GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
0, //37 NO PULLUP
0, //38 NO PULLUP
GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
}
};
#endif // ESP32
#endif // _TASMOTA_TEMPLATE_ESP32_H_

View File

@ -48,7 +48,7 @@ enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE };
static const char * HEADER_KEYS[] = { "User-Agent", };
const char HTTP_HEADER[] PROGMEM =
const char HTTP_HEADER1[] PROGMEM =
"<!DOCTYPE html><html lang=\"" D_HTML_LANGUAGE "\" class=\"\">"
"<head>"
"<meta charset='utf-8'>"
@ -848,7 +848,7 @@ void WSContentStart_P(const char* title, bool auth)
if (title != nullptr) {
char ctitle[strlen_P(title) +1];
strcpy_P(ctitle, title); // Get title from flash to RAM
WSContentSend_P(HTTP_HEADER, SettingsText(SET_FRIENDLYNAME1), ctitle);
WSContentSend_P(HTTP_HEADER1, SettingsText(SET_FRIENDLYNAME1), ctitle);
}
}
@ -2175,7 +2175,7 @@ void HandleInformation(void)
WSContentSend_P(PSTR("}1}2&nbsp;")); // Empty line
WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP.getChipId());
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP.getFlashChipId());
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP_getFlashChipId());
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP.getFlashChipRealSize() / 1024);
WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%dkB"), ESP.getFlashChipSize() / 1024);
WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP.getSketchSize() / 1024);

View File

@ -1216,6 +1216,7 @@ bool LightModuleInit(void)
if (XlgtCall(FUNC_MODULE_INIT)) {
// serviced
}
#ifdef ESP8266
else if (SONOFF_BN == my_module_type) { // PWM Single color led (White)
light_type = LT_PWM1;
}
@ -1234,6 +1235,7 @@ bool LightModuleInit(void)
}
light_type = LT_PWM2;
}
#endif // ESP8266
if (light_type > LT_BASIC) {
devices_present++;
@ -1701,12 +1703,12 @@ void LightAnimate(void)
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
if (Light.power || Light.fade_running) {
if (Settings.sleep > PWM_MAX_SLEEP) {
sleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth
ssleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth
} else {
sleep = Settings.sleep; // or keep the current sleep if it's lower than 50
ssleep = Settings.sleep; // or keep the current sleep if it's lower than 50
}
} else {
sleep = Settings.sleep;
ssleep = Settings.sleep;
}
if (!Light.power) { // All channels powered off
@ -1891,11 +1893,12 @@ void LightAnimate(void)
bool isChannelGammaCorrected(uint32_t channel) {
if (!Settings.light_correction) { return false; } // Gamma correction not activated
if (channel >= Light.subtype) { return false; } // Out of range
#ifdef ESP8266
if (PHILIPS == my_module_type) {
if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return false; } // PMW reserved for CT
if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return false; } // PMW reserved for CT
}
#endif // ESP8266
return true;
}
@ -2070,6 +2073,7 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) {
uint16_t white_bri10 = cur_col_10[cw0] + cur_col_10[cw1]; // cumulated brightness
uint16_t white_bri10_1023 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023
#ifdef ESP8266
if (PHILIPS == my_module_type) { // channel 1 is the color tone, mapped to cold channel (0..255)
// Xiaomi Philips bulbs follow a different scheme:
cur_col_10[cw1] = light_state.getCT10bits();
@ -2079,7 +2083,9 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) {
} else {
cur_col_10[cw0] = white_bri10_1023; // no gamma, extend to 10 bits
}
} else if (Settings.light_correction) {
} else
#endif // ESP8266
if (Settings.light_correction) {
// if sum of both channels is > 255, then channels are probably uncorrelated
if (white_bri10 <= 1031) { // take a margin of 8 above 1023 to account for rounding errors
// we calculate the gamma corrected sum of CW + WW
@ -2631,7 +2637,9 @@ void CmndDimmerRange(void)
Settings.dimmer_hw_min = parm[1];
Settings.dimmer_hw_max = parm[0];
}
#ifdef ESP8266
if (PWM_DIMMER != my_module_type) restart_flag = 2;
#endif // ESP8266
}
Response_P(PSTR("{\"" D_CMND_DIMMER_RANGE "\":{\"Min\":%d,\"Max\":%d}}"), Settings.dimmer_hw_min, Settings.dimmer_hw_max);
}

View File

@ -565,6 +565,7 @@ bool Xdrv06(uint8_t function)
{
bool result = false;
#ifdef ESP8266
if (SONOFF_BRIDGE == my_module_type) {
switch (function) {
case FUNC_SERIAL:
@ -582,6 +583,7 @@ bool Xdrv06(uint8_t function)
break;
}
}
#endif // ESP8266
return result;
}

View File

@ -213,7 +213,11 @@ void HAssAnnounceRelayLight(void)
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId());
#ifdef USE_LIGHT
if (is_light || PWM_DIMMER == my_module_type)
if (is_light
#ifdef ESP8266
|| PWM_DIMMER == my_module_type
#endif
)
{
char *brightness_command_topic = stemp1;
@ -423,10 +427,13 @@ void HAssAnnounceButtons(void)
uint8_t toggle = 1;
uint8_t hold = 0;
#ifdef ESP8266
if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)))
{
button_present = 1;
} else {
} else
#endif
{
if (pin[GPIO_KEY1 + button_index] < 99) {
button_present = 1;
}
@ -481,8 +488,8 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
char subname[20];
mqtt_data[0] = '\0'; // Clear retained message
// Clear or Set topic
// Clear or Set topic
NoAlNumToUnderscore(subname, MultiSubName); //Replace all non alphaumeric characters to '_' to avoid topic name issues
snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%s"), ESP.getChipId(), sensorname, subname);
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id);
@ -517,7 +524,7 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
case 3:
snprintf_P(param1, sizeof(param1), PSTR("%s"), PressureUnit().c_str());
break;
// case 4: // Speed. Default to km/h if not set to have a graph representation under HAss
// case 4: // Speed. Default to km/h if not set to have a graph representation under HAss
// case 5:
// case 6:
// case 7:
@ -596,8 +603,8 @@ void HAssAnnounceSensors(void)
for (auto subsensor : subsensors) {
snprintf_P(NewSensorName, sizeof(NewSensorName), PSTR("%s %s"), NestedName, subsensor.key);
HAssAnnounceSensor(sensorname, NestedName, NewSensorName, 0, 0, 1, subsensor.key);
}
} else if (subsensor.value.is<JsonArray&>()) {
}
} else if (subsensor.value.is<JsonArray&>()) {
// If there is more than a value on sensor data, 'n' entitites will be created
JsonArray& subsensors = subsensor.value.as<JsonArray&>();
uint8_t subqty = subsensors.size();

View File

@ -838,7 +838,7 @@ void DisplayText(void)
if (!fill) {
*dp = 0;
} else {
linebuf[abs(fill)] = 0;
linebuf[abs(int(fill))] = 0;
}
if (fill<0) {
// right align

View File

@ -665,7 +665,7 @@ bool Xsns37(uint8_t function)
RfSnsAnalyzeRawSignal();
}
}
sleep = 0;
ssleep = 0;
break;
case FUNC_EVERY_SECOND:
RfSnsEverySecond();