From 8b5adb309583f93116ff3845abab2ee53b30d618 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 26 Dec 2020 09:44:01 +0100 Subject: [PATCH 001/105] fix rtc wakeup HH:MM --- lib/libesp32/CORE2_Library/BM8563_RTC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libesp32/CORE2_Library/BM8563_RTC.cpp b/lib/libesp32/CORE2_Library/BM8563_RTC.cpp index 986ccf897..f17262d29 100755 --- a/lib/libesp32/CORE2_Library/BM8563_RTC.cpp +++ b/lib/libesp32/CORE2_Library/BM8563_RTC.cpp @@ -268,8 +268,8 @@ int BM8563_RTC::SetAlarmIRQ(const RTC_TimeTypeDef &RTC_TimeStruct) out_buf[1] = ByteToBcd2(RTC_TimeStruct.Hours) & 0x3f; } - out_buf[2] = 0x00; - out_buf[3] = 0x00; + //out_buf[2] = 0x00; + //out_buf[3] = 0x00; uint8_t reg_value = ReadReg(0x01); From 9b890bcd98944653c1b0d492e2ecb14a6119f8b2 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 26 Dec 2020 09:44:46 +0100 Subject: [PATCH 002/105] add i2s initial microphone support --- tasmota/xdrv_42_i2s_audio.ino | 258 +++++++++++++++++++++++++++++----- 1 file changed, 223 insertions(+), 35 deletions(-) diff --git a/tasmota/xdrv_42_i2s_audio.ino b/tasmota/xdrv_42_i2s_audio.ino index 6f82b63bc..0bb02e652 100644 --- a/tasmota/xdrv_42_i2s_audio.ino +++ b/tasmota/xdrv_42_i2s_audio.ino @@ -17,7 +17,7 @@ along with this program. If not, see . */ -#if (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH)) +#if (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH) || defined(USE_M5STACK_CORE2)) #include "AudioFileSourcePROGMEM.h" #include "AudioFileSourceID3.h" #include "AudioGeneratorMP3.h" @@ -31,18 +31,32 @@ #include "AudioFileSourceBuffer.h" #include "AudioGeneratorAAC.h" +#undef AUDIO_PWR_ON +#undef AUDIO_PWR_OFF +#define AUDIO_PWR_ON +#define AUDIO_PWR_OFF + #ifdef USE_TTGO_WATCH -#undef TTGO_PWR_ON -#undef TTGO_PWR_OFF -#define TTGO_PWR_ON TTGO_audio_power(true); -#define TTGO_PWR_OFF TTGO_audio_power(false); -#else -#undef TTGO_PWR_ON -#undef TTGO_PWR_OFF -#define TTGO_PWR_ON -#define TTGO_PWR_OFF +#undef AUDIO_PWR_ON +#undef AUDIO_PWR_OFF +#define AUDIO_PWR_ON TTGO_audio_power(true); +#define AUDIO_PWR_OFF TTGO_audio_power(false); #endif // USE_TTGO_WATCH +#ifdef USE_M5STACK_CORE2 +#undef AUDIO_PWR_ON +#undef AUDIO_PWR_OFF +#define AUDIO_PWR_ON CORE2_audio_power(true); +#define AUDIO_PWR_OFF CORE2_audio_power(false); +#undef DAC_IIS_BCK +#undef DAC_IIS_WS +#undef DAC_IIS_DOUT +#define DAC_IIS_BCK 12 +#define DAC_IIS_WS 0 +#define DAC_IIS_DOUT 2 +#endif // USE_M5STACK_CORE2 + + #define EXTERNAL_DAC_PLAY 1 #define XDRV_42 42 @@ -82,26 +96,36 @@ AudioGeneratorTalkie *talkie = nullptr; //! MAX98357A + INMP441 DOUBLE I2S BOARD #ifdef ESP8266 -#undef TWATCH_DAC_IIS_BCK -#undef TWATCH_DAC_IIS_WS -#undef TWATCH_DAC_IIS_DOUT -#define TWATCH_DAC_IIS_BCK 15 -#define TWATCH_DAC_IIS_WS 2 -#define TWATCH_DAC_IIS_DOUT 3 +#undef DAC_IIS_BCK +#undef DAC_IIS_WS +#undef DAC_IIS_DOUT +#define DAC_IIS_BCK 15 +#define DAC_IIS_WS 2 +#define DAC_IIS_DOUT 3 #endif // ESP8266 + +// defaults to TTGO WATCH #ifdef ESP32 -#ifndef TWATCH_DAC_IIS_BCK -#undef TWATCH_DAC_IIS_BCK -#define TWATCH_DAC_IIS_BCK 26 +#ifndef DAC_IIS_BCK +#undef DAC_IIS_BCK +#define DAC_IIS_BCK 26 #endif -#ifndef TWATCH_DAC_IIS_WS -#undef TWATCH_DAC_IIS_WS -#define TWATCH_DAC_IIS_WS 25 + +#ifndef DAC_IIS_WS +#undef DAC_IIS_WS +#define DAC_IIS_WS 25 #endif -#ifndef TWATCH_DAC_IIS_DOUT -#undef TWATCH_DAC_IIS_DOUT -#define TWATCH_DAC_IIS_DOUT 33 + +#ifndef DAC_IIS_DOUT +#undef DAC_IIS_DOUT +#define DAC_IIS_DOUT 33 #endif + +#ifndef DAC_IIS_DIN +#undef DAC_IIS_DIN +#define DAC_IIS_DIN 34 +#endif + #endif // ESP32 #ifdef SAY_TIME @@ -147,7 +171,10 @@ uint8_t spPAUSE1[] PROGMEM = {0x00,0x00,0x00,0x00,0xFF,0x0F}; void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) ; void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) { - TTGO_PWR_ON + + if (!out) return; + + AUDIO_PWR_ON talkie = new AudioGeneratorTalkie(); talkie->begin(nullptr, out); @@ -198,7 +225,7 @@ void sayTime(int hour, int minutes, AudioGeneratorTalkie *talkie) { } delete talkie; out->stop(); - TTGO_PWR_OFF + AUDIO_PWR_OFF } #endif @@ -210,11 +237,11 @@ void I2S_Init(void) { #if EXTERNAL_DAC_PLAY out = new AudioOutputI2S(); #ifdef ESP32 - out->SetPinout(TWATCH_DAC_IIS_BCK, TWATCH_DAC_IIS_WS, TWATCH_DAC_IIS_DOUT); + out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT); #endif // ESP32 #else out = new AudioOutputI2S(0, 1); -#endif +#endif // EXTERNAL_DAC_PLAY is2_volume=10; out->SetGain(((float)is2_volume/100.0)*4.0); @@ -241,6 +268,163 @@ void I2S_Init(void) { #endif // ESP32 } + + +#ifdef ESP32 +#define MODE_MIC 0 +#define MODE_SPK 1 +#define Speak_I2S_NUMBER I2S_NUM_0 +//#define MICSRATE 44100 +#define MICSRATE 16000 + +#include + +uint32_t SpeakerMic(uint8_t spkr) { + esp_err_t err = ESP_OK; + + if (out) { + out->stop(); + delete out; + out = nullptr; + } + + i2s_driver_uninstall(Speak_I2S_NUMBER); + if (spkr==MODE_SPK) { + out = new AudioOutputI2S(); + out->SetPinout(DAC_IIS_BCK, DAC_IIS_WS, DAC_IIS_DOUT); + out->SetGain(((float)is2_volume/100.0)*4.0); + out->stop(); + } else { + // config mic + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER), + .sample_rate = MICSRATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, + .communication_format = I2S_COMM_FORMAT_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 2, + //.dma_buf_len = 128, + .dma_buf_len = 1024, + }; + i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM); + err += i2s_driver_install(Speak_I2S_NUMBER, &i2s_config, 0, NULL); + + i2s_pin_config_t tx_pin_config; + tx_pin_config.bck_io_num = DAC_IIS_BCK; + tx_pin_config.ws_io_num = DAC_IIS_WS; + tx_pin_config.data_out_num = DAC_IIS_DOUT; + tx_pin_config.data_in_num = DAC_IIS_DIN; + err += i2s_set_pin(Speak_I2S_NUMBER, &tx_pin_config); + + err += i2s_set_clk(Speak_I2S_NUMBER, MICSRATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO); + } + return err; +} + +#define DATA_SIZE 1024 + +TaskHandle_t mic_task_h; +uint32_t mic_size; +uint8_t *mic_buff; +char mic_path[32]; + +void mic_task(void *arg){ + uint32_t data_offset = 0; + while (1) { + uint32_t bytes_read; + i2s_read(Speak_I2S_NUMBER, (char *)(mic_buff + data_offset), DATA_SIZE, &bytes_read, (100 / portTICK_RATE_MS)); + if (bytes_read != DATA_SIZE) break; + data_offset += DATA_SIZE; + if (data_offset >= mic_size-DATA_SIZE) break; + } + SpeakerMic(MODE_SPK); + SaveWav(mic_path, mic_buff, mic_size); + free(mic_buff); + vTaskDelete(mic_task_h); +} + +uint32_t i2s_record(char *path, uint32_t secs) { + esp_err_t err = ESP_OK; + + if (decoder || mp3) return 0; + + err = SpeakerMic(MODE_MIC); + if (err) { + SpeakerMic(MODE_SPK); + return err; + } + + mic_size = secs * MICSRATE * 2; + + mic_buff = (uint8_t*)heap_caps_malloc(mic_size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (!mic_buff) return 2; + + if (*path=='+') { + path++; + strlcpy(mic_path, path , sizeof(mic_path)); + xTaskCreatePinnedToCore(mic_task, "MIC", 4096, NULL, 3, &mic_task_h, 1); + return 0; + } + + uint32_t data_offset = 0; + uint32_t stime=millis(); + while (1) { + uint32_t bytes_read; + i2s_read(Speak_I2S_NUMBER, (char *)(mic_buff + data_offset), DATA_SIZE, &bytes_read, (100 / portTICK_RATE_MS)); + if (bytes_read != DATA_SIZE) break; + data_offset += DATA_SIZE; + if (data_offset >= mic_size-DATA_SIZE) break; + delay(0); + } + //AddLog_P(LOG_LEVEL_INFO, PSTR("rectime: %d ms"), millis()-stime); + SpeakerMic(MODE_SPK); + // save to path + SaveWav(mic_path, mic_buff, mic_size); + free(mic_buff); + return 0; +} + +static const uint8_t wavHTemplate[] PROGMEM = { // Hardcoded simple WAV header with 0xffffffff lengths all around + 0x52, 0x49, 0x46, 0x46, 0xff, 0xff, 0xff, 0xff, 0x57, 0x41, 0x56, 0x45, + 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x22, 0x56, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, + 0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff }; + +bool SaveWav(char *path, uint8_t *buff, uint32_t size) { + File fwp = fsp->open(path, FILE_WRITE); + uint8_t wavHeader[sizeof(wavHTemplate)]; + memcpy_P(wavHeader, wavHTemplate, sizeof(wavHTemplate)); + + uint8_t channels = 1; + uint32_t hertz = MICSRATE; + uint8_t bps = 16; + + wavHeader[22] = channels & 0xff; + wavHeader[23] = 0; + wavHeader[24] = hertz & 0xff; + wavHeader[25] = (hertz >> 8) & 0xff; + wavHeader[26] = (hertz >> 16) & 0xff; + wavHeader[27] = (hertz >> 24) & 0xff; + int byteRate = hertz * bps * channels / 8; + wavHeader[28] = byteRate & 0xff; + wavHeader[29] = (byteRate >> 8) & 0xff; + wavHeader[30] = (byteRate >> 16) & 0xff; + wavHeader[31] = (byteRate >> 24) & 0xff; + wavHeader[32] = channels * bps / 8; + wavHeader[33] = 0; + wavHeader[34] = bps; + wavHeader[35] = 0; + + fwp.write(wavHeader, sizeof(wavHeader)); + + fwp.write(buff, size); + fwp.close(); + + return true; +} + +#endif // ESP32 + #ifdef ESP32 TaskHandle_t mp3_task_h; @@ -286,7 +470,8 @@ void StatusCallback(void *cbData, int code, const char *string) { void Webradio(const char *url) { if (decoder || mp3) return; - TTGO_PWR_ON + if (!out) return; + AUDIO_PWR_ON ifile = new AudioFileSourceICYStream(url); ifile->RegisterMetadataCB(MDCallback, NULL); buff = new AudioFileSourceBuffer(ifile, preallocateBuffer, preallocateBufferSize); @@ -338,7 +523,7 @@ void StopPlaying() { delete ifile; ifile = NULL; } - TTGO_PWR_OFF + AUDIO_PWR_OFF } void Cmd_WebRadio(void) { @@ -369,10 +554,11 @@ void I2S_WR_Show(void) { void Play_mp3(const char *path) { #if defined(USE_SCRIPT) && defined(USE_SCRIPT_FATFS) if (decoder || mp3) return; + if (!out) return; bool I2S_Task; - TTGO_PWR_ON + AUDIO_PWR_ON if (*path=='+') { I2S_Task = true; path++; @@ -411,13 +597,15 @@ void mp3_delete(void) { delete id3; delete mp3; mp3=nullptr; - TTGO_PWR_OFF + AUDIO_PWR_OFF } #endif // ESP32 void Say(char *text) { - TTGO_PWR_ON + if (!out) return; + + AUDIO_PWR_ON out->begin(); ESP8266SAM *sam = new ESP8266SAM; @@ -425,7 +613,7 @@ void Say(char *text) { delete sam; out->stop(); - TTGO_PWR_OFF + AUDIO_PWR_OFF } From 99ac0ef94a6318eaa570df78cde1b052712bb125 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 26 Dec 2020 09:45:17 +0100 Subject: [PATCH 003/105] core 2 rtc sync and wakeup --- tasmota/xdrv_84_core2.ino | 192 +++++++++++++++++++++++++++++++++++--- 1 file changed, 177 insertions(+), 15 deletions(-) diff --git a/tasmota/xdrv_84_core2.ino b/tasmota/xdrv_84_core2.ino index e3925eef6..9bc18ad0c 100644 --- a/tasmota/xdrv_84_core2.ino +++ b/tasmota/xdrv_84_core2.ino @@ -19,14 +19,18 @@ /* remaining work: -i2s microphone, at least as loudness sensor -rtc use after reboot, sync with internet on regular intervals. +i2s microphone as loudness sensor +rtc better sync */ #ifdef ESP32 #ifdef USE_M5STACK_CORE2 +#include +#include +#include + #include #include #include @@ -41,9 +45,11 @@ struct CORE2_globs { BM8563_RTC Rtc; bool ready; bool tset; - uint32_t shutdownseconds; + int32_t shutdownseconds; + uint8_t wakeup_hour; + uint8_t wakeup_minute; uint8_t shutdowndelay; - + bool timesynced; } core2_globs; struct CORE2_ADC { @@ -79,6 +85,31 @@ void CORE2_Module_Init(void) { void CORE2_Init(void) { + if (Rtc.utc_time < START_VALID_TIME) { + // set rtc from chip + Rtc.utc_time = Get_utc(); + + TIME_T tmpTime; + TasmotaGlobal.ntp_force_sync = true; //force to sync with ntp + // Rtc.utc_time = ReadFromDS3231(); //we read UTC TIME from DS3231 + // from this line, we just copy the function from "void RtcSecond()" at the support.ino ,line 2143 and above + // We need it to set rules etc. + BreakTime(Rtc.utc_time, tmpTime); + if (Rtc.utc_time < START_VALID_TIME ) { + //ds3231ReadStatus = true; //if time in DS3231 is valid, do not update again + } + Rtc.daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); + Rtc.standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); + AddLog_P(LOG_LEVEL_INFO, PSTR("Set time from BM8563 to RTC (" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"), + GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str()); + if (Rtc.local_time < START_VALID_TIME) { // 2016-01-01 + TasmotaGlobal.rules_flag.time_init = 1; + } else { + TasmotaGlobal.rules_flag.time_set = 1; + } + + } + } void CORE2_audio_power(bool power) { @@ -100,6 +131,7 @@ const char HTTP_CORE2_MPU[] PROGMEM = void CORE2_loop(uint32_t flg) { + Sync_RTOS_TIME(); } void CORE2_WebShow(uint32_t json) { @@ -135,24 +167,45 @@ void (* const CORE2_Command[])(void) PROGMEM = { void CORE2_Shutdown(void) { - if (XdrvMailbox.payload >= 30) { - core2_globs.shutdownseconds = XdrvMailbox.payload; + char *mp = strchr(XdrvMailbox.data, ':'); + if (mp) { + core2_globs.wakeup_hour = atoi(XdrvMailbox.data); + core2_globs.wakeup_minute = atoi(mp+1); + core2_globs.shutdownseconds = -1; core2_globs.shutdowndelay = 10; + char tbuff[16]; + sprintf(tbuff,"%02.2d:%02.2d", core2_globs.wakeup_hour, core2_globs.wakeup_minute ); + ResponseCmndChar(tbuff); + } else { + if (XdrvMailbox.payload >= 30) { + core2_globs.shutdownseconds = XdrvMailbox.payload; + core2_globs.shutdowndelay = 10; + } + ResponseCmndNumber(XdrvMailbox.payload); } - ResponseCmndNumber(XdrvMailbox.payload -2); + } void CORE2_DoShutdown(void) { SettingsSaveAll(); RtcSettingsSave(); core2_globs.Rtc.clearIRQ(); - core2_globs.Rtc.SetAlarmIRQ(core2_globs.shutdownseconds); + if (core2_globs.shutdownseconds > 0) { + core2_globs.Rtc.SetAlarmIRQ(core2_globs.shutdownseconds); + } else { + RTC_TimeTypeDef wut; + wut.Hours = core2_globs.wakeup_hour; + wut.Minutes = core2_globs.wakeup_minute; + core2_globs.Rtc.SetAlarmIRQ(wut); + } delay(10); core2_globs.Axp.PowerOff(); } extern uint8_t tbstate[3]; + +// c2ps(a b) float core2_setaxppin(uint32_t sel, uint32_t val) { switch (sel) { case 0: @@ -165,7 +218,25 @@ float core2_setaxppin(uint32_t sel, uint32_t val) { if (val<1 || val>3) val = 1; return tbstate[val - 1] & 1; break; - + case 3: + switch (val) { + case 0: + return core2_globs.Axp.isACIN(); + break; + case 1: + return core2_globs.Axp.isCharging(); + break; + case 2: + return core2_globs.Axp.isVBUS(); + break; + case 3: + return core2_globs.Axp.AXPInState(); + break; + } + break; + default: + GetRtc(); + break; } return 0; } @@ -187,16 +258,107 @@ uint16_t voltage = 2200; } +/* +void SetRtc(void) { + RTC_TimeTypeDef RTCtime; + RTCtime.Hours = RtcTime.hour; + RTCtime.Minutes = RtcTime.minute; + RTCtime.Seconds = RtcTime.second; + core2_globs.Rtc.SetTime(&RTCtime); + + RTC_DateTypeDef RTCdate; + RTCdate.WeekDay = RtcTime.day_of_week; + RTCdate.Month = RtcTime.month; + RTCdate.Date = RtcTime.day_of_month; + RTCdate.Year = RtcTime.year; + core2_globs.Rtc.SetDate(&RTCdate); +} +*/ + + +// needed for sd card time +void Sync_RTOS_TIME(void) { + + if (Rtc.local_time < START_VALID_TIME || core2_globs.timesynced) return; + + core2_globs.timesynced = 1; +// Set freertos time for sd card + + struct timeval tv; + //tv.tv_sec = Rtc.utc_time; + tv.tv_sec = Rtc.local_time; + tv.tv_usec = 0; + + //struct timezone tz; + //tz.tz_minuteswest = 0; + //tz.tz_dsttime = 0; + //settimeofday(&tv, &tz); + + settimeofday(&tv, NULL); +} + +void GetRtc(void) { + RTC_TimeTypeDef RTCtime; + core2_globs.Rtc.GetTime(&RTCtime); + RtcTime.hour = RTCtime.Hours; + RtcTime.minute = RTCtime.Minutes; + RtcTime.second = RTCtime.Seconds; + + + RTC_DateTypeDef RTCdate; + core2_globs.Rtc.GetDate(&RTCdate); + RtcTime.day_of_week = RTCdate.WeekDay; + RtcTime.month = RTCdate.Month; + RtcTime.day_of_month = RTCdate.Date; + RtcTime.year = RTCdate.Year; + + AddLog_P(LOG_LEVEL_INFO, PSTR("RTC: %02d:%02d:%02d"), RTCtime.Hours, RTCtime.Minutes, RTCtime.Seconds); + AddLog_P(LOG_LEVEL_INFO, PSTR("RTC: %02d.%02d.%04d"), RTCdate.Date, RTCdate.Month, RTCdate.Year); + +} + +void Set_utc(uint32_t epoch_time) { +TIME_T tm; + BreakTime(epoch_time, tm); + RTC_TimeTypeDef RTCtime; + RTCtime.Hours = tm.hour; + RTCtime.Minutes = tm.minute; + RTCtime.Seconds = tm.second; + core2_globs.Rtc.SetTime(&RTCtime); + RTC_DateTypeDef RTCdate; + RTCdate.WeekDay = tm.day_of_week; + RTCdate.Month = tm.month; + RTCdate.Date = tm.day_of_month; + RTCdate.Year = tm.year + 1970; + core2_globs.Rtc.SetDate(&RTCdate); +} + +uint32_t Get_utc(void) { + RTC_TimeTypeDef RTCtime; + // 1. read has errors ??? + core2_globs.Rtc.GetTime(&RTCtime); + core2_globs.Rtc.GetTime(&RTCtime); + RTC_DateTypeDef RTCdate; + core2_globs.Rtc.GetDate(&RTCdate); + TIME_T tm; + tm.second = RTCtime.Seconds; + tm.minute = RTCtime.Minutes; + tm.hour = RTCtime.Hours; + tm.day_of_week = RTCdate.WeekDay; + tm.day_of_month = RTCdate.Date; + tm.month = RTCdate.Month; + tm.year =RTCdate.Year - 1970; + return MakeTime(tm); +} + void CORE2_EverySecond(void) { if (core2_globs.ready) { CORE2_GetADC(); - if (RtcTime.year>2000 && core2_globs.tset==false) { - RTC_TimeTypeDef RTCtime; - RTCtime.Hours = RtcTime.hour; - RTCtime.Minutes = RtcTime.minute; - RTCtime.Seconds = RtcTime.second; - core2_globs.Rtc.SetTime(&RTCtime); + if (Rtc.utc_time > START_VALID_TIME && core2_globs.tset==false && abs(Rtc.utc_time - Get_utc()) > 3) { + Set_utc(Rtc.utc_time); + AddLog_P(LOG_LEVEL_INFO, PSTR("Write Time TO BM8563 from NTP (" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"), + GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str()); core2_globs.tset = true; } From 559e9df0aafab736a649d729505667a40aa5cfdc Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 26 Dec 2020 09:45:59 +0100 Subject: [PATCH 004/105] record microphone, guard arrays --- tasmota/xdrv_10_scripter.ino | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index c43f47826..6f7351c7d 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1251,7 +1251,7 @@ float Get_MFVal(uint8_t index, int16_t bind) { if (bind<0) { return maxind; } - if (bind<1 || bind>maxind) bind = maxind; + if (bind < 1 || bind > maxind ) bind = 1; return mflp->rbuff[bind - 1]; } mp += sizeof(struct M_FILT) + ((mflp->numvals & AND_FILT_MASK) - 1) * sizeof(float); @@ -1266,10 +1266,12 @@ void Set_MFVal(uint8_t index, uint16_t bind, float val) { if (count==index) { uint16_t maxind = mflp->numvals & AND_FILT_MASK; if (!bind) { + if (val < 0 || val >= maxind) val = 0; mflp->index = val; } else { - if (bind<1 || bind>maxind) bind = maxind; - mflp->rbuff[bind-1] = val; + if (bind > 1 && bind <= maxind) { + mflp->rbuff[bind-1] = val; + } } return; } @@ -2407,6 +2409,10 @@ chknext: #endif goto exit; } + if (!strncmp(vname, "frnm", 4)) { + if (sp) strlcpy(sp, SettingsText(SET_FRIENDLYNAME1), glob_script_mem.max_ssize); + goto strexit; + } break; case 'g': if (!strncmp(vname, "gtmp", 4)) { @@ -2783,6 +2789,17 @@ chknext: len++; goto exit; } +#if defined(ESP32) && (defined(USE_M5STACK_CORE2)) + if (!strncmp(vname, "rec(", 4)) { + char str[SCRIPT_MAXSSIZE]; + lp = GetStringArgument(lp + 4, OPER_EQU, str, 0); + SCRIPT_SKIP_SPACES + lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0); + fvar = i2s_record(str, fvar); + len++; + goto exit; + } +#endif break; case 's': if (!strncmp(vname, "secs", 4)) { @@ -3800,8 +3817,9 @@ void esp32_beep(int32_t freq ,uint32_t len) { uint8_t pwmpin[5]; void esp_pwm(int32_t value, uint32 freq, uint32_t channel) { - if (channel < 1 || channel > 3) channel = 1; + #ifdef ESP32 + if (channel < 1 || channel > 8) channel = 1; channel+=7; if (value < 0) { if (value <= -64) value = 0; @@ -3817,6 +3835,7 @@ void esp_pwm(int32_t value, uint32 freq, uint32_t channel) { } #else // esp8266 default to range 0-1023 + if (channel < 1 || channel > 5) channel = 1; channel-=1; if (value < 0) { if (value <= -64) value = 0; @@ -7174,7 +7193,8 @@ exgc: char *cp = &label[3]; //todflg=atoi(&label[3]); todflg = strtol(cp, &cp, 10); - if (todflg>=entries) todflg = entries - 1; + if (todflg >= entries) todflg = entries - 1; + if (todflg < 0) todflg = 0; if (*cp=='/') { cp++; divflg = strtol(cp, &cp, 10); @@ -7676,6 +7696,7 @@ bool Xdrv10(uint8_t function) #endif // USE_SCRIPT_FATFS>=0 AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount OK!")); + //fsp->dateTimeCallback(dateTime); glob_script_mem.script_sd_found = 1; char *script; From d75beb92f37ed0e16bf219f192117d49a67346cd Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Dec 2020 12:18:16 +0100 Subject: [PATCH 005/105] Add support character `#` to be replaced by `space`-character Add support character `#` to be replaced by `space`-character in command ``Publish`` topic (#10258) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/support.ino | 11 ++- tasmota/xdrv_02_mqtt.ino | 176 +++++++++++---------------------------- 4 files changed, 59 insertions(+), 130 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 458019d7b..2c8911bad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - Support for GPIO option selection - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs (#10196) - Support for FTC532 8-button touch controller by Peter Franck (#10222) +- Support character `#` to be replaced by `space`-character in command ``Publish`` topic (#10258) ### Changed - Logging from fixed global memory buffer to stack buffer freeing 700 bytes RAM diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e9cb5b4d5..04a07fa85 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -63,6 +63,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for GPIO option selection - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - Support for FTC532 8-button touch controller by Peter Franck [#10222](https://github.com/arendst/Tasmota/issues/10222) +- Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258) ### Changed - Logging from fixed global memory buffer to stack buffer freeing 700 bytes RAM diff --git a/tasmota/support.ino b/tasmota/support.ino index 4f5b0ec18..30436fd2f 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -388,22 +388,25 @@ char* RemoveControlCharacter(char* p) { return p; } -char* ReplaceCommaWithDot(char* p) { - // Replace character ',' with '.' +char* ReplaceChar(char* p, char find, char replace) { char* write = (char*)p; char* read = (char*)p; char ch = '.'; while (ch != '\0') { ch = *read++; - if (ch == ',') { - ch = '.'; + if (ch == find) { + ch = replace; } *write++ = ch; } return p; } +char* ReplaceCommaWithDot(char* p) { + return ReplaceChar(p, ',', '.'); +} + char* LowerCase(char* dest, const char* source) { char* write = dest; diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 5baba474f..a0bc0f494 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -106,8 +106,7 @@ bool is_fingerprint_mono_value(uint8_t finger[20], uint8_t value) { } #endif // USE_MQTT_TLS -void MakeValidMqtt(uint32_t option, char* str) -{ +void MakeValidMqtt(uint32_t option, char* str) { // option 0 = replace by underscore // option 1 = delete character uint32_t i = 0; @@ -147,8 +146,7 @@ void MakeValidMqtt(uint32_t option, char* str) PubSubClient MqttClient; -void MqttInit(void) -{ +void MqttInit(void) { #ifdef USE_MQTT_TLS if ((8883 == Settings.mqtt_port) || (8884 == Settings.mqtt_port)) { // Turn on TLS for port 8883 (TLS) and 8884 (TLS, client certificate) @@ -187,30 +185,25 @@ void MqttInit(void) #endif // USE_MQTT_TLS } -bool MqttIsConnected(void) -{ +bool MqttIsConnected(void) { return MqttClient.connected(); } -void MqttDisconnect(void) -{ +void MqttDisconnect(void) { MqttClient.disconnect(); } -void MqttSubscribeLib(const char *topic) -{ +void MqttSubscribeLib(const char *topic) { MqttClient.subscribe(topic); MqttClient.loop(); // Solve LmacRxBlk:1 messages } -void MqttUnsubscribeLib(const char *topic) -{ +void MqttUnsubscribeLib(const char *topic) { MqttClient.unsubscribe(topic); MqttClient.loop(); // Solve LmacRxBlk:1 messages } -bool MqttPublishLib(const char* topic, bool retained) -{ +bool MqttPublishLib(const char* topic, bool retained) { // If Prefix1 equals Prefix2 disable next MQTT subscription to prevent loop if (!strcmp(SettingsText(SET_MQTTPREFIX1), SettingsText(SET_MQTTPREFIX2))) { char *str = strstr(topic, SettingsText(SET_MQTTPREFIX1)); @@ -231,8 +224,7 @@ void MqttDumpData(char* topic, char* data, uint32_t data_len) { AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_MQTT D_DATA_SIZE " %d, \"%s %s\""), data_len, topic, RemoveControlCharacter(dump_data)); } -void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len) -{ +void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len) { #ifdef USE_DEBUG_DRIVER ShowFreeMem(PSTR("MqttDataHandler")); #endif @@ -274,19 +266,16 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len /*********************************************************************************************/ -void MqttRetryCounter(uint8_t value) -{ +void MqttRetryCounter(uint8_t value) { Mqtt.retry_counter = value; } -void MqttSubscribe(const char *topic) -{ +void MqttSubscribe(const char *topic) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT D_SUBSCRIBE_TO " %s"), topic); MqttSubscribeLib(topic); } -void MqttUnsubscribe(const char *topic) -{ +void MqttUnsubscribe(const char *topic) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT D_UNSUBSCRIBE_FROM " %s"), topic); MqttUnsubscribeLib(topic); } @@ -307,8 +296,7 @@ void MqttPublishLoggingAsync(bool refresh) { } } -void MqttPublish(const char* topic, bool retained) -{ +void MqttPublish(const char* topic, bool retained) { #ifdef USE_DEBUG_DRIVER ShowFreeMem(PSTR("MqttPublish")); #endif @@ -345,13 +333,11 @@ void MqttPublish(const char* topic, bool retained) } } -void MqttPublish(const char* topic) -{ +void MqttPublish(const char* topic) { MqttPublish(topic, false); } -void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained) -{ +void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained) { /* prefix 0 = cmnd using subtopic * prefix 1 = stat using subtopic * prefix 2 = tele using subtopic @@ -399,29 +385,24 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retain #endif // USE_MQTT_AWS_IOT } -void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic) -{ +void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic) { MqttPublishPrefixTopic_P(prefix, subtopic, false); } -void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic, bool retained) -{ +void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic, bool retained) { MqttPublishPrefixTopic_P(prefix, subtopic, retained); XdrvRulesProcess(); } -void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic) -{ +void MqttPublishPrefixTopicRulesProcess_P(uint32_t prefix, const char* subtopic) { MqttPublishPrefixTopicRulesProcess_P(prefix, subtopic, false); } -void MqttPublishTeleSensor(void) -{ +void MqttPublishTeleSensor(void) { MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); // CMND_SENSORRETAIN } -void MqttPublishPowerState(uint32_t device) -{ +void MqttPublishPowerState(uint32_t device) { char stopic[TOPSZ]; char scommand[33]; @@ -455,8 +436,7 @@ void MqttPublishPowerState(uint32_t device) #endif // USE_SONOFF_IFAN } -void MqttPublishAllPowerState(void) -{ +void MqttPublishAllPowerState(void) { for (uint32_t i = 1; i <= TasmotaGlobal.devices_present; i++) { MqttPublishPowerState(i); #ifdef USE_SONOFF_IFAN @@ -465,8 +445,7 @@ void MqttPublishAllPowerState(void) } } -void MqttPublishPowerBlinkState(uint32_t device) -{ +void MqttPublishPowerBlinkState(uint32_t device) { char scommand[33]; if ((device < 1) || (device > TasmotaGlobal.devices_present)) { @@ -480,13 +459,11 @@ void MqttPublishPowerBlinkState(uint32_t device) /*********************************************************************************************/ -uint16_t MqttConnectCount(void) -{ +uint16_t MqttConnectCount(void) { return Mqtt.connect_count; } -void MqttDisconnected(int state) -{ +void MqttDisconnected(int state) { Mqtt.connected = false; Mqtt.retry_counter = Settings.mqtt_retry * Mqtt.retry_counter_delay; @@ -500,8 +477,7 @@ void MqttDisconnected(int state) TasmotaGlobal.rules_flag.mqtt_disconnected = 1; } -void MqttConnected(void) -{ +void MqttConnected(void) { char stopic[TOPSZ]; if (Mqtt.allowed) { @@ -582,8 +558,7 @@ void MqttConnected(void) } } -void MqttReconnect(void) -{ +void MqttReconnect(void) { char stopic[TOPSZ]; Mqtt.allowed = Settings.flag.mqtt_enabled; // SetOption3 - Enable MQTT @@ -708,37 +683,6 @@ void MqttReconnect(void) AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "MFLN not supported by TLS server")); } #ifndef USE_MQTT_TLS_CA_CERT // don't bother with fingerprints if using CA validation -// **** Start patch Castellucci -/* - // create a printable version of the fingerprint received - char buf_fingerprint[64]; - ToHex_P((unsigned char *)tlsClient->getRecvPubKeyFingerprint(), 20, buf_fingerprint, sizeof(buf_fingerprint), ' '); - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_MQTT "Server fingerprint: %s"), buf_fingerprint); - - if (learn_fingerprint1 || learn_fingerprint2) { - // we potentially need to learn the fingerprint just seen - bool fingerprint_matched = false; - const uint8_t *recv_fingerprint = tlsClient->getRecvPubKeyFingerprint(); - if (0 == memcmp(recv_fingerprint, Settings.mqtt_fingerprint[0], 20)) { - fingerprint_matched = true; - } - if (0 == memcmp(recv_fingerprint, Settings.mqtt_fingerprint[1], 20)) { - fingerprint_matched = true; - } - if (!fingerprint_matched) { - // we had no match, so we need to change all fingerprints ready to learn - if (learn_fingerprint1) { - memcpy(Settings.mqtt_fingerprint[0], recv_fingerprint, 20); - } - if (learn_fingerprint2) { - memcpy(Settings.mqtt_fingerprint[1], recv_fingerprint, 20); - } - AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "Fingerprint learned: %s"), buf_fingerprint); - - SettingsSaveAll(); // save settings - } - } -*/ const uint8_t *recv_fingerprint = tlsClient->getRecvPubKeyFingerprint(); // create a printable version of the fingerprint received char buf_fingerprint[64]; @@ -766,7 +710,6 @@ void MqttReconnect(void) SettingsSaveAll(); // save settings } - // **** End patch Castellucci #endif // !USE_MQTT_TLS_CA_CERT } #endif // USE_MQTT_TLS @@ -781,8 +724,7 @@ void MqttReconnect(void) } } -void MqttCheck(void) -{ +void MqttCheck(void) { if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT if (!MqttIsConnected()) { TasmotaGlobal.global_state.mqtt_down = 1; @@ -802,8 +744,7 @@ void MqttCheck(void) } } -bool KeyTopicActive(uint32_t key) -{ +bool KeyTopicActive(uint32_t key) { // key = 0 - Button topic // key = 1 - Switch topic key &= 1; @@ -817,8 +758,7 @@ bool KeyTopicActive(uint32_t key) \*********************************************************************************************/ #if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT) -void CmndMqttFingerprint(void) -{ +void CmndMqttFingerprint(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) { char fingerprint[60]; if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(fingerprint))) { @@ -838,8 +778,7 @@ void CmndMqttFingerprint(void) } #endif -void CmndMqttUser(void) -{ +void CmndMqttUser(void) { if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_MQTT_USER, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_USER : XdrvMailbox.data); TasmotaGlobal.restart_flag = 2; @@ -847,8 +786,7 @@ void CmndMqttUser(void) ResponseCmndChar(SettingsText(SET_MQTT_USER)); } -void CmndMqttPassword(void) -{ +void CmndMqttPassword(void) { if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_MQTT_PWD, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_PASS : XdrvMailbox.data); ResponseCmndChar(SettingsText(SET_MQTT_PWD)); @@ -858,16 +796,14 @@ void CmndMqttPassword(void) } } -void CmndMqttlog(void) -{ +void CmndMqttlog(void) { if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) { Settings.mqttlog_level = XdrvMailbox.payload; } ResponseCmndNumber(Settings.mqttlog_level); } -void CmndMqttHost(void) -{ +void CmndMqttHost(void) { if (XdrvMailbox.data_len > 0) { SettingsUpdateText(SET_MQTT_HOST, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_HOST : XdrvMailbox.data); TasmotaGlobal.restart_flag = 2; @@ -875,8 +811,7 @@ void CmndMqttHost(void) ResponseCmndChar(SettingsText(SET_MQTT_HOST)); } -void CmndMqttPort(void) -{ +void CmndMqttPort(void) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 65536)) { Settings.mqtt_port = (1 == XdrvMailbox.payload) ? MQTT_PORT : XdrvMailbox.payload; TasmotaGlobal.restart_flag = 2; @@ -884,8 +819,7 @@ void CmndMqttPort(void) ResponseCmndNumber(Settings.mqtt_port); } -void CmndMqttRetry(void) -{ +void CmndMqttRetry(void) { if ((XdrvMailbox.payload >= MQTT_RETRY_SECS) && (XdrvMailbox.payload < 32001)) { Settings.mqtt_retry = XdrvMailbox.payload; Mqtt.retry_counter = Settings.mqtt_retry; @@ -893,8 +827,7 @@ void CmndMqttRetry(void) ResponseCmndNumber(Settings.mqtt_retry); } -void CmndStateText(void) -{ +void CmndStateText(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_STATE_TEXT)) { if (!XdrvMailbox.usridx) { ResponseCmndAll(SET_STATE_TXT1, MAX_STATE_TEXT); @@ -910,8 +843,7 @@ void CmndStateText(void) } } -void CmndMqttClient(void) -{ +void CmndMqttClient(void) { if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) { SettingsUpdateText(SET_MQTT_CLIENT, (SC_DEFAULT == Shortcut()) ? MQTT_CLIENT_ID : XdrvMailbox.data); TasmotaGlobal.restart_flag = 2; @@ -919,8 +851,7 @@ void CmndMqttClient(void) ResponseCmndChar(SettingsText(SET_MQTT_CLIENT)); } -void CmndFullTopic(void) -{ +void CmndFullTopic(void) { if (XdrvMailbox.data_len > 0) { MakeValidMqtt(1, XdrvMailbox.data); if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); } @@ -936,8 +867,7 @@ void CmndFullTopic(void) ResponseCmndChar(SettingsText(SET_MQTT_FULLTOPIC)); } -void CmndPrefix(void) -{ +void CmndPrefix(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_MQTT_PREFIXES)) { if (!XdrvMailbox.usridx) { ResponseCmndAll(SET_MQTTPREFIX1, MAX_MQTT_PREFIXES); @@ -953,14 +883,16 @@ void CmndPrefix(void) } } -void CmndPublish(void) -{ +void CmndPublish(void) { + // Allow wildcard character "#" as space replacement in topic (#10258) + // publish cmnd/theo#arends/power 2 ==> publish cmnd/theo arends/power 2 if (XdrvMailbox.data_len > 0) { char *payload_part; char *mqtt_part = strtok_r(XdrvMailbox.data, " ", &payload_part); if (mqtt_part) { char stemp1[TOPSZ]; strlcpy(stemp1, mqtt_part, sizeof(stemp1)); + ReplaceChar(stemp1, '#', ' '); if ((payload_part != nullptr) && strlen(payload_part)) { strlcpy(TasmotaGlobal.mqtt_data, payload_part, sizeof(TasmotaGlobal.mqtt_data)); } else { @@ -973,8 +905,7 @@ void CmndPublish(void) } } -void CmndGroupTopic(void) -{ +void CmndGroupTopic(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_GROUP_TOPICS)) { if (XdrvMailbox.data_len > 0) { uint32_t settings_text_index = (1 == XdrvMailbox.index) ? SET_MQTT_GRP_TOPIC : SET_MQTT_GRP_TOPIC2 + XdrvMailbox.index - 2; @@ -1023,8 +954,7 @@ void CmndGroupTopic(void) } } -void CmndTopic(void) -{ +void CmndTopic(void) { if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) { MakeValidMqtt(0, XdrvMailbox.data); if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); } @@ -1040,8 +970,7 @@ void CmndTopic(void) ResponseCmndChar(SettingsText(SET_MQTT_TOPIC)); } -void CmndButtonTopic(void) -{ +void CmndButtonTopic(void) { if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) { MakeValidMqtt(0, XdrvMailbox.data); if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); } @@ -1055,8 +984,7 @@ void CmndButtonTopic(void) ResponseCmndChar(SettingsText(SET_MQTT_BUTTON_TOPIC)); } -void CmndSwitchTopic(void) -{ +void CmndSwitchTopic(void) { if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) { MakeValidMqtt(0, XdrvMailbox.data); if (!strcmp(XdrvMailbox.data, TasmotaGlobal.mqtt_client)) { SetShortcutDefault(); } @@ -1070,8 +998,7 @@ void CmndSwitchTopic(void) ResponseCmndChar(SettingsText(SET_MQTT_SWITCH_TOPIC)); } -void CmndButtonRetain(void) -{ +void CmndButtonRetain(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { if (!XdrvMailbox.payload) { for (uint32_t i = 1; i <= MAX_KEYS; i++) { @@ -1083,8 +1010,7 @@ void CmndButtonRetain(void) ResponseCmndStateText(Settings.flag.mqtt_button_retain); // CMND_BUTTONRETAIN } -void CmndSwitchRetain(void) -{ +void CmndSwitchRetain(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { if (!XdrvMailbox.payload) { for (uint32_t i = 1; i <= MAX_SWITCHES; i++) { @@ -1096,8 +1022,7 @@ void CmndSwitchRetain(void) ResponseCmndStateText(Settings.flag.mqtt_switch_retain); // CMND_SWITCHRETAIN } -void CmndPowerRetain(void) -{ +void CmndPowerRetain(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { if (!XdrvMailbox.payload) { char stemp1[TOPSZ]; @@ -1116,8 +1041,7 @@ void CmndPowerRetain(void) ResponseCmndStateText(Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN } -void CmndSensorRetain(void) -{ +void CmndSensorRetain(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { if (!XdrvMailbox.payload) { ResponseClear(); From 9baa1bd9f47664bfefb7f0e00f4147e1f078c096 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Dec 2020 14:51:24 +0100 Subject: [PATCH 006/105] Remove obsolete switch timer re-arm code Remove obsolete switch timer re-arm code possibly attributing to watch dog restarts (#10237) --- tasmota/support_switch.ino | 136 +++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 72 deletions(-) diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index 5e10796ea..36dc2bb39 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -25,8 +25,8 @@ * Inspired by (https://github.com/OLIMEX/olimex-iot-firmware-esp8266/blob/master/olimex/user/user_switch2.c) \*********************************************************************************************/ -const uint8_t SWITCH_PROBE_INTERVAL = 10; // Time in milliseconds between switch input probe -const uint8_t SWITCH_FAST_PROBE_INTERVAL =2;// Time in milliseconds between switch input probe for AC detection +const uint8_t SWITCH_PROBE_INTERVAL = 10; // Time in milliseconds between switch input probe +const uint8_t SWITCH_FAST_PROBE_INTERVAL = 2; // Time in milliseconds between switch input probe for AC detection const uint8_t AC_PERIOD = (20 + SWITCH_FAST_PROBE_INTERVAL - 1) / SWITCH_FAST_PROBE_INTERVAL; // Duration of an AC wave in probe intervals // Switch Mode definietions @@ -89,7 +89,6 @@ void SwitchProbe(void) { if (TasmotaGlobal.uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit uint32_t state_filter; - uint32_t switch_probe_interval; uint32_t first_change = Switch.first_change; uint32_t debounce_flags = Settings.switch_debounce % 10; bool force_high = (debounce_flags &1); // 51, 101, 151 etc @@ -97,7 +96,6 @@ void SwitchProbe(void) { bool ac_detect = (debounce_flags == 9); if (ac_detect) { - switch_probe_interval = SWITCH_FAST_PROBE_INTERVAL; if (Settings.switch_debounce < 2 * AC_PERIOD * SWITCH_FAST_PROBE_INTERVAL + 9) { state_filter = 2 * AC_PERIOD; } else if (Settings.switch_debounce > (0x7f - 2 * AC_PERIOD) * SWITCH_FAST_PROBE_INTERVAL) { @@ -106,89 +104,87 @@ void SwitchProbe(void) { state_filter = (Settings.switch_debounce - 9) / SWITCH_FAST_PROBE_INTERVAL; } } else { - switch_probe_interval = SWITCH_PROBE_INTERVAL; state_filter = Settings.switch_debounce / SWITCH_PROBE_INTERVAL; // 5, 10, 15 } for (uint32_t i = 0; i < MAX_SWITCHES; i++) { - if (PinUsed(GPIO_SWT1, i)) { - // Olimex user_switch2.c code to fix 50Hz induced pulses - if (1 == digitalRead(Pin(GPIO_SWT1, i))) { + if (!PinUsed(GPIO_SWT1, i)) { continue; } - if (ac_detect) { // Enabled with SwitchDebounce x9 - Switch.state[i] |= 0x80; - if (Switch.state[i] > 0x80) { - Switch.state[i]--; - if (0x80 == Switch.state[i]) { - Switch.virtual_state[i] = 0; + // Olimex user_switch2.c code to fix 50Hz induced pulses + if (1 == digitalRead(Pin(GPIO_SWT1, i))) { + + if (ac_detect) { // Enabled with SwitchDebounce x9 + Switch.state[i] |= 0x80; + if (Switch.state[i] > 0x80) { + Switch.state[i]--; + if (0x80 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + Switch.first_change = false; + } + } + } else { + + if (force_high) { // Enabled with SwitchDebounce x1 + if (1 == Switch.virtual_state[i]) { + Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 + } + } + + if (Switch.state[i] < state_filter) { + Switch.state[i]++; + if (state_filter == Switch.state[i]) { + Switch.virtual_state[i] = 1; + } + } + } + } else { + + if (ac_detect) { // Enabled with SwitchDebounce x9 + /* + * Moes MS-104B and similar devices using an AC detection circuitry + * on their switch inputs generating an ~4 ms long low pulse every + * AC wave. We start the time measurement on the falling edge. + * + * state: bit7: previous state, bit6..0: counter + */ + if (Switch.state[i] & 0x80) { + Switch.state[i] &= 0x7f; + if (Switch.state[i] < state_filter - 2 * AC_PERIOD) { + Switch.state[i] += 2 * AC_PERIOD; + } else { + Switch.state[i] = state_filter; + Switch.virtual_state[i] = 1; + if (first_change) { + Switch.last_state[i] = 1; Switch.first_change = false; } } } else { - - if (force_high) { // Enabled with SwitchDebounce x1 - if (1 == Switch.virtual_state[i]) { - Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 - } - } - - if (Switch.state[i] < state_filter) { - Switch.state[i]++; - if (state_filter == Switch.state[i]) { - Switch.virtual_state[i] = 1; + if (Switch.state[i] > 0x00) { + Switch.state[i]--; + if (0x00 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + Switch.first_change = false; } } } } else { - if (ac_detect) { // Enabled with SwitchDebounce x9 - /* - * Moes MS-104B and similar devices using an AC detection circuitry - * on their switch inputs generating an ~4 ms long low pulse every - * AC wave. We start the time measurement on the falling edge. - * - * state: bit7: previous state, bit6..0: counter - */ - if (Switch.state[i] & 0x80) { - Switch.state[i] &= 0x7f; - if (Switch.state[i] < state_filter - 2 * AC_PERIOD) { - Switch.state[i] += 2 * AC_PERIOD; - } else { - Switch.state[i] = state_filter; - Switch.virtual_state[i] = 1; - if (first_change) { - Switch.last_state[i] = 1; - Switch.first_change = false; - } - } - } else { - if (Switch.state[i] > 0x00) { - Switch.state[i]--; - if (0x00 == Switch.state[i]) { - Switch.virtual_state[i] = 0; - Switch.first_change = false; - } - } + if (force_low) { // Enabled with SwitchDebounce x2 + if (0 == Switch.virtual_state[i]) { + Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 } - } else { + } - if (force_low) { // Enabled with SwitchDebounce x2 - if (0 == Switch.virtual_state[i]) { - Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 - } - } - - if (Switch.state[i] > 0) { - Switch.state[i]--; - if (0 == Switch.state[i]) { - Switch.virtual_state[i] = 0; - } + if (Switch.state[i] > 0) { + Switch.state[i]--; + if (0 == Switch.state[i]) { + Switch.virtual_state[i] = 0; } } } } } - TickerSwitch.attach_ms(switch_probe_interval, SwitchProbe); // Re-arm as core 2.3.0 does only support ONCE mode } void SwitchInit(void) { @@ -215,12 +211,8 @@ void SwitchInit(void) { Switch.virtual_state[i] = Switch.last_state[i]; } if (Switch.present) { - if (ac_detect) { - TickerSwitch.attach_ms(SWITCH_FAST_PROBE_INTERVAL, SwitchProbe); - Switch.first_change = true; - } else { - TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); - } + Switch.first_change = true; + TickerSwitch.attach_ms((ac_detect) ? SWITCH_FAST_PROBE_INTERVAL : SWITCH_PROBE_INTERVAL, SwitchProbe); } } From 8d6f8f505faf03415347967baf39844978fa0585 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 26 Dec 2020 15:12:46 +0100 Subject: [PATCH 007/105] Change once tickers --- tasmota/support_udp.ino | 6 +++--- tasmota/tasmota_globals.h | 3 +++ tasmota/xdrv_20_hue.ino | 1 - tasmota/xdrv_21_wemo.ino | 3 +-- tasmota/xdrv_21_wemo_multi.ino | 2 -- tasmota/xlgt_05_sonoff_l1.ino | 3 +-- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino index d430374e5..f83788a59 100644 --- a/tasmota/support_udp.ino +++ b/tasmota/support_udp.ino @@ -158,13 +158,13 @@ void PollUdp(void) #ifdef USE_EMULATION_WEMO if (EMUL_WEMO == Settings.flag2.emulation) { if (strstr_P(packet_buffer, URN_BELKIN_DEVICE) != nullptr) { // type1 echo dot 2g, echo 1g's - TickerMSearch.attach_ms(response_delay, WemoRespondToMSearch, 1); + TickerMSearch.once_ms(response_delay, WemoRespondToMSearch, 1); return; } else if ((strstr_P(packet_buffer, UPNP_ROOTDEVICE) != nullptr) || // type2 Echo 2g (echo & echo plus) (strstr_P(packet_buffer, SSDPSEARCH_ALL) != nullptr) || (strstr_P(packet_buffer, SSDP_ALL) != nullptr)) { - TickerMSearch.attach_ms(response_delay, WemoRespondToMSearch, 2); + TickerMSearch.once_ms(response_delay, WemoRespondToMSearch, 2); return; } } @@ -176,7 +176,7 @@ void PollUdp(void) (strstr_P(packet_buffer, UPNP_ROOTDEVICE) != nullptr) || (strstr_P(packet_buffer, SSDPSEARCH_ALL) != nullptr) || (strstr_P(packet_buffer, SSDP_ALL) != nullptr)) { - TickerMSearch.attach_ms(response_delay, HueRespondToMSearch); + TickerMSearch.once_ms(response_delay, HueRespondToMSearch); return; } } diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 8dbdb2073..7ef12bb8d 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -164,6 +164,9 @@ String EthernetMacAddress(void); #endif #ifdef USE_ZIGBEE #define USE_UNISHOX_COMPRESSION // Add support for string compression +#endif +#ifdef USE_EMULATION_HUE +#define USE_UNISHOX_COMPRESSION // Add support for string compression #endif // See https://github.com/esp8266/Arduino/pull/4889 diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index 87557c997..e7289af7f 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -80,7 +80,6 @@ void HueRespondToMSearch(void) { char message[TOPSZ]; - TickerMSearch.detach(); if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) { char response[320]; snprintf_P(response, sizeof(response), HUE_RESPONSE, WiFi.localIP().toString().c_str(), HueBridgeId().c_str()); diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index af5d7f176..b63c89e89 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -17,7 +17,7 @@ along with this program. If not, see . */ -#if defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined (USE_EMULATION_WEMO_SINGLE) +#if defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_WEMO_SINGLE) /*********************************************************************************************\ * Belkin WeMo emulation \*********************************************************************************************/ @@ -58,7 +58,6 @@ void WemoRespondToMSearch(int echo_type) { char message[TOPSZ]; - TickerMSearch.detach(); if (PortUdp.beginPacket(udp_remote_ip, udp_remote_port)) { char type[24]; if (1 == echo_type) { // type1 echo 1g & dot 2g diff --git a/tasmota/xdrv_21_wemo_multi.ino b/tasmota/xdrv_21_wemo_multi.ino index 7806b2999..09c05b718 100644 --- a/tasmota/xdrv_21_wemo_multi.ino +++ b/tasmota/xdrv_21_wemo_multi.ino @@ -419,8 +419,6 @@ WemoSwitch *wemoDevice[MAX_FRIENDLYNAMES] = {}; int numOfWemoSwitch = 0; void WemoRespondToMSearch(int echo_type) { - TickerMSearch.detach(); - for (uint32_t i = 0; i < numOfWemoSwitch; i++) { wemoDevice[i]->WemoRespondToMSearch(echo_type); } diff --git a/tasmota/xlgt_05_sonoff_l1.ino b/tasmota/xlgt_05_sonoff_l1.ino index 38f9a3000..fa13765b2 100644 --- a/tasmota/xlgt_05_sonoff_l1.ino +++ b/tasmota/xlgt_05_sonoff_l1.ino @@ -64,7 +64,6 @@ struct SNFL1 { Ticker SnfL1StartDelay; void SnfL1SendDelayed(void) { - SnfL1StartDelay.detach(); SnfL1Send(); } @@ -276,7 +275,7 @@ bool SnfL1SetChannels(void) static bool first_call = true; if (first_call) { - SnfL1StartDelay.attach_ms(900, SnfL1SendDelayed); // Allow startup time for Nuvotron microcontroller + SnfL1StartDelay.once_ms(900, SnfL1SendDelayed); // Allow startup time for Nuvotron microcontroller first_call = false; } else { SnfL1Send(); From f4268cad154ab6c94ae324c21aa6975884a57001 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 26 Dec 2020 19:45:06 +0100 Subject: [PATCH 008/105] Add ``IR_RCV_WHILE_SENDING`` compile time option to revert #10041 --- tasmota/my_user_config.h | 1 + tasmota/xdrv_05_irremote.ino | 12 +++++++++--- tasmota/xdrv_05_irremote_full.ino | 30 ++++++++++++++++++------------ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 2cd7f6229..e75f54ee5 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -725,6 +725,7 @@ #define IR_RCV_BUFFER_SIZE 100 // Max number of packets allowed in capture buffer (default 100 (*2 bytes ram)) #define IR_RCV_TIMEOUT 15 // Number of milli-Seconds of no-more-data before we consider a message ended (default 15) #define IR_RCV_MIN_UNKNOWN_SIZE 6 // Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255) + #define IR_RCV_WHILE_SENDING 0 // Turns on receiver while sending messages, i.e. receive your own. This is unreliable and can cause IR timing issues // -- Zigbee interface ---------------------------- //#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+49k code, +3k mem) diff --git a/tasmota/xdrv_05_irremote.ino b/tasmota/xdrv_05_irremote.ino index 6e3bad365..881ce62bf 100644 --- a/tasmota/xdrv_05_irremote.ino +++ b/tasmota/xdrv_05_irremote.ino @@ -62,6 +62,12 @@ def ir_expand(ir_compact): #include #include +// Receiving IR while sending at the same time (i.e. receiving your own signal) was dsiabled in #10041 +// At the demand of @pilaGit, you can `#define IR_RCV_WHILE_SENDING 1` to bring back this behavior +#ifndef IR_RCV_WHILE_SENDING +#define IR_RCV_WHILE_SENDING 0 +#endif + enum IrErrors { IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_PROTO_UNSUPPORTED }; const char kIrRemoteCommands[] PROGMEM = "|" D_CMND_IRSEND ; @@ -291,7 +297,7 @@ uint32_t IrRemoteCmndIrSendJson(void) protocol_text, protocol, bits, ulltoa(data, dvalue, 10), Uint64toHex(data, hvalue, bits), repeat, protocol_code); #ifdef USE_IR_RECEIVE - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } #endif // USE_IR_RECEIVE switch (protocol_code) { // Equals IRremoteESP8266.h enum decode_type_t @@ -309,12 +315,12 @@ uint32_t IrRemoteCmndIrSendJson(void) #endif default: #ifdef USE_IR_RECEIVE - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } #endif // USE_IR_RECEIVE return IE_PROTO_UNSUPPORTED; } #ifdef USE_IR_RECEIVE - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } #endif // USE_IR_RECEIVE return IE_NO_ERROR; diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index ce75d09db..9c62e0fca 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -65,6 +65,12 @@ def ir_expand(ir_compact): #include #include +// Receiving IR while sending at the same time (i.e. receiving your own signal) was dsiabled in #10041 +// At the demand of @pilaGit, you can `#define IR_RCV_WHILE_SENDING 1` to bring back this behavior +#ifndef IR_RCV_WHILE_SENDING +#define IR_RCV_WHILE_SENDING 0 +#endif + enum IrErrors { IE_RESPONSE_PROVIDED, IE_NO_ERROR, IE_INVALID_RAWDATA, IE_INVALID_JSON, IE_SYNTAX_IRSEND, IE_SYNTAX_IRHVAC, IE_UNSUPPORTED_HVAC, IE_UNSUPPORTED_PROTOCOL, IE_MEMORY }; @@ -462,7 +468,7 @@ uint32_t IrRemoteCmndIrHvacJson(void) state.sleep = root.getInt(PSTR(D_JSON_IRHVAC_SLEEP), state.sleep); //if (json[D_JSON_IRHVAC_CLOCK]) { state.clock = json[D_JSON_IRHVAC_CLOCK]; } // not sure it's useful to support 'clock' - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } if (stateMode == StateModes::SEND_ONLY || stateMode == StateModes::SEND_STORE) { IRac ac(Pin(GPIO_IRSEND)); bool success = ac.sendAc(state, irhvac_stateful && irac_prev_state.protocol == state.protocol ? &irac_prev_state : nullptr); @@ -471,7 +477,7 @@ uint32_t IrRemoteCmndIrHvacJson(void) if (stateMode == StateModes::STORE_ONLY || stateMode == StateModes::SEND_STORE) { // store state in memory irac_prev_state = state; } - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); Response_P(PSTR("{\"" D_CMND_IRHVAC "\":%s}"), sendACJsonState(state).c_str()); return IE_RESPONSE_PROVIDED; @@ -529,9 +535,9 @@ uint32_t IrRemoteCmndIrSendJson(void) // AddLog_P(LOG_LEVEL_DEBUG, PSTR("IRS: protocol %d, bits %d, data 0x%s (%s), repeat %d"), // protocol, bits, ulltoa(data, dvalue, 10), Uint64toHex(data, hvalue, bits), repeat); - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } bool success = irsend->send(protocol, data, bits, repeat); - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } if (!success) { ResponseCmndChar(D_JSON_PROTOCOL_NOT_SUPPORTED); @@ -554,11 +560,11 @@ uint32_t IrRemoteSendGC(char ** pp, uint32_t count, uint32_t repeat) { GC[i] = strtol(strtok_r(nullptr, ",", pp), nullptr, 0); if (!GC[i]) { return IE_INVALID_RAWDATA; } } - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } for (uint32_t r = 0; r <= repeat; r++) { irsend->sendGC(GC, count+1); } - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } return IE_NO_ERROR; } @@ -609,7 +615,7 @@ uint32_t IrRemoteSendRawFormatted(char ** pp, uint32_t count, uint32_t repeat) { raw_array[i++] = mark; // Mark } } - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } for (uint32_t r = 0; r <= repeat; r++) { // AddLog_P(LOG_LEVEL_DEBUG, PSTR("sendRaw count=%d, space=%d, mark=%d, freq=%d"), count, space, mark, freq); irsend->sendRaw(raw_array, i, freq); @@ -617,7 +623,7 @@ uint32_t IrRemoteSendRawFormatted(char ** pp, uint32_t count, uint32_t repeat) { irsend->space(40000); // since we don't know the inter-message gap, place an arbitrary 40ms gap } } - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } } else if (6 == count) { // NEC Protocol // IRsend raw,0,8620,4260,544,411,1496,010101101000111011001110000000001100110000000001100000000000000010001100 uint16_t raw_array[strlen(*pp)*2+3]; // Header + bits + end @@ -636,7 +642,7 @@ uint32_t IrRemoteSendRawFormatted(char ** pp, uint32_t count, uint32_t repeat) { } } raw_array[i++] = parm[2]; // Trailing mark - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } for (uint32_t r = 0; r <= repeat; r++) { // AddLog_P(LOG_LEVEL_DEBUG, PSTR("sendRaw %d %d %d %d %d %d"), raw_array[0], raw_array[1], raw_array[2], raw_array[3], raw_array[4], raw_array[5]); irsend->sendRaw(raw_array, i, freq); @@ -644,7 +650,7 @@ uint32_t IrRemoteSendRawFormatted(char ** pp, uint32_t count, uint32_t repeat) { irsend->space(inter_message); // since we don't know the inter-message gap, place an arbitrary 40ms gap } } - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } } else { return IE_INVALID_RAWDATA; } // Invalid number of parameters return IE_NO_ERROR; @@ -713,11 +719,11 @@ uint32_t IrRemoteSendRawStandard(char ** pp, uint16_t freq, uint32_t count, uint // AddLog_P(LOG_LEVEL_DEBUG, PSTR("Arr %d %d %d %d %d %d %d %d"), arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7]); if (0 == count) { return IE_INVALID_RAWDATA; } - if (irrecv != nullptr) { irrecv->disableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } for (uint32_t r = 0; r <= repeat; r++) { irsend->sendRaw(arr, count, freq); } - if (irrecv != nullptr) { irrecv->enableIRIn(); } + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } if (nullptr != arr) { free(arr); From 76a4dfb1c17b32ea106c03fd0ba1c062e1c4ca3a Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 26 Dec 2020 19:53:25 +0100 Subject: [PATCH 009/105] Fixing fat fingers --- tasmota/xdrv_05_irremote_full.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 9c62e0fca..31dd22968 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -477,7 +477,7 @@ uint32_t IrRemoteCmndIrHvacJson(void) if (stateMode == StateModes::STORE_ONLY || stateMode == StateModes::SEND_STORE) { // store state in memory irac_prev_state = state; } - if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); + if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->enableIRIn(); } Response_P(PSTR("{\"" D_CMND_IRHVAC "\":%s}"), sendACJsonState(state).c_str()); return IE_RESPONSE_PROVIDED; From 01ad0510a1113743fcc064d76de358fbf849d345 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Sun, 27 Dec 2020 10:51:29 +0100 Subject: [PATCH 010/105] Fix problem of config loss Sometimes the deepsleep loop is too fast and causes a config reset. Fixed --- tasmota/xdrv_29_deepsleep.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index 6b6492f1a..43ad54c6b 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -142,6 +142,7 @@ void DeepSleepStart(void) WifiShutdown(); RtcSettings.ultradeepsleep = RtcSettings.nextwakeup - UtcTime(); RtcSettingsSave(); + RtcRebootReset(); #ifdef ESP8266 ESP.deepSleep(100 * RtcSettings.deepsleep_slip * deepsleep_sleeptime); #endif // ESP8266 From 51d39798d49c046727bf3c189a4481e49196008e Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 27 Dec 2020 14:13:23 +0100 Subject: [PATCH 011/105] Reduce tasmota-minmal Making `WebColor` and `Template` commands read-only Saves 4kb on tasmota-minimal. No changes for other versions. --- tasmota/support_command.ino | 4 +++- tasmota/xdrv_01_webserver.ino | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index a226f8312..34a3bd2e3 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1284,12 +1284,14 @@ void CmndTemplate(void) } } else { - if (JsonTemplate(XdrvMailbox.data)) { // Free 336 bytes StaticJsonBuffer stack space by moving code to function +#ifndef FIRMWARE_MINIMAL // if tasmota-minimal, `Template` is read-only + if (JsonTemplate(XdrvMailbox.data)) { if (USER_MODULE == Settings.module) { TasmotaGlobal.restart_flag = 2; } } else { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); error = true; } +#endif // FIRMWARE_MINIMAL } if (!error) { TemplateJson(); } } diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 1deb269d0..243ab46d5 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -3401,7 +3401,9 @@ void CmndWebColor(void) } } else { +#ifndef FIRMWARE_MINIMAL // if tasmota-minimal, read only and don't parse JSON JsonWebColor(XdrvMailbox.data); +#endif // FIRMWARE_MINIMAL } } Response_P(PSTR("{\"" D_CMND_WEBCOLOR "\":[")); From 496302b442fdc063ef30ba7ac633530a352ca37e Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 15:19:42 +0100 Subject: [PATCH 012/105] African language file --- tasmota/language/af-AF.h | 932 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 932 insertions(+) create mode 100644 tasmota/language/af-AF.h diff --git a/tasmota/language/af-AF.h b/tasmota/language/af-AF.h new file mode 100644 index 000000000..9150e2c38 --- /dev/null +++ b/tasmota/language/af-AF.h @@ -0,0 +1,932 @@ +/* + af-AF.h - localization for Afrikaans - Afrikaans for Tasmota + + Copyright (C) 2020 Christiaan Heerze + + 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 . +*/ + +#ifndef _LANGUAGE_EN_GB_H_ +#define _LANGUAGE_EN_GB_H_ + +/*************************** ATTENTION *******************************\ + * + * Due to memory constraints only UTF-8 is supported. + * To save code space keep text as short as possible. + * Time and Date provided by SDK can not be localized (yet). + * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. + * Use online command Prefix to translate cmnd, stat and tele. + * + * Updated until v9.2.1.0 +\*********************************************************************/ + +//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) +// https://www.science.co.il/language/Locale-codes.php +#define LANGUAGE_LCID 2057 +// HTML (ISO 639-1) Language Code +#define D_HTML_LANGUAGE "af" + +// "2017-03-07T11:08:02" - ISO8601:2004 +#define D_YEAR_MONTH_SEPARATOR "-" +#define D_MONTH_DAY_SEPARATOR "-" +#define D_DATE_TIME_SEPARATOR "T" +#define D_HOUR_MINUTE_SEPARATOR ":" +#define D_MINUTE_SECOND_SEPARATOR ":" + +#define D_DAY3LIST "SonMaaDinWoeDonVryDonSat" +#define D_MONTH3LIST "JanFebMaaAprMeiJunJulAugSepOktNovDes" + +// Non JSON decimal separator +#define D_DECIMAL_SEPARATOR "." + +// Common +#define D_ADMIN "Admin" +#define D_AIR_QUALITY "Luggehalte" +#define D_AP "AP" // Access Point +#define D_AS "as" +#define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery +#define D_BLINK "Flits" +#define D_BLINKOFF "FlitsAf" +#define D_BOOT_COUNT "Opstarttelling" +#define D_BRIGHTLIGHT "Helder" +#define D_BSSID "BSSId" +#define D_BUTTON "Knoppie" +#define D_BY "deur" // Written by me +#define D_BYTES "Bytes" +#define D_CELSIUS "Celsius" +#define D_CHANNEL "Kanaal" +#define D_CO2 "Koolstofdioksied" +#define D_CODE "kode" // Button code +#define D_COLDLIGHT "Koud" +#define D_COMMAND "Bevel" +#define D_CONNECTED "Gekoppel" +#define D_CORS_DOMAIN "CORS Domain" +#define D_COUNT "Telling" +#define D_COUNTER "Opnemer" +#define D_CT_POWER "CT Power" +#define D_CURRENT "Stroom" // As in Voltage and Current +#define D_DATA "Data" +#define D_DARKLIGHT "Donker" +#define D_DEBUG "Ontfout" +#define D_DEWPOINT "Dou punt" +#define D_DISABLED "Gedeaktiveer" +#define D_DISTANCE "Afstand" +#define D_DNS_SERVER "DNS" +#define D_DO "Opgeloste suurstof" +#define D_DONE "Klaar" +#define D_DST_TIME "DST" +#define D_EC "EC" +#define D_ECO2 "eCO₂" +#define D_EMULATION "Emulasie" +#define D_ENABLED "Geaktiveer" +#define D_ERASE "Vee uit" +#define D_ERROR "Fout" +#define D_FAHRENHEIT "Fahrenheit" +#define D_FAILED "Misluk " +#define D_FALLBACK "Terugval" +#define D_FALLBACK_TOPIC "Terugval onderwerp" +#define D_FALSE "Onwaar" +#define D_FILE "Lêer" +#define D_FLOW_RATE "Vloeitempo" +#define D_FREE_MEMORY "Vrye geheue" +#define D_PSR_MAX_MEMORY "PS-RAM geheue" +#define D_PSR_FREE_MEMORY "PS-RAM vrye geheue" +#define D_FREQUENCY "Frekwensie" +#define D_GAS "Gas" +#define D_GATEWAY "Gateway" +#define D_GROUP "Groep" +#define D_HOST "Gasheer" +#define D_HOSTNAME "Gasheername" +#define D_HUMIDITY "Humiditeit" +#define D_IMMEDIATE "onmiddellik" // Button immediate +#define D_INDEX "Indeks" +#define D_INFO "Inligting" +#define D_INFRARED "Infrarooi" +#define D_INITIALIZED "Geïnisialiseer" +#define D_IP_ADDRESS "IP-adresse" +#define D_LIGHT "Lig" +#define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index +#define D_MODULE "Module" +#define D_MOISTURE "Vog" +#define D_MQTT "MQTT" +#define D_MULTI_PRESS "multi-press" +#define D_NOISE "Geraas" +#define D_NONE "Geen" +#define D_O2 "Suurstof" +#define D_OFF "Uit" +#define D_OFFLINE "Vanlyn" +#define D_OK "Ok" +#define D_ON "aan" +#define D_ONLINE "Aanlyn" +#define D_ORP "ORP" +#define D_PASSWORD "Wagwoord" +#define D_PH "pH" +#define D_PORT "Poort" +#define D_POWER_FACTOR "Krag faktor" +#define D_POWERUSAGE "Krag" +#define D_POWERUSAGE_ACTIVE "Regte krag" +#define D_POWERUSAGE_APPARENT "Oënskynlike krag" +#define D_POWERUSAGE_REACTIVE "reaktiewe krag" +#define D_PRESSURE "Druk" +#define D_PRESSUREATSEALEVEL "Druk op seevlak" +#define D_PROGRAM_FLASH_SIZE "Program Flash Grootte" +#define D_PROGRAM_SIZE "Program Grootte" +#define D_PROJECT "Projek" +#define D_RAIN "Reën" +#define D_RANGE "Gebied" +#define D_RECEIVED "Ontvang" +#define D_RESTART "Herbegin" +#define D_RESTARTING "Herbegin" +#define D_RESTART_REASON "Herlaai rede" +#define D_RESTORE "herstel" +#define D_RETAINED "behou" +#define D_RULE "Reël" +#define D_SAVE "Stoor" +#define D_SENSOR "Sensor" +#define D_SSID "SSId" +#define D_START "Begin" +#define D_STD_TIME "STD" +#define D_STOP "Stop" +#define D_SUBNET_MASK "Subnet Masker" +#define D_SUBSCRIBE_TO "Teken in op" +#define D_UNSUBSCRIBE_FROM "Teken uit van" +#define D_SUCCESSFUL "Suksesvol" +#define D_SUNRISE "Sonsopkoms" +#define D_SUNSET "Sononder" +#define D_TEMPERATURE "Temperatuur" +#define D_TO "naar" +#define D_TOGGLE "Verwissel" +#define D_TOPIC "Onderwerp" +#define D_TOTAL_USAGE "Totale gebruik" +#define D_TRANSMIT "Stuur" +#define D_TRUE "Waar" +#define D_TVOC "TVOC" +#define D_UPGRADE "opgradeer" +#define D_UPLOAD "Laai op" +#define D_UPTIME "Uptyd" +#define D_USER "Gebruiker" +#define D_UTC_TIME "UTC" +#define D_UV_INDEX "UV Indeks" +#define D_UV_INDEX_1 "Laag" +#define D_UV_INDEX_2 "Middel" +#define D_UV_INDEX_3 "Hoog" +#define D_UV_INDEX_4 "Gevaarlik" +#define D_UV_INDEX_5 "1ste/2de graad sonbrand" +#define D_UV_INDEX_6 "3e graad sonbrand" +#define D_UV_INDEX_7 "Buite bereik" // Out of Range +#define D_UV_LEVEL "UV Level" +#define D_UV_POWER "UV krag" +#define D_VERSION "Weergawe" +#define D_VOLTAGE "Spanning" +#define D_VOLUME "Volume" +#define D_WEIGHT "Gewig" +#define D_WARMLIGHT "Warm" +#define D_WEB_SERVER "Webbediener" + +// tasmota.ino +#define D_WARNING_MINIMAL_VERSION "WAARSKUWING Hierdie weergawe ondersteun nie aanhoudende instellings nie" +#define D_LEVEL_10 "level 1-0" +#define D_LEVEL_01 "level 0-1" +#define D_SERIAL_LOGGING_DISABLED "Syslog-logging is uitgeskakel" +#define D_SYSLOG_LOGGING_REENABLED "Syslog-logging is weer geaktiveer" + +#define D_SET_BAUDRATE_TO "Stem Baudrate op" +#define D_RECEIVED_TOPIC "Ontvang onderwerp" +#define D_DATA_SIZE "Data grootte" +#define D_ANALOG_INPUT "Analoog" + +// support.ino +#define D_OSWATCH "osWatch" +#define D_BLOCKED_LOOP "Geblokkeerde lus" +#define D_WPS_FAILED_WITH_STATUS "WPSconfig kon nie status kry nie" +#define D_ACTIVE_FOR_3_MINUTES "3 minute aktief" +#define D_FAILED_TO_START "kon nie begin nie" +#define D_PATCH_ISSUE_2186 "Patch issue 2186" +#define D_CONNECTING_TO_AP "Koppel tans aan AP" +#define D_IN_MODE "in mode" +#define D_CONNECT_FAILED_NO_IP_ADDRESS "Kon nie verbind nie omdat geen IP-adres ontvang is nie" +#define D_CONNECT_FAILED_AP_NOT_REACHED "Kon nie verbind nie, aangesien toegang nie bereik kan word nie" +#define D_CONNECT_FAILED_WRONG_PASSWORD "Kon nie verbind nie" +#define D_CONNECT_FAILED_AP_TIMEOUT "Kon nie verbinding maak met AP-time-out nie" +#define D_ATTEMPTING_CONNECTION "Attempting connection..." +#define D_CHECKING_CONNECTION "Probeer tans verbinding ..." +#define D_QUERY_DONE "Navraag gedoen. MQTT-dienste gevind" +#define D_MQTT_SERVICE_FOUND "MQTT-diens gevind op" +#define D_FOUND_AT "gevind op" +#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nie gevind nie" + +// settings.ino +#define D_SAVED_TO_FLASH_AT "Gestoor in die flash op" +#define D_LOADED_FROM_FLASH_AT "Uit flash gelaai by" +#define D_USE_DEFAULTS "Gebruik standaardinstellings" +#define D_ERASED_SECTOR "Uitgewis sektor" + +// xdrv_02_webserver.ino +#define D_NOSCRIPT "Skakel JavaScript aan om Tasmota te gebruik" +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware
gradeer asseblief op" +#define D_WEBSERVER_ACTIVE_ON "Webbediener aktief op" +#define D_WITH_IP_ADDRESS "met IP-adres" +#define D_WEBSERVER_STOPPED "Webbediener gestop" +#define D_FILE_NOT_FOUND "Lêer nie gevind nie" +#define D_REDIRECTED "Herlei na captive portal" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager stel AccessPoint in en hou Station" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager het AccessPoint ingestel" +#define D_TRYING_TO_CONNECT "Probeer om toestel aan netwerk te koppel" + +#define D_RESTART_IN "Begin weer binne" +#define D_SECONDS "sekondes" +#define D_DEVICE_WILL_RESTART "Toestel sal binne 'n paar sekondes weer begin" +#define D_BUTTON_TOGGLE "Wissel" +#define D_CONFIGURATION "Konfigurasie" +#define D_INFORMATION "Inligting" +#define D_FIRMWARE_UPGRADE "Firmware-opgradering" +#define D_CONSOLE "Konsole" +#define D_CONFIRM_RESTART "Bevestig weer te begin" + +#define D_CONFIGURE_MODULE "Configure Module" +#define D_CONFIGURE_WIFI "Configure WiFi" +#define D_CONFIGURE_MQTT "Configure MQTT" +#define D_CONFIGURE_DOMOTICZ "Configure Domoticz" +#define D_CONFIGURE_LOGGING "Configure Logging" +#define D_CONFIGURE_OTHER "Configure Other" +#define D_CONFIRM_RESET_CONFIGURATION "Confirm Reset Configuration" +#define D_RESET_CONFIGURATION "Reset Configuration" +#define D_BACKUP_CONFIGURATION "Backup Configuration" +#define D_RESTORE_CONFIGURATION "Restore Configuration" +#define D_MAIN_MENU "Main Menu" + +#define D_MODULE_PARAMETERS "Module parameters" +#define D_MODULE_TYPE "Module type" +#define D_PULLUP_ENABLE "No Button/Switch pull-up" +#define D_ADC "ADC" +#define D_GPIO "GPIO" +#define D_SERIAL_IN "Serial In" +#define D_SERIAL_OUT "Serial Out" + +#define D_WIFI_PARAMETERS "Wifi parameters" +#define D_SCAN_FOR_WIFI_NETWORKS "Scan for wifi networks" +#define D_SCAN_DONE "Scan done" +#define D_NO_NETWORKS_FOUND "No networks found" +#define D_REFRESH_TO_SCAN_AGAIN "Refresh to scan again" +#define D_DUPLICATE_ACCESSPOINT "Duplicate AccessPoint" +#define D_SKIPPING_LOW_QUALITY "Skipping due to low quality" +#define D_RSSI "RSSI" +#define D_WEP "WEP" +#define D_WPA_PSK "WPA PSK" +#define D_WPA2_PSK "WPA2 PSK" +#define D_AP1_SSID "AP1 SSId" +#define D_AP1_PASSWORD "AP1 Password" +#define D_AP2_SSID "AP2 SSId" +#define D_AP2_PASSWORD "AP2 Password" + +#define D_MQTT_PARAMETERS "MQTT parameters" +#define D_CLIENT "Client" +#define D_FULL_TOPIC "Full Topic" + +#define D_LOGGING_PARAMETERS "Logging parameters" +#define D_SERIAL_LOG_LEVEL "Serial log level" +#define D_MQTT_LOG_LEVEL "Mqtt log level" +#define D_WEB_LOG_LEVEL "Web log level" +#define D_SYS_LOG_LEVEL "Syslog level" +#define D_MORE_DEBUG "More debug" +#define D_SYSLOG_HOST "Syslog host" +#define D_SYSLOG_PORT "Syslog port" +#define D_TELEMETRY_PERIOD "Telemetry period" + +#define D_OTHER_PARAMETERS "Other parameters" +#define D_TEMPLATE "Template" +#define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" +#define D_WEB_ADMIN_PASSWORD "Web Admin Password" +#define D_MQTT_ENABLE "MQTT enable" +#define D_MQTT_TLS_ENABLE "MQTT TLS" +#define D_FRIENDLY_NAME "Friendly Name" +#define D_BELKIN_WEMO "Belkin WeMo" +#define D_HUE_BRIDGE "Hue Bridge" +#define D_SINGLE_DEVICE "single device" +#define D_MULTI_DEVICE "multi device" + +#define D_CONFIGURE_TEMPLATE "Configure Template" +#define D_TEMPLATE_PARAMETERS "Template parameters" +#define D_TEMPLATE_NAME "Name" +#define D_BASE_TYPE "Based on" +#define D_TEMPLATE_FLAGS "Options" + +#define D_SAVE_CONFIGURATION "Save configuration" +#define D_CONFIGURATION_SAVED "Configuration saved" +#define D_CONFIGURATION_RESET "Configuration reset" + +#define D_PROGRAM_VERSION "Program Version" +#define D_BUILD_DATE_AND_TIME "Build Date & Time" +#define D_CORE_AND_SDK_VERSION "Core/SDK Version" +#define D_FLASH_WRITE_COUNT "Flash write Count" +#define D_MAC_ADDRESS "MAC Address" +#define D_MQTT_HOST "MQTT Host" +#define D_MQTT_PORT "MQTT Port" +#define D_MQTT_CLIENT "MQTT Client" +#define D_MQTT_USER "MQTT User" +#define D_MQTT_TOPIC "MQTT Topic" +#define D_MQTT_GROUP_TOPIC "MQTT Group Topic" +#define D_MQTT_FULL_TOPIC "MQTT Full Topic" +#define D_MQTT_NO_RETAIN "MQTT No Retain" +#define D_MDNS_DISCOVERY "mDNS Discovery" +#define D_MDNS_ADVERTISE "mDNS Advertise" +#define D_ESP_CHIP_ID "ESP Chip Id" +#define D_FLASH_CHIP_ID "Flash Chip Id" +#define D_FLASH_CHIP_SIZE "Flash Size" +#define D_FREE_PROGRAM_SPACE "Free Program Space" + +#define D_UPGRADE_BY_WEBSERVER "Upgrade by web server" +#define D_OTA_URL "OTA Url" +#define D_START_UPGRADE "Start upgrade" +#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade by file upload" +#define D_UPLOAD_STARTED "Upload started" +#define D_UPGRADE_STARTED "Upgrade started" +#define D_UPLOAD_DONE "Upload done" +#define D_UPLOAD_TRANSFER "Upload transfer" +#define D_TRANSFER_STARTED "Transfer started" +#define D_UPLOAD_ERR_1 "No file selected" +#define D_UPLOAD_ERR_2 "Not enough space" +#define D_UPLOAD_ERR_3 "Invalid file signature" +#define D_UPLOAD_ERR_4 "Program flash size is larger than real flash size" +#define D_UPLOAD_ERR_5 "Upload buffer miscompare" +#define D_UPLOAD_ERR_6 "Upload failed. Enable logging 3" +#define D_UPLOAD_ERR_7 "Upload aborted" +#define D_UPLOAD_ERR_8 "File invalid" +#define D_UPLOAD_ERR_9 "File too large" +#define D_UPLOAD_ERR_10 "Failed to init RF chip" +#define D_UPLOAD_ERR_11 "Failed to erase RF chip" +#define D_UPLOAD_ERR_12 "Failed to write to RF chip" +#define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_14 "Not compatible" +#define D_UPLOAD_ERROR_CODE "Upload error code" + +#define D_ENTER_COMMAND "Enter command" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected" +#define D_NEED_USER_AND_PASSWORD "Need user=&password=" + +// xdrv_01_mqtt.ino +#define D_FINGERPRINT "Verify TLS fingerprint..." +#define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to" +#define D_RETRY_IN "Retry in" +#define D_VERIFIED "Verified using Fingerprint" +#define D_INSECURE "Insecure connection due to invalid Fingerprint" +#define D_CONNECT_FAILED_TO "Connect failed to" + +// xplg_wemohue.ino +#define D_MULTICAST_DISABLED "Multicast disabled" +#define D_MULTICAST_REJOINED "Multicast (re)joined" +#define D_MULTICAST_JOIN_FAILED "Multicast join failed" +#define D_FAILED_TO_SEND_RESPONSE "Failed to send response" + +#define D_WEMO "WeMo" +#define D_WEMO_BASIC_EVENT "WeMo basic event" +#define D_WEMO_EVENT_SERVICE "WeMo event service" +#define D_WEMO_META_SERVICE "WeMo meta service" +#define D_WEMO_SETUP "WeMo setup" +#define D_RESPONSE_SENT "Response sent" + +#define D_HUE "Hue" +#define D_HUE_BRIDGE_SETUP "Hue setup" +#define D_HUE_API_NOT_IMPLEMENTED "Hue API not implemented" +#define D_HUE_API "Hue API" +#define D_HUE_POST_ARGS "Hue POST args" +#define D_3_RESPONSE_PACKETS_SENT "3 response packets sent" + +// xdrv_07_domoticz.ino +#define D_DOMOTICZ_PARAMETERS "Domoticz parameters" +#define D_DOMOTICZ_IDX "Idx" +#define D_DOMOTICZ_KEY_IDX "Key idx" +#define D_DOMOTICZ_SWITCH_IDX "Switch idx" +#define D_DOMOTICZ_SENSOR_IDX "Sensor idx" + #define D_DOMOTICZ_TEMP "Temp" + #define D_DOMOTICZ_TEMP_HUM "Temp,Hum" + #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" + #define D_DOMOTICZ_POWER_ENERGY "Power,Energy" + #define D_DOMOTICZ_ILLUMINANCE "Illuminance" + #define D_DOMOTICZ_COUNT "Count/PM1" + #define D_DOMOTICZ_VOLTAGE "Voltage/PM2.5" + #define D_DOMOTICZ_CURRENT "Current/PM10" + #define D_DOMOTICZ_AIRQUALITY "AirQuality" + #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" +#define D_DOMOTICZ_UPDATE_TIMER "Update timer" + +// xdrv_09_timers.ino +#define D_CONFIGURE_TIMER "Configure Timer" +#define D_TIMER_PARAMETERS "Timer parameters" +#define D_TIMER_ENABLE "Enable Timers" +#define D_TIMER_ARM "Enable" +#define D_TIMER_TIME "Time" +#define D_TIMER_DAYS "Days" +#define D_TIMER_REPEAT "Repeat" +#define D_TIMER_OUTPUT "Output" +#define D_TIMER_ACTION "Action" + +// xdrv_10_knx.ino +#define D_CONFIGURE_KNX "Configure KNX" +#define D_KNX_PARAMETERS "KNX Parameters" +#define D_KNX_GENERAL_CONFIG "General" +#define D_KNX_PHYSICAL_ADDRESS "Physical Address" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Must be unique on the KNX network )" +#define D_KNX_ENABLE "Enable KNX" +#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data to Send to Group Addresses" +#define D_ADD "Add" +#define D_DELETE "Delete" +#define D_REPLY "Reply" +#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from" +#define D_RECEIVED_FROM "Received from" +#define D_KNX_COMMAND_WRITE "Write" +#define D_KNX_COMMAND_READ "Read" +#define D_KNX_COMMAND_OTHER "Other" +#define D_SENT_TO "sent to" +#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." +#define D_KNX_ENHANCEMENT "Communication Enhancement" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" + +// xdrv_23_zigbee +#define D_ZIGBEE_PERMITJOIN_ACTIVE "Devices allowed to join" +#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee Mapping" +#define D_ZIGBEE_NOT_STARTED "Zigbee not started" +#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Mapping in progress (%d s. remaining)" +#define D_ZIGBEE_MAPPING_NOT_PRESENT "No mapping" +#define D_ZIGBEE_MAP_REFRESH "Zigbee Map Refresh" +#define D_ZIGBEE_MAP "Zigbee Map" +#define D_ZIGBEE_PERMITJOIN "Zigbee Permit Join" +#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key" +#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device" +#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute" +#define D_ZIGBEE_INVALID_PARAM "Invalid parameter" +#define D_ZIGBEE_MISSING_PARAM "Missing parameters" +#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s" +#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command" +#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload" +#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s" +#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)" +#define D_ZIGBEE_NO_ATTRIBUTE "No attribute in list" +#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Unsupported attribute type" +#define D_ZIGBEE_JSON_REQUIRED "Config requires JSON objects" +#define D_ZIGBEE_RESET_1_OR_2 "1 or 2 to reset" +#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address" +#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'" + +// xdrv_03_energy.ino +#define D_ENERGY_TODAY "Energy Today" +#define D_ENERGY_YESTERDAY "Energy Yesterday" +#define D_ENERGY_TOTAL "Energy Total" + +// xdrv_27_shutter.ino +#define D_OPEN "Open" +#define D_CLOSE "Close" +#define D_DOMOTICZ_SHUTTER "Shutter" + +// xdrv_28_pcf8574.ino +#define D_CONFIGURE_PCF8574 "Configure PCF8574" +#define D_PCF8574_PARAMETERS "PCF8574 parameters" +#define D_INVERT_PORTS "Invert Ports" +#define D_DEVICE "Device" +#define D_DEVICE_INPUT "Input" +#define D_DEVICE_OUTPUT "Output" + +// xsns_05_ds18b20.ino +#define D_SENSOR_BUSY "Sensor busy" +#define D_SENSOR_CRC_ERROR "Sensor CRC error" +#define D_SENSORS_FOUND "Sensors found" + +// xsns_06_dht.ino +#define D_TIMEOUT_WAITING_FOR "Timeout waiting for" +#define D_START_SIGNAL_LOW "start signal low" +#define D_START_SIGNAL_HIGH "start signal high" +#define D_PULSE "pulse" +#define D_CHECKSUM_FAILURE "Checksum failure" + +// xsns_07_sht1x.ino +#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor did not ACK command" +#define D_SHT1X_FOUND "SHT1X found" + +// xsns_18_pms5003.ino +#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter +#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter +#define D_PARTICALS_BEYOND "Particles" + +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + +// xsns_32_mpu6050.ino +#define D_AX_AXIS "Accel. X-Axis" +#define D_AY_AXIS "Accel. Y-Axis" +#define D_AZ_AXIS "Accel. Z-Axis" +#define D_GX_AXIS "Gyro X-Axis" +#define D_GY_AXIS "Gyro Y-Axis" +#define D_GZ_AXIS "Gyro Z-Axis" + +// xsns_34_hx711.ino +#define D_HX_CAL_REMOVE "Remove weigth" +#define D_HX_CAL_REFERENCE "Load reference weigth" +#define D_HX_CAL_DONE "Calibrated" +#define D_HX_CAL_FAIL "Calibration failed" +#define D_RESET_HX711 "Reset Scale" +#define D_CONFIGURE_HX711 "Configure Scale" +#define D_HX711_PARAMETERS "Scale parameters" +#define D_ITEM_WEIGHT "Item weight" +#define D_REFERENCE_WEIGHT "Reference weigth" +#define D_CALIBRATE "Calibrate" +#define D_CALIBRATION "Calibration" + +//xsns_35_tx20.ino +#define D_TX20_WIND_DIRECTION "Wind Direction" +#define D_TX20_WIND_SPEED "Wind Speed" +#define D_TX20_WIND_SPEED_MIN "Wind Speed Min" +#define D_TX20_WIND_SPEED_MAX "Wind Speed Max" +#define D_TX20_NORTH "N" +#define D_TX20_EAST "E" +#define D_TX20_SOUTH "S" +#define D_TX20_WEST "W" + +// xsns_53_sml.ino +#define D_TPWRIN "Total-In" +#define D_TPWROUT "Total-Out" +#define D_TPWRCURR "Current-In/Out" +#define D_TPWRCURR1 "Current-In p1" +#define D_TPWRCURR2 "Current-In p2" +#define D_TPWRCURR3 "Current-In p3" +#define D_Strom_L1 "Current L1" +#define D_Strom_L2 "Current L2" +#define D_Strom_L3 "Current L3" +#define D_Spannung_L1 "Voltage L1" +#define D_Spannung_L2 "Voltage L2" +#define D_Spannung_L3 "Voltage L3" +#define D_METERNR "Meter_number" +#define D_METERSID "Service ID" +#define D_GasIN "Counter" // Gas-Verbrauch +#define D_H2oIN "Counter" // H2o-Verbrauch +#define D_StL1L2L3 "Current L1+L2+L3" +#define D_SpL1L2L3 "Voltage L1+L2+L3/3" + +// tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box +#define D_SENSOR_NONE "None" +#define D_SENSOR_USER "User" +#define D_SENSOR_OPTION "Option" +#define D_SENSOR_DHT11 "DHT11" +#define D_SENSOR_AM2301 "AM2301" +#define D_SENSOR_SI7021 "SI7021" +#define D_SENSOR_DS18X20 "DS18x20" +#define D_SENSOR_I2C_SCL "I2C SCL" +#define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Player" +#define D_SENSOR_IRSEND "IRsend" +#define D_SENSOR_SWITCH "Switch" // Suffix "1" +#define D_SENSOR_BUTTON "Button" // Suffix "1" +#define D_SENSOR_RELAY "Relay" // Suffix "1i" +#define D_SENSOR_LED "Led" // Suffix "1i" +#define D_SENSOR_LED_LINK "LedLink" // Suffix "i" +#define D_SENSOR_PWM "PWM" // Suffix "1" +#define D_SENSOR_COUNTER "Counter" // Suffix "1" +#define D_SENSOR_IRRECV "IRrecv" +#define D_SENSOR_MHZ_RX "MHZ Rx" +#define D_SENSOR_MHZ_TX "MHZ Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" +#define D_SENSOR_SAIR_RX "SAir Rx" +#define D_SENSOR_SAIR_TX "SAir Tx" +#define D_SENSOR_SPI_CS "SPI CS" +#define D_SENSOR_SPI_DC "SPI DC" +#define D_SENSOR_SPI_MISO "SPI MISO" +#define D_SENSOR_SPI_MOSI "SPI MOSI" +#define D_SENSOR_SPI_CLK "SPI CLK" +#define D_SENSOR_BACKLIGHT "Backlight" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" +#define D_SENSOR_HPMA_RX "HPMA Rx" +#define D_SENSOR_HPMA_TX "HPMA Tx" +#define D_SENSOR_SBR_RX "SerBr Rx" +#define D_SENSOR_SBR_TX "SerBr Tx" +#define D_SENSOR_SR04_TRIG "SR04 Tri/TX" +#define D_SENSOR_SR04_ECHO "SR04 Ech/RX" +#define D_SENSOR_SDM120_TX "SDMx20 Tx" +#define D_SENSOR_SDM120_RX "SDMx20 Rx" +#define D_SENSOR_SDM630_TX "SDM630 Tx" +#define D_SENSOR_SDM630_RX "SDM630 Rx" +#define D_SENSOR_WE517_TX "WE517 Tx" +#define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_TM1638_CLK "TM16 CLK" +#define D_SENSOR_TM1638_DIO "TM16 DIO" +#define D_SENSOR_TM1638_STB "TM16 STB" +#define D_SENSOR_HX711_SCK "HX711 SCK" +#define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532" +#define D_SENSOR_TX2X_TX "TX2x" +#define D_SENSOR_RFSEND "RFSend" +#define D_SENSOR_RFRECV "RFrecv" +#define D_SENSOR_TUYA_TX "Tuya Tx" +#define D_SENSOR_TUYA_RX "Tuya Rx" +#define D_SENSOR_MGC3130_XFER "MGC3130 Xfr" +#define D_SENSOR_MGC3130_RESET "MGC3130 Rst" +#define D_SENSOR_SSPI_MISO "SSPI MISO" +#define D_SENSOR_SSPI_MOSI "SSPI MOSI" +#define D_SENSOR_SSPI_SCLK "SSPI SCLK" +#define D_SENSOR_SSPI_CS "SSPI CS" +#define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" +#define D_SENSOR_AZ_RX "AZ Rx" +#define D_SENSOR_AZ_TX "AZ Tx" +#define D_SENSOR_MAX31855_CS "MX31855 CS" +#define D_SENSOR_MAX31855_CLK "MX31855 CLK" +#define D_SENSOR_MAX31855_DO "MX31855 DO" +#define D_SENSOR_MAX31865_CS "MX31865 CS" +#define D_SENSOR_NRG_SEL "HLWBL SEL" // Suffix "i" +#define D_SENSOR_NRG_CF1 "HLWBL CF1" +#define D_SENSOR_HLW_CF "HLW8012 CF" +#define D_SENSOR_HJL_CF "BL0937 CF" +#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx" +#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx" +#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" +#define D_SENSOR_CSE7766_TX "CSE7766 Tx" +#define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" +#define D_SENSOR_P9813_CLK "P9813 Clk" +#define D_SENSOR_P9813_DAT "P9813 Dat" +#define D_SENSOR_MY92X1_DI "MY92x1 DI" +#define D_SENSOR_MY92X1_DCKI "MY92x1 DCKI" +#define D_SENSOR_ARIRFRCV "ALux IrRcv" +#define D_SENSOR_ARIRFSEL "ALux IrSel" +#define D_SENSOR_TXD "Serial Tx" +#define D_SENSOR_RXD "Serial Rx" +#define D_SENSOR_ROTARY "Rotary" // Suffix "1A" +#define D_SENSOR_HRE_CLOCK "HRE Clock" +#define D_SENSOR_HRE_DATA "HRE Data" +#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ" +#define D_SENSOR_BUZZER "Buzzer" +#define D_SENSOR_OLED_RESET "OLED Reset" +#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" +#define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" +#define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" +#define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" +#define D_SENSOR_IBEACON_TX "iBeacon TX" +#define D_SENSOR_IBEACON_RX "iBeacon RX" +#define D_SENSOR_RDM6300_RX "RDM6300 RX" +#define D_SENSOR_CC1101_CS "CC1101 CS" +#define D_SENSOR_A4988_DIR "A4988 DIR" +#define D_SENSOR_A4988_STP "A4988 STP" +#define D_SENSOR_A4988_ENA "A4988 ENA" +#define D_SENSOR_A4988_MS1 "A4988 MS1" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" +#define D_SENSOR_AS608_TX "AS608 Tx" +#define D_SENSOR_AS608_RX "AS608 Rx" +#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" +#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" +#define D_SENSOR_DDSU666_TX "DDSU666 Tx" +#define D_SENSOR_DDSU666_RX "DDSU666 Rx" +#define D_SENSOR_SM2135_CLK "SM2135 Clk" +#define D_SENSOR_SM2135_DAT "SM2135 Dat" +#define D_SENSOR_DEEPSLEEP "DeepSleep" +#define D_SENSOR_EXS_ENABLE "EXS Enable" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" +#define D_SENSOR_GPS_RX "GPS RX" +#define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" +#define D_SENSOR_LE01MR_RX "LE-01MR Rx" +#define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" +#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" +#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" +#define D_SENSOR_HRXL_RX "HRXL Rx" +#define D_SENSOR_DYP_RX "DYP Rx" +#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_SENSOR_ADC_INPUT "ADC Input" +#define D_SENSOR_ADC_TEMP "ADC Temp" +#define D_SENSOR_ADC_LIGHT "ADC Light" +#define D_SENSOR_ADC_BUTTON "ADC Button" +#define D_SENSOR_ADC_RANGE "ADC Range" +#define D_SENSOR_ADC_CT_POWER "ADC CT Power" +#define D_SENSOR_ADC_JOYSTICK "ADC Joystick" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" +#define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" +#define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" +#define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" +#define D_SENSOR_RC522_RST "RC522 Rst" + +// Units +#define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" +#define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" +#define D_UNIT_HERTZ "Hz" +#define D_UNIT_HOUR "h" +#define D_UNIT_GALLONS "gal" +#define D_UNIT_GALLONS_PER_MIN "g/m" +#define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" +#define D_UNIT_KILOGRAM "kg" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" +#define D_UNIT_KILOOHM "kΩ" +#define D_UNIT_KILOWATTHOUR "kWh" +#define D_UNIT_LITERS "L" +#define D_UNIT_LITERS_PER_MIN "L/m" +#define D_UNIT_LUX "lx" +#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³" +#define D_UNIT_MICROMETER "µm" +#define D_UNIT_MICROSECOND "µs" +#define D_UNIT_MICROSIEMENS_PER_CM "µS/cm" +#define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLILITERS "ml" +#define D_UNIT_MILLIMETER "mm" +#define D_UNIT_MILLIMETER_MERCURY "mmHg" +#define D_UNIT_MILLISECOND "ms" +#define D_UNIT_MILLIVOLT "mV" +#define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" +#define D_UNIT_PARTS_PER_DECILITER "ppd" +#define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" +#define D_UNIT_PRESSURE "hPa" +#define D_UNIT_SECOND "sec" +#define D_UNIT_SECTORS "sectors" +#define D_UNIT_VA "VA" +#define D_UNIT_VAR "VAr" +#define D_UNIT_VOLT "V" +#define D_UNIT_WATT "W" +#define D_UNIT_WATTHOUR "Wh" +#define D_UNIT_WATT_METER_QUADRAT "W/m²" + +//SDM220, SDM120, LE01MR +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" +#define D_TOTAL_ACTIVE "Total Active" + +//SOLAXX1 +#define D_PV1_VOLTAGE "PV1 Voltage" +#define D_PV1_CURRENT "PV1 Current" +#define D_PV1_POWER "PV1 Power" +#define D_PV2_VOLTAGE "PV2 Voltage" +#define D_PV2_CURRENT "PV2 Current" +#define D_PV2_POWER "PV2 Power" +#define D_SOLAR_POWER "Solar Power" +#define D_INVERTER_POWER "Inverter Power" +#define D_STATUS "Status" +#define D_WAITING "Waiting" +#define D_CHECKING "Checking" +#define D_WORKING "Working" +#define D_FAILURE "Failure" +#define D_SOLAX_ERROR_0 "No Error Code" +#define D_SOLAX_ERROR_1 "Grid Lost Fault" +#define D_SOLAX_ERROR_2 "Grid Voltage Fault" +#define D_SOLAX_ERROR_3 "Grid Frequency Fault" +#define D_SOLAX_ERROR_4 "Pv Voltage Fault" +#define D_SOLAX_ERROR_5 "Isolation Fault" +#define D_SOLAX_ERROR_6 "Over Temperature Fault" +#define D_SOLAX_ERROR_7 "Fan Fault" +#define D_SOLAX_ERROR_8 "Other Device Fault" + +//xdrv_10_scripter.ino +#define D_CONFIGURE_SCRIPT "Edit script" +#define D_SCRIPT "edit script" +#define D_SDCARD_UPLOAD "file upload" +#define D_SDCARD_DIR "sd card directory" +#define D_UPL_DONE "Done" +#define D_SCRIPT_CHARS_LEFT "chars left" +#define D_SCRIPT_CHARS_NO_MORE "no more chars" +#define D_SCRIPT_DOWNLOAD "Download" +#define D_SCRIPT_ENABLE "script enable" +#define D_SCRIPT_UPLOAD "Upload" +#define D_SCRIPT_UPLOAD_FILES "Upload files" + +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_FLICKER "IRQ Pin flicker!" +#define D_AS3935_POWEROFF "Powerd Off" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + +// xnrg_15_teleinfo Denky (Teleinfo) +#define D_CONTRACT "Contract" +#define D_POWER_LOAD "Power load" +#define D_CURRENT_TARIFF "Current Tariff" +#define D_TARIFF "Tariff" +#define D_OVERLOAD "ADPS" +#define D_MAX_POWER "Max Power" +#define D_MAX_CURRENT "Max Current" + +// xsns_79_as608.ino +#define D_FP_ENROLL_PLACEFINGER "Place finger" +#define D_FP_ENROLL_REMOVEFINGER "Remove finger" +#define D_FP_ENROLL_PLACESAMEFINGER "Place same finger again" +#define D_FP_ENROLL_RETRY "Error so retry" +#define D_FP_ENROLL_RESTART "Restart" +#define D_FP_ENROLL_ERROR "Error" +#define D_FP_ENROLL_RESET "Reset" +#define D_FP_ENROLL_ACTIVE "Active" +#define D_FP_ENROLL_INACTIVE "Inactive" +// Indexed by Adafruit_Fingerprint.h defines +#define D_FP_PACKETRECIEVEERR "Comms error" // 0x01 Error when receiving data package +#define D_FP_NOFINGER "" // 0x02 No finger on the sensor +#define D_FP_IMAGEFAIL "Imaging error" // 0x03 Failed to enroll the finger +#define D_FP_IMAGEMESS "Image too messy" // 0x06 Failed to generate character file due to overly disorderly fingerprint image +#define D_FP_FEATUREFAIL "Fingerprint too small" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image +#define D_FP_NOMATCH "No match" // 0x08 Finger doesn't match +#define D_FP_NOTFOUND "Did not find a match" // 0x09 Failed to find matching finger +#define D_FP_ENROLLMISMATCH "Fingerprint did not match" // 0x0A Failed to combine the character files +#define D_FP_BADLOCATION "Bad location" // 0x0B Addressed PageID is beyond the finger library +#define D_FP_DBRANGEFAIL "DB range error" // 0x0C Error when reading template from library or invalid template +#define D_FP_UPLOADFEATUREFAIL "Upload feature error" // 0x0D Error when uploading template +#define D_FP_PACKETRESPONSEFAIL "Packet response error" // 0x0E Module failed to receive the following data packages +#define D_FP_UPLOADFAIL "Upload error" // 0x0F Error when uploading image +#define D_FP_DELETEFAIL "Delete error" // 0x10 Failed to delete the template +#define D_FP_DBCLEARFAIL "DB Clear error" // 0x11 Failed to clear finger library +#define D_FP_PASSFAIL "Password error" // 0x13 Find whether the fingerprint passed or failed +#define D_FP_INVALIDIMAGE "Image invalid" // 0x15 Failed to generate image because of lac of valid primary image +#define D_FP_FLASHERR "Flash write error" // 0x18 Error when writing flash +#define D_FP_INVALIDREG "Invalid number" // 0x1A Invalid register number +#define D_FP_ADDRCODE "Address code" // 0x20 Address code +#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed +#define D_FP_UNKNOWNERROR "Error" // Any other error + +#endif // _LANGUAGE_EN_GB_H_ \ No newline at end of file From d3f2a8614bb8d1e6f13ace0f7a9f5f8232ed7c2c Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 15:20:48 +0100 Subject: [PATCH 013/105] Rename af-AF.h to af_AF.h --- tasmota/language/{af-AF.h => af_AF.h} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tasmota/language/{af-AF.h => af_AF.h} (97%) diff --git a/tasmota/language/af-AF.h b/tasmota/language/af_AF.h similarity index 97% rename from tasmota/language/af-AF.h rename to tasmota/language/af_AF.h index 9150e2c38..e2135774d 100644 --- a/tasmota/language/af-AF.h +++ b/tasmota/language/af_AF.h @@ -929,4 +929,4 @@ #define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed #define D_FP_UNKNOWNERROR "Error" // Any other error -#endif // _LANGUAGE_EN_GB_H_ \ No newline at end of file +#endif // _LANGUAGE_EN_GB_H_ From 85bbb3c2473632ce1a8068f6a6d05bcec87a86b2 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 15:47:53 +0100 Subject: [PATCH 014/105] Update af_AF.h --- tasmota/language/af_AF.h | 122 +++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index e2135774d..3ab9cff0d 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -256,45 +256,45 @@ #define D_CONSOLE "Konsole" #define D_CONFIRM_RESTART "Bevestig weer te begin" -#define D_CONFIGURE_MODULE "Configure Module" -#define D_CONFIGURE_WIFI "Configure WiFi" -#define D_CONFIGURE_MQTT "Configure MQTT" -#define D_CONFIGURE_DOMOTICZ "Configure Domoticz" -#define D_CONFIGURE_LOGGING "Configure Logging" -#define D_CONFIGURE_OTHER "Configure Other" -#define D_CONFIRM_RESET_CONFIGURATION "Confirm Reset Configuration" -#define D_RESET_CONFIGURATION "Reset Configuration" -#define D_BACKUP_CONFIGURATION "Backup Configuration" -#define D_RESTORE_CONFIGURATION "Restore Configuration" -#define D_MAIN_MENU "Main Menu" +#define D_CONFIGURE_MODULE "Stel module in" +#define D_CONFIGURE_WIFI "Stel WiFi in" +#define D_CONFIGURE_MQTT "Stel MQTT in" +#define D_CONFIGURE_DOMOTICZ "Stel Domoticz in" +#define D_CONFIGURE_LOGGING "Stel logging in" +#define D_CONFIGURE_OTHER "Stel ander in" +#define D_CONFIRM_RESET_CONFIGURATION "Bevestig die herstel van die konfigurasie" +#define D_RESET_CONFIGURATION "Stel die konfigurasie terug" +#define D_BACKUP_CONFIGURATION "Rugsteun die konfigurasie" +#define D_RESTORE_CONFIGURATION "Stel die konfigurasie terug" +#define D_MAIN_MENU "Hoofkieslys" -#define D_MODULE_PARAMETERS "Module parameters" -#define D_MODULE_TYPE "Module type" -#define D_PULLUP_ENABLE "No Button/Switch pull-up" +#define D_MODULE_PARAMETERS "Moduleparameters" +#define D_MODULE_TYPE "Module tipe" +#define D_PULLUP_ENABLE "Geen knoppie/skakelaar optrek" #define D_ADC "ADC" #define D_GPIO "GPIO" -#define D_SERIAL_IN "Serial In" -#define D_SERIAL_OUT "Serial Out" +#define D_SERIAL_IN "Serial in" +#define D_SERIAL_OUT "Serial uit" -#define D_WIFI_PARAMETERS "Wifi parameters" -#define D_SCAN_FOR_WIFI_NETWORKS "Scan for wifi networks" -#define D_SCAN_DONE "Scan done" -#define D_NO_NETWORKS_FOUND "No networks found" -#define D_REFRESH_TO_SCAN_AGAIN "Refresh to scan again" -#define D_DUPLICATE_ACCESSPOINT "Duplicate AccessPoint" -#define D_SKIPPING_LOW_QUALITY "Skipping due to low quality" +#define D_WIFI_PARAMETERS "Wifi-parameters" +#define D_SCAN_FOR_WIFI_NETWORKS "Soek vir wifi-netwerke" +#define D_SCAN_DONE "Skandering gedoen" +#define D_NO_NETWORKS_FOUND "Geen netwerke gevind nie" +#define D_REFRESH_TO_SCAN_AGAIN "Verfris om weer te skandeer" +#define D_DUPLICATE_ACCESSPOINT "Duplikaat AccessPoint" +#define D_SKIPPING_LOW_QUALITY "Slaan oor as gevolg van lae gehalte" #define D_RSSI "RSSI" #define D_WEP "WEP" #define D_WPA_PSK "WPA PSK" #define D_WPA2_PSK "WPA2 PSK" #define D_AP1_SSID "AP1 SSId" -#define D_AP1_PASSWORD "AP1 Password" +#define D_AP1_PASSWORD "AP1 Wagwoord" #define D_AP2_SSID "AP2 SSId" -#define D_AP2_PASSWORD "AP2 Password" +#define D_AP2_PASSWORD "AP2 Wagwoord" -#define D_MQTT_PARAMETERS "MQTT parameters" -#define D_CLIENT "Client" -#define D_FULL_TOPIC "Full Topic" +#define D_MQTT_PARAMETERS "MQTT-parameters" +#define D_CLIENT "Kliënt" +#define D_FULL_TOPIC "Volledige onderwerp" #define D_LOGGING_PARAMETERS "Logging parameters" #define D_SERIAL_LOG_LEVEL "Serial log level" @@ -306,48 +306,48 @@ #define D_SYSLOG_PORT "Syslog port" #define D_TELEMETRY_PERIOD "Telemetry period" -#define D_OTHER_PARAMETERS "Other parameters" -#define D_TEMPLATE "Template" -#define D_ACTIVATE "Activate" -#define D_DEVICE_NAME "Device Name" -#define D_WEB_ADMIN_PASSWORD "Web Admin Password" -#define D_MQTT_ENABLE "MQTT enable" +#define D_OTHER_PARAMETERS "Ander parameters" +#define D_TEMPLATE "Sjabloon" +#define D_ACTIVATE "Aktiveer" +#define D_DEVICE_NAME "Toestel naam" +#define D_WEB_ADMIN_PASSWORD "Webadministrateurwagwoord" +#define D_MQTT_ENABLE "MQTT inskakel" #define D_MQTT_TLS_ENABLE "MQTT TLS" -#define D_FRIENDLY_NAME "Friendly Name" +#define D_FRIENDLY_NAME "Vriendelike naam" #define D_BELKIN_WEMO "Belkin WeMo" #define D_HUE_BRIDGE "Hue Bridge" -#define D_SINGLE_DEVICE "single device" -#define D_MULTI_DEVICE "multi device" +#define D_SINGLE_DEVICE "enkele toestel" +#define D_MULTI_DEVICE "multi toestel" -#define D_CONFIGURE_TEMPLATE "Configure Template" -#define D_TEMPLATE_PARAMETERS "Template parameters" -#define D_TEMPLATE_NAME "Name" -#define D_BASE_TYPE "Based on" -#define D_TEMPLATE_FLAGS "Options" +#define D_CONFIGURE_TEMPLATE "Konfigureer sjabloon" +#define D_TEMPLATE_PARAMETERS "Sjabloon parameters" +#define D_TEMPLATE_NAME "Naam" +#define D_BASE_TYPE "Gebaseer op" +#define D_TEMPLATE_FLAGS "Opsies" -#define D_SAVE_CONFIGURATION "Save configuration" -#define D_CONFIGURATION_SAVED "Configuration saved" -#define D_CONFIGURATION_RESET "Configuration reset" +#define D_SAVE_CONFIGURATION "Stoor konfigurasie" +#define D_CONFIGURATION_SAVED "Konfigurasie gestoor" +#define D_CONFIGURATION_RESET "Konfigurasie terugstel" -#define D_PROGRAM_VERSION "Program Version" -#define D_BUILD_DATE_AND_TIME "Build Date & Time" -#define D_CORE_AND_SDK_VERSION "Core/SDK Version" -#define D_FLASH_WRITE_COUNT "Flash write Count" -#define D_MAC_ADDRESS "MAC Address" -#define D_MQTT_HOST "MQTT Host" -#define D_MQTT_PORT "MQTT Port" -#define D_MQTT_CLIENT "MQTT Client" -#define D_MQTT_USER "MQTT User" -#define D_MQTT_TOPIC "MQTT Topic" -#define D_MQTT_GROUP_TOPIC "MQTT Group Topic" -#define D_MQTT_FULL_TOPIC "MQTT Full Topic" -#define D_MQTT_NO_RETAIN "MQTT No Retain" -#define D_MDNS_DISCOVERY "mDNS Discovery" -#define D_MDNS_ADVERTISE "mDNS Advertise" +#define D_PROGRAM_VERSION "Programweergawe" +#define D_BUILD_DATE_AND_TIME "Bou datum en tyd" +#define D_CORE_AND_SDK_VERSION "Core/SDK weergawe" +#define D_FLASH_WRITE_COUNT "Flash skryf tel" +#define D_MAC_ADDRESS "MAC adress" +#define D_MQTT_HOST "MQTT gasheer" +#define D_MQTT_PORT "MQTT poort" +#define D_MQTT_CLIENT "MQTT kliënt" +#define D_MQTT_USER "MQTT gebruiker" +#define D_MQTT_TOPIC "MQTT onderwerp" +#define D_MQTT_GROUP_TOPIC "MQTT groeponderwerp" +#define D_MQTT_FULL_TOPIC "MQTT volledige onderwerp" +#define D_MQTT_NO_RETAIN "MQTT geen behoud" +#define D_MDNS_DISCOVERY "mDNS ontdekking" +#define D_MDNS_ADVERTISE "mDNS adverteer" #define D_ESP_CHIP_ID "ESP Chip Id" #define D_FLASH_CHIP_ID "Flash Chip Id" #define D_FLASH_CHIP_SIZE "Flash Size" -#define D_FREE_PROGRAM_SPACE "Free Program Space" +#define D_FREE_PROGRAM_SPACE "Vrye program grootte" #define D_UPGRADE_BY_WEBSERVER "Upgrade by web server" #define D_OTA_URL "OTA Url" From 83b3aa576da923748e33df154922e1fa2caa980b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 27 Dec 2020 16:25:34 +0100 Subject: [PATCH 015/105] Add BSSID and Signal Strength Indicator to GUI wifi scan result (#10253) Add BSSID and Signal Strength Indicator to GUI wifi scan result (#10253) --- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_configurations.h | 3 ++ tasmota/xdrv_01_webserver.ino | 63 +++++++++++++++++++++++++++++++- 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c8911bad..4e938070f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs (#10196) - Support for FTC532 8-button touch controller by Peter Franck (#10222) - Support character `#` to be replaced by `space`-character in command ``Publish`` topic (#10258) +- BSSID and Signal Strength Indicator to GUI wifi scan result (#10253) ### Changed - Logging from fixed global memory buffer to stack buffer freeing 700 bytes RAM diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 04a07fa85..b3c8ada89 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -64,6 +64,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - Support for FTC532 8-button touch controller by Peter Franck [#10222](https://github.com/arendst/Tasmota/issues/10222) - Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258) +- BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253) ### Changed - Logging from fixed global memory buffer to stack buffer freeing 700 bytes RAM diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e75f54ee5..f649f3664 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -415,6 +415,7 @@ #define WEB_PORT 80 // Web server Port for User and Admin mode #define WEB_USERNAME "admin" // Web server Admin mode user name // #define USE_JAVASCRIPT_ES6 // Enable ECMAScript6 syntax using less JavaScript code bytes (fails on IE11) + #define USE_ENHANCED_GUI_WIFI_SCAN // Enable wifi scan output with BSSID (+0k5 code) // #define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code) #define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem common) #define USE_EMULATION_WEMO // Enable Belkin WeMo emulation for Alexa (+6k code, +2k mem common) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 7b5e63372..52bd19c58 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -472,6 +472,7 @@ #undef USE_KNX // Disable KNX IP Protocol Support //#undef USE_WEBSERVER // Disable Webserver +#undef USE_ENHANCED_GUI_WIFI_SCAN // Disable wifi scan output with BSSID (+0k5 code) //#undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) #define USE_EMULATION // Enable Hue emulation #define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem common) @@ -607,6 +608,7 @@ #undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set #undef USE_KNX // Disable KNX IP Protocol Support //#undef USE_WEBSERVER // Disable Webserver +#undef USE_ENHANCED_GUI_WIFI_SCAN // Disable wifi scan output with BSSID (+0k5 code) #undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) //#undef USE_EMULATION // Disable Wemo or Hue emulation //#undef USE_EMULATION_HUE // Disable Hue Bridge emulation for Alexa (+14k code, +2k mem common) @@ -739,6 +741,7 @@ //#undef USE_MQTT_TLS // Disable TLS support won't work as the MQTTHost is not set #undef USE_KNX // Disable KNX IP Protocol Support //#undef USE_WEBSERVER // Disable Webserver +#undef USE_ENHANCED_GUI_WIFI_SCAN // Disable wifi scan output with BSSID (+0k5 code) #undef USE_WEBSEND_RESPONSE // Disable command WebSend response message (+1k code) #undef USE_EMULATION // Disable Wemo or Hue emulation #undef USE_EMULATION_HUE // Disable Hue Bridge emulation for Alexa (+14k code, +2k mem common) diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 243ab46d5..82dd3b182 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -651,6 +651,12 @@ const char HTTP_HEAD_STYLE_ZIGBEE[] PROGMEM = #endif // USE_UNISHOX_COMPRESSION #endif // USE_ZIGBEE +const char HTTP_HEAD_STYLE_SSI[] PROGMEM = + // Signal Strength Indicator + ".si{display:inline-flex;align-items:flex-end;height:15px;padding:0}" + ".si i{width:3px;margin-right:1px;border-radius:3px;background-color:#%06x}" + ".si .b0{height:25%%}.si .b1{height:50%%}.si .b2{height:75%%}.si .b3{height:100%%}.o30{opacity:.3}"; + const char HTTP_HEAD_STYLE3[] PROGMEM = "" @@ -2084,7 +2090,11 @@ void HandleWifiConfiguration(void) WSContentStart_P(PSTR(D_CONFIGURE_WIFI), !WifiIsInManagerMode()); WSContentSend_P(HTTP_SCRIPT_WIFI); +#ifdef USE_ENHANCED_GUI_WIFI_SCAN + WSContentSendStyle_P(HTTP_HEAD_STYLE_SSI, WebColor(COL_TEXT)); +#else WSContentSendStyle(); +#endif // USE_ENHANCED_GUI_WIFI_SCAN if (HTTP_MANAGER_RESET_ONLY != Web.state) { if (Webserver->hasArg("scan")) { @@ -2105,6 +2115,7 @@ void HandleWifiConfiguration(void) indices[i] = i; } + // RSSI SORT for (uint32_t i = 0; i < n; i++) { for (uint32_t j = i + 1; j < n; j++) { @@ -2114,6 +2125,47 @@ void HandleWifiConfiguration(void) } } +#ifdef USE_ENHANCED_GUI_WIFI_SCAN + //display networks in page + for (uint32_t i = 0; i < n; i++) { + if (indices[i] < n) { + int32_t rssi = WiFi.RSSI(indices[i]); + String ssid = WiFi.SSID(indices[i]); + DEBUG_CORE_LOG(PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), + ssid.c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); + + // Print SSID + WSContentSend_P(PSTR("
%s
"), HtmlEscape(ssid).c_str()); + + String nextSSID = ""; + // Handle all APs with the same SSID + for (uint32_t j = 0; j < n; j++) { + if ((indices[j] < n) && ((nextSSID = WiFi.SSID(indices[j])) == ssid)) { + // Update RSSI / quality + rssi = WiFi.RSSI(indices[j]); + uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi); + uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4); + + // Print item + WSContentSend_P(PSTR("
%s(%d)
"), + rssi, rssi_as_quality, + WiFi.BSSIDstr(indices[j]).c_str(), + WiFi.channel(indices[j]) + ); + // Print signal strength indicator + for (uint32_t k = 0; k < 4; ++k) { + WSContentSend_P(PSTR(""), k, (num_bars < k) ? PSTR(" o30") : PSTR("")); + } + WSContentSend_P(PSTR("
")); + + indices[j] = n; + } + delay(0); + } + WSContentSend_P(PSTR("
")); + } + } +#else // No USE_ENHANCED_GUI_WIFI_SCAN // remove duplicates ( must be RSSI sorted ) String cssid; for (uint32_t i = 0; i < n; i++) { @@ -2135,6 +2187,7 @@ void HandleWifiConfiguration(void) DEBUG_CORE_LOG(PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), rssi); int quality = WifiGetRssiAsQuality(rssi); +/* int auth = WiFi.encryptionType(indices[i]); char encryption[20]; WSContentSend_P(PSTR("
%s (%d) %s %d%% (%d dBm)
"), @@ -2143,9 +2196,17 @@ void HandleWifiConfiguration(void) GetTextIndexed(encryption, sizeof(encryption), auth +1, kEncryptionType), quality, rssi ); - delay(0); +*/ + WSContentSend_P(PSTR("
%s (%d) %d%% (%d dBm)
"), + HtmlEscape(WiFi.SSID(indices[i])).c_str(), + WiFi.channel(indices[i]), + quality, rssi + ); + delay(0); } +#endif // USE_ENHANCED_GUI_WIFI_SCAN + WSContentSend_P(PSTR("
")); } } else { From 6df2af7a48cf740698c7ae4da74be35947b17616 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 16:40:41 +0100 Subject: [PATCH 016/105] Update af_AF.h --- tasmota/language/af_AF.h | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 3ab9cff0d..94e37f607 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -349,30 +349,30 @@ #define D_FLASH_CHIP_SIZE "Flash Size" #define D_FREE_PROGRAM_SPACE "Vrye program grootte" -#define D_UPGRADE_BY_WEBSERVER "Upgrade by web server" +#define D_UPGRADE_BY_WEBSERVER "Opgradeer per webbediener" #define D_OTA_URL "OTA Url" -#define D_START_UPGRADE "Start upgrade" -#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade by file upload" -#define D_UPLOAD_STARTED "Upload started" -#define D_UPGRADE_STARTED "Upgrade started" -#define D_UPLOAD_DONE "Upload done" -#define D_UPLOAD_TRANSFER "Upload transfer" -#define D_TRANSFER_STARTED "Transfer started" -#define D_UPLOAD_ERR_1 "No file selected" -#define D_UPLOAD_ERR_2 "Not enough space" -#define D_UPLOAD_ERR_3 "Invalid file signature" -#define D_UPLOAD_ERR_4 "Program flash size is larger than real flash size" -#define D_UPLOAD_ERR_5 "Upload buffer miscompare" -#define D_UPLOAD_ERR_6 "Upload failed. Enable logging 3" -#define D_UPLOAD_ERR_7 "Upload aborted" -#define D_UPLOAD_ERR_8 "File invalid" -#define D_UPLOAD_ERR_9 "File too large" -#define D_UPLOAD_ERR_10 "Failed to init RF chip" -#define D_UPLOAD_ERR_11 "Failed to erase RF chip" -#define D_UPLOAD_ERR_12 "Failed to write to RF chip" -#define D_UPLOAD_ERR_13 "Failed to decode RF firmware" -#define D_UPLOAD_ERR_14 "Not compatible" -#define D_UPLOAD_ERROR_CODE "Upload error code" +#define D_START_UPGRADE "Begin opgradering" +#define D_UPGRADE_BY_FILE_UPLOAD "Gradeer op volgens lêeroplaai" +#define D_UPLOAD_STARTED "Oplaai begin" +#define D_UPGRADE_STARTED "Opgradering is begin" +#define D_UPLOAD_DONE "Oplaai gedoen" +#define D_UPLOAD_TRANSFER "Laai oordrag op" +#define D_TRANSFER_STARTED "Oordrag is begin" +#define D_UPLOAD_ERR_1 "Geen lêer is gekies nie" +#define D_UPLOAD_ERR_2 "Nie genoeg plek nie" +#define D_UPLOAD_ERR_3 "Ongeldige lêerhandtekening" +#define D_UPLOAD_ERR_4 "Programgrootte is groter as geheue" +#define D_UPLOAD_ERR_5 "Laai buffer verkeerd op" +#define D_UPLOAD_ERR_6 "Kon nie oplaai nie. Aktiveer logging 3" +#define D_UPLOAD_ERR_7 "Oplaai afgebreek" +#define D_UPLOAD_ERR_8 "Lêer ongeldig" +#define D_UPLOAD_ERR_9 "Lêer is te groot" +#define D_UPLOAD_ERR_10 "Kon nie RF-skyfie inisieer nie" +#define D_UPLOAD_ERR_11 "Kon nie RF-skyfie uitvee nie" +#define D_UPLOAD_ERR_12 "Kon nie na RF-skyfie skryf nie" +#define D_UPLOAD_ERR_13 "Kon nie RF-firmware dekodeer nie" +#define D_UPLOAD_ERR_14 "Nie versoenbaar nie" +#define D_UPLOAD_ERROR_CODE "Laai foutkode op" #define D_ENTER_COMMAND "Enter command" #define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected" From 7a1539d4ff5ea60b22b6b2ca117e9f66a904ad48 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 16:41:30 +0100 Subject: [PATCH 017/105] Update af_AF.h --- tasmota/language/af_AF.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 94e37f607..718375454 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#ifndef _LANGUAGE_EN_GB_H_ -#define _LANGUAGE_EN_GB_H_ +#ifndef _LANGUAGE_AF_AF_H_ +#define _LANGUAGE_AF_AF_H_ /*************************** ATTENTION *******************************\ * From 802c963e1b45eb3da11bb2e97977a4b544499717 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 16:46:02 +0100 Subject: [PATCH 018/105] Update af_AF.h --- tasmota/language/af_AF.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 718375454..893705bc9 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -374,14 +374,14 @@ #define D_UPLOAD_ERR_14 "Nie versoenbaar nie" #define D_UPLOAD_ERROR_CODE "Laai foutkode op" -#define D_ENTER_COMMAND "Enter command" -#define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected" -#define D_NEED_USER_AND_PASSWORD "Need user=&password=" +#define D_ENTER_COMMAND "Voer die opdrag in" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "Skakel weblog 2 aan as antwoord verwag word" +#define D_NEED_USER_AND_PASSWORD "Benodig user=&password=" // xdrv_01_mqtt.ino -#define D_FINGERPRINT "Verify TLS fingerprint..." -#define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to" -#define D_RETRY_IN "Retry in" +#define D_FINGERPRINT "Verifieer TLS-vingerafdruk ..." +#define D_TLS_CONNECT_FAILED_TO "TLS Connect kon nie" +#define D_RETRY_IN "Probeer weer" #define D_VERIFIED "Verified using Fingerprint" #define D_INSECURE "Insecure connection due to invalid Fingerprint" #define D_CONNECT_FAILED_TO "Connect failed to" From 08d116bb7b4057c0da6c0d47d8a1f52c5584edb9 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 17:24:31 +0100 Subject: [PATCH 019/105] Update af_AF.h --- tasmota/language/af_AF.h | 170 +++++++++++++++++++-------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 893705bc9..7a65d987e 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -382,29 +382,29 @@ #define D_FINGERPRINT "Verifieer TLS-vingerafdruk ..." #define D_TLS_CONNECT_FAILED_TO "TLS Connect kon nie" #define D_RETRY_IN "Probeer weer" -#define D_VERIFIED "Verified using Fingerprint" -#define D_INSECURE "Insecure connection due to invalid Fingerprint" -#define D_CONNECT_FAILED_TO "Connect failed to" +#define D_VERIFIED "Geverifieer met behulp van vingerafdruk" +#define D_INSECURE "Onveilige verbinding weens ongeldige vingerafdruk" +#define D_CONNECT_FAILED_TO "Kon nie verbind nie" // xplg_wemohue.ino -#define D_MULTICAST_DISABLED "Multicast disabled" -#define D_MULTICAST_REJOINED "Multicast (re)joined" -#define D_MULTICAST_JOIN_FAILED "Multicast join failed" -#define D_FAILED_TO_SEND_RESPONSE "Failed to send response" +#define D_MULTICAST_DISABLED "Multicast gedeaktiveer" +#define D_MULTICAST_REJOINED "Multicast (weer) aangesluit" +#define D_MULTICAST_JOIN_FAILED "Multicast aansluiting het misluk" +#define D_FAILED_TO_SEND_RESPONSE "Kon nie antwoord stuur nie" #define D_WEMO "WeMo" -#define D_WEMO_BASIC_EVENT "WeMo basic event" -#define D_WEMO_EVENT_SERVICE "WeMo event service" +#define D_WEMO_BASIC_EVENT "WeMo basiese event" +#define D_WEMO_EVENT_SERVICE "WeMo geleentheids service" #define D_WEMO_META_SERVICE "WeMo meta service" -#define D_WEMO_SETUP "WeMo setup" -#define D_RESPONSE_SENT "Response sent" +#define D_WEMO_SETUP "WeMo opstelling" +#define D_RESPONSE_SENT "Antwoord gestuur" #define D_HUE "Hue" -#define D_HUE_BRIDGE_SETUP "Hue setup" -#define D_HUE_API_NOT_IMPLEMENTED "Hue API not implemented" +#define D_HUE_BRIDGE_SETUP "Hue opstelling" +#define D_HUE_API_NOT_IMPLEMENTED "Hue API nie geïmplementeer nie" #define D_HUE_API "Hue API" #define D_HUE_POST_ARGS "Hue POST args" -#define D_3_RESPONSE_PACKETS_SENT "3 response packets sent" +#define D_3_RESPONSE_PACKETS_SENT "3 antwoordpakkies gestuur" // xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Domoticz parameters" @@ -415,98 +415,98 @@ #define D_DOMOTICZ_TEMP "Temp" #define D_DOMOTICZ_TEMP_HUM "Temp,Hum" #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" - #define D_DOMOTICZ_POWER_ENERGY "Power,Energy" - #define D_DOMOTICZ_ILLUMINANCE "Illuminance" - #define D_DOMOTICZ_COUNT "Count/PM1" - #define D_DOMOTICZ_VOLTAGE "Voltage/PM2.5" - #define D_DOMOTICZ_CURRENT "Current/PM10" - #define D_DOMOTICZ_AIRQUALITY "AirQuality" + #define D_DOMOTICZ_POWER_ENERGY "Krag, Energie" + #define D_DOMOTICZ_ILLUMINANCE "Beligting" + #define D_DOMOTICZ_COUNT "Telling/PM1" + #define D_DOMOTICZ_VOLTAGE "Spanning/PM2.5" + #define D_DOMOTICZ_CURRENT "Krag/PM10" + #define D_DOMOTICZ_AIRQUALITY "Lug kwaliteit" #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" -#define D_DOMOTICZ_UPDATE_TIMER "Update timer" +#define D_DOMOTICZ_UPDATE_TIMER "Dateer tydopdatering op" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Configure Timer" -#define D_TIMER_PARAMETERS "Timer parameters" -#define D_TIMER_ENABLE "Enable Timers" -#define D_TIMER_ARM "Enable" -#define D_TIMER_TIME "Time" -#define D_TIMER_DAYS "Days" -#define D_TIMER_REPEAT "Repeat" -#define D_TIMER_OUTPUT "Output" -#define D_TIMER_ACTION "Action" +#define D_CONFIGURE_TIMER "Stel timer in" +#define D_TIMER_PARAMETERS "Timer-parameters" +#define D_TIMER_ENABLE "Aktiveer timers" +#define D_TIMER_ARM "Aktiveer" +#define D_TIMER_TIME "Tyd" +#define D_TIMER_DAYS "Dae" +#define D_TIMER_REPEAT "Herhaal" +#define D_TIMER_OUTPUT "Uitset" +#define D_TIMER_ACTION "Aksie" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "Configure KNX" -#define D_KNX_PARAMETERS "KNX Parameters" -#define D_KNX_GENERAL_CONFIG "General" -#define D_KNX_PHYSICAL_ADDRESS "Physical Address" -#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Must be unique on the KNX network )" -#define D_KNX_ENABLE "Enable KNX" -#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data to Send to Group Addresses" -#define D_ADD "Add" -#define D_DELETE "Delete" -#define D_REPLY "Reply" -#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from" -#define D_RECEIVED_FROM "Received from" -#define D_KNX_COMMAND_WRITE "Write" -#define D_KNX_COMMAND_READ "Read" -#define D_KNX_COMMAND_OTHER "Other" -#define D_SENT_TO "sent to" -#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." -#define D_KNX_ENHANCEMENT "Communication Enhancement" +#define D_CONFIGURE_KNX "Stel KNX op" +#define D_KNX_PARAMETERS "KNX-parameters" +#define D_KNX_GENERAL_CONFIG "Algemene" +#define D_KNX_PHYSICAL_ADDRESS "Fisiese adres" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Moet uniek wees in die KNX-netwerk )" +#define D_KNX_ENABLE "Aktiveer KNX" +#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data om na groepadresse te stuur" +#define D_ADD "Voeg by" +#define D_DELETE "Vee uit" +#define D_REPLY "Antwoord" +#define D_KNX_GROUP_ADDRESS_TO_READ "Groepadresse om data van te ontvang" +#define D_RECEIVED_FROM "Ontvang van" +#define D_KNX_COMMAND_WRITE "Skryf" +#define D_KNX_COMMAND_READ "Lees" +#define D_KNX_COMMAND_OTHER "Ander" +#define D_SENT_TO "gestuur na" +#define D_KNX_WARNING "Die groepadres ( 0 / 0 / 0 ) is gereserveer en kan nie gebruik word nie." +#define D_KNX_ENHANCEMENT "Kommunikasieverbetering" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" #define D_KNX_TX_SCENE "KNX SCENE TX" #define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_23_zigbee -#define D_ZIGBEE_PERMITJOIN_ACTIVE "Devices allowed to join" -#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee Mapping" -#define D_ZIGBEE_NOT_STARTED "Zigbee not started" -#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Mapping in progress (%d s. remaining)" -#define D_ZIGBEE_MAPPING_NOT_PRESENT "No mapping" -#define D_ZIGBEE_MAP_REFRESH "Zigbee Map Refresh" -#define D_ZIGBEE_MAP "Zigbee Map" -#define D_ZIGBEE_PERMITJOIN "Zigbee Permit Join" -#define D_ZIGBEE_GENERATE_KEY "generating random Zigbee network key" -#define D_ZIGBEE_UNKNOWN_DEVICE "Unknown device" -#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Unknown attribute" -#define D_ZIGBEE_INVALID_PARAM "Invalid parameter" -#define D_ZIGBEE_MISSING_PARAM "Missing parameters" -#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Unknown attribute name (ignored): %s" -#define D_ZIGBEE_TOO_MANY_CLUSTERS "No more than one cluster id per command" -#define D_ZIGBEE_WRONG_DELIMITER "Wrong delimiter for payload" -#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Unrecognized zigbee command: %s" -#define D_ZIGBEE_TOO_MANY_COMMANDS "Only 1 command allowed (%d)" -#define D_ZIGBEE_NO_ATTRIBUTE "No attribute in list" -#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Unsupported attribute type" -#define D_ZIGBEE_JSON_REQUIRED "Config requires JSON objects" -#define D_ZIGBEE_RESET_1_OR_2 "1 or 2 to reset" -#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM found at address" -#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Randomizing Zigbee parameters, please check with 'ZbConfig'" +#define D_ZIGBEE_PERMITJOIN_ACTIVE "Toestelle wat toegelaat word om aan te sluit" +#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee-kartering" +#define D_ZIGBEE_NOT_STARTED "Zigbee het nie begin nie" +#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Kartering aan die gang (% d s. Oor)" +#define D_ZIGBEE_MAPPING_NOT_PRESENT "Geen kartering nie" +#define D_ZIGBEE_MAP_REFRESH "Zigbee kartering Refresh" +#define D_ZIGBEE_MAP "Zigbee-kaart" +#define D_ZIGBEE_PERMITJOIN "Zigbee Permit sluit aan" +#define D_ZIGBEE_GENERATE_KEY "genereer ewekansige Zigbee-netwerksleutel" +#define D_ZIGBEE_UNKNOWN_DEVICE "Onbekende toestel" +#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Onbekende kenmerk" +#define D_ZIGBEE_INVALID_PARAM "Ongeldige parameter" +#define D_ZIGBEE_MISSING_PARAM "Ontbrekende parameters" +#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Onbekende kenmerknaam (geïgnoreer): %s" +#define D_ZIGBEE_TOO_MANY_CLUSTERS "Nie meer as een groep-ID per opdrag nie" +#define D_ZIGBEE_WRONG_DELIMITER "Verkeerde afbakening vir payload" +#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Onherkenbare zigbee-opdrag: %s" +#define D_ZIGBEE_TOO_MANY_COMMANDS "Slegs 1 opdrag toegelaat (%d)" +#define D_ZIGBEE_NO_ATTRIBUTE "Geen kenmerk in die lys nie" +#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Nie-ondersteunde kenmerktipe" +#define D_ZIGBEE_JSON_REQUIRED "Config benodig JSON-voorwerpe" +#define D_ZIGBEE_RESET_1_OR_2 "1 of 2 om te herstel" +#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres" +#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'" // xdrv_03_energy.ino -#define D_ENERGY_TODAY "Energy Today" -#define D_ENERGY_YESTERDAY "Energy Yesterday" -#define D_ENERGY_TOTAL "Energy Total" +#define D_ENERGY_TODAY "Energie Vandag" +#define D_ENERGY_YESTERDAY "Energie Gister" +#define D_ENERGY_TOTAL "Energie Totaal" // xdrv_27_shutter.ino -#define D_OPEN "Open" -#define D_CLOSE "Close" -#define D_DOMOTICZ_SHUTTER "Shutter" +#define D_OPEN "Maak oop" +#define D_CLOSE "Maak toe" +#define D_DOMOTICZ_SHUTTER "Luik" // xdrv_28_pcf8574.ino #define D_CONFIGURE_PCF8574 "Configure PCF8574" #define D_PCF8574_PARAMETERS "PCF8574 parameters" -#define D_INVERT_PORTS "Invert Ports" -#define D_DEVICE "Device" -#define D_DEVICE_INPUT "Input" -#define D_DEVICE_OUTPUT "Output" +#define D_INVERT_PORTS "Keer poorte om" +#define D_DEVICE "Toestel" +#define D_DEVICE_INPUT "Invoer" +#define D_DEVICE_OUTPUT "Uitvoer" // xsns_05_ds18b20.ino -#define D_SENSOR_BUSY "Sensor busy" -#define D_SENSOR_CRC_ERROR "Sensor CRC error" -#define D_SENSORS_FOUND "Sensors found" +#define D_SENSOR_BUSY "Sensor besig" +#define D_SENSOR_CRC_ERROR "Sensor CRC fout" +#define D_SENSORS_FOUND "Sensors gevind" // xsns_06_dht.ino #define D_TIMEOUT_WAITING_FOR "Timeout waiting for" From 25d36dbe5a64846d0d324d8eb6672ac7cf4fcacd Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 17:42:33 +0100 Subject: [PATCH 020/105] Update af_AF.h --- tasmota/language/af_AF.h | 94 ++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 7a65d987e..d6ad43af5 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -419,7 +419,7 @@ #define D_DOMOTICZ_ILLUMINANCE "Beligting" #define D_DOMOTICZ_COUNT "Telling/PM1" #define D_DOMOTICZ_VOLTAGE "Spanning/PM2.5" - #define D_DOMOTICZ_CURRENT "Krag/PM10" + #define D_DOMOTICZ_CURRENT "Stroom/PM10" #define D_DOMOTICZ_AIRQUALITY "Lug kwaliteit" #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" #define D_DOMOTICZ_UPDATE_TIMER "Dateer tydopdatering op" @@ -509,28 +509,28 @@ #define D_SENSORS_FOUND "Sensors gevind" // xsns_06_dht.ino -#define D_TIMEOUT_WAITING_FOR "Timeout waiting for" -#define D_START_SIGNAL_LOW "start signal low" -#define D_START_SIGNAL_HIGH "start signal high" -#define D_PULSE "pulse" -#define D_CHECKSUM_FAILURE "Checksum failure" +#define D_TIMEOUT_WAITING_FOR "Tyduitstyd wag vir" +#define D_START_SIGNAL_LOW "begin sein laag" +#define D_START_SIGNAL_HIGH "begin sein hoog" +#define D_PULSE "pols" +#define D_CHECKSUM_FAILURE "Checksum het misluk" // xsns_07_sht1x.ino -#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor did not ACK command" -#define D_SHT1X_FOUND "SHT1X found" +#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor het nie ACK opdrag" +#define D_SHT1X_FOUND "SHT1X gevind" // xsns_18_pms5003.ino #define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter -#define D_PARTICALS_BEYOND "Particles" +#define D_PARTICALS_BEYOND "Deeltjies" // xsns_27_apds9960.ino -#define D_GESTURE "Gesture" -#define D_COLOR_RED "Red" -#define D_COLOR_GREEN "Green" -#define D_COLOR_BLUE "Blue" +#define D_GESTURE "Gebaar" +#define D_COLOR_RED "Rooi" +#define D_COLOR_GREEN "Groen" +#define D_COLOR_BLUE "Blou" #define D_CCT "CCT" -#define D_PROXIMITY "Proximity" +#define D_PROXIMITY "Nabyheid" // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" @@ -541,47 +541,47 @@ #define D_GZ_AXIS "Gyro Z-Axis" // xsns_34_hx711.ino -#define D_HX_CAL_REMOVE "Remove weigth" -#define D_HX_CAL_REFERENCE "Load reference weigth" -#define D_HX_CAL_DONE "Calibrated" -#define D_HX_CAL_FAIL "Calibration failed" -#define D_RESET_HX711 "Reset Scale" -#define D_CONFIGURE_HX711 "Configure Scale" -#define D_HX711_PARAMETERS "Scale parameters" -#define D_ITEM_WEIGHT "Item weight" -#define D_REFERENCE_WEIGHT "Reference weigth" -#define D_CALIBRATE "Calibrate" -#define D_CALIBRATION "Calibration" +#define D_HX_CAL_REMOVE "Verwyder gewig" +#define D_HX_CAL_REFERENCE "Laai verwysingsgewig" +#define D_HX_CAL_DONE "Gekalibreer" +#define D_HX_CAL_FAIL "Kon nie kalibreer nie" +#define D_RESET_HX711 "Stel die skaal terug" +#define D_CONFIGURE_HX711 "Stel skaal op" +#define D_HX711_PARAMETERS "Skaal parameters" +#define D_ITEM_WEIGHT "Gewig van die item" +#define D_REFERENCE_WEIGHT "Verwysingsgewig" +#define D_CALIBRATE "Kalibreer" +#define D_CALIBRATION "Kalibrasie" //xsns_35_tx20.ino -#define D_TX20_WIND_DIRECTION "Wind Direction" -#define D_TX20_WIND_SPEED "Wind Speed" -#define D_TX20_WIND_SPEED_MIN "Wind Speed Min" -#define D_TX20_WIND_SPEED_MAX "Wind Speed Max" +#define D_TX20_WIND_DIRECTION "Windrigting" +#define D_TX20_WIND_SPEED "Wind spoed" +#define D_TX20_WIND_SPEED_MIN "Wind spoed Min" +#define D_TX20_WIND_SPEED_MAX "Wind spoed Max" #define D_TX20_NORTH "N" -#define D_TX20_EAST "E" +#define D_TX20_EAST "O" #define D_TX20_SOUTH "S" #define D_TX20_WEST "W" // xsns_53_sml.ino -#define D_TPWRIN "Total-In" -#define D_TPWROUT "Total-Out" -#define D_TPWRCURR "Current-In/Out" -#define D_TPWRCURR1 "Current-In p1" -#define D_TPWRCURR2 "Current-In p2" -#define D_TPWRCURR3 "Current-In p3" -#define D_Strom_L1 "Current L1" -#define D_Strom_L2 "Current L2" -#define D_Strom_L3 "Current L3" -#define D_Spannung_L1 "Voltage L1" -#define D_Spannung_L2 "Voltage L2" -#define D_Spannung_L3 "Voltage L3" -#define D_METERNR "Meter_number" +#define D_TPWRIN "Totaal-In" +#define D_TPWROUT "Totaal-Uit" +#define D_TPWRCURR "Stroom-In/Uit" +#define D_TPWRCURR1 "Stroom-In p1" +#define D_TPWRCURR2 "Stroom-In p2" +#define D_TPWRCURR3 "Stroom-In p3" +#define D_Strom_L1 "Stroom L1" +#define D_Strom_L2 "Stroom L2" +#define D_Strom_L3 "Stroom L3" +#define D_Spannung_L1 "Spanning L1" +#define D_Spannung_L2 "Spanning L2" +#define D_Spannung_L3 "Spanning L3" +#define D_METERNR "Meter nommmer" #define D_METERSID "Service ID" -#define D_GasIN "Counter" // Gas-Verbrauch -#define D_H2oIN "Counter" // H2o-Verbrauch -#define D_StL1L2L3 "Current L1+L2+L3" -#define D_SpL1L2L3 "Voltage L1+L2+L3/3" +#define D_GasIN "Teller" // Gas-Verbrauch +#define D_H2oIN "Teller" // H2o-Verbrauch +#define D_StL1L2L3 "Stroom L1+L2+L3" +#define D_SpL1L2L3 "Spanning L1+L2+L3/3" // tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box #define D_SENSOR_NONE "None" From 41d2e2675c8f8c6b7a106a0a05ef58fa5accd405 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 19:15:05 +0100 Subject: [PATCH 021/105] Update af_AF.h --- tasmota/language/af_AF.h | 106 +++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index d6ad43af5..a93ff2a4d 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -584,9 +584,9 @@ #define D_SpL1L2L3 "Spanning L1+L2+L3/3" // tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box -#define D_SENSOR_NONE "None" -#define D_SENSOR_USER "User" -#define D_SENSOR_OPTION "Option" +#define D_SENSOR_NONE "Geen" +#define D_SENSOR_USER "Gebruiker" +#define D_SENSOR_OPTION "Opsie" #define D_SENSOR_DHT11 "DHT11" #define D_SENSOR_AM2301 "AM2301" #define D_SENSOR_SI7021 "SI7021" @@ -594,16 +594,16 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" -#define D_SENSOR_DFR562 "MP3 Player" -#define D_SENSOR_IRSEND "IRsend" -#define D_SENSOR_SWITCH "Switch" // Suffix "1" -#define D_SENSOR_BUTTON "Button" // Suffix "1" -#define D_SENSOR_RELAY "Relay" // Suffix "1i" +#define D_SENSOR_DFR562 "MP3 Speler" +#define D_SENSOR_IRSEND "IRstuurder" +#define D_SENSOR_SWITCH "SKakelaar" // Suffix "1" +#define D_SENSOR_BUTTON "Knoppie" // Suffix "1" +#define D_SENSOR_RELAY "Relais" // Suffix "1i" #define D_SENSOR_LED "Led" // Suffix "1i" #define D_SENSOR_LED_LINK "LedLink" // Suffix "i" #define D_SENSOR_PWM "PWM" // Suffix "1" -#define D_SENSOR_COUNTER "Counter" // Suffix "1" -#define D_SENSOR_IRRECV "IRrecv" +#define D_SENSOR_COUNTER "Teller" // Suffix "1" +#define D_SENSOR_IRRECV "IRontvanger" #define D_SENSOR_MHZ_RX "MHZ Rx" #define D_SENSOR_MHZ_TX "MHZ Tx" #define D_SENSOR_PZEM004_RX "PZEM004 Rx" @@ -641,8 +641,8 @@ #define D_SENSOR_HX711_DAT "HX711 DAT" #define D_SENSOR_FTC532 "FTC532" #define D_SENSOR_TX2X_TX "TX2x" -#define D_SENSOR_RFSEND "RFSend" -#define D_SENSOR_RFRECV "RFrecv" +#define D_SENSOR_RFSEND "RFstuurder" +#define D_SENSOR_RFRECV "RFontvanger" #define D_SENSOR_TUYA_TX "Tuya Tx" #define D_SENSOR_TUYA_RX "Tuya Rx" #define D_SENSOR_MGC3130_XFER "MGC3130 Xfr" @@ -681,12 +681,12 @@ #define D_SENSOR_ARIRFSEL "ALux IrSel" #define D_SENSOR_TXD "Serial Tx" #define D_SENSOR_RXD "Serial Rx" -#define D_SENSOR_ROTARY "Rotary" // Suffix "1A" -#define D_SENSOR_HRE_CLOCK "HRE Clock" +#define D_SENSOR_ROTARY "Draai" // Suffix "1A" +#define D_SENSOR_HRE_CLOCK "HRE Klok" #define D_SENSOR_HRE_DATA "HRE Data" #define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ" -#define D_SENSOR_BUZZER "Buzzer" -#define D_SENSOR_OLED_RESET "OLED Reset" +#define D_SENSOR_BUZZER "Gonser" +#define D_SENSOR_OLED_RESET "OLED Herstel" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" #define D_SENSOR_ZIGBEE_RST "Zigbee Rst" @@ -710,8 +710,8 @@ #define D_SENSOR_DDSU666_RX "DDSU666 Rx" #define D_SENSOR_SM2135_CLK "SM2135 Clk" #define D_SENSOR_SM2135_DAT "SM2135 Dat" -#define D_SENSOR_DEEPSLEEP "DeepSleep" -#define D_SENSOR_EXS_ENABLE "EXS Enable" +#define D_SENSOR_DEEPSLEEP "Diep slaap" +#define D_SENSOR_EXS_ENABLE "EXS Inskakel" #define D_SENSOR_CLIENT_TX "Client TX" #define D_SENSOR_CLIENT_RX "Client RX" #define D_SENSOR_CLIENT_RESET "Client RST" @@ -732,11 +732,11 @@ #define D_SENSOR_TELEINFO_RX "TInfo Rx" #define D_SENSOR_TELEINFO_ENABLE "TInfo EN" #define D_SENSOR_LMT01_PULSE "LMT01 Pulse" -#define D_SENSOR_ADC_INPUT "ADC Input" -#define D_SENSOR_ADC_TEMP "ADC Temp" -#define D_SENSOR_ADC_LIGHT "ADC Light" -#define D_SENSOR_ADC_BUTTON "ADC Button" -#define D_SENSOR_ADC_RANGE "ADC Range" +#define D_SENSOR_ADC_INPUT "ADC Insette" +#define D_SENSOR_ADC_TEMP "ADC Temperatuur" +#define D_SENSOR_ADC_LIGHT "ADC Lig" +#define D_SENSOR_ADC_BUTTON "ADC Knoppie" +#define D_SENSOR_ADC_RANGE "ADC Reekse" #define D_SENSOR_ADC_CT_POWER "ADC CT Power" #define D_SENSOR_ADC_JOYSTICK "ADC Joystick" #define D_GPIO_WEBCAM_PWDN "CAM_PWDN" @@ -761,8 +761,8 @@ #define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" #define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" #define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" -#define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Reset" -#define D_SENSOR_RC522_RST "RC522 Rst" +#define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Herstel" +#define D_SENSOR_RC522_RST "RC522 Herstel" // Units #define D_UNIT_AMPERE "A" @@ -810,39 +810,39 @@ #define D_UNIT_WATT_METER_QUADRAT "W/m²" //SDM220, SDM120, LE01MR -#define D_PHASE_ANGLE "Phase Angle" -#define D_IMPORT_ACTIVE "Import Active" -#define D_EXPORT_ACTIVE "Export Active" -#define D_IMPORT_REACTIVE "Import Reactive" -#define D_EXPORT_REACTIVE "Export Reactive" -#define D_TOTAL_REACTIVE "Total Reactive" +#define D_PHASE_ANGLE "Fasehoek" +#define D_IMPORT_ACTIVE "Invoer aktief" +#define D_EXPORT_ACTIVE "Uitvoer aktief" +#define D_IMPORT_REACTIVE "Import reaktief" +#define D_EXPORT_REACTIVE "Uitvoer reaktief" +#define D_TOTAL_REACTIVE "Totaal reaktief" #define D_UNIT_KWARH "kVArh" #define D_UNIT_ANGLE "Deg" -#define D_TOTAL_ACTIVE "Total Active" +#define D_TOTAL_ACTIVE "Totaal aktief" //SOLAXX1 -#define D_PV1_VOLTAGE "PV1 Voltage" -#define D_PV1_CURRENT "PV1 Current" -#define D_PV1_POWER "PV1 Power" -#define D_PV2_VOLTAGE "PV2 Voltage" -#define D_PV2_CURRENT "PV2 Current" -#define D_PV2_POWER "PV2 Power" -#define D_SOLAR_POWER "Solar Power" -#define D_INVERTER_POWER "Inverter Power" +#define D_PV1_VOLTAGE "PV1 Spanning" +#define D_PV1_CURRENT "PV1 Stroom" +#define D_PV1_POWER "PV1 Krag" +#define D_PV2_VOLTAGE "PV2 Spanning" +#define D_PV2_CURRENT "PV2 Stroom" +#define D_PV2_POWER "PV2 Krag" +#define D_SOLAR_POWER "Sonkrag" +#define D_INVERTER_POWER "Omskakelaarkrag" #define D_STATUS "Status" -#define D_WAITING "Waiting" -#define D_CHECKING "Checking" -#define D_WORKING "Working" -#define D_FAILURE "Failure" -#define D_SOLAX_ERROR_0 "No Error Code" -#define D_SOLAX_ERROR_1 "Grid Lost Fault" -#define D_SOLAX_ERROR_2 "Grid Voltage Fault" -#define D_SOLAX_ERROR_3 "Grid Frequency Fault" -#define D_SOLAX_ERROR_4 "Pv Voltage Fault" -#define D_SOLAX_ERROR_5 "Isolation Fault" -#define D_SOLAX_ERROR_6 "Over Temperature Fault" -#define D_SOLAX_ERROR_7 "Fan Fault" -#define D_SOLAX_ERROR_8 "Other Device Fault" +#define D_WAITING "Wag" +#define D_CHECKING "Nagaan" +#define D_WORKING "Werk" +#define D_FAILURE "Mislukking" +#define D_SOLAX_ERROR_0 "Geen foutkode nie" +#define D_SOLAX_ERROR_1 "Netspanning verlies fout" +#define D_SOLAX_ERROR_2 "Netspanning spanning fout" +#define D_SOLAX_ERROR_3 "Netspanning frekwensie fout" +#define D_SOLAX_ERROR_4 "Pv stroom fout" +#define D_SOLAX_ERROR_5 "Isolasiefout" +#define D_SOLAX_ERROR_6 "Storing by oormatige temperatuur" +#define D_SOLAX_ERROR_7 "Waaierstoring" +#define D_SOLAX_ERROR_8 "Ander toestelfout" //xdrv_10_scripter.ino #define D_CONFIGURE_SCRIPT "Edit script" From 5aa6e76728b18e582b100f4f498e5d3cb728070e Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 19:19:18 +0100 Subject: [PATCH 022/105] Update af_AF.h --- tasmota/language/af_AF.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index a93ff2a4d..84226a8ef 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -845,17 +845,17 @@ #define D_SOLAX_ERROR_8 "Ander toestelfout" //xdrv_10_scripter.ino -#define D_CONFIGURE_SCRIPT "Edit script" -#define D_SCRIPT "edit script" -#define D_SDCARD_UPLOAD "file upload" +#define D_CONFIGURE_SCRIPT "Wysig skrif" +#define D_SCRIPT "wysig skrif" +#define D_SDCARD_UPLOAD "lêer oplaai" #define D_SDCARD_DIR "sd card directory" -#define D_UPL_DONE "Done" -#define D_SCRIPT_CHARS_LEFT "chars left" -#define D_SCRIPT_CHARS_NO_MORE "no more chars" -#define D_SCRIPT_DOWNLOAD "Download" -#define D_SCRIPT_ENABLE "script enable" -#define D_SCRIPT_UPLOAD "Upload" -#define D_SCRIPT_UPLOAD_FILES "Upload files" +#define D_UPL_DONE "Klaar" +#define D_SCRIPT_CHARS_LEFT "karakters oor" +#define D_SCRIPT_CHARS_NO_MORE "nie meer karakters nie" +#define D_SCRIPT_DOWNLOAD "Aflaai" +#define D_SCRIPT_ENABLE "skrip inskakel" +#define D_SCRIPT_UPLOAD "Laai op" +#define D_SCRIPT_UPLOAD_FILES "Laai lêers op" //xsns_67_as3935.ino #define D_AS3935_GAIN "gain:" From 2e05ca25f11b42827d83d401a1f1bab21ec22333 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 20:27:23 +0100 Subject: [PATCH 023/105] Update af_AF.h --- tasmota/language/af_AF.h | 118 +++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 84226a8ef..583b15bed 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -858,75 +858,75 @@ #define D_SCRIPT_UPLOAD_FILES "Laai lêers op" //xsns_67_as3935.ino -#define D_AS3935_GAIN "gain:" -#define D_AS3935_ENERGY "energy:" -#define D_AS3935_DISTANCE "distance:" -#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_GAIN "versterking:" +#define D_AS3935_ENERGY "energie:" +#define D_AS3935_DISTANCE "afstand:" +#define D_AS3935_DISTURBER "steur:" #define D_AS3935_VRMS "µVrms:" #define D_AS3935_APRX "aprx.:" -#define D_AS3935_AWAY "away" -#define D_AS3935_LIGHT "lightning" -#define D_AS3935_OUT "lightning out of range" -#define D_AS3935_NOT "distance not determined" -#define D_AS3935_ABOVE "lightning overhead" -#define D_AS3935_NOISE "noise detected" -#define D_AS3935_DISTDET "disturber detected" -#define D_AS3935_INTNOEV "Interrupt with no Event!" -#define D_AS3935_FLICKER "IRQ Pin flicker!" -#define D_AS3935_POWEROFF "Powerd Off" -#define D_AS3935_NOMESS "listening..." -#define D_AS3935_ON "On" -#define D_AS3935_OFF "Off" -#define D_AS3935_INDOORS "Indoors" -#define D_AS3935_OUTDOORS "Outdoors" -#define D_AS3935_CAL_FAIL "calibration failed" -#define D_AS3935_CAL_OK "calibration set to:" +#define D_AS3935_AWAY "weg" +#define D_AS3935_LIGHT "weerlig" +#define D_AS3935_OUT "weerlig buite bereik" +#define D_AS3935_NOT "afstand nie bepaal nie" +#define D_AS3935_ABOVE "weerlig oorhoofse" +#define D_AS3935_NOISE "geraas bespeur" +#define D_AS3935_DISTDET "steuring bespeur" +#define D_AS3935_INTNOEV "Onderbreek met geen geleentheid nie!" +#define D_AS3935_FLICKER "IRQ Pin flikker!" +#define D_AS3935_POWEROFF "Skakel af" +#define D_AS3935_NOMESS "luister..." +#define D_AS3935_ON "Aan" +#define D_AS3935_OFF "Uit" +#define D_AS3935_INDOORS "Binnenshuis" +#define D_AS3935_OUTDOORS "Buite" +#define D_AS3935_CAL_FAIL "kalibrasie het misluk" +#define D_AS3935_CAL_OK "kalibrasie ingestel op:" //xsns_68_opentherm.ino #define D_SENSOR_BOILER_OT_RX "OpenTherm RX" #define D_SENSOR_BOILER_OT_TX "OpenTherm TX" // xnrg_15_teleinfo Denky (Teleinfo) -#define D_CONTRACT "Contract" -#define D_POWER_LOAD "Power load" -#define D_CURRENT_TARIFF "Current Tariff" -#define D_TARIFF "Tariff" +#define D_CONTRACT "Kontrak" +#define D_POWER_LOAD "Kraglading" +#define D_CURRENT_TARIFF "Stroom tarief" +#define D_TARIFF "Tarief" #define D_OVERLOAD "ADPS" -#define D_MAX_POWER "Max Power" -#define D_MAX_CURRENT "Max Current" +#define D_MAX_POWER "Max krag" +#define D_MAX_CURRENT "Max stroom" // xsns_79_as608.ino -#define D_FP_ENROLL_PLACEFINGER "Place finger" -#define D_FP_ENROLL_REMOVEFINGER "Remove finger" -#define D_FP_ENROLL_PLACESAMEFINGER "Place same finger again" -#define D_FP_ENROLL_RETRY "Error so retry" -#define D_FP_ENROLL_RESTART "Restart" -#define D_FP_ENROLL_ERROR "Error" -#define D_FP_ENROLL_RESET "Reset" -#define D_FP_ENROLL_ACTIVE "Active" -#define D_FP_ENROLL_INACTIVE "Inactive" +#define D_FP_ENROLL_PLACEFINGER "Plaas vinger" +#define D_FP_ENROLL_REMOVEFINGER "Verwyder vinger" +#define D_FP_ENROLL_PLACESAMEFINGER "Plaas dieselfde vinger weer" +#define D_FP_ENROLL_RETRY "Fout, probeer dus weer" +#define D_FP_ENROLL_RESTART "Begin oor" +#define D_FP_ENROLL_ERROR "Fout" +#define D_FP_ENROLL_RESET "Stel terug" +#define D_FP_ENROLL_ACTIVE "Aktief" +#define D_FP_ENROLL_INACTIVE "Onaktief" // Indexed by Adafruit_Fingerprint.h defines -#define D_FP_PACKETRECIEVEERR "Comms error" // 0x01 Error when receiving data package -#define D_FP_NOFINGER "" // 0x02 No finger on the sensor -#define D_FP_IMAGEFAIL "Imaging error" // 0x03 Failed to enroll the finger -#define D_FP_IMAGEMESS "Image too messy" // 0x06 Failed to generate character file due to overly disorderly fingerprint image -#define D_FP_FEATUREFAIL "Fingerprint too small" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image -#define D_FP_NOMATCH "No match" // 0x08 Finger doesn't match -#define D_FP_NOTFOUND "Did not find a match" // 0x09 Failed to find matching finger -#define D_FP_ENROLLMISMATCH "Fingerprint did not match" // 0x0A Failed to combine the character files -#define D_FP_BADLOCATION "Bad location" // 0x0B Addressed PageID is beyond the finger library -#define D_FP_DBRANGEFAIL "DB range error" // 0x0C Error when reading template from library or invalid template -#define D_FP_UPLOADFEATUREFAIL "Upload feature error" // 0x0D Error when uploading template -#define D_FP_PACKETRESPONSEFAIL "Packet response error" // 0x0E Module failed to receive the following data packages -#define D_FP_UPLOADFAIL "Upload error" // 0x0F Error when uploading image -#define D_FP_DELETEFAIL "Delete error" // 0x10 Failed to delete the template -#define D_FP_DBCLEARFAIL "DB Clear error" // 0x11 Failed to clear finger library -#define D_FP_PASSFAIL "Password error" // 0x13 Find whether the fingerprint passed or failed -#define D_FP_INVALIDIMAGE "Image invalid" // 0x15 Failed to generate image because of lac of valid primary image -#define D_FP_FLASHERR "Flash write error" // 0x18 Error when writing flash -#define D_FP_INVALIDREG "Invalid number" // 0x1A Invalid register number -#define D_FP_ADDRCODE "Address code" // 0x20 Address code -#define D_FP_PASSVERIFY "Password verified" // 0x21 Verify the fingerprint passed -#define D_FP_UNKNOWNERROR "Error" // Any other error +#define D_FP_PACKETRECIEVEERR "Komms-fout" // 0x01 Error when receiving data package +#define D_FP_NOFINGER "Geen vinger op die sensor nie" // 0x02 No finger on the sensor +#define D_FP_IMAGEFAIL "Beeldfout" // 0x03 Failed to enroll the finger +#define D_FP_IMAGEMESS "Beeld te deurmekaar" // 0x06 Failed to generate character file due to overly disorderly fingerprint image +#define D_FP_FEATUREFAIL "Vingerafdruk te klein" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image +#define D_FP_NOMATCH "Nie opgewasse" // 0x08 Finger doesn't match +#define D_FP_NOTFOUND "Kon nie 'n ekwivalent vind nie" // 0x09 Failed to find matching finger +#define D_FP_ENROLLMISMATCH "Vingerafdruk stem nie ooreen nie" // 0x0A Failed to combine the character files +#define D_FP_BADLOCATION "Slegte ligging" // 0x0B Addressed PageID is beyond the finger library +#define D_FP_DBRANGEFAIL "DB-reeksfout" // 0x0C Error when reading template from library or invalid template +#define D_FP_UPLOADFEATUREFAIL "Fout by die oplaai van funksie" // 0x0D Error when uploading template +#define D_FP_PACKETRESPONSEFAIL "Fout van pakketrespons" // 0x0E Module failed to receive the following data packages +#define D_FP_UPLOADFAIL "Oplaaifout" // 0x0F Error when uploading image +#define D_FP_DELETEFAIL "Vee fout" // 0x10 Failed to delete the template +#define D_FP_DBCLEARFAIL "DB leegfout" // 0x11 Failed to clear finger library +#define D_FP_PASSFAIL "Wagwoordfout" // 0x13 Find whether the fingerprint passed or failed +#define D_FP_INVALIDIMAGE "Prent ongeldig" // 0x15 Failed to generate image because of lac of valid primary image +#define D_FP_FLASHERR "Flash skryffout" // 0x18 Error when writing flash +#define D_FP_INVALIDREG "Ongeldige nommer" // 0x1A Invalid register number +#define D_FP_ADDRCODE "Adres kode" // 0x20 Address code +#define D_FP_PASSVERIFY "Wagwoord geverifieer" // 0x21 Verify the fingerprint passed +#define D_FP_UNKNOWNERROR "Fout" // Any other error -#endif // _LANGUAGE_EN_GB_H_ +#endif // _LANGUAGE_AF_AF_H_ From cc1513a373a800ffc807e427bf5bdb505b0c848f Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 20:47:48 +0100 Subject: [PATCH 024/105] Update af_AF.h --- tasmota/language/af_AF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 583b15bed..7b92dd04b 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -33,7 +33,7 @@ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) // https://www.science.co.il/language/Locale-codes.php -#define LANGUAGE_LCID 2057 +#define LANGUAGE_LCID 1078 // HTML (ISO 639-1) Language Code #define D_HTML_LANGUAGE "af" From eea2357b6aeab0fc1ab6511577344700933340f4 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 20:58:23 +0100 Subject: [PATCH 025/105] Update af_AF.h --- tasmota/language/af_AF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 7b92dd04b..2b0974c97 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -1,5 +1,5 @@ /* - af-AF.h - localization for Afrikaans - Afrikaans for Tasmota + af_AF.h - localization for Afrikaans - Afrikaans for Tasmota Copyright (C) 2020 Christiaan Heerze From 2a1051f3f48b445ef41339d778650cacf9a83845 Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 21:03:56 +0100 Subject: [PATCH 026/105] Update af_AF.h --- tasmota/language/af_AF.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 2b0974c97..fdf5e14f4 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -110,6 +110,7 @@ #define D_HOST "Gasheer" #define D_HOSTNAME "Gasheername" #define D_HUMIDITY "Humiditeit" +#define D_ILLUMINANCE "Verligting" #define D_IMMEDIATE "onmiddellik" // Button immediate #define D_INDEX "Indeks" #define D_INFO "Inligting" From f1076712d02dc7dca934820380c8fd1fec98e7cb Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 21:26:03 +0100 Subject: [PATCH 027/105] Update platformio.ini --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index 6c0f401df..d7d6caa45 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,6 +21,7 @@ default_envs = ; tasmota-display ; tasmota-zbbridge ; tasmota-ir +; tasmota-AF ; tasmota-BG ; tasmota-BR ; tasmota-CN From 9e9b32719d5bc594b5db6ee414c2fdc3f299e03d Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 21:27:40 +0100 Subject: [PATCH 028/105] Update platformio_tasmota_env.ini --- platformio_tasmota_env.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index 428fac8ce..f24794b68 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -67,6 +67,9 @@ build_flags = ${common.build_flags} -DFIRMWARE_ZBBRIDGE board_build.f_cpu = 160000000L lib_extra_dirs = lib/lib_ssl +[env:tasmota-AF] +build_flags = ${common.build_flags} -DMY_LANGUAGE=af_AF + [env:tasmota-BG] build_flags = ${common.build_flags} -DMY_LANGUAGE=bg_BG From f2b5eb13957eec6de5cd0559b09635c63bbb351a Mon Sep 17 00:00:00 2001 From: crispy78 <42983001+crispy78@users.noreply.github.com> Date: Sun, 27 Dec 2020 21:30:06 +0100 Subject: [PATCH 029/105] Update my_user_config.h --- tasmota/my_user_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e75f54ee5..c7867161a 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -340,6 +340,7 @@ // -- Localization -------------------------------- // If non selected the default en-GB will be used +//#define MY_LANGUAGE af_AF // Afrikaans in South Africa //#define MY_LANGUAGE bg_BG // Bulgarian in Bulgaria //#define MY_LANGUAGE cs_CZ // Czech in Czech //#define MY_LANGUAGE de_DE // German in Germany From d161026534c9092b1bbe0f5224172a2a1facadd4 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Dec 2020 11:53:02 +0100 Subject: [PATCH 030/105] Add support for Afrikaans language translations by Christiaan Heerze --- .github/workflows/CI_github.yml | 39 ++++++++++++++++++++------- .github/workflows/CI_github_ESP32.yml | 36 +++++++++++++++++++------ .github/workflows/Tasmota_build.yml | 24 +++++++++++++++++ CHANGELOG.md | 1 + RELEASENOTES.md | 5 ++-- platformio_tasmota32.ini | 1 + platformio_tasmota_env32.ini | 4 +++ 7 files changed, 90 insertions(+), 20 deletions(-) diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml index b8844bb5c..74cd0573a 100644 --- a/.github/workflows/CI_github.yml +++ b/.github/workflows/CI_github.yml @@ -1,6 +1,6 @@ name: Tasmota CI -on: +on: pull_request: jobs: @@ -16,7 +16,7 @@ jobs: pip install -U platformio platformio upgrade --dev platformio update - - name: Run PlatformIO + - name: Run PlatformIO run: platformio run -e tasmota - uses: actions/upload-artifact@v2 with: @@ -79,7 +79,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-sensors: runs-on: ubuntu-latest steps: @@ -156,6 +156,25 @@ jobs: name: firmware path: ./build_output/firmware + tasmota-AF: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + tasmota-BG: runs-on: ubuntu-latest steps: @@ -174,7 +193,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-BR: runs-on: ubuntu-latest steps: @@ -250,7 +269,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-ES: runs-on: ubuntu-latest steps: @@ -269,7 +288,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-FR: runs-on: ubuntu-latest steps: @@ -326,7 +345,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-HU: runs-on: ubuntu-latest steps: @@ -402,7 +421,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-PL: runs-on: ubuntu-latest steps: @@ -478,7 +497,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-SE: runs-on: ubuntu-latest steps: @@ -554,7 +573,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota-UK: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml index aca4ddb15..a36d747dc 100644 --- a/.github/workflows/CI_github_ESP32.yml +++ b/.github/workflows/CI_github_ESP32.yml @@ -23,7 +23,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-webcam: runs-on: ubuntu-latest steps: @@ -103,7 +103,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-sensors: runs-on: ubuntu-latest steps: @@ -164,6 +164,26 @@ jobs: name: firmware path: ./build_output/firmware + tasmota32-AF: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + tasmota32-BG: runs-on: ubuntu-latest steps: @@ -183,7 +203,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-BR: runs-on: ubuntu-latest steps: @@ -263,7 +283,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-ES: runs-on: ubuntu-latest steps: @@ -343,7 +363,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-HU: runs-on: ubuntu-latest steps: @@ -423,7 +443,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-PL: runs-on: ubuntu-latest steps: @@ -503,7 +523,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-SE: runs-on: ubuntu-latest steps: @@ -583,7 +603,7 @@ jobs: with: name: firmware path: ./build_output/firmware - + tasmota32-UK: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index b0044da28..1507fc2c2 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -230,6 +230,30 @@ jobs: name: firmware path: ./build_output/firmware + + tasmota-AF: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota-BG: needs: tasmota_pull runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e938070f..6911291d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. - Support for FTC532 8-button touch controller by Peter Franck (#10222) - Support character `#` to be replaced by `space`-character in command ``Publish`` topic (#10258) - BSSID and Signal Strength Indicator to GUI wifi scan result (#10253) +- Support for Afrikaans language translations by Christiaan Heerze ### Changed - Logging from fixed global memory buffer to stack buffer freeing 700 bytes RAM diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b3c8ada89..4335614c2 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -59,12 +59,13 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ## Changelog v9.2.0.1 ### Added - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) +- Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) +- BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253) - Support for P9813 RGB Led MOSFET controller [#10104](https://github.com/arendst/Tasmota/issues/10104) - Support for GPIO option selection -- Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - Support for FTC532 8-button touch controller by Peter Franck [#10222](https://github.com/arendst/Tasmota/issues/10222) - Support character `#` to be replaced by `space`-character in command ``Publish`` topic [#10258](https://github.com/arendst/Tasmota/issues/10258) -- BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253) +- Support for Afrikaans language translations by Christiaan Heerze ### Changed - Logging from fixed global memory buffer to stack buffer freeing 700 bytes RAM diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index c3aa37f2f..1fe7667a2 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -15,6 +15,7 @@ default_envs = ${build_envs.default_envs} ; tasmota32-display ; tasmota32-ir ; tasmota32-ircustom +; tasmota32-AF ; tasmota32-BG ; tasmota32-BR ; tasmota32-CN diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 4fd87373c..ff416538e 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -70,6 +70,10 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic extends = env:tasmota32 build_flags = ${common32.build_flags} ${irremoteesp_full.build_flags} -DFIRMWARE_IR_CUSTOM +[env:tasmota32-AF] +extends = env:tasmota32 +build_flags = ${common32.build_flags} -DMY_LANGUAGE=af_AF + [env:tasmota32-BG] extends = env:tasmota32 build_flags = ${common32.build_flags} -DMY_LANGUAGE=bg_BG From ad5b04934dc39442620350b9b6defb0952d56809 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Mon, 28 Dec 2020 12:27:45 +0100 Subject: [PATCH 031/105] Update xdrv_27_shutter.ino code and variable optimization. Now internally testest against regression test --- tasmota/xdrv_27_shutter.ino | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index 735277e32..e46dbbca7 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -155,7 +155,7 @@ void ShutterRtc50mS(void) } } -int32_t ShutterPercentToRealPosition(uint32_t percent, uint32_t index) +int32_t ShutterPercentToRealPosition(int16_t percent, uint32_t index) { if (Settings.shutter_set50percent[index] != 50) { return (percent <= 5) ? Settings.shuttercoeff[2][index] * percent*10 : (Settings.shuttercoeff[1][index] * percent + (Settings.shuttercoeff[0][index]*10))*10; @@ -177,26 +177,26 @@ int32_t ShutterPercentToRealPosition(uint32_t percent, uint32_t index) } else { //AddLog_P(LOG_LEVEL_ERROR, PSTR("Shutter[%d].open_max: %d"),index, Shutter[index].open_max); if (0 == k) { - realpos = SHT_DIV_ROUND(SHT_DIV_ROUND(percent * Shutter[index].open_max * calibrate_pos[k+1], Settings.shuttercoeff[k][index]), 10 ); + realpos = SHT_DIV_ROUND((int64_t)percent * Shutter[index].open_max * calibrate_pos[k+1], Settings.shuttercoeff[k][index]*10 ); //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realposition TEMP3: %d, %d %%, coeff %d"), realpos, percent, Settings.shuttercoeff[k][index]); } else { //uint32_t addon = ( percent*10 - Settings.shuttercoeff[k-1][index] ) * Shutter[index].open_max * (calibrate_pos[k+1] - calibrate_pos[k]) / (Settings.shuttercoeff[k][index] -Settings.shuttercoeff[k-1][index]) / 100; //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realposition TEMP2: %d, %d %%, coeff %d"), addon, (calibrate_pos[k+1] - calibrate_pos[k]), (Settings.shuttercoeff[k][index] -Settings.shuttercoeff[k-1][index])); - realpos += SHT_DIV_ROUND(SHT_DIV_ROUND((percent*10 - Settings.shuttercoeff[k-1][index] ) * Shutter[index].open_max * (calibrate_pos[k+1] - calibrate_pos[k]), Settings.shuttercoeff[k][index] - Settings.shuttercoeff[k-1][index]), 100); + realpos += SHT_DIV_ROUND(((int64_t)percent*10 - Settings.shuttercoeff[k-1][index] ) * Shutter[index].open_max * (calibrate_pos[k+1] - calibrate_pos[k]), (Settings.shuttercoeff[k][index] - Settings.shuttercoeff[k-1][index])*100); } break; } } - return realpos; + return realpos < 0 ? 0 : realpos; } } -uint8_t ShutterRealToPercentPosition(int64_t realpos, uint32_t index) +uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index) { if (Settings.shutter_set50percent[index] != 50) { return (Settings.shuttercoeff[2][index] * 5 > realpos/10) ? SHT_DIV_ROUND(realpos/10, Settings.shuttercoeff[2][index]) : SHT_DIV_ROUND(realpos/10-Settings.shuttercoeff[0][index]*10, Settings.shuttercoeff[1][index]); } else { - uint64_t realpercent; + int64_t realpercent; for (uint32_t j = 0; j < 5; j++) { if (realpos >= Shutter[index].open_max * calibrate_pos[j+1] / 100) { realpercent = SHT_DIV_ROUND(Settings.shuttercoeff[j][index], 10); @@ -204,18 +204,17 @@ uint8_t ShutterRealToPercentPosition(int64_t realpos, uint32_t index) } else { //AddLog_P(LOG_LEVEL_ERROR, PSTR("Shutter[%d].open_max: %d"),index, Shutter[index].open_max); if (0 == j) { - realpercent = SHT_DIV_ROUND(SHT_DIV_ROUND((realpos - SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[j], 100)) * Settings.shuttercoeff[j][index], calibrate_pos[j+1]/10), Shutter[index].open_max); - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realpercent TEMP3: %d %%, %d, coeff %d"), realpercent, realpos, Shutter[index].open_max * calibrate_pos[j+1] / 100); + realpercent = SHT_DIV_ROUND(((int64_t)realpos - SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[j], 100)) * Settings.shuttercoeff[j][index], calibrate_pos[j+1]/10*Shutter[index].open_max); } else { //uint16_t addon = ( realpos - (Shutter[index].open_max * calibrate_pos[j] / 100) ) * 10 * (Settings.shuttercoeff[j][index] - Settings.shuttercoeff[j-1][index]) / (calibrate_pos[j+1] - calibrate_pos[j])/Shutter[index].open_max; //uint16_t addon = ( realpercent*10 - Settings.shuttercoeff[j-1][index] ) * Shutter[index].open_max * (calibrate_pos[j+1] - calibrate_pos[j]) / (Settings.shuttercoeff[j][index] -Settings.shuttercoeff[j-1][index]) / 100; //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realpercent TEMP2: %d %%, delta %d, %d, coeff %d"), addon,( realpos - (Shutter[index].open_max * calibrate_pos[j] / 100) ) , (calibrate_pos[j+1] - calibrate_pos[j])* Shutter[index].open_max/100, (Settings.shuttercoeff[j][index] -Settings.shuttercoeff[j-1][index])); - realpercent += SHT_DIV_ROUND(SHT_DIV_ROUND((realpos - SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[j], 100)) * (Settings.shuttercoeff[j][index] - Settings.shuttercoeff[j-1][index]), (calibrate_pos[j+1] - calibrate_pos[j])/10), Shutter[index].open_max) ; - } + realpercent += SHT_DIV_ROUND(((int64_t)realpos - SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[j], 100)) * (Settings.shuttercoeff[j][index] - Settings.shuttercoeff[j-1][index]), (calibrate_pos[j+1] - calibrate_pos[j])/10*Shutter[index].open_max) ; + } break; } } - return (int16_t)realpercent < 0 ? 0 : realpercent; + return realpercent < 0 ? 0 : realpercent; } } From 4d516c65a6b3d1a2ddfbbf7144028c368a84df3e Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Dec 2020 12:36:44 +0100 Subject: [PATCH 032/105] Prep for embedded ESP32 module template re-introduction --- tasmota/tasmota_template.h | 495 +++--------------------------- tasmota/tasmota_template_legacy.h | 480 +++++++++++++++++++++++++++++ 2 files changed, 515 insertions(+), 460 deletions(-) create mode 100644 tasmota/tasmota_template_legacy.h diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 48dd7a30f..c38b037bc 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -836,462 +836,15 @@ typedef struct MYTMPLT { //******************************************************************************************** #ifdef ESP8266 +#include "tasmota_template_legacy.h" -// User selectable GPIO functionality -// ATTENTION: No additions are supported -enum LegacyUserSelectablePins { - GPI8_NONE, // Not used - GPI8_DHT11, // DHT11 - GPI8_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321 - GPI8_SI7021, // iTead SI7021 - GPI8_DSB, // Single wire DS18B20 or DS18S20 - GPI8_I2C_SCL, // I2C SCL - GPI8_I2C_SDA, // I2C SDA - GPI8_WS2812, // WS2812 Led string - GPI8_IRSEND, // IR remote - GPI8_SWT1, // User connected external switches - GPI8_SWT2, - GPI8_SWT3, - GPI8_SWT4, - GPI8_SWT5, - GPI8_SWT6, - GPI8_SWT7, - GPI8_SWT8, - GPI8_KEY1, // Button usually connected to GPIO0 - GPI8_KEY2, - GPI8_KEY3, - GPI8_KEY4, - GPI8_REL1, // Relays - GPI8_REL2, - GPI8_REL3, - GPI8_REL4, - GPI8_REL5, - GPI8_REL6, - GPI8_REL7, - GPI8_REL8, - GPI8_REL1_INV, - GPI8_REL2_INV, - GPI8_REL3_INV, - GPI8_REL4_INV, - GPI8_REL5_INV, - GPI8_REL6_INV, - GPI8_REL7_INV, - GPI8_REL8_INV, - GPI8_PWM1, // RGB Red or C Cold White - GPI8_PWM2, // RGB Green or CW Warm White - GPI8_PWM3, // RGB Blue - GPI8_PWM4, // RGBW (Cold) White - GPI8_PWM5, // RGBCW Warm White - GPI8_CNTR1, - GPI8_CNTR2, - GPI8_CNTR3, - GPI8_CNTR4, - GPI8_PWM1_INV, // RGB Red or C Cold White - GPI8_PWM2_INV, // RGB Green or CW Warm White - GPI8_PWM3_INV, // RGB Blue - GPI8_PWM4_INV, // RGBW (Cold) White - GPI8_PWM5_INV, // RGBCW Warm White - GPI8_IRRECV, // IR receiver - GPI8_LED1, // Leds - GPI8_LED2, - GPI8_LED3, - GPI8_LED4, - GPI8_LED1_INV, - GPI8_LED2_INV, - GPI8_LED3_INV, - GPI8_LED4_INV, - GPI8_MHZ_TXD, // MH-Z19 Serial interface - GPI8_MHZ_RXD, // MH-Z19 Serial interface - GPI8_PZEM0XX_TX, // PZEM0XX Serial interface - GPI8_PZEM004_RX, // PZEM004T Serial interface - GPI8_SAIR_TX, // SenseAir Serial interface - GPI8_SAIR_RX, // SenseAir Serial interface - GPI8_SPI_CS, // SPI Chip Select - GPI8_SPI_DC, // SPI Data Direction - GPI8_BACKLIGHT, // Display backlight control - GPI8_PMS5003_RX, // Plantower PMS5003 Serial interface - GPI8_SDS0X1_RX, // Nova Fitness SDS011 Serial interface - GPI8_SBR_TX, // Serial Bridge Serial interface - GPI8_SBR_RX, // Serial Bridge Serial interface - GPI8_SR04_TRIG, // SR04 Trigger/TX pin - GPI8_SR04_ECHO, // SR04 Echo/RX pin - GPI8_SDM120_TX, // SDM120 Serial interface - GPI8_SDM120_RX, // SDM120 Serial interface - GPI8_SDM630_TX, // SDM630 Serial interface - GPI8_SDM630_RX, // SDM630 Serial interface - GPI8_TM16CLK, // TM1638 Clock - GPI8_TM16DIO, // TM1638 Data I/O - GPI8_TM16STB, // TM1638 Strobe - GPI8_SWT1_NP, // User connected external switches - GPI8_SWT2_NP, - GPI8_SWT3_NP, - GPI8_SWT4_NP, - GPI8_SWT5_NP, - GPI8_SWT6_NP, - GPI8_SWT7_NP, - GPI8_SWT8_NP, - GPI8_KEY1_NP, // Button usually connected to GPIO0 - GPI8_KEY2_NP, - GPI8_KEY3_NP, - GPI8_KEY4_NP, - GPI8_CNTR1_NP, - GPI8_CNTR2_NP, - GPI8_CNTR3_NP, - GPI8_CNTR4_NP, - GPI8_PZEM016_RX, // PZEM-014,016 Serial Modbus interface - GPI8_PZEM017_RX, // PZEM-003,017 Serial Modbus interface - GPI8_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player - GPI8_SDS0X1_TX, // Nova Fitness SDS011 Serial interface - GPI8_HX711_SCK, // HX711 Load Cell clock - GPI8_HX711_DAT, // HX711 Load Cell data - GPI8_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin - GPI8_RFSEND, // RF transmitter - GPI8_RFRECV, // RF receiver - GPI8_TUYA_TX, // Tuya Serial interface - GPI8_TUYA_RX, // Tuya Serial interface - GPI8_MGC3130_XFER, // MGC3130 Transfer - GPI8_MGC3130_RESET, // MGC3130 Reset - GPI8_SSPI_MISO, // Software SPI Master Input Client Output - GPI8_SSPI_MOSI, // Software SPI Master Output Client Input - GPI8_SSPI_SCLK, // Software SPI Serial Clock - GPI8_SSPI_CS, // Software SPI Chip Select - GPI8_SSPI_DC, // Software SPI Data or Command - GPI8_RF_SENSOR, // Rf receiver with sensor decoding - GPI8_AZ_TXD, // AZ-Instrument 7798 Serial interface - GPI8_AZ_RXD, // AZ-Instrument 7798 Serial interface - GPI8_MAX31855CS, // MAX31855 Serial interface - GPI8_MAX31855CLK, // MAX31855 Serial interface - GPI8_MAX31855DO, // MAX31855 Serial interface - GPI8_KEY1_INV, // Inverted buttons - GPI8_KEY2_INV, - GPI8_KEY3_INV, - GPI8_KEY4_INV, - GPI8_KEY1_INV_NP, // Inverted buttons without pull-up - GPI8_KEY2_INV_NP, - GPI8_KEY3_INV_NP, - GPI8_KEY4_INV_NP, - GPI8_NRG_SEL, // HLW8012/HLJ-01 Sel output (1 = Voltage) - GPI8_NRG_SEL_INV, // HLW8012/HLJ-01 Sel output (0 = Voltage) - GPI8_NRG_CF1, // HLW8012/HLJ-01 CF1 voltage / current - GPI8_HLW_CF, // HLW8012 CF power - GPI8_HJL_CF, // HJL-01/BL0937 CF power - GPI8_MCP39F5_TX, // MCP39F501 Serial interface (Shelly2) - GPI8_MCP39F5_RX, // MCP39F501 Serial interface (Shelly2) - GPI8_MCP39F5_RST, // MCP39F501 Reset (Shelly2) - GPI8_PN532_TXD, // PN532 NFC Serial Tx - GPI8_PN532_RXD, // PN532 NFC Serial Rx - GPI8_SM16716_CLK, // SM16716 CLOCK - GPI8_SM16716_DAT, // SM16716 DATA - GPI8_SM16716_SEL, // SM16716 SELECT - GPI8_DI, // my92x1 PWM input - GPI8_DCKI, // my92x1 CLK input - GPI8_CSE7766_TX, // CSE7766 Serial interface (S31 and Pow R2) - Not used anymore 20200121 - GPI8_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2) - GPI8_ARIRFRCV, // AriLux RF Receive input - GPI8_TXD, // Serial interface - GPI8_RXD, // Serial interface - GPI8_ROT1A, // Rotary switch1 A Pin - GPI8_ROT1B, // Rotary switch1 B Pin - GPI8_ROT2A, // Rotary switch2 A Pin - GPI8_ROT2B, // Rotary switch2 B Pin - GPI8_HRE_CLOCK, // Clock/Power line for HR-E Water Meter - GPI8_HRE_DATA, // Data line for HR-E Water Meter - GPI8_ADE7953_IRQ, // ADE7953 IRQ - GPI8_LEDLNK, // Link led - GPI8_LEDLNK_INV, // Inverted link led - GPI8_ARIRFSEL, // Arilux RF Receive input selected - GPI8_BUZZER, // Buzzer - GPI8_BUZZER_INV, // Inverted buzzer - GPI8_OLED_RESET, // OLED Display Reset - GPI8_SOLAXX1_TX, // Solax Inverter tx pin - GPI8_SOLAXX1_RX, // Solax Inverter rx pin - GPI8_ZIGBEE_TX, // Zigbee Serial interface - GPI8_ZIGBEE_RX, // Zigbee Serial interface - GPI8_RDM6300_RX, // RDM6300 RX - GPI8_IBEACON_TX, // HM17 IBEACON TX - GPI8_IBEACON_RX, // HM17 IBEACON RX - GPI8_A4988_DIR, // A4988 direction pin - GPI8_A4988_STP, // A4988 step pin - GPI8_A4988_ENA, // A4988 enabled pin - GPI8_A4988_MS1, // A4988 microstep pin1 - GPI8_A4988_MS2, // A4988 microstep pin2 - GPI8_A4988_MS3, // A4988 microstep pin3 - GPI8_DDS2382_TX, // DDS2382 Serial interface - GPI8_DDS2382_RX, // DDS2382 Serial interface - GPI8_DDSU666_TX, // DDSU666 Serial interface - GPI8_DDSU666_RX, // DDSU666 Serial interface - GPI8_SM2135_CLK, // SM2135 Clk - GPI8_SM2135_DAT, // SM2135 Dat - GPI8_DEEPSLEEP, // Kill switch for deepsleep - GPI8_EXS_ENABLE, // EXS MCU Enable - GPI8_TASMOTACLIENT_TXD, // Client TX - GPI8_TASMOTACLIENT_RXD, // Client RX - GPI8_TASMOTACLIENT_RST, // Client Reset Pin - GPI8_TASMOTACLIENT_RST_INV, // Client Reset Inverted - GPI8_HPMA_RX, // Honeywell HPMA115S0 Serial interface - GPI8_HPMA_TX, // Honeywell HPMA115S0 Serial interface - GPI8_GPS_RX, // GPS serial interface - GPI8_GPS_TX, // GPS serial interface - GPI8_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20 - GPI8_DHT11_OUT, // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 - GPI8_HM10_RX, // HM10-BLE-Mijia-bridge serial interface - GPI8_HM10_TX, // HM10-BLE-Mijia-bridge serial interface - GPI8_LE01MR_RX, // F&F LE-01MR energy meter - GPI8_LE01MR_TX, // F&F LE-01MR energy meter - GPI8_CC1101_GDO0, // CC1101 pin for RX - GPI8_CC1101_GDO2, // CC1101 pin for RX - GPI8_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor - GPI8_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX - GPI8_AS3935, // Franklin Lightning Sensor - GPI8_PMS5003_TX, // Plantower PMS5003 Serial interface - GPI8_BOILER_OT_RX, // OpenTherm Boiler RX pin - GPI8_BOILER_OT_TX, // OpenTherm Boiler TX pin - GPI8_WINDMETER_SPEED, // WindMeter speed counter pin - GPI8_BL0940_RX, // BL0940 serial interface - GPI8_TCP_TX, // TCP Serial bridge - GPI8_TCP_RX, // TCP Serial bridge - GPI8_TELEINFO_RX, // TELEINFO serial interface - GPI8_TELEINFO_ENABLE,// TELEINFO Enable PIN - GPI8_LMT01, // LMT01 input counting pin - GPI8_IEM3000_TX, // IEM3000 Serial interface - GPI8_IEM3000_RX, // IEM3000 Serial interface - GPI8_ZIGBEE_RST, // Zigbee reset - GPI8_DYP_RX, - GPI8_SENSOR_END }; +/********************************************************************************************\ + * ESP8266 Module Templates +\********************************************************************************************/ -// Programmer selectable GPIO functionality -enum LegacyProgramSelectablePins { - GPI8_FIX_START = 251, - GPI8_SPI_MISO, // SPI MISO library fixed pin GPIO12 - GPI8_SPI_MOSI, // SPI MOSI library fixed pin GPIO13 - GPI8_SPI_CLK, // SPI Clk library fixed pin GPIO14 - GPI8_USER, // User configurable needs to be 255 - GPI8_MAX }; +#define USER_MODULE 255 -// Indexed by LegacyUserSelectablePins to convert legacy (8-bit) GPIOs -const uint16_t kGpioConvert[] PROGMEM = { - GPIO_NONE, - AGPIO(GPIO_DHT11), // DHT11 - AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 - AGPIO(GPIO_SI7021), // iTead SI7021 - AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20 - AGPIO(GPIO_I2C_SCL), // I2C SCL - AGPIO(GPIO_I2C_SDA), // I2C SDA - AGPIO(GPIO_WS2812), // WS2812 Led string - AGPIO(GPIO_IRSEND), // IR remote - AGPIO(GPIO_SWT1), // Switch - AGPIO(GPIO_SWT1) +1, - AGPIO(GPIO_SWT1) +2, - AGPIO(GPIO_SWT1) +3, - AGPIO(GPIO_SWT1) +4, - AGPIO(GPIO_SWT1) +5, - AGPIO(GPIO_SWT1) +6, - AGPIO(GPIO_SWT1) +7, - AGPIO(GPIO_KEY1), // Button - AGPIO(GPIO_KEY1) +1, - AGPIO(GPIO_KEY1) +2, - AGPIO(GPIO_KEY1) +3, - AGPIO(GPIO_REL1), // Relay - AGPIO(GPIO_REL1) +1, - AGPIO(GPIO_REL1) +2, - AGPIO(GPIO_REL1) +3, - AGPIO(GPIO_REL1) +4, - AGPIO(GPIO_REL1) +5, - AGPIO(GPIO_REL1) +6, - AGPIO(GPIO_REL1) +7, - AGPIO(GPIO_REL1_INV), // Relay inverted - AGPIO(GPIO_REL1_INV) +1, - AGPIO(GPIO_REL1_INV) +2, - AGPIO(GPIO_REL1_INV) +3, - AGPIO(GPIO_REL1_INV) +4, - AGPIO(GPIO_REL1_INV) +5, - AGPIO(GPIO_REL1_INV) +6, - AGPIO(GPIO_REL1_INV) +7, - AGPIO(GPIO_PWM1), // PWM - AGPIO(GPIO_PWM1) +1, - AGPIO(GPIO_PWM1) +2, - AGPIO(GPIO_PWM1) +3, - AGPIO(GPIO_PWM1) +4, - AGPIO(GPIO_CNTR1), // Counter - AGPIO(GPIO_CNTR1) +1, - AGPIO(GPIO_CNTR1) +2, - AGPIO(GPIO_CNTR1) +3, - AGPIO(GPIO_PWM1_INV), // PWM inverted - AGPIO(GPIO_PWM1_INV) +1, - AGPIO(GPIO_PWM1_INV) +2, - AGPIO(GPIO_PWM1_INV) +3, - AGPIO(GPIO_PWM1_INV) +4, - AGPIO(GPIO_IRRECV), // IR receive - AGPIO(GPIO_LED1), // Led - AGPIO(GPIO_LED1) +1, - AGPIO(GPIO_LED1) +2, - AGPIO(GPIO_LED1) +3, - AGPIO(GPIO_LED1_INV), // Led inverted - AGPIO(GPIO_LED1_INV) +1, - AGPIO(GPIO_LED1_INV) +2, - AGPIO(GPIO_LED1_INV) +3, - AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface - AGPIO(GPIO_MHZ_RXD), - AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface - AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface - AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface - AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface - AGPIO(GPIO_SPI_CS), // SPI Chip Select - AGPIO(GPIO_SPI_DC), // SPI Data Direction - AGPIO(GPIO_BACKLIGHT), // Display backlight control - AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface - AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface - AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface - AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface - AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin - AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface - AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface - AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface - AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface - AGPIO(GPIO_TM16CLK), // TM1638 Clock - AGPIO(GPIO_TM16DIO), // TM1638 Data I/O - AGPIO(GPIO_TM16STB), // TM1638 Strobe - AGPIO(GPIO_SWT1_NP), // Switch no pullup - AGPIO(GPIO_SWT1_NP) +1, - AGPIO(GPIO_SWT1_NP) +2, - AGPIO(GPIO_SWT1_NP) +3, - AGPIO(GPIO_SWT1_NP) +4, - AGPIO(GPIO_SWT1_NP) +5, - AGPIO(GPIO_SWT1_NP) +6, - AGPIO(GPIO_SWT1_NP) +7, - AGPIO(GPIO_KEY1_NP), // Button no pullup - AGPIO(GPIO_KEY1_NP) +1, - AGPIO(GPIO_KEY1_NP) +2, - AGPIO(GPIO_KEY1_NP) +3, - AGPIO(GPIO_CNTR1_NP), // Counter no pullup - AGPIO(GPIO_CNTR1_NP) +1, - AGPIO(GPIO_CNTR1_NP) +2, - AGPIO(GPIO_CNTR1_NP) +3, - AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface - AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface - AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface - AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface - AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock - AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data - AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin - AGPIO(GPIO_RFSEND), // RF transmitter - AGPIO(GPIO_RFRECV), // RF receiver - AGPIO(GPIO_TUYA_TX), // Tuya Serial interface - AGPIO(GPIO_TUYA_RX), // Tuya Serial interface - AGPIO(GPIO_MGC3130_XFER), - AGPIO(GPIO_MGC3130_RESET), - AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output - AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input - AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock - AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select - AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command - AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding - AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface - AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface - AGPIO(GPIO_MAX31855CS), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface - AGPIO(GPIO_KEY1_INV), // Button inverted - AGPIO(GPIO_KEY1_INV) +1, - AGPIO(GPIO_KEY1_INV) +2, - AGPIO(GPIO_KEY1_INV) +3, - AGPIO(GPIO_KEY1_INV_NP), // Button inverted no pullup - AGPIO(GPIO_KEY1_INV_NP) +1, - AGPIO(GPIO_KEY1_INV_NP) +2, - AGPIO(GPIO_KEY1_INV_NP) +3, - AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) - AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) - AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current - AGPIO(GPIO_HLW_CF), // HLW8012 CF power - AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power - AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) - AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx - AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx - AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK - AGPIO(GPIO_SM16716_DAT), // SM16716 DATA - AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT - AGPIO(GPIO_DI), // my92x1 PWM input - AGPIO(GPIO_DCKI), // my92x1 CLK input - AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) - AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) - AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input - AGPIO(GPIO_TXD), // Serial interface - AGPIO(GPIO_RXD), // Serial interface - AGPIO(GPIO_ROT1A), // Rotary A Pin - AGPIO(GPIO_ROT1B), // Rotary B Pin - AGPIO(GPIO_ROT1A) +1, // Rotary A Pin - AGPIO(GPIO_ROT1B) +1, // Rotary B Pin - AGPIO(GPIO_HRE_CLOCK), - AGPIO(GPIO_HRE_DATA), - AGPIO(GPIO_ADE7953_IRQ), // ADE7953 IRQ - AGPIO(GPIO_LEDLNK), // Link led - AGPIO(GPIO_LEDLNK_INV), // Inverted link led - AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected - AGPIO(GPIO_BUZZER), // Buzzer - AGPIO(GPIO_BUZZER_INV), // Inverted buzzer - AGPIO(GPIO_OLED_RESET), // OLED Display Reset - AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin - AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin - AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_RDM6300_RX), - AGPIO(GPIO_IBEACON_TX), - AGPIO(GPIO_IBEACON_RX), - AGPIO(GPIO_A4988_DIR), // A4988 direction pin - AGPIO(GPIO_A4988_STP), // A4988 step pin - AGPIO(GPIO_A4988_ENA), // A4988 enabled pin - AGPIO(GPIO_A4988_MS1), // A4988 microstep pin1 - AGPIO(GPIO_A4988_MS1) +1, // A4988 microstep pin2 - AGPIO(GPIO_A4988_MS1) +2, // A4988 microstep pin3 - AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface - AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface - AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface - AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface - AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT), // SM2135 DATA - AGPIO(GPIO_DEEPSLEEP), - AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable - AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX - AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX - AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset - AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted - AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface - AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface - AGPIO(GPIO_GPS_RX), // GPS serial interface - AGPIO(GPIO_GPS_TX), // GPS serial interface - AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20 - AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 - AGPIO(GPIO_HM10_RX), // GPS serial interface - AGPIO(GPIO_HM10_TX), // GPS serial interface - AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin - AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin - AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX - AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX - AGPIO(GPIO_HRXL_RX), - AGPIO(GPIO_ELECTRIQ_MOODL_TX), - AGPIO(GPIO_AS3935), // AS3935 IRQ Pin - AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface - AGPIO(GPIO_BOILER_OT_RX), - AGPIO(GPIO_BOILER_OT_TX), - AGPIO(GPIO_WINDMETER_SPEED), - AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge - AGPIO(GPIO_TELEINFO_RX), - AGPIO(GPIO_TELEINFO_ENABLE), - AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO - AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface - AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface - AGPIO(GPIO_ZIGBEE_RST), // Zigbee reset - AGPIO(GPIO_DYP_RX) -}; - -/********************************************************************************************/ // Supported hardware modules - enum SupportedModules { SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH, SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS, SONOFF_DEV, H801, @@ -1303,8 +856,6 @@ enum SupportedModules { SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE, MAXMODULE }; -#define USER_MODULE 255 - const char kModuleNames[] PROGMEM = "Sonoff Basic|Sonoff RF|Sonoff SV|Sonoff TH|Sonoff Dual|Sonoff Pow|Sonoff 4CH|Sonoff S2X|Slampher|Sonoff Touch|" "Sonoff LED|1 Channel|4 Channel|Motor C/AC|ElectroDragon|EXS Relay(s)|WiOn|Generic|Sonoff Dev|H801|" @@ -2696,18 +2247,42 @@ const mytmplt8285 kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = { }; #endif // ESP8266 -#ifdef ESP32 -/********************************************************************************************/ -// Supported hardware modules -enum SupportedModules { WEMOS, ESP32_CAM_AITHINKER, MAXMODULE }; +#ifdef ESP32 +/********************************************************************************************\ + * ESP32 Module templates +\********************************************************************************************/ #define USER_MODULE 255 -const char kModuleNames[] PROGMEM = "ESP32-DevKit|ESP32 Cam AiThinker"; +// Supported hardware modules +enum SupportedModules { + WEMOS, + ESP32_CAM_AITHINKER, +// ESP32_Solo, +// WT32_ETH01, +// TTGO_WATCH, +// M5STACK_CORE2, + MAXMODULE }; + +const char kModuleNames[] PROGMEM = + "ESP32-DevKit|" + "ESP32-Cam|" +// "ESP32-Solo|" +// "WT32-Eth01|" +// "TTGO Watch|" +// "M5Stack Core2|" + ; // Default module settings -const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS, ESP32_CAM_AITHINKER }; +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { + WEMOS, + ESP32_CAM_AITHINKER, +// ESP32_Solo, +// WT32_ETH01, +// TTGO_WATCH, +// M5STACK_CORE2, +}; const mytmplt kModules PROGMEM = { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) diff --git a/tasmota/tasmota_template_legacy.h b/tasmota/tasmota_template_legacy.h new file mode 100644 index 000000000..153a6801b --- /dev/null +++ b/tasmota/tasmota_template_legacy.h @@ -0,0 +1,480 @@ +/* + tasmota_template_legacy.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 . +*/ + +#ifndef _TASMOTA_TEMPLATE_LEGACY_H_ +#define _TASMOTA_TEMPLATE_LEGACY_H_ + +#ifdef ESP8266 +//******************************************************************************************** +// User selectable GPIO functionality +// ATTENTION: No additions are supported +enum LegacyUserSelectablePins { + GPI8_NONE, // Not used + GPI8_DHT11, // DHT11 + GPI8_DHT22, // DHT21, DHT22, AM2301, AM2302, AM2321 + GPI8_SI7021, // iTead SI7021 + GPI8_DSB, // Single wire DS18B20 or DS18S20 + GPI8_I2C_SCL, // I2C SCL + GPI8_I2C_SDA, // I2C SDA + GPI8_WS2812, // WS2812 Led string + GPI8_IRSEND, // IR remote + GPI8_SWT1, // User connected external switches + GPI8_SWT2, + GPI8_SWT3, + GPI8_SWT4, + GPI8_SWT5, + GPI8_SWT6, + GPI8_SWT7, + GPI8_SWT8, + GPI8_KEY1, // Button usually connected to GPIO0 + GPI8_KEY2, + GPI8_KEY3, + GPI8_KEY4, + GPI8_REL1, // Relays + GPI8_REL2, + GPI8_REL3, + GPI8_REL4, + GPI8_REL5, + GPI8_REL6, + GPI8_REL7, + GPI8_REL8, + GPI8_REL1_INV, + GPI8_REL2_INV, + GPI8_REL3_INV, + GPI8_REL4_INV, + GPI8_REL5_INV, + GPI8_REL6_INV, + GPI8_REL7_INV, + GPI8_REL8_INV, + GPI8_PWM1, // RGB Red or C Cold White + GPI8_PWM2, // RGB Green or CW Warm White + GPI8_PWM3, // RGB Blue + GPI8_PWM4, // RGBW (Cold) White + GPI8_PWM5, // RGBCW Warm White + GPI8_CNTR1, + GPI8_CNTR2, + GPI8_CNTR3, + GPI8_CNTR4, + GPI8_PWM1_INV, // RGB Red or C Cold White + GPI8_PWM2_INV, // RGB Green or CW Warm White + GPI8_PWM3_INV, // RGB Blue + GPI8_PWM4_INV, // RGBW (Cold) White + GPI8_PWM5_INV, // RGBCW Warm White + GPI8_IRRECV, // IR receiver + GPI8_LED1, // Leds + GPI8_LED2, + GPI8_LED3, + GPI8_LED4, + GPI8_LED1_INV, + GPI8_LED2_INV, + GPI8_LED3_INV, + GPI8_LED4_INV, + GPI8_MHZ_TXD, // MH-Z19 Serial interface + GPI8_MHZ_RXD, // MH-Z19 Serial interface + GPI8_PZEM0XX_TX, // PZEM0XX Serial interface + GPI8_PZEM004_RX, // PZEM004T Serial interface + GPI8_SAIR_TX, // SenseAir Serial interface + GPI8_SAIR_RX, // SenseAir Serial interface + GPI8_SPI_CS, // SPI Chip Select + GPI8_SPI_DC, // SPI Data Direction + GPI8_BACKLIGHT, // Display backlight control + GPI8_PMS5003_RX, // Plantower PMS5003 Serial interface + GPI8_SDS0X1_RX, // Nova Fitness SDS011 Serial interface + GPI8_SBR_TX, // Serial Bridge Serial interface + GPI8_SBR_RX, // Serial Bridge Serial interface + GPI8_SR04_TRIG, // SR04 Trigger/TX pin + GPI8_SR04_ECHO, // SR04 Echo/RX pin + GPI8_SDM120_TX, // SDM120 Serial interface + GPI8_SDM120_RX, // SDM120 Serial interface + GPI8_SDM630_TX, // SDM630 Serial interface + GPI8_SDM630_RX, // SDM630 Serial interface + GPI8_TM16CLK, // TM1638 Clock + GPI8_TM16DIO, // TM1638 Data I/O + GPI8_TM16STB, // TM1638 Strobe + GPI8_SWT1_NP, // User connected external switches + GPI8_SWT2_NP, + GPI8_SWT3_NP, + GPI8_SWT4_NP, + GPI8_SWT5_NP, + GPI8_SWT6_NP, + GPI8_SWT7_NP, + GPI8_SWT8_NP, + GPI8_KEY1_NP, // Button usually connected to GPIO0 + GPI8_KEY2_NP, + GPI8_KEY3_NP, + GPI8_KEY4_NP, + GPI8_CNTR1_NP, + GPI8_CNTR2_NP, + GPI8_CNTR3_NP, + GPI8_CNTR4_NP, + GPI8_PZEM016_RX, // PZEM-014,016 Serial Modbus interface + GPI8_PZEM017_RX, // PZEM-003,017 Serial Modbus interface + GPI8_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player + GPI8_SDS0X1_TX, // Nova Fitness SDS011 Serial interface + GPI8_HX711_SCK, // HX711 Load Cell clock + GPI8_HX711_DAT, // HX711 Load Cell data + GPI8_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin + GPI8_RFSEND, // RF transmitter + GPI8_RFRECV, // RF receiver + GPI8_TUYA_TX, // Tuya Serial interface + GPI8_TUYA_RX, // Tuya Serial interface + GPI8_MGC3130_XFER, // MGC3130 Transfer + GPI8_MGC3130_RESET, // MGC3130 Reset + GPI8_SSPI_MISO, // Software SPI Master Input Client Output + GPI8_SSPI_MOSI, // Software SPI Master Output Client Input + GPI8_SSPI_SCLK, // Software SPI Serial Clock + GPI8_SSPI_CS, // Software SPI Chip Select + GPI8_SSPI_DC, // Software SPI Data or Command + GPI8_RF_SENSOR, // Rf receiver with sensor decoding + GPI8_AZ_TXD, // AZ-Instrument 7798 Serial interface + GPI8_AZ_RXD, // AZ-Instrument 7798 Serial interface + GPI8_MAX31855CS, // MAX31855 Serial interface + GPI8_MAX31855CLK, // MAX31855 Serial interface + GPI8_MAX31855DO, // MAX31855 Serial interface + GPI8_KEY1_INV, // Inverted buttons + GPI8_KEY2_INV, + GPI8_KEY3_INV, + GPI8_KEY4_INV, + GPI8_KEY1_INV_NP, // Inverted buttons without pull-up + GPI8_KEY2_INV_NP, + GPI8_KEY3_INV_NP, + GPI8_KEY4_INV_NP, + GPI8_NRG_SEL, // HLW8012/HLJ-01 Sel output (1 = Voltage) + GPI8_NRG_SEL_INV, // HLW8012/HLJ-01 Sel output (0 = Voltage) + GPI8_NRG_CF1, // HLW8012/HLJ-01 CF1 voltage / current + GPI8_HLW_CF, // HLW8012 CF power + GPI8_HJL_CF, // HJL-01/BL0937 CF power + GPI8_MCP39F5_TX, // MCP39F501 Serial interface (Shelly2) + GPI8_MCP39F5_RX, // MCP39F501 Serial interface (Shelly2) + GPI8_MCP39F5_RST, // MCP39F501 Reset (Shelly2) + GPI8_PN532_TXD, // PN532 NFC Serial Tx + GPI8_PN532_RXD, // PN532 NFC Serial Rx + GPI8_SM16716_CLK, // SM16716 CLOCK + GPI8_SM16716_DAT, // SM16716 DATA + GPI8_SM16716_SEL, // SM16716 SELECT + GPI8_DI, // my92x1 PWM input + GPI8_DCKI, // my92x1 CLK input + GPI8_CSE7766_TX, // CSE7766 Serial interface (S31 and Pow R2) - Not used anymore 20200121 + GPI8_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2) + GPI8_ARIRFRCV, // AriLux RF Receive input + GPI8_TXD, // Serial interface + GPI8_RXD, // Serial interface + GPI8_ROT1A, // Rotary switch1 A Pin + GPI8_ROT1B, // Rotary switch1 B Pin + GPI8_ROT2A, // Rotary switch2 A Pin + GPI8_ROT2B, // Rotary switch2 B Pin + GPI8_HRE_CLOCK, // Clock/Power line for HR-E Water Meter + GPI8_HRE_DATA, // Data line for HR-E Water Meter + GPI8_ADE7953_IRQ, // ADE7953 IRQ + GPI8_LEDLNK, // Link led + GPI8_LEDLNK_INV, // Inverted link led + GPI8_ARIRFSEL, // Arilux RF Receive input selected + GPI8_BUZZER, // Buzzer + GPI8_BUZZER_INV, // Inverted buzzer + GPI8_OLED_RESET, // OLED Display Reset + GPI8_SOLAXX1_TX, // Solax Inverter tx pin + GPI8_SOLAXX1_RX, // Solax Inverter rx pin + GPI8_ZIGBEE_TX, // Zigbee Serial interface + GPI8_ZIGBEE_RX, // Zigbee Serial interface + GPI8_RDM6300_RX, // RDM6300 RX + GPI8_IBEACON_TX, // HM17 IBEACON TX + GPI8_IBEACON_RX, // HM17 IBEACON RX + GPI8_A4988_DIR, // A4988 direction pin + GPI8_A4988_STP, // A4988 step pin + GPI8_A4988_ENA, // A4988 enabled pin + GPI8_A4988_MS1, // A4988 microstep pin1 + GPI8_A4988_MS2, // A4988 microstep pin2 + GPI8_A4988_MS3, // A4988 microstep pin3 + GPI8_DDS2382_TX, // DDS2382 Serial interface + GPI8_DDS2382_RX, // DDS2382 Serial interface + GPI8_DDSU666_TX, // DDSU666 Serial interface + GPI8_DDSU666_RX, // DDSU666 Serial interface + GPI8_SM2135_CLK, // SM2135 Clk + GPI8_SM2135_DAT, // SM2135 Dat + GPI8_DEEPSLEEP, // Kill switch for deepsleep + GPI8_EXS_ENABLE, // EXS MCU Enable + GPI8_TASMOTACLIENT_TXD, // Client TX + GPI8_TASMOTACLIENT_RXD, // Client RX + GPI8_TASMOTACLIENT_RST, // Client Reset Pin + GPI8_TASMOTACLIENT_RST_INV, // Client Reset Inverted + GPI8_HPMA_RX, // Honeywell HPMA115S0 Serial interface + GPI8_HPMA_TX, // Honeywell HPMA115S0 Serial interface + GPI8_GPS_RX, // GPS serial interface + GPI8_GPS_TX, // GPS serial interface + GPI8_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20 + GPI8_DHT11_OUT, // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 + GPI8_HM10_RX, // HM10-BLE-Mijia-bridge serial interface + GPI8_HM10_TX, // HM10-BLE-Mijia-bridge serial interface + GPI8_LE01MR_RX, // F&F LE-01MR energy meter + GPI8_LE01MR_TX, // F&F LE-01MR energy meter + GPI8_CC1101_GDO0, // CC1101 pin for RX + GPI8_CC1101_GDO2, // CC1101 pin for RX + GPI8_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor + GPI8_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX + GPI8_AS3935, // Franklin Lightning Sensor + GPI8_PMS5003_TX, // Plantower PMS5003 Serial interface + GPI8_BOILER_OT_RX, // OpenTherm Boiler RX pin + GPI8_BOILER_OT_TX, // OpenTherm Boiler TX pin + GPI8_WINDMETER_SPEED, // WindMeter speed counter pin + GPI8_BL0940_RX, // BL0940 serial interface + GPI8_TCP_TX, // TCP Serial bridge + GPI8_TCP_RX, // TCP Serial bridge + GPI8_TELEINFO_RX, // TELEINFO serial interface + GPI8_TELEINFO_ENABLE,// TELEINFO Enable PIN + GPI8_LMT01, // LMT01 input counting pin + GPI8_IEM3000_TX, // IEM3000 Serial interface + GPI8_IEM3000_RX, // IEM3000 Serial interface + GPI8_ZIGBEE_RST, // Zigbee reset + GPI8_DYP_RX, + GPI8_SENSOR_END }; + +// Programmer selectable GPIO functionality +enum LegacyProgramSelectablePins { + GPI8_FIX_START = 251, + GPI8_SPI_MISO, // SPI MISO library fixed pin GPIO12 + GPI8_SPI_MOSI, // SPI MOSI library fixed pin GPIO13 + GPI8_SPI_CLK, // SPI Clk library fixed pin GPIO14 + GPI8_USER, // User configurable needs to be 255 + GPI8_MAX }; + +// Indexed by LegacyUserSelectablePins to convert legacy (8-bit) GPIOs +const uint16_t kGpioConvert[] PROGMEM = { + GPIO_NONE, + AGPIO(GPIO_DHT11), // DHT11 + AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_SI7021), // iTead SI7021 + AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_I2C_SCL), // I2C SCL + AGPIO(GPIO_I2C_SDA), // I2C SDA + AGPIO(GPIO_WS2812), // WS2812 Led string + AGPIO(GPIO_IRSEND), // IR remote + AGPIO(GPIO_SWT1), // Switch + AGPIO(GPIO_SWT1) +1, + AGPIO(GPIO_SWT1) +2, + AGPIO(GPIO_SWT1) +3, + AGPIO(GPIO_SWT1) +4, + AGPIO(GPIO_SWT1) +5, + AGPIO(GPIO_SWT1) +6, + AGPIO(GPIO_SWT1) +7, + AGPIO(GPIO_KEY1), // Button + AGPIO(GPIO_KEY1) +1, + AGPIO(GPIO_KEY1) +2, + AGPIO(GPIO_KEY1) +3, + AGPIO(GPIO_REL1), // Relay + AGPIO(GPIO_REL1) +1, + AGPIO(GPIO_REL1) +2, + AGPIO(GPIO_REL1) +3, + AGPIO(GPIO_REL1) +4, + AGPIO(GPIO_REL1) +5, + AGPIO(GPIO_REL1) +6, + AGPIO(GPIO_REL1) +7, + AGPIO(GPIO_REL1_INV), // Relay inverted + AGPIO(GPIO_REL1_INV) +1, + AGPIO(GPIO_REL1_INV) +2, + AGPIO(GPIO_REL1_INV) +3, + AGPIO(GPIO_REL1_INV) +4, + AGPIO(GPIO_REL1_INV) +5, + AGPIO(GPIO_REL1_INV) +6, + AGPIO(GPIO_REL1_INV) +7, + AGPIO(GPIO_PWM1), // PWM + AGPIO(GPIO_PWM1) +1, + AGPIO(GPIO_PWM1) +2, + AGPIO(GPIO_PWM1) +3, + AGPIO(GPIO_PWM1) +4, + AGPIO(GPIO_CNTR1), // Counter + AGPIO(GPIO_CNTR1) +1, + AGPIO(GPIO_CNTR1) +2, + AGPIO(GPIO_CNTR1) +3, + AGPIO(GPIO_PWM1_INV), // PWM inverted + AGPIO(GPIO_PWM1_INV) +1, + AGPIO(GPIO_PWM1_INV) +2, + AGPIO(GPIO_PWM1_INV) +3, + AGPIO(GPIO_PWM1_INV) +4, + AGPIO(GPIO_IRRECV), // IR receive + AGPIO(GPIO_LED1), // Led + AGPIO(GPIO_LED1) +1, + AGPIO(GPIO_LED1) +2, + AGPIO(GPIO_LED1) +3, + AGPIO(GPIO_LED1_INV), // Led inverted + AGPIO(GPIO_LED1_INV) +1, + AGPIO(GPIO_LED1_INV) +2, + AGPIO(GPIO_LED1_INV) +3, + AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_RXD), + AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface + AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface + AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface + AGPIO(GPIO_SPI_CS), // SPI Chip Select + AGPIO(GPIO_SPI_DC), // SPI Data Direction + AGPIO(GPIO_BACKLIGHT), // Display backlight control + AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface + AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin + AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface + AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface + AGPIO(GPIO_TM16CLK), // TM1638 Clock + AGPIO(GPIO_TM16DIO), // TM1638 Data I/O + AGPIO(GPIO_TM16STB), // TM1638 Strobe + AGPIO(GPIO_SWT1_NP), // Switch no pullup + AGPIO(GPIO_SWT1_NP) +1, + AGPIO(GPIO_SWT1_NP) +2, + AGPIO(GPIO_SWT1_NP) +3, + AGPIO(GPIO_SWT1_NP) +4, + AGPIO(GPIO_SWT1_NP) +5, + AGPIO(GPIO_SWT1_NP) +6, + AGPIO(GPIO_SWT1_NP) +7, + AGPIO(GPIO_KEY1_NP), // Button no pullup + AGPIO(GPIO_KEY1_NP) +1, + AGPIO(GPIO_KEY1_NP) +2, + AGPIO(GPIO_KEY1_NP) +3, + AGPIO(GPIO_CNTR1_NP), // Counter no pullup + AGPIO(GPIO_CNTR1_NP) +1, + AGPIO(GPIO_CNTR1_NP) +2, + AGPIO(GPIO_CNTR1_NP) +3, + AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface + AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface + AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface + AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock + AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data + AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin + AGPIO(GPIO_RFSEND), // RF transmitter + AGPIO(GPIO_RFRECV), // RF receiver + AGPIO(GPIO_TUYA_TX), // Tuya Serial interface + AGPIO(GPIO_TUYA_RX), // Tuya Serial interface + AGPIO(GPIO_MGC3130_XFER), + AGPIO(GPIO_MGC3130_RESET), + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input + AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock + AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select + AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command + AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding + AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface + AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface + AGPIO(GPIO_MAX31855CS), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface + AGPIO(GPIO_KEY1_INV), // Button inverted + AGPIO(GPIO_KEY1_INV) +1, + AGPIO(GPIO_KEY1_INV) +2, + AGPIO(GPIO_KEY1_INV) +3, + AGPIO(GPIO_KEY1_INV_NP), // Button inverted no pullup + AGPIO(GPIO_KEY1_INV_NP) +1, + AGPIO(GPIO_KEY1_INV_NP) +2, + AGPIO(GPIO_KEY1_INV_NP) +3, + AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) + AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) + AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current + AGPIO(GPIO_HLW_CF), // HLW8012 CF power + AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power + AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) + AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx + AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx + AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK + AGPIO(GPIO_SM16716_DAT), // SM16716 DATA + AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT + AGPIO(GPIO_DI), // my92x1 PWM input + AGPIO(GPIO_DCKI), // my92x1 CLK input + AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input + AGPIO(GPIO_TXD), // Serial interface + AGPIO(GPIO_RXD), // Serial interface + AGPIO(GPIO_ROT1A), // Rotary A Pin + AGPIO(GPIO_ROT1B), // Rotary B Pin + AGPIO(GPIO_ROT1A) +1, // Rotary A Pin + AGPIO(GPIO_ROT1B) +1, // Rotary B Pin + AGPIO(GPIO_HRE_CLOCK), + AGPIO(GPIO_HRE_DATA), + AGPIO(GPIO_ADE7953_IRQ), // ADE7953 IRQ + AGPIO(GPIO_LEDLNK), // Link led + AGPIO(GPIO_LEDLNK_INV), // Inverted link led + AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected + AGPIO(GPIO_BUZZER), // Buzzer + AGPIO(GPIO_BUZZER_INV), // Inverted buzzer + AGPIO(GPIO_OLED_RESET), // OLED Display Reset + AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin + AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin + AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface + AGPIO(GPIO_RDM6300_RX), + AGPIO(GPIO_IBEACON_TX), + AGPIO(GPIO_IBEACON_RX), + AGPIO(GPIO_A4988_DIR), // A4988 direction pin + AGPIO(GPIO_A4988_STP), // A4988 step pin + AGPIO(GPIO_A4988_ENA), // A4988 enabled pin + AGPIO(GPIO_A4988_MS1), // A4988 microstep pin1 + AGPIO(GPIO_A4988_MS1) +1, // A4988 microstep pin2 + AGPIO(GPIO_A4988_MS1) +2, // A4988 microstep pin3 + AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface + AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface + AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK + AGPIO(GPIO_SM2135_DAT), // SM2135 DATA + AGPIO(GPIO_DEEPSLEEP), + AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted + AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_GPS_RX), // GPS serial interface + AGPIO(GPIO_GPS_TX), // GPS serial interface + AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_HM10_RX), // GPS serial interface + AGPIO(GPIO_HM10_TX), // GPS serial interface + AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin + AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin + AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX + AGPIO(GPIO_HRXL_RX), + AGPIO(GPIO_ELECTRIQ_MOODL_TX), + AGPIO(GPIO_AS3935), // AS3935 IRQ Pin + AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_BOILER_OT_RX), + AGPIO(GPIO_BOILER_OT_TX), + AGPIO(GPIO_WINDMETER_SPEED), + AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge + AGPIO(GPIO_TELEINFO_RX), + AGPIO(GPIO_TELEINFO_ENABLE), + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO + AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface + AGPIO(GPIO_ZIGBEE_RST), // Zigbee reset + AGPIO(GPIO_DYP_RX) +}; + +/********************************************************************************************/ +#endif // ESP8266 + +#endif // _TASMOTA_TEMPLATE_LEGACY_H_ From 6058cf014ef57d5fdd53c7c383cbc3684e0630a5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 28 Dec 2020 18:01:02 +0100 Subject: [PATCH 033/105] Prep for embedded ESP32 module template re-introduction --- tasmota/support.ino | 17 +++- tasmota/tasmota_template.h | 200 +++++++++++++++++++++++++++---------- 2 files changed, 164 insertions(+), 53 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 30436fd2f..577c8bb95 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1304,6 +1304,17 @@ uint8_t ModuleNr(void) return (USER_MODULE == Settings.module) ? 0 : Settings.module +1; } +uint32_t ModuleTemplate(uint32_t module) { + uint32_t i = 0; + for (i = 0; i < sizeof(kModuleNiceList); i++) { + if (Settings.module == pgm_read_byte(kModuleNiceList + i)) { + break; + } + } + if (i == sizeof(kModuleNiceList)) { i = 0; } + return i; +} + bool ValidTemplateModule(uint32_t index) { for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) { @@ -1399,7 +1410,7 @@ void TemplateGpios(myio *gp) GetInternalTemplate(&src, Settings.module, 1); #endif // ESP8266 #ifdef ESP32 - memcpy_P(&src, &kModules.gp, sizeof(mycfgio)); + memcpy_P(&src, &kModules[ModuleTemplate(Settings.module)].gp, sizeof(mycfgio)); #endif // ESP32 } // 11 85 00 85 85 00 00 00 15 38 85 00 00 81 @@ -1429,7 +1440,7 @@ gpio_flag ModuleFlag(void) GetInternalTemplate(&flag, Settings.module, 2); #endif // ESP8266 #ifdef ESP32 - memcpy_P(&flag, &kModules.flag, sizeof(gpio_flag)); + memcpy_P(&flag, &kModules[ModuleTemplate(Settings.module)].flag, sizeof(gpio_flag)); #endif // ESP32 } @@ -1446,7 +1457,7 @@ void ModuleDefault(uint32_t module) GetInternalTemplate(&Settings.user_template, module, 3); #endif // ESP8266 #ifdef ESP32 - memcpy_P(&Settings.user_template, &kModules, sizeof(mytmplt)); + memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt)); #endif // ESP32 } diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index c38b037bc..be9507d60 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -2259,74 +2259,174 @@ const mytmplt8285 kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = { enum SupportedModules { WEMOS, ESP32_CAM_AITHINKER, -// ESP32_Solo, -// WT32_ETH01, -// TTGO_WATCH, -// M5STACK_CORE2, + ESP32_Solo, + WT32_ETH01, + TTGO_WATCH, + M5STACK_CORE2, MAXMODULE }; const char kModuleNames[] PROGMEM = "ESP32-DevKit|" +#ifdef USE_WEBCAM "ESP32-Cam|" +#endif // USE_WEBCAM // "ESP32-Solo|" // "WT32-Eth01|" // "TTGO Watch|" -// "M5Stack Core2|" +#ifdef USE_M5STACK_CORE2 + "M5Stack Core2|" +#endif // USE_M5STACK_CORE2 ; // Default module settings -const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { +const uint8_t kModuleNiceList[] PROGMEM = { WEMOS, +#ifdef USE_WEBCAM ESP32_CAM_AITHINKER, +#endif // USE_WEBCAM // ESP32_Solo, // WT32_ETH01, // TTGO_WATCH, -// M5STACK_CORE2, +#ifdef USE_M5STACK_CORE2 + M5STACK_CORE2, +#endif // USE_M5STACK_CORE2 }; -const mytmplt kModules PROGMEM = -{ // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) - AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - AGPIO(GPIO_USER), // 5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - // 6 IO GPIO6, Flash CLK - // 7 IO GPIO7, Flash D0 - // 8 IO GPIO8, Flash D1 - AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD - AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD - // 11 IO GPIO11, Flash CMD - AGPIO(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.) - AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - AGPIO(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.) - AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT - AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - AGPIO(GPIO_USER), // 18 IO GPIO18, VSPICLK, HS1_DATA7 - AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - 0, // 20 - AGPIO(GPIO_USER), // 21 IO GPIO21, VSPIHD, EMAC_TX_EN - AGPIO(GPIO_USER), // 22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - AGPIO(GPIO_USER), // 23 IO GPIO23, VSPID, HS1_STROBE - 0, // 24 - AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - 0, // 28 - 0, // 29 - 0, // 30 - 0, // 31 - AGPIO(GPIO_USER), // 32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 - AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 - AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 - AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 - AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 - 0, // 37 NO PULLUP - 0, // 38 NO PULLUP - AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 - 0 // Flag +const mytmplt kModules[] PROGMEM = +{ + { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) + AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + AGPIO(GPIO_USER), // 5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK + // 6 IO GPIO6, Flash CLK + // 7 IO GPIO7, Flash D0 + // 8 IO GPIO8, Flash D1 + AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD + AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO GPIO11, Flash CMD + AGPIO(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.) + AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER + AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + AGPIO(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.) + AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + AGPIO(GPIO_USER), // 18 IO GPIO18, VSPICLK, HS1_DATA7 + AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 + 0, // 20 + AGPIO(GPIO_USER), // 21 IO GPIO21, VSPIHD, EMAC_TX_EN + AGPIO(GPIO_USER), // 22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 + AGPIO(GPIO_USER), // 23 IO GPIO23, VSPID, HS1_STROBE + 0, // 24 + AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 + AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 + AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV + 0, // 28 + 0, // 29 + 0, // 30 + 0, // 31 + AGPIO(GPIO_USER), // 32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 + AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 + AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 + AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 + AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 + 0 // Flag + }, +#ifdef USE_WEBCAM + { // ESP32_CAM_AITHINKER - Any ESP32 device with webcam (ESP32) + AGPIO(GPIO_WEBCAM_XCLK), // 0 (I)O GPIO0, CAM_XCLK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + AGPIO(GPIO_WEBCAM_DATA), // 5 IO GPIO5, CAM_DATA1 + // 6 IO GPIO6, Flash CLK + // 7 IO GPIO7, Flash D0 + // 8 IO GPIO8, Flash D1 + AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD + AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO GPIO11, Flash CMD + AGPIO(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.) + AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER + AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + AGPIO(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.) + AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + AGPIO(GPIO_WEBCAM_DATA) +1, // 18 IO GPIO18, CAM_DATA2 + AGPIO(GPIO_WEBCAM_DATA) +2, // 19 IO GPIO19, CAM_DATA3 + 0, // 20 + AGPIO(GPIO_WEBCAM_DATA) +3, // 21 IO GPIO21, CAM_DATA4 + AGPIO(GPIO_WEBCAM_PCLK), // 22 IO LED GPIO22, CAM_PCLK + AGPIO(GPIO_WEBCAM_HREF), // 23 IO GPIO23, CAM_HREF + 0, // 24 + AGPIO(GPIO_WEBCAM_VSYNC), // 25 IO GPIO25, CAM_VSYNC + AGPIO(GPIO_WEBCAM_SIOD), // 26 IO GPIO26, CAM_SIOD + AGPIO(GPIO_WEBCAM_SIOC), // 27 IO GPIO27, CAM_SIOC + 0, // 28 + 0, // 29 + 0, // 30 + 0, // 31 + AGPIO(GPIO_WEBCAM_PWDN), // 32 IO GPIO32, CAM_PWDN + AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 + AGPIO(GPIO_WEBCAM_DATA) +6, // 34 I NO PULLUP GPIO34, CAM_DATA7 + AGPIO(GPIO_WEBCAM_DATA) +7, // 35 I NO PULLUP GPIO35, CAM_DATA8 + AGPIO(GPIO_WEBCAM_DATA) +4, // 36 I NO PULLUP GPIO36, CAM_DATA5 + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_WEBCAM_DATA) +5, // 39 I NO PULLUP GPIO39, CAM_DATA6 + 0 // Flag + } +#endif // USE_WEBCAM +#ifdef USE_M5STACK_CORE2 + { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) + AGPIO(GPIO_USER), // 0 (I)O GPIO0, SPKR_LRCK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD + AGPIO(GPIO_USER), // 2 IO GPIO2, SPKR_DATA + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD + 0, // 4 IO GPIO4, SPI_CS_CARD + 0, // 5 IO GPIO5, SPI_CS_LCD + // 6 IO GPIO6, Flash CLK + // 7 IO GPIO7, Flash D0 + // 8 IO GPIO8, Flash D1 + 0, // 9 IO GPIO9, Flash D2, PSRAM_D3 + 0, // 10 IO GPIO10, Flash D3, PSRAM_D2 + // 11 IO GPIO11, Flash CMD + 0, // 12 (I)O GPIO12, SPKR_CLK + AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER + AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + 0, // 15 (I)O GPIO15, SPI_DC_LCD + 0, // 16 IO GPIO16, PSRAM_CS + 0, // 17 IO GPIO17, PSRAM_CLK + AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, SPI_CLK + AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 + 0, // 20 + 0, // 21 IO GPIO21, I2C_SDA_INTERNAL + 0, // 22 IO LED GPIO22, I2C_SCL_INTERNAL + AGPIO(GPIO_SPI_MOSI), // 23 IO GPIO23, SPI_MOSI + 0, // 24 + AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 + AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 + AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV + 0, // 28 + 0, // 29 + 0, // 30 + 0, // 31 + AGPIO(GPIO_I2C_SDA), // 32 IO GPIO32, I2C_SDA + AGPIO(GPIO_I2C_SCL), // 33 IO GPIO33, I2C_SCL + AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 + AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 + AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + 0, // 37 NO PULLUP + AGPIO(GPIO_SPI_MISO), // 38 NO PULLUP GPIO38, SPI_MISO + 0, // 39 I NO PULLUP GPIO39, INT_TOUCHPAD + 0 // Flag + } +#endif // USE_M5STACK_CORE2 }; /*********************************************************************************************\ From c04c97af882c47e017d35b572326b62868a0940c Mon Sep 17 00:00:00 2001 From: Mike Harris Date: Mon, 28 Dec 2020 15:29:26 -0800 Subject: [PATCH 034/105] Update contributing doc to point to development branch. I think this was a typo, as the dev branch doesn't exist, yet development does. --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34c3c2b98..8a2d4afc5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,13 +47,13 @@ The process is straight-forward. - Fork the Tasmota Repository [git repository](https://github.com/arendst/Tasmota). - Write/Change the code in your Fork for a new feature, bug fix, new sensor, optimization, etc. - Ensure tests work. - - Create a Pull Request against the [**dev**](https://github.com/arendst/Tasmota/tree/dev) branch of Tasmota. + - Create a Pull Request against the [**development**](https://github.com/arendst/Tasmota/tree/development) branch of Tasmota. -1. All pull requests must be done against the dev branch. +1. All pull requests must be done against the development branch. 2. Only relevant files should be touched (Also beware if your editor has auto-formatting feature enabled). 3. Only one feature/fix should be added per PR. 4. If adding a new functionality (new hardware, new library support) not related to an existing component move it to it's own modules (.ino file). -5. PRs that don't compile (fail in CI Tests) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts. +5. PRs that don't compile (fail in CI Tests) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in development - you might need to rebase and resolve conflicts. 6. All pull requests should undergo peer review by at least one contributor other than the creator, excepts for the owner. 7. All pull requests should consider updates to the documentation. 8. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority. From 02f34a3d6d0ca5892ca9fe3986fe11a23e0372ee Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 29 Dec 2020 10:35:44 +0100 Subject: [PATCH 035/105] Add IR_SEND_INVERTED and IR_SEND_USE_MODULATION compile options --- tasmota/my_user_config.h | 4 ++++ tasmota/xdrv_05_irremote.ino | 2 +- tasmota/xdrv_05_irremote_full.ino | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index fc108ce9f..7c354c8bf 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -719,6 +719,10 @@ // -- IR Remote features - subset of IR protocols -------------------------- #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k3 code, 0k3 mem, 48 iram) + #define IR_SEND_INVERTED false // Invert the output. (default = false) e.g. LED is illuminated when GPIO is LOW rather than HIGH. + // Setting inverted to something other than the default could easily destroy your IR LED if you are overdriving it. + // Unless you REALLY know what you are doing, don't change this. + #define IR_SEND_USE_MODULATION true // Do we do frequency modulation during transmission? i.e. If not, assume a 100% duty cycle. #define USE_IR_SEND_NEC // Support IRsend NEC protocol #define USE_IR_SEND_RC5 // Support IRsend Philips RC5 protocol #define USE_IR_SEND_RC6 // Support IRsend Philips RC6 protocol diff --git a/tasmota/xdrv_05_irremote.ino b/tasmota/xdrv_05_irremote.ino index 881ce62bf..efa048465 100644 --- a/tasmota/xdrv_05_irremote.ino +++ b/tasmota/xdrv_05_irremote.ino @@ -128,7 +128,7 @@ IRsend *irsend = nullptr; void IrSendInit(void) { - irsend = new IRsend(Pin(GPIO_IRSEND)); // an IR led is at GPIO_IRSEND + irsend = new IRsend(Pin(GPIO_IRSEND), IR_SEND_INVERTED, IR_SEND_USE_MODULATION); // an IR led is at GPIO_IRSEND irsend->begin(); } diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 31dd22968..4bfd00da2 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -136,7 +136,7 @@ StateModes strToStateMode(class JsonParserToken token, StateModes def); // decla void IrSendInit(void) { - irsend = new IRsend(Pin(GPIO_IRSEND)); // an IR led is at GPIO_IRSEND + irsend = new IRsend(Pin(GPIO_IRSEND), IR_SEND_INVERTED, IR_SEND_USE_MODULATION); // an IR led is at GPIO_IRSEND irsend->begin(); } @@ -470,7 +470,7 @@ uint32_t IrRemoteCmndIrHvacJson(void) if (!IR_RCV_WHILE_SENDING && (irrecv != nullptr)) { irrecv->disableIRIn(); } if (stateMode == StateModes::SEND_ONLY || stateMode == StateModes::SEND_STORE) { - IRac ac(Pin(GPIO_IRSEND)); + IRac ac(Pin(GPIO_IRSEND), IR_SEND_INVERTED, IR_SEND_USE_MODULATION); bool success = ac.sendAc(state, irhvac_stateful && irac_prev_state.protocol == state.protocol ? &irac_prev_state : nullptr); if (!success) { return IE_SYNTAX_IRHVAC; } } From cb71466bd449b0e9c32a863bc27d274d7b86230e Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Tue, 29 Dec 2020 09:53:15 +0000 Subject: [PATCH 036/105] webserver - move all compressed scripts to subfolders /html_uncompressed and /htmlcompressed. Add utility tools/unishox/compress-html-uncompressed.py to compress all files found in tasmota/html_uncompressed and write compressed version to tasmota/htmlcompressed --- tasmota/html_compressed/HTTP_HEADER1_ES6.h | 22 + tasmota/html_compressed/HTTP_HEADER1_NOES6.h | 22 + .../html_compressed/HTTP_HEAD_LAST_SCRIPT.h | 16 + tasmota/html_compressed/HTTP_HEAD_STYLE1.h | 24 + tasmota/html_compressed/HTTP_HEAD_STYLE2.h | 20 + .../html_compressed/HTTP_HEAD_STYLE_ZIGBEE.h | 19 + tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h | 39 ++ .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 30 + .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 27 + .../html_compressed/HTTP_SCRIPT_ROOT_PART2.h | 17 + .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 33 ++ .../html_compressed/HTTP_SCRIPT_TEMPLATE.h | 20 + tasmota/html_uncompressed/HTTP_HEADER1_ES6.h | 16 + .../html_uncompressed/HTTP_HEADER1_NOES6.h | 22 + .../html_uncompressed/HTTP_HEAD_LAST_SCRIPT.h | 12 + tasmota/html_uncompressed/HTTP_HEAD_STYLE1.h | 12 + tasmota/html_uncompressed/HTTP_HEAD_STYLE2.h | 11 + .../HTTP_HEAD_STYLE_ZIGBEE.h | 5 + .../html_uncompressed/HTTP_SCRIPT_CONSOL.h | 49 ++ .../HTTP_SCRIPT_MODULE_TEMPLATE.h | 24 + .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 24 + .../HTTP_SCRIPT_ROOT_PART2.h | 11 + .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 44 ++ .../html_uncompressed/HTTP_SCRIPT_TEMPLATE.h | 21 + tasmota/xdrv_01_webserver.ino | 555 ++---------------- tools/unishox/compress-html-uncompressed.py | 137 +++++ 26 files changed, 724 insertions(+), 508 deletions(-) create mode 100644 tasmota/html_compressed/HTTP_HEADER1_ES6.h create mode 100644 tasmota/html_compressed/HTTP_HEADER1_NOES6.h create mode 100644 tasmota/html_compressed/HTTP_HEAD_LAST_SCRIPT.h create mode 100644 tasmota/html_compressed/HTTP_HEAD_STYLE1.h create mode 100644 tasmota/html_compressed/HTTP_HEAD_STYLE2.h create mode 100644 tasmota/html_compressed/HTTP_HEAD_STYLE_ZIGBEE.h create mode 100644 tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h create mode 100644 tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h create mode 100644 tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h create mode 100644 tasmota/html_compressed/HTTP_SCRIPT_ROOT_PART2.h create mode 100644 tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h create mode 100644 tasmota/html_compressed/HTTP_SCRIPT_TEMPLATE.h create mode 100644 tasmota/html_uncompressed/HTTP_HEADER1_ES6.h create mode 100644 tasmota/html_uncompressed/HTTP_HEADER1_NOES6.h create mode 100644 tasmota/html_uncompressed/HTTP_HEAD_LAST_SCRIPT.h create mode 100644 tasmota/html_uncompressed/HTTP_HEAD_STYLE1.h create mode 100644 tasmota/html_uncompressed/HTTP_HEAD_STYLE2.h create mode 100644 tasmota/html_uncompressed/HTTP_HEAD_STYLE_ZIGBEE.h create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_PART2.h create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_TEMPLATE.h create mode 100644 tools/unishox/compress-html-uncompressed.py diff --git a/tasmota/html_compressed/HTTP_HEADER1_ES6.h b/tasmota/html_compressed/HTTP_HEADER1_ES6.h new file mode 100644 index 000000000..d95dc2499 --- /dev/null +++ b/tasmota/html_compressed/HTTP_HEADER1_ES6.h @@ -0,0 +1,22 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_HEADER1_SIZE = 371; +const char HTTP_HEADER1_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C" + "\x3C\x7C\x3D\x87\xD7\x8F\x62\x0C\x2B\xF7\x8F\x87\xB0\xF6\x1F\x87\xA0\xA7\x62\x1F" + "\x87\xA0\xD7\x56\x83\x15\x7F\xF3\xA3\xE1\xF6\x2E\x8C\x1D\x67\x3E\x7D\x90\x21\x52" + "\xEB\x1A\xCF\x87\xB0\xCF\x58\xF8\xCC\xFD\x1E\xC4\x1E\x75\x3E\xA3\xE1\xEC\x1F\xD1" + "\x28\x51\xF0\x46\x67\xA1\xB3\xAC\x7F\x44\xA1\x47\x56\xF6\xD6\xD8\x47\x5F\x83\xB0" + "\x99\xF0\xE4\x3A\x88\x5F\x9F\xCE\xBF\x07\x61\x58\xE0\x99\xF3\xB0\xF6\x1D\x87\xE1" + "\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A\xD1\xF5\xE3\xD0\xEC\x04\x19\x67\xA7\x83\xFE\x8C" + "\xA3\xF0\xCE\xFE\x8D\x87\xCE\x16\x10\x47\x50\x54\x75\x56\x1D\x54\x30\xEA\x18\x19" + "\xF0\xFB\x3E\xCF\x0C\x71\xF3\xC7\xC3\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26" + "\x35\xF5\x10\xE3\x22\xD1\x0E\xEF\x8E\xF1\xE0\xD5\xE0\x48\xBA\x6A\x16\xFE\x64\x5E" + "\x61\x30\xEB\x3E\x77\x7C\x77\x8F\x1E\x18\x7C\xD3\xE1\xF8\xC7\x1D\xDD\x3B\xC7\x4A" + "\x32\x18\xCF\x87\x74\x11\xA4\x1F\x0F\x87\xDD\x33\x65\x1F\x67\x68\xFB\x19\x7E\xF0" + "\xFE\x7C\x43\xEC\xF3\x04\x19\xC7\x78\xF0\x3E\x11\xF0\xC1\xF0\xFC\x1F\xDE\x13\x07" + "\xCE\x96\x20\x84\xCC\xDF\x51\x05\xBE\xA7\xCF\xE7\x74\xFB\x0B\x2C\x43\xEC\xEA\x30" + "\x77\x8F\x06"; + +#define HTTP_HEADER1 Decompress(HTTP_HEADER1_COMPRESSED,HTTP_HEADER1_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_HEADER1_NOES6.h b/tasmota/html_compressed/HTTP_HEADER1_NOES6.h new file mode 100644 index 000000000..fae966b15 --- /dev/null +++ b/tasmota/html_compressed/HTTP_HEADER1_NOES6.h @@ -0,0 +1,22 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_HEADER1_SIZE = 425; +const char HTTP_HEADER1_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C" + "\x3C\x7C\x3D\x87\xD7\x8F\x62\x0C\x2B\xF7\x8F\x87\xB0\xF6\x1F\x87\xA0\xA7\x62\x1F" + "\x87\xA0\xD7\x56\x83\x15\x7F\xF3\xA3\xE1\xF6\x2E\x8C\x1D\x67\x3E\x7D\x90\x21\x52" + "\xEB\x1A\xCF\x87\xB0\xCF\x58\xF8\xCC\xFD\x1E\xC4\x1E\x75\x3E\xA3\xE1\xEC\x1F\xD1" + "\x28\x51\xF0\x46\x67\xA1\xB3\xAC\x7F\x44\xA1\x47\x56\xF6\xD6\xD8\x47\x5F\x83\xB0" + "\x99\xF0\xE4\x3A\x88\x5F\x9F\xCE\xBF\x07\x61\x58\xE0\x99\xF3\xB0\xF6\x1D\x87\xE1" + "\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A\xD1\xF5\xE3\xD0\xEC\x04\x19\x67\xA7\x83\xFE\x8C" + "\xA3\xF0\xCE\xFE\x8D\x87\xCE\x16\x10\x47\x50\x54\x75\x56\x1D\x54\x30\xEA\x18\x19" + "\xF0\xFB\x3E\xCF\x06\x05\xF0\x75\xB9\xC9\x8E\x3B\xBE\x3B\xC7\xB7\xEE\x85\xFF\x90" + "\x98\x18\xB1\xAF\xA8\xE8\x3C\xE8\x98\x4C\x6B\xEA\x21\xC6\x45\xA2\x1D\xDF\x1D\xE3" + "\xC1\xEE\x04\x4C\x38\xD5\xE0\x4F\xC3\x8D\x42\xDF\xCC\x8B\xCC\x26\x1D\x67\xC1\x27" + "\x0D\xF0\xC3\xBB\xA7\x78\xF6\xB1\xC7\x77\x4E\xF1\xD2\x8C\x86\x33\xE1\xDD\x04\x69" + "\x07\xC3\xE1\xF7\x4C\xD9\x47\xD9\xDA\x3E\xC6\x5F\xBC\x3F\x9F\x10\xFB\x3C\xC1\x06" + "\x70\x23\xE3\xE3\xE1\x1D\xD3\x07\x78\xF6\x8F\xEF\x09\x83\xE7\x4B\x10\x42\x66\x6F" + "\xA8\x82\xDF\x53\xE7\xF3\xBA\x7D\x85\x96\x21\xF6\x75\x18\x3B\xC7\x83\xDC"; + +#define HTTP_HEADER1 Decompress(HTTP_HEADER1_COMPRESSED,HTTP_HEADER1_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_HEAD_LAST_SCRIPT.h b/tasmota/html_compressed/HTTP_HEAD_LAST_SCRIPT.h new file mode 100644 index 000000000..feaa2ee1e --- /dev/null +++ b/tasmota/html_compressed/HTTP_HEAD_LAST_SCRIPT.h @@ -0,0 +1,16 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_HEAD_LAST_SCRIPT_SIZE = 226; +const char HTTP_HEAD_LAST_SCRIPT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x46\xB1\x0E\xE9\xDE\x3D\xA6\x77\xF5\x47\xC3\x8C\xEA\x2D\x3E" + "\x09\x81\x8B\x1A\xFA\x8E\x86\xA1\x6F\xE6\x45\xE6\x13\x0E\xB3\xE5\x61\x04\x77\x4F" + "\xBD\xE1\x82\xE8\xEA\x1C\x2E\xAB\x38\xEA\xA6\x6C\xAB\xFB\xB3\xAB\xCC\x26\x1D\x1F" + "\x67\x78\xF0\x3E\x2B\x42\x67\x77\x4E\x81\x3E\x1E\xA1\x47\xE1\xF2\x8E\xF1\xED\xD3" + "\x07\x77\x4F\x7A\x8F\x7C\xEF\x1E\xDD\x3D\xEA\x3D\xF3\xDE\x3E\xFA\xC6\xB3\xEC\xF7" + "\xCF\x87\x77\x4F\x7A\x8F\x7C\xE8\x2A\x2B\xFC\x57\x55\xFD\x1C\x2E\x99\xDD\x3E\xF4" + "\x43\xEC\xEF\x1F\xA3\xF4\x77\x4F\xE0\x27\x57\xEB\x1A\xCF\xB3\xBC\x77\x8E\xF1\xDA" + "\x04\x1C\x87\x44\x3E\xCF\x7C\xF3\x04\x7C\xB0\xF0\x7B\xA8\xED\x9D\xB3\xC1\xEE\x3D" + "\xC3\xE1\x1D\xD3\x58\x87\x78\xF0\x7A\x1D\x9E\x0F\xFA\x32\x8F\xC3"; + +#define HTTP_HEAD_LAST_SCRIPT Decompress(HTTP_HEAD_LAST_SCRIPT_COMPRESSED,HTTP_HEAD_LAST_SCRIPT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_HEAD_STYLE1.h b/tasmota/html_compressed/HTTP_HEAD_STYLE1.h new file mode 100644 index 000000000..52440cd82 --- /dev/null +++ b/tasmota/html_compressed/HTTP_HEAD_STYLE1.h @@ -0,0 +1,24 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_HEAD_STYLE1_SIZE = 591; +const char HTTP_HEAD_STYLE1_COMPRESSED[] PROGMEM = "\x3D\x3D\x46\x41\x33\xF0\x4D\x33\x3A\x8C\x6B\x08\x4F\x3A\x3A\xB7\x86\x0B\xA3\xAB" + "\xCC\x26\x1D\x1E\xD1\x96\x20\x9B\xC3\xC7\x99\xCD\x21\x86\xC3\xC1\x8C\xEA\x3A\xFD" + "\xA6\xD6\x79\x9C\x84\xC6\x9E\x0F\x70\x21\xE1\xA7\xB4\x75\x86\x68\x3D\xFC\x17\xC2" + "\x1E\x67\x91\xF4\x71\xF1\x1B\x0F\x07\xB8\x61\xED\x1B\x7F\x1E\xDE\x3C\xCE\x33\xA6" + "\x93\x1A\x8E\x33\xC1\xEE\x2D\xE1\x82\xE8\xF6\x8F\xE8\x94\x28\xF3\x39\x1B\x3E\x8F" + "\xA3\xC1\x0E\xC3\x61\xD7\xED\x36\xEF\x0F\x1E\x63\xB3\xE2\x3F\x9D\x63\xB0\xD8\x78" + "\x3A\xC7\xD8\xE3\x4D\xA3\xAC\x14\xAD\x0D\xC3\x68\x29\x57\x04\xCD\x84\x3C\x0B\x3E" + "\x08\x7B\x6E\xF0\xC1\x74\x7B\xD4\x64\x31\x9F\x03\x14\xC3\x34\x1D\x86\xC3\xDF\x04" + "\x1E\x11\x41\x06\x8F\xEC\x4D\xC3\xDF\x04\x3D\xF1\x8D\x3C\x02\x0F\x03\x87\x5F\xF4" + "\x78\x55\x1E\x67\x38\x86\x1B\x0F\x06\x6F\xF5\xA1\xD8\x47\x5D\x85\xA3\xDC\x79\x9D" + "\x67\x21\x0C\x04\x9C\xCF\xF7\xC3\xCC\x10\xF1\xE3\x89\x1F\x47\xD1\xE0\xF7\x10\x21" + "\x71\x3E\x09\x1C\x28\x82\xC7\x2A\x01\x54\xCD\x95\x7F\x76\x7B\x7E\xFD\xA6\xD6\x79" + "\x82\x1E\xA0\x78\x04\x2C\xC8\xE7\xCF\xA3\xE8\xF0\x42\x9E\x8F\x0A\xA3\xCC\xE5\xCF" + "\x90\xC3\x61\xE0\x11\xF8\xFA\xC3\x37\xF3\x01\x60\xF9\xE7\x62\xEB\x01\x6B\x45\x1D" + "\x82\x19\x1E\xDA\x66\xCA\x04\x2E\x0A\x83\x7D\x4F\xE0\x83\xC9\xE9\x8B\x1B\xA1\x19" + "\x1E\x66\x6F\xE2\x5F\x59\xD5\xEB\xEF\x1D\x7E\x7F\xD3\x2A\x01\x9B\x98\x1E\xEA\x10" + "\x11\x39\x7D\x38\xC8\x61\xB0\xF0\x7B\x8D"; + +#define HTTP_HEAD_STYLE1 Decompress(HTTP_HEAD_STYLE1_COMPRESSED,HTTP_HEAD_STYLE1_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_HEAD_STYLE2.h b/tasmota/html_compressed/HTTP_HEAD_STYLE2.h new file mode 100644 index 000000000..4c1da5898 --- /dev/null +++ b/tasmota/html_compressed/HTTP_HEAD_STYLE2.h @@ -0,0 +1,20 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_HEAD_STYLE2_SIZE = 478; +const char HTTP_HEAD_STYLE2_COMPRESSED[] PROGMEM = "\x1C\x2E\xAB\x38\xF6\x8E\xCF\x88\xFE\x79\x9C\x67\x82\x04\x18\xA7\x5F\xEC\x4D\x17" + "\xE3\xCC\xE3\x3A\x59\x7D\x8D\x3C\x0E\xB0\xCD\x07\xBF\x82\xF8\x43\xCC\xF2\x3E\x8E" + "\x3E\x23\x61\xE0\x3C\x0B\x3E\x08\x52\x02\xDE\x67\x58\xA7\xA3\xC2\xA8\xF3\x39\x47" + "\x4C\x2F\xB1\xA7\x83\x19\xD4\x75\xFB\x4D\xAC\xF3\x39\x0E\x94\x5F\x63\x4F\x03\xFA" + "\x25\x0A\x3C\xCE\x46\xCF\xA3\xE8\xF0\x75\x90\xFB\x1C\x69\xB4\x75\xD7\xEF\xBD\xB5" + "\xB9\xC7\x58\x82\xFF\x75\xB9\xC7\x99\xC6\x74\xC2\xF1\xE0\x15\x2A\x2B\x86\x2F\xFE" + "\xCF\x9E\x63\x33\x7A\x9F\xCF\x07\xB8\x10\x78\x18\x3C\xC5\x61\x9B\xF9\xED\x04\xCE" + "\x2A\x01\x0F\x71\xD0\x77\xD8\x80\xA7\x50\x15\xB1\x21\xEF\xF0\x29\xD4\x05\x4C\x4A" + "\xCF\x68\x23\xF0\xDF\x4C\xD9\x47\x58\x8C\x3C\x04\x2E\x06\xBB\x39\x9E\x0F\x71\xD0" + "\x61\xED\x30\x16\x5D\x1E\x61\x33\x14\x08\x38\x05\x85\xA3\xDC\x08\x33\x0F\x71\xD0" + "\xD4\x08\x56\xFF\xA3\xC2\x81\x22\xE0\x20\xCD\x3D\xC7\x4F\x82\x17\x20\x60\x8D\xC7" + "\xD3\x1A\x78\x19\x62\x09\xBC\x3C\x79\x9C\xA2\x18\x6C\x3C\x0D\xBF\x8F\x6F\x1E\x67" + "\x38\x86\x1B\x11\xCA\x21\x86\xC3\xC1\xEE"; + +#define HTTP_HEAD_STYLE2 Decompress(HTTP_HEAD_STYLE2_COMPRESSED,HTTP_HEAD_STYLE2_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_HEAD_STYLE_ZIGBEE.h b/tasmota/html_compressed/HTTP_HEAD_STYLE_ZIGBEE.h new file mode 100644 index 000000000..29269d0d0 --- /dev/null +++ b/tasmota/html_compressed/HTTP_HEAD_STYLE_ZIGBEE.h @@ -0,0 +1,19 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_HEAD_STYLE_ZIGBEE_SIZE = 363; +const char HTTP_HEAD_STYLE_ZIGBEE_COMPRESSED[] PROGMEM = "\x3A\x0E\xA3\xDA\x3B\x0D\x87\x5F\xB4\xDB\xBC\x3C\x79\x8E\xCF\x88\xFE\x75\x8E\xC3" + "\x61\xE0\x66\x7B\x6B\x73\x8F\x3F\xB0\xAE\xB4\xCD\x9E\x04\xDF\x0C\x0A\xCC\x8F\x3D" + "\xE0\xB7\x99\xD6\x38\x2C\x0C\xD0\xF0\x3F\xA2\x50\xA3\xCC\xE5\x32\x18\x6C\x3C\x0A" + "\x7A\x3C\x2A\x2B\x8F\x33\x92\x88\x61\xB0\xF0\x08\x39\x29\xE6\x72\x88\x61\xB1\x7B" + "\x02\xD1\x01\x0A\x69\xD7\xFB\x13\x45\xF8\xF3\x39\x64\x30\xD8\x78\x1B\x7F\x1E\xDE" + "\x3A\xC2\x66\x28\xF3\x3A\xCE\x59\x0C\x36\x1E\xE3\xA0\xEA\x3C\xCF\x3B\x31\x4F\xE7" + "\x51\xD0\x75\x1E\x67\x98\xE6\x63\x3E\xCF\x68\x79\xD4\xFA\x8F\x33\xD8\x7B\x01\x13" + "\x5E\x04\x1D\x5C\x16\xB8\x14\xB1\xDE\xC0\x85\xD3\x04\x3D\xD0\xE7\x10\xC3\x61\xE0" + "\x75\x86\x68\x3D\xFC\x17\xC2\x1E\x61\x8B\xFF\xDF\x51\x07\x81\x67\xCF\x15\x83\x0F" + "\x33\x90\x81\x0F\x5F\x04\x2D\x53\xFA\x3C\x2A\x2B\x8F\x33\xAC\xE6\x10\x22\x70\x54" + "\x08\xFC\x0C\x82\x0F\x0A\x67\x30\x81\x23\x81\x23\xDA\x08\x34\x4C\xEF\xE7\x74\xEB" + "\x3A\xC7\x04\x75\x1C\x98\x43\x0D\x87\x78\xF0\x13\x31\x47\x99\xC8\x43\x0D\x87\xB8"; + +#define HTTP_HEAD_STYLE_ZIGBEE Decompress(HTTP_HEAD_STYLE_ZIGBEE_COMPRESSED,HTTP_HEAD_STYLE_ZIGBEE_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h new file mode 100644 index 000000000..91e1fab76 --- /dev/null +++ b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_SCRIPT_CONSOL_SIZE = 853; +const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x82\x30\x2F\x83\xAD\xCE\x41\x1D" + "\xD1\x87\x78\xF6\x99\xDF\xD0\x67\x56\x1F\x0F\xB3\xEC\xEA\xA3\xC0\x61\x3B\xF9\x56" + "\x8D\x78\x2E\x8E\xE8\x54\x77\x8F\x14\x7C\x63\x8E\xE9\xF7\x47\x21\xF6\x77\x8F\x05" + "\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7\x74\xFB\x0C\xE4\x3E\xCE" + "\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0\x78\x23\x21\x65\xF2\xD2" + "\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3\xC0\x21\x45\x3E\x1F\x67" + "\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD\x2A\x01\xF1\xEE\x3E\x02" + "\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE\x3D\xBA\x60\xEE\x9B\x0F" + "\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD\x3B\xC7\x83\xDC\x6C\x3E" + "\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F\xD4\x77\x4E\xF1\xE0\xD8" + "\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08\x7C\x28\x1D\xD0\x41\xCA" + "\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F" + "\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\x03\x69\xD4\x21\xE0\x43\xE1\xB0\xE9\xF7\xE1\x99" + "\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4\x3B\x0E\xF1\xE0\xB4\x43" + "\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44\x92\x7C\x3E\x1C\x67\x78" + "\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13\xE1\xEA\x14\x7E\x02\x2E" + "\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xDE\x1E\x4F\x71\xE0\xD8\x74\xC1\x8F\x8E\xE9\xF6" + "\x43\xC4\xCA\x8F\xB3\xA8\xFB\x0F\xC7\x68\x33\x94\x7C\x3E\xCE\xD9\x68\x87\x6F\x0E" + "\xAA\xF8\xB6\x77\x8F\x06\xC3\xA7\x9F\x08\x77\x4E\xF1\xE0\xF7\x05\x47\xCF\x3A\x04" + "\x4E\x4A\x4E\xA3\xE8\x43\xBC\x78\xFB\xA1\x7F\xE4\x62\xC2\xF3\x3C\x1E\xE1\xF0\x8E" + "\xE8\x47\x78\xF0\x67\x7F\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF0\x23\xF2\xF4\x28\xEE" + "\x9D\xE3\xDA\x08\x7C\xA2\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F\xCE\xE9\xF6" + "\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE2\xDD\x82\x0F\x12\xA3\x81\x13\x97\xB3\xA8" + "\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2\x0C\xFF\x1F" + "\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13\xA6\x7C\x3E" + "\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76\xC3\xE3\xF0" + "\x50\x60\x85\xC4\x31\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E\x04\x2E\x2E" + "\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C\x67\xC3\xE1" + "\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78\x41\xC9\x67" + "\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28\x33\xA0\xCC" + "\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x44\x01\x0B\x1C\x3B\xC7\x50\x7C\x7C" + "\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; + +#define HTTP_SCRIPT_CONSOL Decompress(HTTP_SCRIPT_CONSOL_COMPRESSED,HTTP_SCRIPT_CONSOL_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h new file mode 100644 index 000000000..e7f059b0b --- /dev/null +++ b/tasmota/html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 602; +const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\xD4\x2B\xC7\x83\x02\xF8\x3A\xDC\xE4\x1B\x3B\xBA\x75\x1A\x8E\xF1" + "\xED\x33\xBF\xAC\x3E\x09\x81\x8B\x1A\xFA\x8E\x81\xFD\xDD\x32\x61\x31\xAF\xA8\xEE" + "\x9F\x78\x32\xB7\x38\xFB\x3B\xC7\x8C\x3A\x53\x36\x51\x07\x9D\x4F\xA8\xF9\xA7\x83" + "\x51\xD2\xC6\x0C\x7C\x21\x06\x2B\x42\x10\xEE\xE1\xDE\x3C\x1E\xE0\x44\xCD\xB2\x8E" + "\xE8\xF1\xD5\xE0\x41\xCD\xAC\xF9\xE3\xF4\x71\x91\xB0\xC1\x86\x71\x9D\x44\x38\xF8" + "\x71\x9D\x44\x19\xD4\x30\xEA\x08\xEA\xA3\xE1\xAB\xC7\x74\xFB\x3C\x85\x1F\x67\x6C" + "\x78\xEF\x1D\x42\xCF\x9E\x3F\x47\x19\x1B\x0E\x37\x08\xC1\xE0\x23\xE5\x1D\x01\x07" + "\x4D\xF1\xD0\x27\xC3\xD4\x28\xF0\x63\x3E\x77\x74\xF8\x11\xE3\x4F\x1A\x75\x9D\x67" + "\x78\xF6\x8C\x04\x5B\xC7\xBD\xA7\x59\xC8\x7B\xE7\x42\x19\x7F\x7D\x45\xD8\x23\x3C" + "\x0C\x3A\x7D\x8D\xC3\x36\x08\x3B\x70\x24\xE0\x87\x78\xF0\x7B\x82\x3E\x0A\x04\xAC" + "\xC8\xE3\x3C\x16\x9E\x81\x1E\x34\xED\x9D\xB3\xBC\x7B\x43\x3E\x0A\xF1\xEF\x69\xEF" + "\x82\x17\x2A\x01\xE7\x8D\x30\x77\x6C\xF8\x7C\x0C\xEF\x1E\xD1\xC0\x89\x50\xE3\x70" + "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x21\x64\x47\x21" + "\xE0\xB4\xF4\x3E\x0E\x04\x2C\x8D\x9D\xD3\xBB\xA7\xA1\xC8\xCE\xF1\xDA\x3B\xA7\xD9" + "\xDC\x3E\xCE\xD9\x69\xDE\x3C\xF4\xEA\xA3\xBC\x78\x3D\xCC\x71\xDD\x3E\xC5\x1F\x67" + "\x6C\x78\xEF\x1D\x0C\xEC\x21\x6C\xF8\x2C\xED\x9C\x87\x82\xA3\xA7\xA8\xC8\x26\x74" + "\x33\xDF\x68\xED\x0B\x68\xC8\xF8\x77\x47\x1F\x87\x19\xDE\x3B\x47\xD9\xF6\x79\x9F" + "\x64\x2B\x44\x11\xF1\xF6\x08\xDC\x58\xF8\xD0\xEE\xF8\xEA\x1E\x04\x3E\x42\xF3\xC7" + "\x4F\xB1\x81\x58\x6C\xEE\x9D\x87\xB8\xE5\x1D\x84\x3C\x75\x1E\xC3\xD0\x10\x78\x4B" + "\x40\x83\x9E\x9F\x67\xB0\xEF\x02\x35\xD3\x96\x76\x10\xF1\xD4\x7B\x0F\x43\xB0\x10" + "\x6F\x1F\x87\xB0\xEF\x1E\x18\xE3\xBA\x7D\x8F\x1F\x67\x6C\x78\xEF\x1D\x37\xB9\xFC" + "\x85\x15\x10\xD2\x08\xF9\x80\x8D\x48\x10\x72\x13\xBA\x3C\x7A\x1C\x48\xEF\x1D\xA2" + "\x04\x3E\x47\x4F\x3F\x1E\x34\xC0\x20\xD0\x3D\xA0\x85\xC9\xF9\xE0\xF7\x1E\xE3"; + +#define HTTP_SCRIPT_MODULE_TEMPLATE Decompress(HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED,HTTP_SCRIPT_MODULE_TEMPLATE_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h new file mode 100644 index 000000000..2f61ce116 --- /dev/null +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -0,0 +1,27 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_SCRIPT_ROOT_SIZE = 524; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x69\x9D\xFD\x59\xF0\xFB\x3E\xCF\x1A" + "\x60\xEE\x85\x67\x4B\xF8\xF0\xB1\xAF\xAB\xC7\x40\x9F\x0F\x50\xA3\xE1\xF0\xE4\x3B" + "\xC7\xB4\xAC\xF8\x30\xF0\x18\x4E\xFE\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE3\xC1\xEE" + "\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE" + "\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3" + "\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xDA" + "\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F" + "\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x80\x7F\x1F\x0D\x87" + "\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B" + "\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C" + "\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2" + "\x85\x02\x4D\x71\xA0\x83\x5C\xEC\xA1\x47\xE1\xE9\x42\x02\x4E\x4E\x72\x99\x0C\x36" + "\x1E\x07\xC5\x6D\x33\xAF\xC3\x2C\x36\x79\xF6\x0F\xFE\xC6\x02\x56\x72\xC1\x0F\x1E" + "\x10\xFC\x3D\x0E\xCA\xF8\x24\xD9\x0C\xF7\x1D\x83\xC7\x51\xEC\x3E\x8F\xA3\xEC\xFC" + "\x3D\x04\xD3\x30\x43\xCE\xE9\x9B\x28\xEB\xB0\xB4\x7B\x8F\x30\xDF\x53\xF9\xE0\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE6\x7B\x0E\xF1\xE1\x8E\x3B\xA7\xD8\x47\x21\xF6\x77" + "\x8E\x85\xBD\xCF\xE4\x28\xA8\x86\x90\x47\xCF\x1E\x0F\x71\xEE\x3C\x1B\x0E\x98\x31" + "\xF1\xDD\x3E\xC8\x78\x99\x51\xF6\x75\x1F\x67\x43\xB4\x34\xF8\x72\x1F\x67\x6C\xAC" + "\xEA\xAF\x8B\x67\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x02\xA3\xE7\x9D\x02\x27" + "\x23\x96\x75\x1F\x42\x1D\xE3\xC1\xEE"; + +#define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_PART2.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_PART2.h new file mode 100644 index 000000000..17af45427 --- /dev/null +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_PART2.h @@ -0,0 +1,17 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_SCRIPT_ROOT_PART2_SIZE = 222; +const char HTTP_SCRIPT_ROOT_PART2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x06\x77\x4C\xCE\xAD\x3A\x86\x1D\xE3\xDB\xA6\x0E\xEB\x1C" + "\x77\x4F\xBF\x1F\x67\x78\xEF\x1E\xDD\x30\x77\x4C\xCF\x87\xC3\xEC\x51\xF6\x7F\x8F" + "\xF1\x99\xF0\xF8\x7D\x88\x7D\x9D\xE3\xDA\x67\x7F\x5E\x08\xF8\xC7\x1D\xD3\xEF\xC1" + "\x1C\xC3\xEC\xEF\x1D\x08\xCE\xC2\x16\xCF\x2A\x01\x85\x87\x9D\x3D\x46\x41\x33\xA0" + "\xEB\x0C\xD0\x7B\xF8\x2F\x84\x3E\x1F\x61\x6F\x3B\xF9\xD6\x3D\xFB\x13\x5F\x51\xDD" + "\xAC\x5F\xD1\xE1\x54\x75\x7C\x78\x71\xDD\x3E\xCE\xDF\x82\x3B\x67\xD9\xF4\x7D\x1D" + "\x40\x89\x14\x10\xE2\x9D\xE3\xA8\x57\x82\x3B\xA7\xD9\xDB\x04\x1D\x14\xE5\x10\x21" + "\xE8\xA7\x6C\xFB\x3A\x8E\x46\xCF\xA3\xE8\xEA\xD6\x7D\x1F\x47\x78\xEF\x1F\x67\x83" + "\xDC\x7B\x88\x2B\x3B\xA7\xD9\xFA\x3E\xCE\xD9\x99\xDB\xD3\xB6\x7D\x9F\x0F\xB3\xB6" + "\x30\xEF\x1E\x0F\x70\xF8\x47\x74\x2B\x3B\xC7\x83"; + +#define HTTP_SCRIPT_ROOT_PART2 Decompress(HTTP_SCRIPT_ROOT_PART2_COMPRESSED,HTTP_SCRIPT_ROOT_PART2_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h new file mode 100644 index 000000000..bb52fbbcd --- /dev/null +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_SCRIPT_ROOT_SIZE = 744; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x78\x23\x02\xF8\x3A\xDC\xE4\x15\x9D\xD1\x87\x78" + "\xF6\x99\xDF\xD5\x9F\x0F\xB3\xEC\xF1\xA6\x0E\xE8\x56\x74\xBF\x8F\x0B\x1A\xFA\xBC" + "\x74\x09\xF0\xF5\x0A\x3E\x1F\x0E\x43\xBC\x7B\x4A\xCF\x83\x0F\x01\x84\xEF\xE5\x5A" + "\x35\xE0\xBA\x3B\xA1\x51\xDE\x3C\x1E\xED\x30\x77\x4D\x87\xF0\xF9\xC2\xC2\x08\xEF" + "\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36\x10\xD2" + "\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8\x86\x5E" + "\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\xA0\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0\xE9\xF7" + "\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC\x7C\x3E" + "\x1C\xA6\xC8\x10\x78\x07\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\xD8" + "\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56\x38\x26\xBD\x46" + "\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0\xF6\x1D\xE2\x04" + "\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE\xCA\x14\x7E\x1E" + "\x94\x20\x24\xE4\xE7\x29\x90\xC3\x61\xE0\x7C\x56\xD3\x3A\xFC\x32\xC3\x67\x9F\x60" + "\xFF\xEC\x60\x25\x67\x2C\x10\xF1\xE1\x0F\xC3\xD0\xEC\xAF\x82\x4D\x90\xCF\x71\xD8" + "\x3C\x75\x1E\xC3\xE8\xFA\x3E\xCF\xC3\xD0\x4D\x33\x04\x3C\xEE\x99\xB2\x8E\xBB\x0B" + "\x47\xB8\xF3\x0D\xF5\x3F\x9E\x0C\x67\x51\xD6\x3E\xF4\x78\x55\x1E\x67\xB0\xEF\x1E" + "\x18\xE3\xBA\x7D\x84\x72\x1F\x67\x78\xE8\x5B\xDC\xFE\x42\x8A\x88\x69\x04\x7C\xF1" + "\xE0\xF7\x1E\xE3\xC6\x98\x47\x77\xE6\x3C\x28\xEF\x23\xDA\x6C\x3A\x60\xC7\xC7\x74" + "\xFB\x21\xE2\x65\x47\xD9\xD4\x7D\x9D\x0E\xD0\xD3\xE1\xC8\x7D\x9D\xB2\xB3\xAA\xBE" + "\x2D\x9D\xE3\xC1\xB0\xE9\xE7\xC2\x1D\xD3\xBC\x78\x0A\x8F\x9E\x74\x08\x9C\x93\xD9" + "\xD4\x7D\x08\x77\x8F\x07\xB8\xF7\x02\x27\x2E\x9E\x66\x76\x77\x46\x5F\xCE\xAD\x33" + "\xBF\x9D\xE3\xDA\x15\x9D\xD3\xEC\xFD\x78\xCC\xF8\x7D\x9D\xBD\x33\xBF\x9D\xB3\xEC" + "\xFD\x9F\x67\x6C\x65\xFC\xEF\x1E\x01\x1B\x0D\xD0\x48\xC3\x41\x0B\x9C\x40\x53\xC5" + "\x3E\x63\xC2\x8F\x87\x19\x02\x36\x36\x33\xE7\x74\xC1\xDE\x3D\xBA\x61\x1D\xD3\x07" + "\x79\x1E\xD0\x50\xDE\x81\x0B\x2F\x3D\xC9\x85\xE6\x8F\x68\x26\x73\xD0\x08\x79\x81" + "\xEE"; + +#define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_TEMPLATE.h b/tasmota/html_compressed/HTTP_SCRIPT_TEMPLATE.h new file mode 100644 index 000000000..36ac7939d --- /dev/null +++ b/tasmota/html_compressed/HTTP_SCRIPT_TEMPLATE.h @@ -0,0 +1,20 @@ +///////////////////////////////////////////////////////////////////// +// compressed by tools/unishox/compress-html-uncompressed.py +///////////////////////////////////////////////////////////////////// + +const size_t HTTP_SCRIPT_TEMPLATE_SIZE = 303; +const char HTTP_SCRIPT_TEMPLATE_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x08\x77\x45\x9D\x46\x0E\xF1\xED\x33\xBF\xA3\x61\xF3\x98" + "\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3\xBA\x77\x8F\x06\xC3\xA6" + "\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xC7\x4E\xE9\xDE\x3D\xBA\x60" + "\xEE\xD0\xAD\xF1\xD3\xEE\xC4\x32\x2F\x55\xD3\x3E\x1F\x0E\x61\xFA\x3F\x45\x42\xB7" + "\xC7\x4F\x55\xD0\xBF\x1F\x0F\x87\x29\xB3\xBC\x7B\x48\x10\x70\x43\xBC\x78\x3D\xC7" + "\xB8\xF0\x6C\x3A\x60\xC7\xC7\x74\xFB\x21\xE2\x65\x47\xD9\xD4\x2C\xEA\xAF\x8B\x67" + "\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x0F\x71\x9D\xFD\x06\x78\x04\x4E\x2A\x01" + "\x4D\x87\x21\xDD\x21\xC0\x83\xBF\xE9\xD4\x6B\x3A\x87\x8E\xA3\x43\xAB\x0F\x18\x7C" + "\x1C\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\x86\x05\xB4\x77\x4E\xC3\xDC\x72\x1D" + "\x87\x78\xF0\x46\x87\xCC\x3A\x78\x56\x98\xA3\xBA\x77\x8F\x1A\x60\xEE\xB1\xC7\x74" + "\xFB\xF1\xC8\x7D\x9D\xE3\xA1\x19\xD8\x42\xD9\xF0\xF8\x7D\x9F\x67\x78\xF6\x82\x55" + "\x03\x43\xC1\xEE\x1E\x04\x5C\x44\x10\xB2\x93\xEC\xEA\x3E\xCE\xF1\xE3\x3C\x7C\x3D" + "\x86"; + +#define HTTP_SCRIPT_TEMPLATE Decompress(HTTP_SCRIPT_TEMPLATE_COMPRESSED,HTTP_SCRIPT_TEMPLATE_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_HEADER1_ES6.h b/tasmota/html_uncompressed/HTTP_HEADER1_ES6.h new file mode 100644 index 000000000..d89b93352 --- /dev/null +++ b/tasmota/html_uncompressed/HTTP_HEADER1_ES6.h @@ -0,0 +1,16 @@ +const char HTTP_HEADER1[] PROGMEM = + "" + "" + "" + "" + "%s - %s" + + ""; diff --git a/tasmota/html_uncompressed/HTTP_HEAD_STYLE1.h b/tasmota/html_uncompressed/HTTP_HEAD_STYLE1.h new file mode 100644 index 000000000..3ec441914 --- /dev/null +++ b/tasmota/html_uncompressed/HTTP_HEAD_STYLE1.h @@ -0,0 +1,12 @@ +const char HTTP_HEAD_STYLE1[] PROGMEM = + "" "\0" @@ -1739,7 +1739,7 @@ const char ZB_WEB_U[] PROGMEM = "" "%s" // name "%s" // sbatt (Battery Indicator) - "
" // slqi + "
" // slqi "\0" // +++++++++++++++++++++++++++++++++++++++++++++++++++++++ //=ZB_WEB_BATTERY @@ -1779,22 +1779,22 @@ const char ZB_WEB_U[] PROGMEM = // ++++++++++++++++++++vvvvvvvvvvvvvvvvvvv++++++++++++++++++++ enum { ZB_WEB_CSS=0, - ZB_WEB_PERMITJOIN_ACTIVE=512, - ZB_WEB_VIS_JS_BEFORE=566, - ZB_WEB_VIS_JS_AFTER=1039, - ZB_WEB_AUTO_REFRESH=1103, - ZB_WEB_MAP_REFRESH=1169, - ZB_WEB_STATUS_LINE=1235, - ZB_WEB_BATTERY=1344, - ZB_WEB_LAST_SEEN=1394, - ZB_WEB_COLOR_RGB=1442, - ZB_WEB_LINE_START=1502, - ZB_WEB_LIGHT_CT=1542, - ZB_WEB_END_STATUS=1597, - ZB_WEB_LINE_END=1614, + ZB_WEB_PERMITJOIN_ACTIVE=507, + ZB_WEB_VIS_JS_BEFORE=561, + ZB_WEB_VIS_JS_AFTER=1034, + ZB_WEB_AUTO_REFRESH=1098, + ZB_WEB_MAP_REFRESH=1164, + ZB_WEB_STATUS_LINE=1230, + ZB_WEB_BATTERY=1338, + ZB_WEB_LAST_SEEN=1388, + ZB_WEB_COLOR_RGB=1436, + ZB_WEB_LINE_START=1496, + ZB_WEB_LIGHT_CT=1536, + ZB_WEB_END_STATUS=1591, + ZB_WEB_LINE_END=1608, }; -// Compressed from 1631 to 1109, -32.0% +// Compressed from 1625 to 1111, -31.6% const char ZB_WEB[] PROGMEM = "\x00\x66\x3D\x0E\xCA\xB1\xC1\x33\xF0\xF6\xD1\xEE\x3D\x3D\x46\x41\x33\xF0\xE8\x6D" "\xA1\x15\x08\x79\xF6\x51\xDD\x3C\xCC\x6F\xFD\x47\x58\x62\xB4\x21\x0E\xF1\xED\x1F" "\xD1\x28\x51\xE6\x72\x99\x0C\x36\x1E\x0C\x67\x51\xD7\xED\x36\xB3\xCC\xE7\x99\xF4" @@ -1805,52 +1805,52 @@ const char ZB_WEB[] PROGMEM = "\x00\x66\x3D\x0E\xCA\xB1\xC1\x33\xF0\xF6\xD1\xEE\ "\x13\x7C\x30\x2B\x32\x3C\xF7\x82\xDE\x67\x58\xE0\xB0\x33\x43\xC0\xEC\xF8\x8F\xE7" "\x99\xC8\x43\x0D\x8B\xD8\x16\x88\x83\x17\xFF\xBE\xA2\x0F\x02\xCF\x9E\x07\x58\x66" "\x83\xDF\xC1\x7C\x21\xD6\x1E\x05\x9F\x3C\xCC\xEF\xE7\x74\xEB\x3A\xC3\x08\xEA\x3C" - "\x8C\x18\x30\x77\x8F\x71\xD3\xDE\xD3\xDA\x09\x59\xA1\x80\x99\xB0\xF1\x61\x68\xF7" - "\x1D\x7B\x4C\x6F\x8F\x33\x01\x33\x61\xD6\xF8\x43\xC0\x21\xEE\x87\x34\x86\x1B\x0F" - "\x03\x2C\x41\x37\x87\x8F\x33\x8C\xF7\x1D\x0B\xDE\xD5\xA0\x85\xC2\x91\xCB\x21\x86" - "\xC3\xC0\x24\xF0\x90\x30\xD8\x08\x5C\x2A\x01\x1D\x7F\xB1\x34\x5F\x8F\x33\x96\x43" - "\x0D\x80\x9B\xBA\x1E\x4D\xB0\x41\xC9\x8E\x83\x8E\x32\x04\x3E\x17\x4E\x56\x9F\x47" - "\xD1\x02\x1D\x13\x90\x81\x0E\x89\xCD\x64\x08\xB4\x4E\x51\x02\x1D\x13\x9E\x20\x46" - "\xC1\x8E\x59\x02\x27\x13\x87\x1B\x3E\x8F\xA3\xDC\x74\x2C\x39\x6C\xF6\x96\x0C\xB0" - "\xF6\x8C\x8F\x33\xA1\xCB\x3D\xC7\xA1\xD8\x40\x83\xCA\x4C\xE1\x7C\xF4\x18\x7E\x1E" - "\x83\x8F\xC3\xDE\x47\xA7\x86\x5F\x2F\x51\x90\x4C\xF8\x7D\x82\x16\xD4\x71\xFD\x9E" - "\x0F\xB3\xF0\xFA\x2F\x1E\x87\x67\x86\x5F\x1F\x88\xF7\xCF\x43\xB0\x71\xF8\x7A\x1D" - "\x83\x0F\xC9\xC2\xF9\xE9\xE0\xFF\xA3\x29\x51\x90\xC6\x7C\x3D\x94\xCD\x94\x76\x1A" - "\xEC\xCE\xC1\x06\x91\xEC\x5E\xF8\x67\xC3\xD8\x2A\x2B\xA8\x67\x8F\x33\xB0\xEC\x17" - "\xC3\x0D\x07\x8E\x81\xE0\xD3\xB0\xCF\x7C\x75\xF3\xA1\xFC\xF9\xA1\xD9\xEA\xBE\x12" - "\xC2\xCE\x67\x60\xB1\xA2\x02\x3D\x73\xA0\xDD\xE3\xA1\xAF\xC7\xB0\xFC\x3D\x0E\xC0" - "\x41\xCB\x0F\xC3\xD0\x4D\x33\x5A\x21\xF0\xF6\x0D\x32\x04\x2C\x2A\x01\xF6\x02\x17" - "\x2A\x01\xC7\xB0\x13\x78\x9F\x30\x60\xC1\xE0\x10\xF8\x1C\x38\xD9\x02\x17\x32\xC7" - "\x3E\xD9\x0C\x36\x02\x1F\x22\xC7\x31\xB2\x04\x4E\x3A\xC1\x1B\x98\xF0\xB4\x78\x55" - "\x0F\x7E\xCC\x8F\x1F\x7E\xD3\x6B\x3C\xC7\x65\x0A\x3C\x1E\xC3\xF0\x85\xF5\x8E\x09" - "\xAA\xC4\x16\x58\x88\xCF\x7C\x74\x35\xF8\xF4\x3B\x04\xD3\x33\xF0\x16\x78\x63\x3F" - "\x0C\xEF\xE8\x3C\xEA\xBD\xE7\xF3\xE0\x98\x18\xB1\xAF\xA8\xE8\x3C\xE8\x98\x4C\x6B" - "\xEA\x21\xC6\x45\xA2\x1D\xD0\x46\xE0\xC8\xEF\x1E\x0C\xEF\xEB\x06\x56\xE7\x78\xF8" - "\x7B\x47\xBF\x82\xC6\x78\xF3\x3D\xB8\x79\x9E\xDF\x0A\xB1\x8C\xF3\x3D\x81\xEF\xC3" - "\x09\x9E\xC3\xA8\x10\x78\x3D\x3D\x87\x90\x87\x37\x4F\x61\xEE\x3A\x8B\xE0\x89\x70" - "\x76\x1B\x01\x16\xC9\x81\xC7\x3C\x7B\x0F\x71\xD4\x4C\x11\x2C\xB0\x82\xD1\x9E\x04" - "\x6C\x6A\xC4\x30\x7B\x0F\x71\xEE\x3D\xC7\x83\x3B\xFA\x12\xEA\xCF\x87\xB6\x70\xBE" - "\x08\x32\x41\x0B\x6C\x3E\x73\x1F\x46\x7B\xE3\xA1\x70\x20\xCC\x3B\xA0\x89\xC1\x49" - "\xD4\x25\xD5\x9D\x40\x85\xC0\x29\xDE\x3C\x02\x27\x20\xC0\x87\xCB\xA9\xF9\xE7\x45" - "\x5A\x35\xE0\xBA\x3B\xA6\x05\xF0\x75\xB9\xC7\x74\xEF\x1E\xD0\xB0\x3B\xAD\xCE\x3A" - "\x7D\x85\x96\x21\xDD\x3B\xC7\x83\xDC\x75\x1C\x89\x32\x04\x8C\x78\x61\xF8\x7A\x1D" - "\x83\x0F\xC3\xD0\xC6\x7C\x6A\xB0\xEB\x73\x8F\x87\xD9\xB4\x77\xCF\xB4\x35\xD0\xAC" - "\x10\xF8\x7D\x8F\x3A\x3E\xCF\xC3\xD0\x70\xBA\xAC\xE3\xF0\xFA\xF1\xE8\x76\x02\x14" - "\x73\xD0\xEC\x31\x9F\x1A\x7E\x4E\x17\xCF\x4A\xFA\x0C\x2B\xF7\x8F\x87\xD9\xB6\x84" - "\x42\xAB\xE7\xD9\xF8\x7A\x50\x87\xE1\xE8\x39\x56\xD0\x4C\xF8\x7D\x9C\x64\x6C\x3E" - "\x8E\x3C\x22\x36\x23\xEB\xC8\xEB\x47\xD7\x81\x07\xA0\x7E\x38\xFC\x3D\x0E\xCA\x10" - "\xFC\x3D\x28\x43\xF0\xFA\xF0\x22\x47\x3D\x04\xD3\x30\x43\xC4\x88\x22\x35\x16\xA3" - "\xEB\xC7\xD8\x21\xE7\x1E\xF6\x9F\x67\xE4\xE1\x7C\xF4\xD0\x42\x98\x7B\x07\x51\xEC" - "\x04\x2C\x18\xF6\x1F\x42\x1F\x47\xD0\x22\x73\xFE\x75\x9D\x63\x82\x3C\xCF\xA1\x06" - "\x1B\x0F\x61\xF8\x7A\x1D\x9A\x7E\x4E\x17\xCF\x4A\x10\x10\xEB\x82\x17\x40\x10\xFA" - "\x38\xE8\x8D\x87\xD1\xC7\x44\x6C\x3E\x8E\x3A\x23\x61\xEC\x3F\x0F\xD1\xE4\x6C\x39" - "\x08\x8C\x1C\xDD\xF1\xE0\xFA\x74\x42\x1F\x41\xCE\x17\xD0\x23\x67\xE6\xC0\x46\xCC" - "\x83\x08\xF3\x3C\x8F\xA3\x8E\x88\x8D\x87\xD1\xC7\x44\x46\xC3\xE8\xE3\xA2\x23\x60" - "\x20\xE7\x60\x91\x3C\x11\xF8\x67\x04\x3E\x18\xD0\x78\x17\x86\x5F\x1F\x0F\x61\xCC" - "\x3D\x87\xE1\xFA\x3C\x96\x7B\xE7\x82\x9C\x2F\x82\x17\x45\x6C\x10\xB8\x1B\x20\xCA" - "\x91\xF4\x21\xEC\x3F\x0F\x4F\x0D\xB0\x82\x3F\x0F\xD1\xE4\x71\x7D\x7C\xF0\x77\x0F" - "\x43\xB0\x81\x06\x61\xF4\x21\x1A\x02\x17\x45\xB6\x70\xBE\x08\x5D\x06\x23\xB2\x84" - "\x3F\x0F\xAF\x1E\xD6\x7B\x81\x32\x6C\xE1\x7C"; + "\x8C\x18\x30\x77\x8F\x71\xD3\xDA\x7B\x41\x2B\x33\x30\x13\x36\x1E\x2C\x2D\x1E\xE3" + "\xAF\x69\x8D\xF1\xE6\x60\x26\x6C\x3A\xDF\x08\x78\x04\x3D\xCC\xE6\x90\xC3\x61\xE0" + "\x65\x88\x26\xF0\xF1\xE6\x71\x9E\xE3\xA1\x7B\x56\x82\x17\x0A\x07\x2C\x86\x1B\x0F" + "\x2A\x01\x93\xC2\x30\xC3\x60\x21\x6F\xC7\x5F\xEC\x4D\x17\xE3\xCC\xE5\x90\xC3\x60" + "\x26\xEE\x47\x91\xF4\x71\xF1\x1B\x0F\x71\xD3\xDA\x8E\x83\x8E\x32\x04\x3E\x16\xCE" + "\x56\x9F\x47\xD1\x02\x15\x03\x90\x81\x0E\x81\xCD\x64\x08\x94\x0E\x51\x02\x1D\x03" + "\x9E\x20\x45\xC1\x0E\x59\x02\x27\x12\xE7\x1B\x3E\x8F\xA3\xDC\x74\x2C\x39\x6C\xF6" + "\x96\x0C\xB0\xF6\x8C\x8F\x33\xA1\xCB\x3D\xC7\xA1\xD8\x40\x83\xCA\x24\xE1\x7C\xF4" + "\x18\x7E\x1E\x83\x8F\xC3\xDE\x47\xA7\x86\x5F\x2F\x51\x90\x4C\xF8\x7D\x82\x16\xCE" + "\x71\xFD\x9E\x0F\xB3\xF0\xFA\x2F\x1E\x87\x67\x86\x5F\x1F\x88\xF7\xCF\x43\xB0\x71" + "\xF8\x7A\x1D\x83\x0F\xC9\xC2\xF9\xE9\xE0\xFF\xA3\x29\x51\x90\xC6\x7C\x3D\x94\xCD" + "\x94\x76\x1A\xEC\xCE\xC1\x06\x91\xEC\x5E\xF8\x67\xC3\xD8\x2A\x2B\xA8\x67\x8F\x33" + "\xB0\xEC\x17\xC3\x0D\x07\x8E\x81\xE0\xD3\xB0\xCF\x7C\x75\xF3\xA1\xFC\xF9\xA1\xD9" + "\xEA\xBE\x12\xC2\xCE\x67\x60\xB1\xA2\x02\x3D\x73\xA0\xDD\xE3\xA1\xAF\xC7\xB0\xFC" + "\x3D\x0E\xC0\x41\xCB\x0F\xC3\xD0\x4D\x33\x5A\x21\xF0\xF6\x0D\x32\x04\x2C\x2A\x01" + "\xF6\x02\x17\x2A\x01\xC7\xB0\x13\x78\x9C\x30\x60\xC1\xE0\x10\xF8\x1C\x38\xD9\x02" + "\x17\x32\x27\x3E\xD9\x0C\x36\x02\x1F\x22\x47\x31\xB2\x04\x4E\x3A\x01\x1B\x98\xA0" + "\xB4\x78\x55\x0F\x7E\xCC\x8F\x1F\x7E\xD3\x6B\x3C\xC7\x65\x0A\x3C\x1E\xC3\xF0\x85" + "\xF5\x8E\x09\xAA\xC4\x16\x58\x88\xCF\x7C\x74\x35\xF8\xF4\x3B\x04\xD3\x33\xF0\x16" + "\x78\x63\x3F\x0C\xEF\xE8\x3C\xEA\xBD\xE7\xF3\xE0\x98\x18\xB1\xAF\xA8\xE8\x3C\xE8" + "\x98\x4C\x6B\xEA\x21\xC6\x45\xA2\x1D\xD0\x46\xE0\xC8\xEF\x1E\x0C\xEF\xEB\x06\x56" + "\xE7\x78\xF8\x7B\x47\xBF\x82\xC6\x78\xF3\x3D\xB8\x79\x9E\xDF\x0A\xB1\x8C\xF3\x3D" + "\x81\xEF\xC3\x09\x9E\xC3\xA8\x10\x78\x3D\x3D\x87\x90\x87\x37\x4F\x61\xEE\x3A\x8B" + "\xE0\x89\x70\x76\x1B\x01\x16\xC9\x81\xC7\x3C\x7B\x0F\x71\xD4\x4C\x11\x2C\xB0\x82" + "\xD1\x9E\x04\x6C\x6A\xC4\x30\x7B\x0F\x71\xEE\x3D\xC7\x83\x3B\xFA\x12\xEA\xCF\x87" + "\xB6\x70\xBE\x08\x32\x41\x0B\x6C\x3E\x73\x1F\x46\x7B\xE3\xA1\x70\x20\xCC\x3B\xA0" + "\x89\xC1\x49\xD4\x25\xD5\x9D\x40\x85\xC0\x29\xDE\x3C\x02\x27\x20\xC0\x87\xCB\xA9" + "\xF9\xE7\x45\x5A\x35\xE0\xBA\x3B\xA6\x05\xF0\x75\xB9\xC7\x74\xEF\x1E\xD0\xB0\x3B" + "\xAD\xCE\x3A\x7D\x85\x96\x21\xDD\x3B\xC7\x83\xDC\x75\x1C\x89\x32\x04\x8C\x78\x61" + "\xF8\x7A\x1D\x83\x0F\xC3\xD0\xC6\x7C\x6A\xB0\xEB\x73\x8F\x87\xD9\xB4\x77\xCF\xB4" + "\x35\xD0\xAC\x10\xF8\x7D\x8F\x3A\x3E\xCF\xC3\xD0\x70\xBA\xAC\xE3\xF0\xFA\xF1\xE8" + "\x76\x02\x14\x73\xD0\xEC\x31\x9F\x1A\x7E\x4E\x17\xCF\x4A\xFA\x0C\x2B\xF7\x8F\x87" + "\xD9\xB6\x84\x42\xAB\xE7\xD9\xF8\x7A\x50\x87\xE1\xE8\x39\x56\xD0\x4C\xF8\x7D\x9C" + "\x64\x6C\x3E\x8E\x3C\x22\x36\x23\xEB\xC8\xEB\x47\xD7\x81\x07\xA0\x7E\x38\xFC\x3D" + "\x0E\xCA\x10\xFC\x3D\x28\x43\xF0\xFA\xF0\x22\x47\x3D\x04\xD3\x30\x43\xC4\x88\x22" + "\x35\x16\xA3\xEB\xC7\xD8\x21\xE7\x1E\xD3\xEC\xFC\x9C\x2F\x9E\x9A\x08\x52\xCF\x60" + "\xEA\x3D\x80\x85\x82\x9E\xC3\xE8\x43\xE8\xFA\x04\x4E\x7F\x8E\xB3\xAC\x70\x47\x99" + "\xF4\x20\xC3\x61\xEC\x3F\x0F\x43\xB3\x4F\xC9\xC2\xF9\xE9\x42\x02\x1D\x70\x44\xE8" + "\xA7\x1C\xA2\x36\x1F\x47\x1D\x11\xB0\xFA\x38\xE8\x8D\x87\xB0\xFC\x3F\x47\x91\xB0" + "\xE4\x22\x30\x73\x77\xC7\x83\xE9\xD1\x08\x7D\x07\x38\x5F\x40\x8D\x9F\x9B\x01\x1B" + "\x32\x0C\x23\xCC\xF2\x3E\x8E\x3A\x22\x36\x1F\x47\x1D\x11\x1B\x0F\xA3\x8E\x88\x8D" + "\x80\x83\x9D\x82\x44\xF0\x47\xE1\x98\x10\xF8\x62\x41\xE0\x5E\x19\x7C\x7C\x3D\x87" + "\x30\xF6\x1F\x87\xE8\xF2\x59\xEF\x9E\x0A\x70\xBE\x08\x5D\x15\xA0\x42\xE0\x6C\x83" + "\x2A\x2B\x47\xD0\x87\xB0\xFC\x3D\x3C\x36\xC2\x08\xFC\x3F\x47\x91\xC5\xF5\xF3\xC1" + "\xDC\x3D\x0E\xC2\x04\x19\x87\xD0\x84\x68\x08\x5D\x16\xC9\xC2\xF8\x21\x74\x18\x4E" + "\xCA\x10\xFC\x3E\xBC\x7B\x59\xEE\x04\xC9\xB3\x85\xF3"; // ++++++++++++++++++++^^^^^^^^^^^^^^^^^^^++++++++++++++++++++ // ++++++++++++++++++++ DO NOT EDIT ABOVE ++++++++++++++++++++ @@ -1887,7 +1887,11 @@ extern "C" { uint32_t convert_seconds_to_dhm(uint32_t seconds, char *unit, uint8_t *color){ static uint32_t conversions[3] = {24 * 3600, 3600, 60}; static char units[3] = { 'd', 'h', 'm'}; // day, hour, minute - static uint8_t colors[3] = { 0x60, 0xA0, 0xEA}; + uint8_t color_text_8 = WebColor(COL_TEXT) & 0xFF; // color of text on 8 bits + uint8_t color_back_8 = WebColor(COL_BACKGROUND) & 0xFF; // color of background on 8 bits + uint8_t colors[3] = { (uint8_t) changeUIntScale(6, 0, 16, color_back_8, color_text_8), // 6/16 of text + (uint8_t) changeUIntScale(10, 0, 16, color_back_8, color_text_8), // 10/16 of text color + color_text_8}; for(int i = 0; i < 3; ++i) { *color = colors[i]; *unit = units[i]; @@ -1915,7 +1919,7 @@ void ZigbeeShow(bool json) if (!zigbee_num) { return; } if (zigbee_num > 255) { zigbee_num = 255; } - WSContentSend_P(msg[ZB_WEB_CSS]); + WSContentSend_P(msg[ZB_WEB_CSS], WebColor(COL_TEXT)); // WSContentSend_compressed(ZB_WEB, 0); // sort elements by name, then by id From 805b69e289bdb0fca38354553ee51d84a41f0df4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Tue, 29 Dec 2020 15:55:14 +0100 Subject: [PATCH 045/105] add tasmota-AF --- .github/workflows/Tasmota_build_master.yml | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index 244bfe8ce..5d1453c60 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -230,6 +230,30 @@ jobs: name: firmware path: ./build_output/firmware + + tasmota-AF: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota-BG: needs: tasmota_pull runs-on: ubuntu-latest From 8fb6ba2bf7c7bfaf70c587f62e854b7ce6b08325 Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Tue, 29 Dec 2020 17:42:36 +0100 Subject: [PATCH 046/105] fix: ST7789 display driver for 135*240px Improved the driver to support both 135*240 and 240*240 formats. These are the most common for the ST7789 display. Fixes #10282 --- .../Arduino_ST7789.cpp | 68 ++++++++++++------- .../Arduino_ST7789-gemu-1.0/Arduino_ST7789.h | 20 ++++-- tasmota/xdsp_12_ST7789.ino | 18 +++-- 3 files changed, 72 insertions(+), 34 deletions(-) diff --git a/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.cpp b/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.cpp index f45b33095..74837242b 100644 --- a/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.cpp +++ b/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.cpp @@ -27,7 +27,7 @@ uint16_t Arduino_ST7789::GetColorFromIndex(uint8_t index) { } static const uint8_t PROGMEM - cmd_240x240[] = { // Initialization commands for 7789 screens + init_cmd[] = { // Initialization commands for 7789 screens 10, // 9 commands in list: ST7789_SWRESET, ST_CMD_DELAY, // 1: Software reset, no args, w/delay 150, // 150 ms delay @@ -38,14 +38,6 @@ static const uint8_t PROGMEM 10, // 10 ms delay ST7789_MADCTL , 1, // 4: Memory access ctrl (directions), 1 arg: 0x00, // Row addr/col addr, bottom to top refresh - ST7789_CASET , 4, // 5: Column addr set, 4 args, no delay: - 0x00, ST7789_240x240_XSTART, // XSTART = 0 - (ST7789_TFTWIDTH+ST7789_240x240_XSTART) >> 8, - (ST7789_TFTWIDTH+ST7789_240x240_XSTART) & 0xFF, // XEND = 240 - ST7789_RASET , 4, // 6: Row addr set, 4 args, no delay: - 0x00, ST7789_240x240_YSTART, // YSTART = 0 - (ST7789_TFTHEIGHT+ST7789_240x240_YSTART) >> 8, - (ST7789_TFTHEIGHT+ST7789_240x240_YSTART) & 0xFF, // YEND = 240 ST7789_INVON , ST_CMD_DELAY, // 7: Inversion ON 10, ST7789_NORON , ST_CMD_DELAY, // 8: Normal display on, no args, w/delay @@ -75,7 +67,7 @@ inline uint16_t swapcolor(uint16_t x) { // Constructor when using software SPI. All output pins are configurable. Arduino_ST7789::Arduino_ST7789(int8_t dc, int8_t rst, int8_t sid, int8_t sclk, int8_t cs, int8_t bp) - : Renderer(ST7789_TFTWIDTH, ST7789_TFTHEIGHT) + : Renderer(_width, _height) { _cs = cs; _dc = dc; @@ -91,7 +83,7 @@ Arduino_ST7789::Arduino_ST7789(int8_t dc, int8_t rst, int8_t sid, int8_t sclk, i // Constructor when using hardware SPI. Faster, but must use SPI pins // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.) Arduino_ST7789::Arduino_ST7789(int8_t dc, int8_t rst, int8_t cs, int8_t bp) - : Renderer(ST7789_TFTWIDTH, ST7789_TFTHEIGHT) { + : Renderer(_width, _height) { _cs = cs; _dc = dc; _rst = rst; @@ -335,29 +327,59 @@ void Arduino_ST7789::setRotation(uint8_t m) { case 0: writedata(ST7789_MADCTL_MX | ST7789_MADCTL_MY | ST7789_MADCTL_RGB); - _xstart = _colstart; - // _ystart = _rowstart; - _ystart = 80; + _xstart = 0; + _ystart = 0; + if (_width==240 && _height==240) { + _xstart = ST7789_240x240_XSTART_R0; + _ystart = ST7789_240x240_YSTART_R0; + } + if (_width==135 && _height==240) { + _xstart = ST7789_135x240_XSTART_R0; + _ystart = ST7789_135x240_YSTART_R0; + } break; case 1: writedata(ST7789_MADCTL_MY | ST7789_MADCTL_MV | ST7789_MADCTL_RGB); - _ystart = _colstart; - // _xstart = _rowstart; - _xstart = 80; + _ystart = 0; + _xstart = 0; + if (_width==240 && _height==240) { + _xstart = ST7789_240x240_XSTART_R1; + _ystart = ST7789_240x240_YSTART_R1; + } + if (_width==240 && _height==135) { + _xstart = ST7789_135x240_XSTART_R1; + _ystart = ST7789_135x240_YSTART_R1; + } break; case 2: writedata(ST7789_MADCTL_RGB); - _xstart = _colstart; - _ystart = _rowstart; + _xstart = 0; + _ystart = 0; + if (_width==240 && _height==240) { + _xstart = ST7789_240x240_XSTART_R2; + _ystart = ST7789_240x240_YSTART_R2; + } + if (_width==135 && _height==240) { + _xstart = ST7789_135x240_XSTART_R2; + _ystart = ST7789_135x240_YSTART_R2; + } break; case 3: writedata(ST7789_MADCTL_MX | ST7789_MADCTL_MV | ST7789_MADCTL_RGB); - _ystart = _colstart; - _xstart = _rowstart; + _xstart = 0; + _ystart = 0; + if (_width==240 && _height==240) { + _xstart = ST7789_240x240_XSTART_R3; + _ystart = ST7789_240x240_YSTART_R3; + } + if (_width==240 && _height==135) { + _xstart = ST7789_135x240_XSTART_R3; + _ystart = ST7789_135x240_YSTART_R3; + } break; } } @@ -533,12 +555,10 @@ inline void Arduino_ST7789::DC_LOW(void) { void Arduino_ST7789::init(uint16_t width, uint16_t height) { commonInit(NULL); - _colstart = ST7789_240x240_XSTART; - _rowstart = ST7789_240x240_YSTART; _height = height; _width = width; - displayInit(cmd_240x240); + displayInit(init_cmd); setRotation(2); diff --git a/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.h b/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.h index 2d97346e7..3dfaa03a8 100644 --- a/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.h +++ b/lib/lib_display/Arduino_ST7789-gemu-1.0/Arduino_ST7789.h @@ -39,11 +39,23 @@ //#define SPI_HAS_TRANSACTION // already defined in SPI.h -#define ST7789_TFTWIDTH 240 -#define ST7789_TFTHEIGHT 240 +#define ST7789_240x240_XSTART_R0 0 +#define ST7789_240x240_YSTART_R0 80 +#define ST7789_240x240_XSTART_R1 80 +#define ST7789_240x240_YSTART_R1 0 +#define ST7789_240x240_XSTART_R2 0 +#define ST7789_240x240_YSTART_R2 0 +#define ST7789_240x240_XSTART_R3 0 +#define ST7789_240x240_YSTART_R3 0 -#define ST7789_240x240_XSTART 0 -#define ST7789_240x240_YSTART 0 +#define ST7789_135x240_XSTART_R0 53 +#define ST7789_135x240_YSTART_R0 40 +#define ST7789_135x240_XSTART_R1 40 +#define ST7789_135x240_YSTART_R1 52 +#define ST7789_135x240_XSTART_R2 52 +#define ST7789_135x240_YSTART_R2 40 +#define ST7789_135x240_XSTART_R3 40 +#define ST7789_135x240_YSTART_R3 53 #define ST_CMD_DELAY 0x80 // special signifier for command lists diff --git a/tasmota/xdsp_12_ST7789.ino b/tasmota/xdsp_12_ST7789.ino index 3c85f168a..1c9ec1aff 100644 --- a/tasmota/xdsp_12_ST7789.ino +++ b/tasmota/xdsp_12_ST7789.ino @@ -64,11 +64,11 @@ void ST7789_InitDriver() if (XDSP_12 == Settings.display_model) { - if (Settings.display_width != ST7789_TFTWIDTH) { - Settings.display_width = ST7789_TFTWIDTH; + if (!Settings.display_width) { + Settings.display_width = 240; } - if (Settings.display_height != ST7789_TFTHEIGHT) { - Settings.display_height = ST7789_TFTHEIGHT; + if (!Settings.display_height) { + Settings.display_height = 240; } // disable screen buffer @@ -130,9 +130,15 @@ void ST7789_InitDriver() #ifdef SHOW_SPLASH // Welcome text - renderer->setTextFont(2); renderer->setTextColor(ST7789_WHITE,ST7789_BLACK); - renderer->DrawStringAt(30, 100, "ST7789 TFT!", ST7789_WHITE,0); + int fontSize = 2; + renderer->setTextFont(2); + if (Settings.display_width<240) { + fontSize = 1; + } + renderer->setTextFont(fontSize); + int fontHeight = 12 * fontSize; + renderer->DrawStringAt(30, (Settings.display_height-fontHeight)/2, "ST7789 TFT!", ST7789_WHITE,0); delay(1000); #endif From f004cfea60928a723419b35a618fce26fb30c1c1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Dec 2020 17:42:53 +0100 Subject: [PATCH 047/105] Breaking change regarding MFRC522 and ILI9341 - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` - Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` --- CHANGELOG.md | 7 ++- RELEASENOTES.md | 6 +- platformio_tasmota32.ini | 1 + platformio_tasmota_env32.ini | 8 +++ tasmota/support.ino | 10 +++- tasmota/support_tasmota.ino | 62 ++++++++++++++------- tasmota/tasmota_configurations_ESP32.h | 20 ++++++- tasmota/tasmota_template.h | 76 ++++++++++++++------------ tasmota/tasmota_version.h | 2 +- tasmota/xdrv_80_odroidgo.ino | 34 ++++++++++++ tasmota/xdsp_04_ili9341.ino | 13 ++++- tasmota/xsns_80_mfrc522.ino | 6 +- 12 files changed, 182 insertions(+), 63 deletions(-) create mode 100644 tasmota/xdrv_80_odroidgo.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 706721d0b..4e45bf32e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [9.2.0.1] +## [9.2.0.2] +### Breaking Changed +- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` +- Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` + +## [9.2.0.1] 20201229 ### Added - Milliseconds to console output (#10152) - Support for P9813 RGB Led MOSFET controller (#10104) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b9ed48538..1f9677073 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -56,7 +56,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v9.2.0.1 +## Changelog v9.2.0.2 ### Added - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) @@ -69,6 +69,10 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for IR inverted leds using ``#define IR_SEND_INVERTED true`` [#10301](https://github.com/arendst/Tasmota/issues/10301) - Support for disabling 38kHz IR modulation using ``#define IR_SEND_USE_MODULATION false`` [#10301](https://github.com/arendst/Tasmota/issues/10301) +### Breaking Changed +- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` +- Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` + ### Changed - Logging from heap to stack freeing 700 bytes RAM diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 1fe7667a2..430fcc344 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -8,6 +8,7 @@ default_envs = ${build_envs.default_envs} ; *** Uncomment by deleting ";" in the line(s) below to select version(s) ; tasmota32 ; tasmota32-webcam +; tasmota32-odroidgo ; tasmota32-minimal ; tasmota32-lite ; tasmota32-knx diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index ff416538e..886b2cfaf 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -36,6 +36,14 @@ board_build.f_cpu = 240000000L build_flags = ${common32.build_flags} -DFIRMWARE_WEBCAM lib_extra_dirs = lib/libesp32, lib/lib_basic +[env:tasmota32-odroidgo] +extends = env:tasmota32 +board = odroid_esp32 +board_build.f_cpu = 160000000L +board_build.partitions = esp32_partition_app1984k_ffat12M.csv +build_flags = ${common32.build_flags} -DFIRMWARE_ODROID_GO +lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display + [env:tasmota32-minimal] extends = env:tasmota32 build_flags = ${common32.build_flags} -DFIRMWARE_MINIMAL diff --git a/tasmota/support.ino b/tasmota/support.ino index 577c8bb95..fcf21a014 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1307,7 +1307,7 @@ uint8_t ModuleNr(void) uint32_t ModuleTemplate(uint32_t module) { uint32_t i = 0; for (i = 0; i < sizeof(kModuleNiceList); i++) { - if (Settings.module == pgm_read_byte(kModuleNiceList + i)) { + if (module == pgm_read_byte(kModuleNiceList + i)) { break; } } @@ -1346,6 +1346,9 @@ String AnyModuleName(uint32_t index) if (USER_MODULE == index) { return String(SettingsText(SET_TEMPLATE_NAME)); } else { +#ifdef ESP32 + index = ModuleTemplate(index); +#endif char name[TOPSZ]; return String(GetTextIndexed(name, sizeof(name), index, kModuleNames)); } @@ -1451,6 +1454,11 @@ void ModuleDefault(uint32_t module) { if (USER_MODULE == module) { module = WEMOS; } // Generic Settings.user_template_base = module; + +#ifdef ESP32 + module = ModuleTemplate(module); +#endif + char name[TOPSZ]; SettingsUpdateText(SET_TEMPLATE_NAME, GetTextIndexed(name, sizeof(name), module, kModuleNames)); #ifdef ESP8266 diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index bd92688f6..58b79e905 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1594,24 +1594,47 @@ void GpioInit(void) #ifdef ESP8266 if ((2 == Pin(GPIO_TXD)) || (H801 == TasmotaGlobal.module_type)) { Serial.set_tx(2); } +#endif + + TasmotaGlobal.soft_spi_enabled = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); #ifdef USE_SPI - TasmotaGlobal.spi_enabled = (((PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_CS) > 14)) || (Pin(GPIO_SPI_CS) < 12)) || ((PinUsed(GPIO_SPI_DC) && (Pin(GPIO_SPI_DC) > 14)) || (Pin(GPIO_SPI_DC) < 12))); - if (TasmotaGlobal.spi_enabled) { - TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); - SetPin(12, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); - SetPin(13, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); - SetPin(14, AGPIO(GPIO_SPI_CLK)); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK)")); + uint32_t pin_cs = Pin(GPIO_SPI_CS); + uint32_t pin_dc = Pin(GPIO_SPI_DC); + if (PinUsed(GPIO_RC522_CS)) { + pin_cs = Pin(GPIO_RC522_CS); + } + if (PinUsed(GPIO_ILI9341_CS)) { + pin_cs = Pin(GPIO_ILI9341_CS); + if (PinUsed(GPIO_ILI9341_DC)) { + pin_dc = Pin(GPIO_ILI9341_DC); + } + } + +#ifdef ESP8266 + if (!TasmotaGlobal.soft_spi_enabled) { + // If SPI_CS is used it must be valid + TasmotaGlobal.spi_enabled = ((pin_cs < 99) && ((pin_cs > 14) || (pin_cs < 12))); + if (TasmotaGlobal.spi_enabled && (pin_dc < 99)) { + // If SPI_DC is used it must be valid + TasmotaGlobal.spi_enabled = ((pin_dc > 14) || (pin_dc < 12)); + } + if (TasmotaGlobal.spi_enabled) { + TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK)")); + } } -#endif // USE_SPI #endif // ESP8266 #ifdef ESP32 -#ifdef USE_SPI - if (PinUsed(GPIO_SPI_CS) || PinUsed(GPIO_SPI_DC)) { - if ((15 == Pin(GPIO_SPI_CS)) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI + if (pin_cs < 99) { +/* + // Do not do this as ESP32 can have SPI_CS everywhere + if ((15 == pin_cs) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); SetPin(12, AGPIO(GPIO_SPI_MISO)); TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); @@ -1619,7 +1642,7 @@ void GpioInit(void) TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); SetPin(14, AGPIO(GPIO_SPI_CLK)); } - else if ((5 == Pin(GPIO_SPI_CS)) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI + else if ((5 == pin_cs) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); SetPin(19, AGPIO(GPIO_SPI_MISO)); TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); @@ -1644,24 +1667,25 @@ void GpioInit(void) SetPin(18, AGPIO(GPIO_SPI_CLK)); } TasmotaGlobal.spi_enabled = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); +*/ + TasmotaGlobal.spi_enabled = (pin_cs < 99); if (TasmotaGlobal.spi_enabled) { - if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO)) { + if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); } - else if (PinUsed(GPIO_SPI_MOSI)) { + else if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); } - else if (PinUsed(GPIO_SPI_MISO)) { + else if (PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); } } } -#endif // USE_SPI #endif // ESP32 - TasmotaGlobal.soft_spi_enabled = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); +#endif // USE_SPI for (uint32_t i = 0; i < ARRAY_SIZE(TasmotaGlobal.my_module.io); i++) { uint32_t mpin = ValidPin(i, TasmotaGlobal.my_module.io[i]); diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index 86e27a534..c3bb7044b 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -33,9 +33,27 @@ #define CODE_IMAGE_STR "webcam" #define USE_WEBCAM -#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #endif // FIRMWARE_WEBCAM +/*********************************************************************************************\ + * [tasmota32-odroidgo.bin] + * Provide an image with useful supported sensors enabled +\*********************************************************************************************/ + +#ifdef FIRMWARE_ODROID_GO + +#undef CODE_IMAGE_STR +#define CODE_IMAGE_STR "odroid-go" + +#define USE_ODROID_GO // Add support for Odroid Go +#define USE_ADC +#define USE_SPI + #define USE_DISPLAY // Add SPI Display Support (+2k code) + #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code) +#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +#endif // FIRMWARE_ODROID_GO + #endif // ESP32 #endif // _TASMOTA_CONFIGURATIONS_ESP32_H_ diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 5f1eafb8e..46915f280 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -359,19 +359,23 @@ const uint16_t kGpioNiceList[] PROGMEM = { #endif #ifdef USE_SPI - AGPIO(GPIO_SPI_MISO), // SPI MISO - AGPIO(GPIO_SPI_MOSI), // SPI MOSI - AGPIO(GPIO_SPI_CLK), // SPI Clk - AGPIO(GPIO_SPI_CS), // SPI Chip Select - AGPIO(GPIO_SPI_DC), // SPI Data Direction + AGPIO(GPIO_SPI_MISO), // SPI MISO + AGPIO(GPIO_SPI_MOSI), // SPI MOSI + AGPIO(GPIO_SPI_CLK), // SPI Clk + AGPIO(GPIO_SPI_CS), // SPI Chip Select + AGPIO(GPIO_SPI_DC), // SPI Data Direction #ifdef USE_NRF24 // AGPIO(GPIO_NRF24_CS), // AGPIO(GPIO_NRF24_DC), #endif +#ifdef USE_RC522 + AGPIO(GPIO_RC522_CS), // RC522 Rfid Chip Select + AGPIO(GPIO_RC522_RST), // RC522 Rfid Reset +#endif #ifdef USE_DISPLAY #ifdef USE_DISPLAY_ILI9341 -// AGPIO(GPIO_ILI9341_CS), -// AGPIO(GPIO_ILI9341_DC), + AGPIO(GPIO_ILI9341_CS), + AGPIO(GPIO_ILI9341_DC), #endif // USE_DISPLAY_ILI9341 #endif // USE_DISPLAY #endif // USE_SPI @@ -710,10 +714,6 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin #endif -#ifdef USE_RC522 - AGPIO(GPIO_RC522_RST), // RC522 Rfid reset -// AGPIO(GPIO_RC522_CS), // RC522 Rfid chip select -#endif /*-------------------------------------------------------------------------------------------*\ * ESP32 specifics @@ -2319,7 +2319,9 @@ const char kModuleNames[] PROGMEM = #ifdef USE_WEBCAM "ESP32-Cam|" #endif // USE_WEBCAM -// "Odroid Go|"" +#ifdef USE_ODROID_GO + "Odroid Go|" +#endif // USE_ODROID_GO // "ESP32-Solo|" // "WT32-Eth01|" // "TTGO Watch|" @@ -2334,7 +2336,9 @@ const uint8_t kModuleNiceList[] PROGMEM = { #ifdef USE_WEBCAM ESP32_CAM_AITHINKER, #endif // USE_WEBCAM -// ODROID_GO, +#ifdef USE_ODROID_GO + ODROID_GO, +#endif // USE_ODROID_GO // ESP32_SOLO, // WT32_ETH01, // TTGO_WATCH, @@ -2435,46 +2439,46 @@ const mytmplt kModules[] PROGMEM = #endif // USE_WEBCAM #ifdef USE_ODROID_GO { // ODROID_GO - (ESP32) - AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, Button1 - AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, BTN-VOLUME + AGPIO(GPIO_TXD), // 1 IO TXD0 GPIO1, TXD0 + AGPIO(GPIO_LEDLNK), // 2 IO GPIO2, STATUS LED + AGPIO(GPIO_RXD), // 3 IO RXD0 GPIO3, RXD0 AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - AGPIO(GPIO_USER), // 5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK + AGPIO(GPIO_ILI9341_CS), // 5 IO GPIO5, VSPI_CS0_LCD // 6 IO GPIO6, Flash CLK // 7 IO GPIO7, Flash D0 // 8 IO GPIO8, Flash D1 - AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD - AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD + 0, // 9 IO GPIO9, Flash D2, U1RXD + 0, // 10 IO GPIO10, Flash D3, U1TXD // 11 IO GPIO11, Flash CMD AGPIO(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.) - AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + AGPIO(GPIO_KEY1) +1, // 13 IO GPIO13, BTN-MENU + AGPIO(GPIO_PWM1), // 14 IO GPIO14, LCD Backlight AGPIO(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.) AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - AGPIO(GPIO_USER), // 18 IO GPIO18, VSPICLK, HS1_DATA7 - AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 + AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, VSPI_CLK + AGPIO(GPIO_SPI_MISO), // 19 IO GPIO19, VSPI_MISO 0, // 20 - AGPIO(GPIO_USER), // 21 IO GPIO21, VSPIHD, EMAC_TX_EN - AGPIO(GPIO_USER), // 22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - AGPIO(GPIO_USER), // 23 IO GPIO23, VSPID, HS1_STROBE + AGPIO(GPIO_ILI9341_DC), // 21 IO GPIO21, SPI_DC_LCD + 0, // 22 IO LED GPIO22, VSPI_CS1_TFLASH + AGPIO(GPIO_SPI_MOSI), // 23 IO GPIO23, VSPI_MOSI 0, // 24 - AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV + 0, // 25 IO GPIO25, DAC_1 (PAM8304A) + 0, // 26 IO GPIO26, DAC_2 (PAM8304A) + AGPIO(GPIO_KEY1) +2, // 27 IO GPIO27, BTN-SELECT 0, // 28 0, // 29 0, // 30 0, // 31 - AGPIO(GPIO_USER), // 32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 - AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 - AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 - AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 - AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + AGPIO(GPIO_SWT1) +4, // 32 IO GPIO32, BTN-A + AGPIO(GPIO_SWT1) +5, // 33 IO GPIO33, BTN-B + AGPIO(GPIO_ADC_JOY), // 34 I NO PULLUP GPIO34, JOY-X (LEFT-RIGHT) + AGPIO(GPIO_ADC_JOY) +1, // 35 I NO PULLUP GPIO35, JOY-Y (UP-DOWN) + AGPIO(GPIO_ADC_RANGE) +2, // 36 I NO PULLUP GPIO36, SENSOR_VP (BATTERY CARGER) 0, // 37 NO PULLUP 0, // 38 NO PULLUP - AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 + AGPIO(GPIO_KEY1) +3, // 39 I NO PULLUP GPIO39, BTN-START 0 // Flag }, #endif // USE_ODROID_GO diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index d4fbfcf76..490f68bd8 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,6 +20,6 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x09020001; +const uint32_t VERSION = 0x09020002; #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/xdrv_80_odroidgo.ino b/tasmota/xdrv_80_odroidgo.ino new file mode 100644 index 000000000..4886f87d6 --- /dev/null +++ b/tasmota/xdrv_80_odroidgo.ino @@ -0,0 +1,34 @@ +/* + xdrv_81_webcam.ino - ESP32 webcam support for Tasmota + + Copyright (C) 2020 Gerhard Mutz and 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 . +*/ + +#ifdef ESP32 +#ifdef USE_ODROID_GO +/*********************************************************************************************\ + * Odroid Go + * + * Clock frequency 160MHz (board_build.f_cpu = 160000000L) + * SPI Flash Size = 16MB (board_build.partitions = esp32_partition_app1984k_ffat12M.csv) + * + * To be done: + * - Audio on GPIO25/26 + * +/*********************************************************************************************/ + +#endif // USE_ODROID_GO +#endif // ESP32 diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index fd61b4a82..adabfe6b0 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -97,7 +97,18 @@ void Ili9341Init(uint8_t mode) void Ili9341InitDriver(void) { + uint32_t pin_cs = Pin(GPIO_SPI_CS); + uint32_t pin_dc = Pin(GPIO_SPI_DC); if (!Settings.display_model) { + if (PinUsed(GPIO_ILI9341_CS)) { + pin_cs = Pin(GPIO_ILI9341_CS); + if (PinUsed(GPIO_ILI9341_DC)) { + pin_dc = Pin(GPIO_ILI9341_DC); + } + Settings.display_model = XDSP_04; + } + + // Legacy Settings.display_model = XDSP_04; } @@ -109,7 +120,7 @@ void Ili9341InitDriver(void) Settings.display_height = ILI9341_TFTHEIGHT; } - tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC)); + tft = new Adafruit_ILI9341(pin_cs, pin_dc); tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 diff --git a/tasmota/xsns_80_mfrc522.ino b/tasmota/xsns_80_mfrc522.ino index 2c970119f..899c77909 100644 --- a/tasmota/xsns_80_mfrc522.ino +++ b/tasmota/xsns_80_mfrc522.ino @@ -17,6 +17,7 @@ along with this program. If not, see . */ +#ifdef USE_SPI #ifdef USE_RC522 /*********************************************************************************************\ * MFRC522 - 13.56 MHz RFID reader @@ -97,8 +98,8 @@ void RC522ScanForTag(void) { } void RC522Init(void) { - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_RC522_RST)) { - Mfrc522 = new MFRC522(Pin(GPIO_SPI_CS), Pin(GPIO_RC522_RST)); + if (PinUsed(GPIO_RC522_CS) && PinUsed(GPIO_RC522_RST)) { + Mfrc522 = new MFRC522(Pin(GPIO_RC522_CS), Pin(GPIO_RC522_RST)); SPI.begin(); Mfrc522->PCD_Init(); // if (Mfrc522->PCD_PerformSelfTest()) { // Saves 0k5 code @@ -155,3 +156,4 @@ bool Xsns80(uint8_t function) { } #endif // USE_RC522 +#endif // USE_SPI From 01647b96dece90cb68dc6aaed371e0e71bc7e1fb Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Dec 2020 17:52:25 +0100 Subject: [PATCH 048/105] Forgot the workflows for odroid-go --- .github/workflows/CI_github_ESP32.yml | 20 +++++++++++++++++ .github/workflows/Tasmota_build.yml | 23 ++++++++++++++++++++ .github/workflows/Tasmota_build_master.yml | 25 +++++++++++++++++++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml index a36d747dc..ecf8bf561 100644 --- a/.github/workflows/CI_github_ESP32.yml +++ b/.github/workflows/CI_github_ESP32.yml @@ -44,6 +44,26 @@ jobs: name: firmware path: ./build_output/firmware + tasmota32-odroidgo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-odroidgo + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + tasmota32-minimal: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 1507fc2c2..fe06a70d2 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -875,6 +875,29 @@ jobs: path: ./build_output/firmware + tasmota32-odroidgo: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-odroidgo + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota32-knx: needs: tasmota_pull runs-on: ubuntu-latest diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index 5d1453c60..4169bd028 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -875,6 +875,29 @@ jobs: path: ./build_output/firmware + tasmota32-odroidgo: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-odroidgo + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota32-knx: needs: tasmota_pull runs-on: ubuntu-latest @@ -1544,7 +1567,7 @@ jobs: [ ! -f ./mv_firmware/tasmota-ir*.* ] || mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-display.* ] || mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-knx.* ] || mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ - [ ! -f ./mv_firmware/tasmota-zbbridge.* ] || mv ./mv_firmware/tasmota-zbbridge.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-zbbridge.* ] || mv ./mv_firmware/tasmota-zbbridge.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota32.* ] || mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-sensors.* ] || mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-minimal.* ] || mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ From 37bd2a99f60092ef0419af6bfbc33c357c2c1c62 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 29 Dec 2020 18:03:05 +0100 Subject: [PATCH 049/105] Add basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin Add basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) --- CHANGELOG.md | 3 +++ RELEASENOTES.md | 1 + platformio_tasmota_env32.ini | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e45bf32e..bd49bc4c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development ## [9.2.0.2] +### Added +- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) + ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` - Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 1f9677073..6f02fa36f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -68,6 +68,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for Afrikaans language translations by Christiaan Heerze - Support for IR inverted leds using ``#define IR_SEND_INVERTED true`` [#10301](https://github.com/arendst/Tasmota/issues/10301) - Support for disabling 38kHz IR modulation using ``#define IR_SEND_USE_MODULATION false`` [#10301](https://github.com/arendst/Tasmota/issues/10301) +- Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630) ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 886b2cfaf..bad0b800a 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -39,7 +39,7 @@ lib_extra_dirs = lib/libesp32, lib/lib_basic [env:tasmota32-odroidgo] extends = env:tasmota32 board = odroid_esp32 -board_build.f_cpu = 160000000L +board_build.f_cpu = 240000000L board_build.partitions = esp32_partition_app1984k_ffat12M.csv build_flags = ${common32.build_flags} -DFIRMWARE_ODROID_GO lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display From 488712c3f0ace7ccb3d6d12dc0c721c7e6e25597 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 29 Dec 2020 19:31:27 +0100 Subject: [PATCH 050/105] Commands `CTRange` and `VirtualCT` --- CHANGELOG.md | 2 + tasmota/i18n.h | 2 + tasmota/my_user_config.h | 2 + tasmota/support_command.ino | 5 + tasmota/tasmota_configurations.h | 2 + tasmota/xdrv_04_light.ino | 463 ++++++++++++++++++++++--------- 6 files changed, 345 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd49bc4c8..d542934fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. ## [9.2.0.2] ### Added - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) +- Command ``CTRange`` to specify the visible CT range the bulb is capable of +- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 17cd2fe53..3fd70be4e 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -425,6 +425,8 @@ #define D_CMND_DIMMER_RANGE "DimmerRange" #define D_CMND_DIMMER_STEP "DimmerStep" #define D_CMND_HSBCOLOR "HSBColor" +#define D_CMND_VIRTUALCT "VirtualCT" +#define D_CMND_CTRANGE "CTRange" #define D_CMND_LED "Led" #define D_CMND_LEDTABLE "LedTable" #define D_CMND_FADE "Fade" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 7c354c8bf..cc75735cf 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -309,6 +309,7 @@ #define LIGHT_WHITE_BLEND_MODE false // [SetOption105] White Blend Mode - used to be `RGBWWTable` last value `0`, now deprecated in favor of this option #define LIGHT_VIRTUAL_CT false // [SetOption106] Virtual CT - Creates a virtual White ColorTemp for RGBW lights #define LIGHT_VIRTUAL_CT_CW false // [SetOption107] Virtual CT Channel - signals whether the hardware white is cold CW (true) or warm WW (false) +#define LIGHT_VIRTUAL_CT_POINTS 3 // Number of reference points for Virtual CT (min 2, default 3) // -- Energy -------------------------------------- #define ENERGY_VOLTAGE_ALWAYS false // [SetOption21] Enable show voltage even if powered off @@ -494,6 +495,7 @@ #define USE_SONOFF_L1 // Add support for Sonoff L1 led control #define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code) #define USE_LIGHT_PALETTE // Add support for color palette (+0k7 code) +#define USE_LIGHT_VIRTUAL_CT // Add support for Virtual White Color Temperature (+1.1k code) #define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code) // -- Counter input ------------------------------- diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 34a3bd2e3..bc1121123 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -941,6 +941,11 @@ void CmndSetoption(void) else if (4 == ptype) { // SetOption82 .. 113 bitWrite(Settings.flag4.data, pindex, XdrvMailbox.payload); switch (pindex) { +#ifdef USE_LIGHT + case 0: // SetOption 82 - (Alexa) Reduced CT range for Alexa (1) + setAlexaCTRange(); + break; +#endif case 3: // SetOption85 - Enable Device Groups case 6: // SetOption88 - PWM Dimmer Buttons control remote devices case 15: // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 52bd19c58..6e4169e82 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -508,6 +508,7 @@ // -- Optional light modules ---------------------- //#undef USE_LIGHT // Enable Dimmer/Light support +#undef USE_LIGHT_VIRTUAL_CT // Disable support for Virtual White Color Temperature (SO106) #undef USE_WS2812 // Disable WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // #undef USE_MY92X1 // Disable support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas #undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code) @@ -643,6 +644,7 @@ //#undef USE_SONOFF_D1 // Disable support for Sonoff D1 Dimmer (+0k7 code) // -- Optional light modules ---------------------- +#undef USE_LIGHT_VIRTUAL_CT // Disable support for Virtual White Color Temperature (SO106) //#undef USE_LIGHT // Also disable all Dimmer/Light support #undef USE_WS2812 // Disable WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // #undef USE_MY92X1 // Disable support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 2cd84f780..a47c4a4ca 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -132,6 +132,10 @@ const char kLightCommands[] PROGMEM = "|" // No prefix D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_DIMMER_RANGE "|" D_CMND_DIMMER_STEP "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|" D_CMND_RGBWWTABLE "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|" D_CMND_WHITE "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR + "|" D_CMND_CTRANGE +#ifdef USE_LIGHT_VIRTUAL_CT + "|" D_CMND_VIRTUALCT +#endif // USE_LIGHT_VIRTUAL_CT #ifdef USE_LIGHT_PALETTE "|" D_CMND_PALETTE #endif // USE_LIGHT_PALETTE @@ -144,6 +148,10 @@ void (* const LightCommand[])(void) PROGMEM = { &CmndColor, &CmndColorTemperature, &CmndDimmer, &CmndDimmerRange, &CmndDimmerStep, &CmndLedTable, &CmndFade, &CmndRgbwwTable, &CmndScheme, &CmndSpeed, &CmndWakeup, &CmndWakeupDuration, &CmndWhite, &CmndChannel, &CmndHsbColor, + &CmndCTRange, +#ifdef USE_LIGHT_VIRTUAL_CT + &CmndVirtualCT, +#endif // USE_LIGHT_VIRTUAL_CT #ifdef USE_LIGHT_PALETTE &CmndPalette, #endif // USE_LIGHT_PALETTE @@ -181,6 +189,12 @@ const uint16_t CT_MAX = 500; // 2000K // Ranges used for Alexa const uint16_t CT_MIN_ALEXA = 200; // also 5000K const uint16_t CT_MAX_ALEXA = 380; // also 2600K +// Virtual CT default values +typedef uint8_t vct_pivot_t[LST_MAX]; +const size_t CT_PIVOTS = LIGHT_VIRTUAL_CT_POINTS; +const vct_pivot_t CT_PIVOTS_RGB PROGMEM = { 255, 255, 255, 0, 0 }; +const vct_pivot_t CT_PIVOTS_CWW PROGMEM = { 0, 0, 0, 255, 0 }; +const vct_pivot_t CT_PIVOTS_WWW PROGMEM = { 0, 0, 0, 0, 255 }; // New version of Gamma correction compute // Instead of a table, we do a multi-linear approximation, which is close enough @@ -308,6 +322,12 @@ struct LIGHT { uint16_t pwm_min = 0; // minimum value for PWM, from DimmerRange, 0..1023 uint16_t pwm_max = 1023; // maxumum value for PWM, from DimmerRange, 0..1023 + + // Virtual CT + uint16_t vct_ct[CT_PIVOTS]; // CT value for each segment +#ifdef USE_LIGHT_VIRTUAL_CT + vct_pivot_t vct_color[CT_PIVOTS]; // array of 3 colors each with 5 values +#endif } Light; power_t LightPower(void) @@ -378,13 +398,6 @@ class LightStateClass { uint8_t _briCT = 255; uint8_t _color_mode = LCM_RGB; // RGB by default - // the CT range below represents the rendered range, - // This is due to Alexa whose CT range is 199..383 - // Hence setting Min=200 and Max=380 makes Alexa use the full range - // Please note that you can still set CT to 153..500, but any - // value below _ct_min_range or above _ct_max_range not change the CT - uint16_t _ct_min_range = CT_MIN; // the minimum CT rendered range - uint16_t _ct_max_range = CT_MAX; // the maximum CT rendered range public: LightStateClass() { @@ -535,22 +548,7 @@ class LightStateClass { inline uint16_t getCT() const { return _ct; // 153..500, or CT_MIN..CT_MAX - } - - // get the CT value within the range into a 10 bits 0..1023 value - uint16_t getCT10bits() const { - return changeUIntScale(_ct, _ct_min_range, _ct_max_range, 0, 1023); - } - - inline void setCTRange(uint16_t ct_min_range, uint16_t ct_max_range) { - _ct_min_range = ct_min_range; - _ct_max_range = ct_max_range; - } - - inline void getCTRange(uint16_t *ct_min_range, uint16_t *ct_max_range) const { - if (ct_min_range) { *ct_min_range = _ct_min_range; } - if (ct_max_range) { *ct_max_range = _ct_max_range; } - } + } // get current color in XY format void getXY(float *x, float *y) { @@ -603,7 +601,7 @@ class LightStateClass { setColorMode(LCM_RGB); // try deactivating CT mode, setColorMode() will check which is legal } else { ct = (ct < CT_MIN ? CT_MIN : (ct > CT_MAX ? CT_MAX : ct)); - _ww = changeUIntScale(ct, _ct_min_range, _ct_max_range, 0, 255); + _ww = changeUIntScale(ct, Light.vct_ct[0], Light.vct_ct[CT_PIVOTS-1], 0, 255); _wc = 255 - _ww; _ct = ct; addCTMode(); @@ -932,15 +930,6 @@ public: return prev; } - void setAlexaCTRange(bool alexa_ct_range) { - // depending on SetOption82, full or limited CT range - if (alexa_ct_range) { - _state->setCTRange(CT_MIN_ALEXA, CT_MAX_ALEXA); // 200..380 - } else { - _state->setCTRange(CT_MIN, CT_MAX); // 153..500 - } - } - inline bool isCTRGBLinked() { return _ct_rgb_linked; } @@ -1190,6 +1179,63 @@ uint8_t change10to8(uint16_t v) { return (0 == v) ? 0 : changeUIntScale(v, 4, 1023, 1, 255); } +/*********************************************************************************************\ + * CT (White Color Temperature) +\*********************************************************************************************/ +// +// Ensure that invariants for Virtual CT are good: +// - CT_MIN <= ct[0] <= ct[1] <= ct[2] <= CT_MAX + +#ifdef USE_LIGHT_VIRTUAL_CT +void checkVirtualCT(void) { + if (Light.vct_ct[0] < CT_MIN) { Light.vct_ct[0] = CT_MIN; } + if (Light.vct_ct[CT_PIVOTS-1] > CT_MAX) { Light.vct_ct[CT_PIVOTS-1] = CT_MAX; } + for (uint32_t i = 0; i < CT_PIVOTS-1; i++) { + if (Light.vct_ct[i+1] < Light.vct_ct[i]) { Light.vct_ct[i+1] = Light.vct_ct[i]; } + } +} +#endif // USE_LIGHT_VIRTUAL_CT + +#ifdef USE_LIGHT_VIRTUAL_CT +// Init default values for virtual CT, depending on the number of channels +void initCTRange(uint32_t channels) { + if (channels == 4) { + if (Settings.flag4.virtual_ct_cw) { // Hardware White is Cold White + memcpy_P(Light.vct_color[0], CT_PIVOTS_CWW, sizeof(Light.vct_color[0])); // Cold white + memcpy_P(Light.vct_color[1], CT_PIVOTS_RGB, sizeof(Light.vct_color[1])); // Warm white + } else { // Hardware White is Warm White + memcpy_P(Light.vct_color[0], CT_PIVOTS_RGB, sizeof(Light.vct_color[0])); // Cold white + memcpy_P(Light.vct_color[1], CT_PIVOTS_CWW, sizeof(Light.vct_color[1])); // Warm white + } + } else if (channels == 5) { + memcpy_P(Light.vct_color[0], CT_PIVOTS_CWW, sizeof(Light.vct_color[0])); // Cold white + memcpy_P(Light.vct_color[1], CT_PIVOTS_WWW, sizeof(Light.vct_color[1])); // Warm white + } else { + memcpy_P(Light.vct_color[0], CT_PIVOTS_RGB, sizeof(Light.vct_color[0])); // Cold white + memcpy_P(Light.vct_color[1], CT_PIVOTS_RGB, sizeof(Light.vct_color[1])); // Warm white + } + for (uint32_t i = 1; i < CT_PIVOTS-1; i++) { + memcpy_P(Light.vct_color[i+1], Light.vct_color[i], sizeof(Light.vct_color[0])); // Copy slot 1 into slot 2 (slot 2 in unused) + } + checkVirtualCT(); +} +#endif // USE_LIGHT_VIRTUAL_CT + +void setCTRange(uint16_t ct_min, uint16_t ct_max) { + Light.vct_ct[0] = ct_min; + for (uint32_t i = 1; i < CT_PIVOTS; i++) { + Light.vct_ct[i] = ct_max; // all slots above [1] are not used + } +} + +void setAlexaCTRange(void) { // depending on SetOption82, full or limited CT range + if (Settings.flag4.alexa_ct_range) { + setCTRange(CT_MIN_ALEXA, CT_MAX_ALEXA); + } else { + setCTRange(CT_MIN, CT_MAX); + } +} + /*********************************************************************************************\ * Gamma correction \*********************************************************************************************/ @@ -1299,9 +1345,14 @@ bool LightModuleInit(void) } else if ((Settings.param[P_RGB_REMAP] & 128) && (LST_RGBW <= pwm_channels)) { // SetOption37 // if RGBW or RGBCW, and SetOption37 >= 128, we manage RGB and W separately, hence adding a device TasmotaGlobal.devices_present++; - } else if ((Settings.flag4.virtual_ct) && (LST_RGBW == pwm_channels)) { - Light.virtual_ct = true; // enabled - TasmotaGlobal.light_type++; // create an additional virtual 5th channel + } else { +#ifdef USE_LIGHT_VIRTUAL_CT + initCTRange(pwm_channels); + if ((Settings.flag4.virtual_ct) && (LST_RGB <= pwm_channels)) { + Light.virtual_ct = true; // enabled + TasmotaGlobal.light_type += 5 - pwm_channels; // pretend it is a 5 channels bulb + } +#endif // USE_LIGHT_VIRTUAL_CT } return (TasmotaGlobal.light_type > LT_BASIC); @@ -1367,7 +1418,7 @@ void LightInit(void) light_controller.setSubType(Light.subtype); light_controller.loadSettings(); - light_controller.setAlexaCTRange(Settings.flag4.alexa_ct_range); + setAlexaCTRange(); light_controller.calcLevels(); // calculate the initial values (#8058) if (LST_SINGLE == Light.subtype) { @@ -1859,7 +1910,6 @@ void LightAnimate(void) bool power_off = false; // make sure we update CT range in case SetOption82 was changed - light_controller.setAlexaCTRange(Settings.flag4.alexa_ct_range); Light.strip_timer_counter++; // set sleep parameter: either settings, @@ -1966,7 +2016,6 @@ void LightAnimate(void) uint16_t cur_col_10[LST_MAX]; // 10 bits resolution Light.update = false; - bool rgbwwtable_applied = false; // did we already applied RGBWWTable (ex: in white_blend_mode or virtual_ct) // first set 8 and 10 bits channels for (uint32_t i = 0; i < LST_MAX; i++) { @@ -1975,58 +2024,19 @@ void LightAnimate(void) cur_col_10[i] = change8to10(Light.new_color[i]); } + bool rgbwwtable_applied_white = false; // did we already applied RGBWWTable to white channels (ex: in white_blend_mode or virtual_ct) if (Light.pwm_multi_channels) { calcGammaMultiChannels(cur_col_10); } else { - calcGammaBulbs(cur_col_10); - - // Now see if we need to mix RGB and True White - // Valid only for LST_RGBW, LST_RGBCW, rgbwwTable[4] is zero, and white is zero (see doc) - if ((LST_RGBW <= Light.subtype) && (Settings.flag4.white_blend_mode) && (0 == cur_col_10[3]+cur_col_10[4])) { - uint32_t min_rgb_10 = min3(cur_col_10[0], cur_col_10[1], cur_col_10[2]); - for (uint32_t i=0; i<3; i++) { - // substract white and adjust according to rgbwwTable - uint32_t adjust10 = change8to10(Settings.rgbwwTable[i]); - cur_col_10[i] = changeUIntScale(cur_col_10[i] - min_rgb_10, 0, 1023, 0, adjust10); - } - - // compute the adjusted white levels for 10 and 8 bits - uint32_t adjust_w_10 = changeUIntScale(Settings.rgbwwTable[3], 0, 255, 0, 1023); - uint32_t white_10 = changeUIntScale(min_rgb_10, 0, 1023, 0, adjust_w_10); // set white power down corrected with rgbwwTable[3] - if (LST_RGBW == Light.subtype) { - // we simply set the white channel - cur_col_10[3] = white_10; - } else { // LST_RGBCW - // we distribute white between cold and warm according to CT value - uint32_t ct = light_state.getCT10bits(); - cur_col_10[4] = changeUIntScale(ct, 0, 1023, 0, white_10); - cur_col_10[3] = white_10 - cur_col_10[4]; - } - rgbwwtable_applied = true; - } else if ((Light.virtual_ct) && (0 == cur_col_10[0]+cur_col_10[1]+cur_col_10[2])) { - // virtual_ct is on and we don't have any RGB set - uint16_t sw_white = Settings.flag4.virtual_ct_cw ? cur_col_10[4] : cur_col_10[3]; // white power for virtual RGB - uint16_t hw_white = Settings.flag4.virtual_ct_cw ? cur_col_10[3] : cur_col_10[4]; // white for hardware LED - uint32_t adjust_sw = change8to10(Settings.flag4.virtual_ct_cw ? Settings.rgbwwTable[4] : Settings.rgbwwTable[3]); - uint32_t adjust_hw = change8to10(Settings.flag4.virtual_ct_cw ? Settings.rgbwwTable[3] : Settings.rgbwwTable[4]); - // set the target channels. Note: Gamma correction was arleady applied - cur_col_10[3] = changeUIntScale(hw_white, 0, 1023, 0, adjust_hw); - cur_col_10[4] = 0; // we don't actually have a 5the channel - sw_white = changeUIntScale(sw_white, 0, 1023, 0, adjust_sw); // pre-adjust virtual channel - for (uint32_t i=0; i<3; i++) { - uint32_t adjust = change8to10(Settings.rgbwwTable[i]); - cur_col_10[i] = changeUIntScale(sw_white, 0, 1023, 0, adjust); - } - rgbwwtable_applied = true; - } + // AddLog_P(LOG_LEVEL_INFO, PSTR(">>> calcGammaBulbs In %03X,%03X,%03X,%03X,%03X"), cur_col_10[0], cur_col_10[1], cur_col_10[2], cur_col_10[3], cur_col_10[4]); + rgbwwtable_applied_white = calcGammaBulbs(cur_col_10); // true means that one PWM channel is used for CT + // AddLog_P(LOG_LEVEL_INFO, PSTR(">>> calcGammaBulbs Out %03X,%03X,%03X,%03X,%03X"), cur_col_10[0], cur_col_10[1], cur_col_10[2], cur_col_10[3], cur_col_10[4]); } // Apply RGBWWTable only if not Settings.flag4.white_blend_mode - if (!rgbwwtable_applied) { - for (uint32_t i = 0; i 1023) ? 1023 : white_bri10; // max 1023 - -#ifdef ESP8266 - if ((PHILIPS == TasmotaGlobal.module_type) || (Settings.flag4.pwm_ct_mode)) { // 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(); - // channel 0=intensity, channel1=temperature - if (Settings.light_correction) { // gamma correction - cur_col_10[cw0] = ledGamma10_10(white_bri10_1023); // 10 bits gamma correction - } else { - cur_col_10[cw0] = white_bri10_1023; // no gamma, extend to 10 bits - } - } 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 - uint16_t white_bri_gamma10 = ledGamma10_10(white_bri10_1023); - // then we split the total energy among the cold and warm leds - cur_col_10[cw0] = changeUIntScale(cur_col_10[cw0], 0, white_bri10_1023, 0, white_bri_gamma10); - cur_col_10[cw1] = changeUIntScale(cur_col_10[cw1], 0, white_bri10_1023, 0, white_bri_gamma10); - } else { - cur_col_10[cw0] = ledGamma10_10(cur_col_10[cw0]); - cur_col_10[cw1] = ledGamma10_10(cur_col_10[cw1]); - } - } - } +// +// Compute the Gamma correction for CW/WW +// Can be used for 2-channels (channels 0,1) or 5 channels (channels 3,4) +// +// It is implicitly called by calcGammaBulb5Channels() +// +// In: +// - 2 channels CW/WW in 10 bits format (0..1023) +// Out: +// - 2 channels CW/WW in 10 bits format, with Gamma corretion (if enabled), replaced in place +// - white_bri10: global brightness of white channel, split over CW/WW (basically the sum of CW+WW, but it's easier to compute on this basis) +// - white_free_cw: signals that CW/WW are free mode, and not linked via CT. This is used when channels are manually set on a channel per channel basis. CT is ignored +// +void calcGammaBulbCW(uint16_t cw10[2], uint16_t *white_bri10_out, bool *white_free_cw_out) { + uint16_t white_bri10 = cw10[0] + cw10[1]; // cumulated brightness + bool white_free_cw = (white_bri10 > 1031); // take a margin of 8 above 1023 to account for rounding errors + white_bri10 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023 if (Settings.light_correction) { - // then apply gamma correction to RGB channels - if (LST_RGB <= Light.subtype) { - for (uint32_t i = 0; i < 3; i++) { - cur_col_10[i] = ledGamma10_10(cur_col_10[i]); - } - } - // If RGBW or Single channel, also adjust White channel - if ((LST_SINGLE == Light.subtype) || (LST_RGBW == Light.subtype)) { - cur_col_10[Light.subtype - 1] = ledGamma10_10(cur_col_10[Light.subtype - 1]); + if (white_free_cw) { + cw10[0] = ledGamma10_10(cw10[0]); + cw10[1] = ledGamma10_10(cw10[1]); + } else { + uint16_t white_bri10_gamma = ledGamma10_10(white_bri10); // gamma corrected white + // now distributed among both channels + cw10[0] = changeUIntScale(cw10[0], 0, white_bri10, 0, white_bri10_gamma); + cw10[1] = changeUIntScale(cw10[1], 0, white_bri10, 0, white_bri10_gamma); + // now use white_bri10_gamma as a reference + white_bri10 = white_bri10_gamma; } } + if (white_bri10_out != nullptr) { *white_bri10_out = white_bri10; } + if (white_free_cw_out != nullptr) { *white_free_cw_out = white_free_cw; } +} + +// +// Calculate the gamma correction for all 5 channels RGBCW +// Computation is valid for 1,3,4,5 channels +// 2-channels bulbs must be handled separately +// +// In: +// - 5 channels RGBCW in 10 bits format (0..1023) +// Out: +// - 5 channels RGBCW in 10 bits format, with Gamma corretion (if enabled), replaced in place +// - white_bri10: global brightness of white channel, split over CW/WW (basically the sum of CW+WW, but it's easier to compute on this basis) +// - white_free_cw: signals that CW/WW are free mode, and not linked via CT. This is used when channels are manually set on a channel per channel basis. CT is ignored +// +void calcGammaBulb5Channels(uint16_t col10[LST_MAX], uint16_t *white_bri10_out, bool *white_free_cw) { + for (uint32_t i = 0; i < 3; i++) { + if (Settings.light_correction) { + col10[i] = ledGamma10_10(col10[i]); + } + } + calcGammaBulbCW(&col10[3], white_bri10_out, white_free_cw); +} + +// sale but converts from 8 bits to 10 bits first +void calcGammaBulb5Channels_8(uint8_t in8[LST_MAX], uint16_t col10[LST_MAX]) { + for (uint32_t i = 0; i < LST_MAX; i++) { + col10[i] = change8to10(in8[i]); + } + calcGammaBulb5Channels(col10, nullptr, nullptr); +} + +bool calcGammaBulbs(uint16_t cur_col_10[5]) { + bool rgbwwtable_applied_white = false; + bool pwm_ct = false; + bool white_free_cw = false; // true if White channels are uncorrelated. Happens when CW+WW>255, i.e. manually setting white channels to exceed to total power of a single channel (may harm the power supply) + // Various values needed for accurate White calculation + // CT value streteched to 0..1023 (from within CT range, so not necessarily from 153 to 500). 0=Cold, 1023=Warm + uint16_t ct = light_state.getCT(); + uint16_t ct_10 = changeUIntScale(ct, Light.vct_ct[0], Light.vct_ct[CT_PIVOTS-1], 0, 1023); + + uint16_t white_bri10 = 0; // White total brightness normalized to 0..1023 + // uint32_t cw1 = Light.subtype - 1; // address for the ColorTone PWM + uint32_t cw0 = Light.subtype - 2; // address for the White Brightness PWM + + // calc basic gamma correction for all types + if ((LST_SINGLE == Light.subtype) || (LST_RGB <= Light.subtype)) { + calcGammaBulb5Channels(cur_col_10, &white_bri10, &white_free_cw); + } else if (LST_COLDWARM == Light.subtype) { + calcGammaBulbCW(cur_col_10, &white_bri10, &white_free_cw); + } + + // Now we know ct_10 and white_bri10 (gamma corrected if needed) + +#ifdef ESP8266 + if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) { + if ((PHILIPS == TasmotaGlobal.module_type) || (Settings.flag4.pwm_ct_mode)) { // channel 1 is the color tone, mapped to cold channel (0..255) + pwm_ct = true; + // Xiaomi Philips bulbs follow a different scheme: + // channel 0=intensity, channel1=temperature + cur_col_10[cw0] = white_bri10; + cur_col_10[cw0+1] = ct_10; + return false; // avoid any interference + } + } +#endif // ESP8266 + + // Now see if we need to mix RGB and White + // Valid only for LST_RGBW, LST_RGBCW, SetOption105 1, and white is zero (see doc) + if ((LST_RGBW <= Light.subtype) && (Settings.flag4.white_blend_mode) && (0 == cur_col_10[3]+cur_col_10[4])) { + uint32_t min_rgb_10 = min3(cur_col_10[0], cur_col_10[1], cur_col_10[2]); + cur_col_10[0] -= min_rgb_10; + cur_col_10[1] -= min_rgb_10; + cur_col_10[2] -= min_rgb_10; + + // Add to white level + uint32_t adjust_w_10 = change8to10(Settings.rgbwwTable[3]); // take the correction factor, bought back to 10 bits + white_bri10 += changeUIntScale(min_rgb_10, 0, 1023, 0, adjust_w_10); // set white power down corrected with rgbwwTable[3] + white_bri10 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023 + rgbwwtable_applied_white = true; + } + +#ifdef USE_LIGHT_VIRTUAL_CT + // compute virtual CT, which is suppsed to be compatible with white_blend_mode + if (Light.virtual_ct && (!white_free_cw) && (LST_RGBW <= Light.subtype)) { // any light with a white channel + vct_pivot_t *pivot = &Light.vct_color[0]; + uint16_t *from_ct = &Light.vct_ct[0]; + + for (uint32_t i = 1; i < CT_PIVOTS-1; i++) { + if (ct > Light.vct_ct[i]) { // if above mid-point, take range [1]..[2] instead of [0]..[1] + pivot++; + from_ct++; + } + } + uint16_t from10[LST_MAX]; + uint16_t to10[LST_MAX]; + calcGammaBulb5Channels_8(*pivot, from10); + calcGammaBulb5Channels_8(*(pivot+1), to10); + + vct_pivot_t *pivot1 = pivot + 1; + // AddLog_P(LOG_LEVEL_INFO, PSTR("+++ from_ct %d, to_ct %d [%03X,%03X,%03X,%03X,%03X] - [%03X,%03X,%03X,%03X,%03X]"), + // *from_ct, *(from_ct+1), (*pivot)[0], (*pivot)[1], (*pivot)[2], (*pivot)[3], (*pivot)[4], + // (*pivot1)[0], (*pivot1)[1], (*pivot1)[2], (*pivot1)[3], (*pivot1)[4]); + // AddLog_P(LOG_LEVEL_INFO, PSTR("+++ from10 [%03X,%03X,%03X,%03X,%03X] - to 10 [%03X,%03X,%03X,%03X,%03X]"), + // from10[0],from10[0],from10[0],from10[0],from10[4], + // to10[0],to10[0],to10[0],to10[0],to10[4]); + + // set both CW/WW to zero since their previous value don't count anymore + cur_col_10[3] = 0; + cur_col_10[4] = 0; + + // Add the interpolated point to each component + for (uint32_t i = 0; i < LST_MAX; i++) { + cur_col_10[i] += changeUIntScale(changeUIntScale(ct, *from_ct, *(from_ct+1), from10[i], to10[i]), 0, 1023, 0, white_bri10); + if (cur_col_10[i] > 1023) { cur_col_10[i] = 1023; } + } + } else +#endif // USE_LIGHT_VIRTUAL_CT + // compute the actual levels for CW/WW + // We know ct_10 and white_bri_10 (which may be Gamma corrected) + // cur_col_10[cw0] and cur_col_10[cw1] were unmodified up to now + if (LST_RGBW == Light.subtype) { + cur_col_10[3] = white_bri10; // simple case, we set the White level to the required brightness + } else if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) { + // if sum of both channels is > 255, then channels are probably uncorrelated + if (!white_free_cw) { + // then we split the total energy among the cold and warm leds + cur_col_10[cw0+1] = changeUIntScale(ct_10, 0, 1023, 0, white_bri10); + cur_col_10[cw0] = white_bri10 - cur_col_10[cw0+1]; + } + } + return rgbwwtable_applied_white; } #ifdef USE_DEVICE_GROUPS @@ -3045,6 +3169,83 @@ void CmndWakeupDuration(void) ResponseCmndNumber(Settings.light_wakeup); } +void CmndCTRange(void) +{ + // Format is "CTRange ctmin,ctmax" + // Ex: + // CTRange 153,500 + // CTRange + // CTRange 200,350 + char *p; + strtok_r(XdrvMailbox.data, ",", &p); + if (p != nullptr) { + int32_t ct_min = strtol(XdrvMailbox.data, nullptr, 0); + int32_t ct_max = strtol(p, nullptr, 0); + if ( (ct_min >= CT_MIN) && (ct_min <= CT_MAX) && + (ct_max >= CT_MIN) && (ct_max <= CT_MAX) && + (ct_min <= ct_max) + ) { + setCTRange(ct_min, ct_max); + } else { + return; // error + } + } + Response_P(PSTR("{\"%s\":\"%d,%d\"}"), XdrvMailbox.command, Light.vct_ct[0], Light.vct_ct[CT_PIVOTS-1]); +} + +#ifdef USE_LIGHT_VIRTUAL_CT +void CmndVirtualCT(void) +{ + if (!Settings.flag4.virtual_ct) { + ResponseCmndChar_P(PSTR("You need to enable `SetOption106 1`")); + return; + } + if (XdrvMailbox.data[0] == ('{')) { + // parse JSON + JsonParser parser(XdrvMailbox.data); + JsonParserObject root = parser.getRootObject(); + if (!root) { return; } + + uint32_t idx = 0; + for (auto key : root) { + if (idx >= CT_PIVOTS) { ResponseCmndChar_P(PSTR("Too many points")); return; } + + int32_t ct_val = strtol(key.getStr(), nullptr, 0); + if ((ct_val < CT_MIN) || (ct_val > CT_MAX)) { ResponseCmndChar_P(PSTR("CT out of range")); return; } + char * color = (char*) key.getValue().getStr(); + // call color parser + Light.vct_ct[idx] = ct_val; + if (LightColorEntry(color, strlen(color))) { + memcpy(&Light.vct_color[idx], Light.entry_color, sizeof(Light.vct_color[idx])); + } + idx++; + } + for (uint32_t i = idx-1; i < CT_PIVOTS-1; i++) { + Light.vct_ct[i+1] = Light.vct_ct[i]; + memcpy(&Light.vct_color[i+1], &Light.vct_color[i], sizeof(Light.vct_color[0])); + } + } + checkVirtualCT(); + + Response_P(PSTR("{\"%s\":{"), XdrvMailbox.command); + uint32_t pivot_len = CT_PIVOTS; + vct_pivot_t * pivot = &Light.vct_color[0]; + if (Light.vct_ct[1] >= Light.vct_ct[2]) { pivot_len = 2; } // only 2 points are valid + + bool end = false; + for (uint32_t i = 0; (i < CT_PIVOTS) && !end; i++) { + if ((i >= CT_PIVOTS-1) || (Light.vct_ct[i] >= Light.vct_ct[i+1])) { + end = true; + } + ResponseAppend_P(PSTR("\"%d\":\"%02X%02X%02X%02X%02X\"%c"), Light.vct_ct[i], + (*pivot)[0], (*pivot)[1], (*pivot)[2], (*pivot)[3], (*pivot)[4], + end ? '}' : ','); + pivot++; + } + ResponseJsonEnd(); +} +#endif // USE_LIGHT_VIRTUAL_CT + #ifdef USE_LIGHT_PALETTE void CmndPalette(void) { From 2afc18bac2da5621d57d631807529b55d14725dc Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 29 Dec 2020 19:58:38 +0100 Subject: [PATCH 051/105] Fix compilation for TuyaMCU --- tasmota/xdrv_04_light.ino | 5 +++++ tasmota/xdrv_16_tuyamcu.ino | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index a47c4a4ca..f0b94bcec 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1221,6 +1221,11 @@ void initCTRange(uint32_t channels) { } #endif // USE_LIGHT_VIRTUAL_CT +void getCTRange(uint16_t * min_ct, uint16_t * max_ct) { + if (min_ct != nullptr) { *min_ct = Light.vct_ct[0]; } + if (max_ct != nullptr) { *max_ct = Light.vct_ct[CT_PIVOTS-1]; } +} + void setCTRange(uint16_t ct_min, uint16_t ct_max) { Light.vct_ct[0] = ct_min; for (uint32_t i = 1; i < CT_PIVOTS; i++) { diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 13a7864c5..51a0a9c5b 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -517,7 +517,7 @@ bool TuyaSetChannels(void) Tuya.Snapshot[0] = changeUIntScale(Light.current_color[0], 0, 255, 0, 100); Tuya.Snapshot[1] = changeUIntScale(Light.current_color[1], 0, 255, 0, 100); } else { // CT Light or RGBWC - light_state.getCTRange(&Tuya.CTMin, &Tuya.CTMax); // SetOption82 - Reduce the CT range from 153..500 to 200..380 to accomodate with Alexa range + getCTRange(&Tuya.CTMin, &Tuya.CTMax); // SetOption82 - Reduce the CT range from 153..500 to 200..380 to accomodate with Alexa range Tuya.Snapshot[0] = light_state.getDimmer(); Tuya.Snapshot[1] = light_state.getCT(); } From e866db7364c1322d83e97b3adac73722b3bc1a0b Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Tue, 29 Dec 2020 22:39:06 +0100 Subject: [PATCH 052/105] feature: SSD1331 SPI display driver Based on release 1.2.0: https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/releases/tag/1.2.0 Inspired by the xdsp_09_SSD1351 driver. --- .../Adafruit_SPITFT_Renderer.cpp | 2217 +++++++++++++++++ .../Adafruit_SPITFT_Renderer.h | 520 ++++ .../Adafruit_SSD1331.cpp | 190 ++ .../Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h | 76 + .../Adafruit_SSD1331-1.2.0/README.md | 24 + .../Adafruit_SSD1331-1.2.0/library.properties | 10 + .../Adafruit_SSD1331-1.2.0/license.txt | 26 + tasmota/xdsp_14_SSD1331.ino | 182 ++ 8 files changed, 3245 insertions(+) create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/README.md create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties create mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt create mode 100644 tasmota/xdsp_14_SSD1331.ino diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp new file mode 100644 index 000000000..d49141a28 --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp @@ -0,0 +1,2217 @@ +/*! + * @file Adafruit_SPITFT.cpp + * + * @mainpage Adafruit SPI TFT Displays (and some others) + * + * @section intro_sec Introduction + * + * Part of Adafruit's GFX graphics library. Originally this class was + * written to handle a range of color TFT displays connected via SPI, + * but over time this library and some display-specific subclasses have + * mutated to include some color OLEDs as well as parallel-interfaced + * displays. The name's been kept for the sake of older code. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + + * @section dependencies Dependencies + * + * This library depends on + * Adafruit_GFX being present on your system. Please make sure you have + * installed the latest version before using this library. + * + * @section author Author + * + * Written by Limor "ladyada" Fried for Adafruit Industries, + * with contributions from the open source community. + * + * @section license License + * + * BSD license, all text here must be included in any redistribution. + */ + +#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all + +#include "Adafruit_SPITFT_Renderer.h" + +#if defined(__AVR__) +#if defined(__AVR_XMEGA__) //only tested with __AVR_ATmega4809__ +#define AVR_WRITESPI(x) for(SPI0_DATA = (x); (!(SPI0_INTFLAGS & _BV(SPI_IF_bp))); ) +#else +#define AVR_WRITESPI(x) for(SPDR = (x); (!(SPSR & _BV(SPIF))); ) +#endif +#endif + +#if defined(PORT_IOBUS) +// On SAMD21, redefine digitalPinToPort() to use the slightly-faster +// PORT_IOBUS rather than PORT (not needed on SAMD51). +#undef digitalPinToPort +#define digitalPinToPort(P) (&(PORT_IOBUS->Group[g_APinDescription[P].ulPort])) +#endif // end PORT_IOBUS + +#if defined(USE_SPI_DMA) + #include + #include "wiring_private.h" // pinPeripheral() function + #include // memalign() function + #define tcNum 2 // Timer/Counter for parallel write strobe PWM + #define wrPeripheral PIO_CCL // Use CCL to invert write strobe + + // DMA transfer-in-progress indicator and callback + static volatile bool dma_busy = false; + static void dma_callback(Adafruit_ZeroDMA *dma) { + dma_busy = false; + } + + #if defined(__SAMD51__) + // Timer/counter info by index # + static const struct { + Tc *tc; // -> Timer/Counter base address + int gclk; // GCLK ID + int evu; // EVSYS user ID + } tcList[] = { + { TC0, TC0_GCLK_ID, EVSYS_ID_USER_TC0_EVU }, + { TC1, TC1_GCLK_ID, EVSYS_ID_USER_TC1_EVU }, + { TC2, TC2_GCLK_ID, EVSYS_ID_USER_TC2_EVU }, + { TC3, TC3_GCLK_ID, EVSYS_ID_USER_TC3_EVU }, + #if defined(TC4) + { TC4, TC4_GCLK_ID, EVSYS_ID_USER_TC4_EVU }, + #endif + #if defined(TC5) + { TC5, TC5_GCLK_ID, EVSYS_ID_USER_TC5_EVU }, + #endif + #if defined(TC6) + { TC6, TC6_GCLK_ID, EVSYS_ID_USER_TC6_EVU }, + #endif + #if defined(TC7) + { TC7, TC7_GCLK_ID, EVSYS_ID_USER_TC7_EVU } + #endif + }; + #define NUM_TIMERS (sizeof tcList / sizeof tcList[0]) ///< # timer/counters + #endif // end __SAMD51__ + +#endif // end USE_SPI_DMA + +// Possible values for Adafruit_SPITFT.connection: +#define TFT_HARD_SPI 0 ///< Display interface = hardware SPI +#define TFT_SOFT_SPI 1 ///< Display interface = software SPI +#define TFT_PARALLEL 2 ///< Display interface = 8- or 16-bit parallel + + +// CONSTRUCTORS ------------------------------------------------------------ + +/*! + @brief Adafruit_SPITFT constructor for software (bitbang) SPI. + @param w Display width in pixels at default rotation setting (0). + @param h Display height in pixels at default rotation setting (0). + @param cs Arduino pin # for chip-select (-1 if unused, tie CS low). + @param dc Arduino pin # for data/command select (required). + @param mosi Arduino pin # for bitbang SPI MOSI signal (required). + @param sck Arduino pin # for bitbang SPI SCK signal (required). + @param rst Arduino pin # for display reset (optional, display reset + can be tied to MCU reset, default of -1 means unused). + @param miso Arduino pin # for bitbang SPI MISO signal (optional, + -1 default, many displays don't support SPI read). + @return Adafruit_SPITFT object. + @note Output pins are not initialized; application typically will + need to call subclass' begin() function, which in turn calls + this library's initSPI() function to initialize pins. +*/ +Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, + int8_t cs, int8_t dc, int8_t mosi, int8_t sck, int8_t rst, int8_t miso) : + Renderer(w, h), connection(TFT_SOFT_SPI), _rst(rst), _cs(cs), _dc(dc) { + swspi._sck = sck; + swspi._mosi = mosi; + swspi._miso = miso; +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(CORE_TEENSY) + #if !defined(KINETISK) + dcPinMask = digitalPinToBitMask(dc); + swspi.sckPinMask = digitalPinToBitMask(sck); + swspi.mosiPinMask = digitalPinToBitMask(mosi); + #endif + dcPortSet = portSetRegister(dc); + dcPortClr = portClearRegister(dc); + swspi.sckPortSet = portSetRegister(sck); + swspi.sckPortClr = portClearRegister(sck); + swspi.mosiPortSet = portSetRegister(mosi); + swspi.mosiPortClr = portClearRegister(mosi); + if(cs >= 0) { + #if !defined(KINETISK) + csPinMask = digitalPinToBitMask(cs); + #endif + csPortSet = portSetRegister(cs); + csPortClr = portClearRegister(cs); + } else { + #if !defined(KINETISK) + csPinMask = 0; + #endif + csPortSet = dcPortSet; + csPortClr = dcPortClr; + } + if(miso >= 0) { + swspi.misoPort = portInputRegister(miso); + #if !defined(KINETISK) + swspi.misoPinMask = digitalPinToBitMask(miso); + #endif + } else { + swspi.misoPort = portInputRegister(dc); + } + #else // !CORE_TEENSY + dcPinMask =digitalPinToBitMask(dc); + swspi.sckPinMask =digitalPinToBitMask(sck); + swspi.mosiPinMask=digitalPinToBitMask(mosi); + dcPortSet =&(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg); + dcPortClr =&(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg); + swspi.sckPortSet =&(PORT->Group[g_APinDescription[sck].ulPort].OUTSET.reg); + swspi.sckPortClr =&(PORT->Group[g_APinDescription[sck].ulPort].OUTCLR.reg); + swspi.mosiPortSet=&(PORT->Group[g_APinDescription[mosi].ulPort].OUTSET.reg); + swspi.mosiPortClr=&(PORT->Group[g_APinDescription[mosi].ulPort].OUTCLR.reg); + if(cs >= 0) { + csPinMask = digitalPinToBitMask(cs); + csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg); + csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg); + } else { + // No chip-select line defined; might be permanently tied to GND. + // Assign a valid GPIO register (though not used for CS), and an + // empty pin bitmask...the nonsense bit-twiddling might be faster + // than checking _cs and possibly branching. + csPortSet = dcPortSet; + csPortClr = dcPortClr; + csPinMask = 0; + } + if(miso >= 0) { + swspi.misoPinMask=digitalPinToBitMask(miso); + swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(miso)); + } else { + swspi.misoPinMask=0; + swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(dc)); + } + #endif // end !CORE_TEENSY + #else // !HAS_PORT_SET_CLR + dcPort =(PORTreg_t)portOutputRegister(digitalPinToPort(dc)); + dcPinMaskSet =digitalPinToBitMask(dc); + swspi.sckPort =(PORTreg_t)portOutputRegister(digitalPinToPort(sck)); + swspi.sckPinMaskSet =digitalPinToBitMask(sck); + swspi.mosiPort =(PORTreg_t)portOutputRegister(digitalPinToPort(mosi)); + swspi.mosiPinMaskSet=digitalPinToBitMask(mosi); + if(cs >= 0) { + csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs)); + csPinMaskSet = digitalPinToBitMask(cs); + } else { + // No chip-select line defined; might be permanently tied to GND. + // Assign a valid GPIO register (though not used for CS), and an + // empty pin bitmask...the nonsense bit-twiddling might be faster + // than checking _cs and possibly branching. + csPort = dcPort; + csPinMaskSet = 0; + } + if(miso >= 0) { + swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(miso)); + swspi.misoPinMask=digitalPinToBitMask(miso); + } else { + swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(dc)); + swspi.misoPinMask=0; + } + csPinMaskClr = ~csPinMaskSet; + dcPinMaskClr = ~dcPinMaskSet; + swspi.sckPinMaskClr = ~swspi.sckPinMaskSet; + swspi.mosiPinMaskClr = ~swspi.mosiPinMaskSet; + #endif // !end HAS_PORT_SET_CLR +#endif // end USE_FAST_PINIO +} + +/*! + @brief Adafruit_SPITFT constructor for hardware SPI using the board's + default SPI peripheral. + @param w Display width in pixels at default rotation setting (0). + @param h Display height in pixels at default rotation setting (0). + @param cs Arduino pin # for chip-select (-1 if unused, tie CS low). + @param dc Arduino pin # for data/command select (required). + @param rst Arduino pin # for display reset (optional, display reset + can be tied to MCU reset, default of -1 means unused). + @return Adafruit_SPITFT object. + @note Output pins are not initialized; application typically will + need to call subclass' begin() function, which in turn calls + this library's initSPI() function to initialize pins. +*/ +#if defined(ESP8266) // See notes below +Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, + int8_t dc, int8_t rst) : Renderer(w, h), + connection(TFT_HARD_SPI), _rst(rst), _cs(cs), _dc(dc) { + hwspi._spi = &SPI; +} +#else // !ESP8266 +Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, + int8_t dc, int8_t rst) : Adafruit_SPITFT(w, h, &SPI, cs, dc, rst) { + // This just invokes the hardware SPI constructor below, + // passing the default SPI device (&SPI). +} +#endif // end !ESP8266 + +#if !defined(ESP8266) +// ESP8266 compiler freaks out at this constructor -- it can't disambiguate +// beteween the SPIClass pointer (argument #3) and a regular integer. +// Solution here it to just not offer this variant on the ESP8266. You can +// use the default hardware SPI peripheral, or you can use software SPI, +// but if there's any library out there that creates a 'virtual' SPIClass +// peripheral and drives it with software bitbanging, that's not supported. +/*! + @brief Adafruit_SPITFT constructor for hardware SPI using a specific + SPI peripheral. + @param w Display width in pixels at default rotation (0). + @param h Display height in pixels at default rotation (0). + @param spiClass Pointer to SPIClass type (e.g. &SPI or &SPI1). + @param cs Arduino pin # for chip-select (-1 if unused, tie CS low). + @param dc Arduino pin # for data/command select (required). + @param rst Arduino pin # for display reset (optional, display reset + can be tied to MCU reset, default of -1 means unused). + @return Adafruit_SPITFT object. + @note Output pins are not initialized in constructor; application + typically will need to call subclass' begin() function, which + in turn calls this library's initSPI() function to initialize + pins. EXCEPT...if you have built your own SERCOM SPI peripheral + (calling the SPIClass constructor) rather than one of the + built-in SPI devices (e.g. &SPI, &SPI1 and so forth), you will + need to call the begin() function for your object as well as + pinPeripheral() for the MOSI, MISO and SCK pins to configure + GPIO manually. Do this BEFORE calling the display-specific + begin or init function. Unfortunate but unavoidable. +*/ +Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, + int8_t cs, int8_t dc, int8_t rst) : Renderer(w, h), + connection(TFT_HARD_SPI), _rst(rst), _cs(cs), _dc(dc) { + hwspi._spi = spiClass; +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(CORE_TEENSY) + #if !defined(KINETISK) + dcPinMask = digitalPinToBitMask(dc); + #endif + dcPortSet = portSetRegister(dc); + dcPortClr = portClearRegister(dc); + if(cs >= 0) { + #if !defined(KINETISK) + csPinMask = digitalPinToBitMask(cs); + #endif + csPortSet = portSetRegister(cs); + csPortClr = portClearRegister(cs); + } else { // see comments below + #if !defined(KINETISK) + csPinMask = 0; + #endif + csPortSet = dcPortSet; + csPortClr = dcPortClr; + } + #else // !CORE_TEENSY + dcPinMask = digitalPinToBitMask(dc); + dcPortSet = &(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg); + dcPortClr = &(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg); + if(cs >= 0) { + csPinMask = digitalPinToBitMask(cs); + csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg); + csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg); + } else { + // No chip-select line defined; might be permanently tied to GND. + // Assign a valid GPIO register (though not used for CS), and an + // empty pin bitmask...the nonsense bit-twiddling might be faster + // than checking _cs and possibly branching. + csPortSet = dcPortSet; + csPortClr = dcPortClr; + csPinMask = 0; + } + #endif // end !CORE_TEENSY + #else // !HAS_PORT_SET_CLR + dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(dc)); + dcPinMaskSet = digitalPinToBitMask(dc); + if(cs >= 0) { + csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs)); + csPinMaskSet = digitalPinToBitMask(cs); + } else { + // No chip-select line defined; might be permanently tied to GND. + // Assign a valid GPIO register (though not used for CS), and an + // empty pin bitmask...the nonsense bit-twiddling might be faster + // than checking _cs and possibly branching. + csPort = dcPort; + csPinMaskSet = 0; + } + csPinMaskClr = ~csPinMaskSet; + dcPinMaskClr = ~dcPinMaskSet; + #endif // end !HAS_PORT_SET_CLR +#endif // end USE_FAST_PINIO +} +#endif // end !ESP8266 + +/*! + @brief Adafruit_SPITFT constructor for parallel display connection. + @param w Display width in pixels at default rotation (0). + @param h Display height in pixels at default rotation (0). + @param busWidth If tft16 (enumeration in header file), is a 16-bit + parallel connection, else 8-bit. + 16-bit isn't fully implemented or tested yet so + applications should pass "tft8bitbus" for now...needed to + stick a required enum argument in there to + disambiguate this constructor from the soft-SPI case. + Argument is ignored on 8-bit architectures (no 'wide' + support there since PORTs are 8 bits anyway). + @param d0 Arduino pin # for data bit 0 (1+ are extrapolated). + The 8 (or 16) data bits MUST be contiguous and byte- + aligned (or word-aligned for wide interface) within + the same PORT register (might not correspond to + Arduino pin sequence). + @param wr Arduino pin # for write strobe (required). + @param dc Arduino pin # for data/command select (required). + @param cs Arduino pin # for chip-select (optional, -1 if unused, + tie CS low). + @param rst Arduino pin # for display reset (optional, display reset + can be tied to MCU reset, default of -1 means unused). + @param rd Arduino pin # for read strobe (optional, -1 if unused). + @return Adafruit_SPITFT object. + @note Output pins are not initialized; application typically will need + to call subclass' begin() function, which in turn calls this + library's initSPI() function to initialize pins. + Yes, the name is a misnomer...this library originally handled + only SPI displays, parallel being a recent addition (but not + wanting to break existing code). +*/ +Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth, + int8_t d0, int8_t wr, int8_t dc, int8_t cs, int8_t rst, int8_t rd) : + Renderer(w, h), connection(TFT_PARALLEL), _rst(rst), _cs(cs), _dc(dc) { + tft8._d0 = d0; + tft8._wr = wr; + tft8._rd = rd; + tft8.wide = (busWidth == tft16bitbus); +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(CORE_TEENSY) + tft8.wrPortSet = portSetRegister(wr); + tft8.wrPortClr = portClearRegister(wr); + #if !defined(KINETISK) + dcPinMask = digitalPinToBitMask(dc); + #endif + dcPortSet = portSetRegister(dc); + dcPortClr = portClearRegister(dc); + if(cs >= 0) { + #if !defined(KINETISK) + csPinMask = digitalPinToBitMask(cs); + #endif + csPortSet = portSetRegister(cs); + csPortClr = portClearRegister(cs); + } else { // see comments below + #if !defined(KINETISK) + csPinMask = 0; + #endif + csPortSet = dcPortSet; + csPortClr = dcPortClr; + } + if(rd >= 0) { // if read-strobe pin specified... + #if defined(KINETISK) + tft8.rdPinMask = 1; + #else // !KINETISK + tft8.rdPinMask = digitalPinToBitMask(rd); + #endif + tft8.rdPortSet = portSetRegister(rd); + tft8.rdPortClr = portClearRegister(rd); + } else { + tft8.rdPinMask = 0; + tft8.rdPortSet = dcPortSet; + tft8.rdPortClr = dcPortClr; + } + // These are all uint8_t* pointers -- elsewhere they're recast + // as necessary if a 'wide' 16-bit interface is in use. + tft8.writePort = portOutputRegister(d0); + tft8.readPort = portInputRegister(d0); + tft8.dirSet = portModeRegister(d0); + tft8.dirClr = portModeRegister(d0); + #else // !CORE_TEENSY + tft8.wrPinMask = digitalPinToBitMask(wr); + tft8.wrPortSet = &(PORT->Group[g_APinDescription[wr].ulPort].OUTSET.reg); + tft8.wrPortClr = &(PORT->Group[g_APinDescription[wr].ulPort].OUTCLR.reg); + dcPinMask = digitalPinToBitMask(dc); + dcPortSet = &(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg); + dcPortClr = &(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg); + if(cs >= 0) { + csPinMask = digitalPinToBitMask(cs); + csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg); + csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg); + } else { + // No chip-select line defined; might be permanently tied to GND. + // Assign a valid GPIO register (though not used for CS), and an + // empty pin bitmask...the nonsense bit-twiddling might be faster + // than checking _cs and possibly branching. + csPortSet = dcPortSet; + csPortClr = dcPortClr; + csPinMask = 0; + } + if(rd >= 0) { // if read-strobe pin specified... + tft8.rdPinMask =digitalPinToBitMask(rd); + tft8.rdPortSet =&(PORT->Group[g_APinDescription[rd].ulPort].OUTSET.reg); + tft8.rdPortClr =&(PORT->Group[g_APinDescription[rd].ulPort].OUTCLR.reg); + } else { + tft8.rdPinMask = 0; + tft8.rdPortSet = dcPortSet; + tft8.rdPortClr = dcPortClr; + } + // Get pointers to PORT write/read/dir bytes within 32-bit PORT + uint8_t dBit = g_APinDescription[d0].ulPin; // d0 bit # in PORT + PortGroup *p = (&(PORT->Group[g_APinDescription[d0].ulPort])); + uint8_t offset = dBit / 8; // d[7:0] byte # within PORT + if(tft8.wide) offset &= ~1; // d[15:8] byte # within PORT + // These are all uint8_t* pointers -- elsewhere they're recast + // as necessary if a 'wide' 16-bit interface is in use. + tft8.writePort = (volatile uint8_t *)&(p->OUT.reg) + offset; + tft8.readPort = (volatile uint8_t *)&(p->IN.reg) + offset; + tft8.dirSet = (volatile uint8_t *)&(p->DIRSET.reg) + offset; + tft8.dirClr = (volatile uint8_t *)&(p->DIRCLR.reg) + offset; + #endif // end !CORE_TEENSY + #else // !HAS_PORT_SET_CLR + tft8.wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(wr)); + tft8.wrPinMaskSet = digitalPinToBitMask(wr); + dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(dc)); + dcPinMaskSet = digitalPinToBitMask(dc); + if(cs >= 0) { + csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs)); + csPinMaskSet = digitalPinToBitMask(cs); + } else { + // No chip-select line defined; might be permanently tied to GND. + // Assign a valid GPIO register (though not used for CS), and an + // empty pin bitmask...the nonsense bit-twiddling might be faster + // than checking _cs and possibly branching. + csPort = dcPort; + csPinMaskSet = 0; + } + if(rd >= 0) { // if read-strobe pin specified... + tft8.rdPort =(PORTreg_t)portOutputRegister(digitalPinToPort(rd)); + tft8.rdPinMaskSet =digitalPinToBitMask(rd); + } else { + tft8.rdPort = dcPort; + tft8.rdPinMaskSet = 0; + } + csPinMaskClr = ~csPinMaskSet; + dcPinMaskClr = ~dcPinMaskSet; + tft8.wrPinMaskClr = ~tft8.wrPinMaskSet; + tft8.rdPinMaskClr = ~tft8.rdPinMaskSet; + tft8.writePort = (PORTreg_t)portOutputRegister(digitalPinToPort(d0)); + tft8.readPort = (PORTreg_t)portInputRegister(digitalPinToPort(d0)); + tft8.portDir = (PORTreg_t)portModeRegister(digitalPinToPort(d0)); + #endif // end !HAS_PORT_SET_CLR +#endif // end USE_FAST_PINIO +} + +// end constructors ------- + + +// CLASS MEMBER FUNCTIONS -------------------------------------------------- + +// begin() and setAddrWindow() MUST be declared by any subclass. + +/*! + @brief Configure microcontroller pins for TFT interfacing. Typically + called by a subclass' begin() function. + @param freq SPI frequency when using hardware SPI. If default (0) + is passed, will fall back on a device-specific value. + Value is ignored when using software SPI or parallel + connection. + @param spiMode SPI mode when using hardware SPI. MUST be one of the + values SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3 + defined in SPI.h. Do NOT attempt to pass '0' for + SPI_MODE0 and so forth...the values are NOT the same! + Use ONLY the defines! (Pity it's not an enum.) + @note Another anachronistically-named function; this is called even + when the display connection is parallel (not SPI). Also, this + could probably be made private...quite a few class functions + were generously put in the public section. +*/ +void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) { + + if(!freq) freq = DEFAULT_SPI_FREQ; // If no freq specified, use default + + // Init basic control pins common to all connection types + if(_cs >= 0) { + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); // Deselect + } + pinMode(_dc, OUTPUT); + digitalWrite(_dc, HIGH); // Data mode + + if(connection == TFT_HARD_SPI) { + +#if defined(SPI_HAS_TRANSACTION) + hwspi.settings = SPISettings(freq, MSBFIRST, spiMode); +#else + hwspi._freq = freq; // Save freq value for later +#endif + hwspi._mode = spiMode; // Save spiMode value for later + // Call hwspi._spi->begin() ONLY if this is among the 'established' + // SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs, + // begin() and pinPeripheral() calls MUST be made in one's calling + // code, BEFORE the screen-specific begin/init function is called. + // Reason for this is that SPI::begin() makes its own calls to + // pinPeripheral() based on g_APinDescription[n].ulPinType, which + // on non-established SPI interface pins will always be PIO_DIGITAL + // or similar, while we need PIO_SERCOM or PIO_SERCOM_ALT...it's + // highly unique between devices and variants for each pin or + // SERCOM so we can't make those calls ourselves here. And the SPI + // device needs to be set up before calling this because it's + // immediately followed with initialization commands. Blargh. + if( +#if !defined(SPI_INTERFACES_COUNT) + 1 +#endif +#if SPI_INTERFACES_COUNT > 0 + (hwspi._spi == &SPI) +#endif +#if SPI_INTERFACES_COUNT > 1 + || (hwspi._spi == &SPI1) +#endif +#if SPI_INTERFACES_COUNT > 2 + || (hwspi._spi == &SPI2) +#endif +#if SPI_INTERFACES_COUNT > 3 + || (hwspi._spi == &SPI3) +#endif +#if SPI_INTERFACES_COUNT > 4 + || (hwspi._spi == &SPI4) +#endif +#if SPI_INTERFACES_COUNT > 5 + || (hwspi._spi == &SPI5) +#endif + ) { + hwspi._spi->begin(); + } + } else if(connection == TFT_SOFT_SPI) { + + pinMode(swspi._mosi, OUTPUT); + digitalWrite(swspi._mosi, LOW); + pinMode(swspi._sck, OUTPUT); + digitalWrite(swspi._sck, LOW); + if(swspi._miso >= 0) { + pinMode(swspi._miso, INPUT); + } + + } else { // TFT_PARALLEL + + // Initialize data pins. We were only passed d0, so scan + // the pin description list looking for the other pins. + // They'll be on the same PORT, and within the next 7 (or 15) bits + // (because we need to write to a contiguous PORT byte or word). +#if defined(__AVR__) + // PORT registers are 8 bits wide, so just need a register match... + for(uint8_t i=0; i= dBit ) && + (g_APinDescription[i].ulPin <= (uint32_t)lastBit)) { + pinMode(i, OUTPUT); + digitalWrite(i, LOW); + } + } + #endif // end !CORE_TEENSY +#endif + pinMode(tft8._wr, OUTPUT); + digitalWrite(tft8._wr, HIGH); + if(tft8._rd >= 0) { + pinMode(tft8._rd, OUTPUT); + digitalWrite(tft8._rd, HIGH); + } + } + + if(_rst >= 0) { + // Toggle _rst low to reset + pinMode(_rst, OUTPUT); + digitalWrite(_rst, HIGH); + delay(100); + digitalWrite(_rst, LOW); + delay(100); + digitalWrite(_rst, HIGH); + delay(200); + } + +#if defined(USE_SPI_DMA) + if(((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) && + (dma.allocate() == DMA_STATUS_OK)) { // Allocate channel + // The DMA library needs to alloc at least one valid descriptor, + // so we do that here. It's not used in the usual sense though, + // just before a transfer we copy descriptor[0] to this address. + if(dptr = dma.addDescriptor(NULL, NULL, 42, DMA_BEAT_SIZE_BYTE, + false, false)) { + // Alloc 2 scanlines worth of pixels on display's major axis, + // whichever that is, rounding each up to 2-pixel boundary. + int major = (WIDTH > HEIGHT) ? WIDTH : HEIGHT; + major += (major & 1); // -> next 2-pixel bound, if needed. + maxFillLen = major * 2; // 2 scanlines + // Note to future self: if you decide to make the pixel buffer + // much larger, remember that DMA transfer descriptors can't + // exceed 65,535 bytes (not 65,536), meaning 32,767 pixels max. + // Not that we have that kind of RAM to throw around right now. + if((pixelBuf[0] = + (uint16_t *)malloc(maxFillLen * sizeof(uint16_t)))) { + // Alloc OK. Get pointer to start of second scanline. + pixelBuf[1] = &pixelBuf[0][major]; + // Determine number of DMA descriptors needed to cover + // entire screen when entire 2-line pixelBuf is used + // (round up for fractional last descriptor). + int numDescriptors = (WIDTH * HEIGHT + (maxFillLen - 1)) / + maxFillLen; + // DMA descriptors MUST be 128-bit (16 byte) aligned. + // memalign() is considered obsolete but it's replacements + // (aligned_alloc() or posix_memalign()) are not currently + // available in the version of ARM GCC in use, but this + // is, so here we are. + if((descriptor = (DmacDescriptor *)memalign(16, + numDescriptors * sizeof(DmacDescriptor)))) { + int dmac_id; + volatile uint32_t *data_reg; + + if(connection == TFT_HARD_SPI) { + // THIS IS AN AFFRONT TO NATURE, but I don't know + // any "clean" way to get the sercom number from the + // the SPIClass pointer (e.g. &SPI or &SPI1), which + // is all we have to work with. SPIClass does contain + // a SERCOM pointer but it is a PRIVATE member! + // Doing an UNSPEAKABLY HORRIBLE THING here, directly + // accessing the first 32-bit value in the SPIClass + // structure, knowing that's (currently) where the + // SERCOM pointer lives, but this ENTIRELY DEPENDS on + // that structure not changing nor the compiler + // rearranging things. Oh the humanity! + + if(*(SERCOM **)hwspi._spi == &sercom0) { + dmac_id = SERCOM0_DMAC_ID_TX; + data_reg = &SERCOM0->SPI.DATA.reg; +#if defined SERCOM1 + } else if(*(SERCOM **)hwspi._spi == &sercom1) { + dmac_id = SERCOM1_DMAC_ID_TX; + data_reg = &SERCOM1->SPI.DATA.reg; +#endif +#if defined SERCOM2 + } else if(*(SERCOM **)hwspi._spi == &sercom2) { + dmac_id = SERCOM2_DMAC_ID_TX; + data_reg = &SERCOM2->SPI.DATA.reg; +#endif +#if defined SERCOM3 + } else if(*(SERCOM **)hwspi._spi == &sercom3) { + dmac_id = SERCOM3_DMAC_ID_TX; + data_reg = &SERCOM3->SPI.DATA.reg; +#endif +#if defined SERCOM4 + } else if(*(SERCOM **)hwspi._spi == &sercom4) { + dmac_id = SERCOM4_DMAC_ID_TX; + data_reg = &SERCOM4->SPI.DATA.reg; +#endif +#if defined SERCOM5 + } else if(*(SERCOM **)hwspi._spi == &sercom5) { + dmac_id = SERCOM5_DMAC_ID_TX; + data_reg = &SERCOM5->SPI.DATA.reg; +#endif +#if defined SERCOM6 + } else if(*(SERCOM **)hwspi._spi == &sercom6) { + dmac_id = SERCOM6_DMAC_ID_TX; + data_reg = &SERCOM6->SPI.DATA.reg; +#endif +#if defined SERCOM7 + } else if(*(SERCOM **)hwspi._spi == &sercom7) { + dmac_id = SERCOM7_DMAC_ID_TX; + data_reg = &SERCOM7->SPI.DATA.reg; +#endif + } + dma.setPriority(DMA_PRIORITY_3); + dma.setTrigger(dmac_id); + dma.setAction(DMA_TRIGGER_ACTON_BEAT); + + // Initialize descriptor list. + for(int d=0; dChannel[dmaChannel].CHEVCTRL.bit.EVOE = 1; + DMAC->Channel[dmaChannel].CHEVCTRL.bit.EVOMODE = 0; + + // CONFIGURE TIMER/COUNTER (for write strobe) + + Tc *timer = tcList[tcNum].tc; // -> Timer struct + int id = tcList[tcNum].gclk; // Timer GCLK ID + GCLK_PCHCTRL_Type pchctrl; + + // Set up timer clock source from GCLK + GCLK->PCHCTRL[id].bit.CHEN = 0; // Stop timer + while(GCLK->PCHCTRL[id].bit.CHEN); // Wait for it + pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK0_Val; + pchctrl.bit.CHEN = 1; // Enable + GCLK->PCHCTRL[id].reg = pchctrl.reg; + while(!GCLK->PCHCTRL[id].bit.CHEN); // Wait for it + + // Disable timer/counter before configuring it + timer->COUNT8.CTRLA.bit.ENABLE = 0; + while(timer->COUNT8.SYNCBUSY.bit.STATUS); + + timer->COUNT8.WAVE.bit.WAVEGEN = 2; // NPWM + timer->COUNT8.CTRLA.bit.MODE = 1; // 8-bit + timer->COUNT8.CTRLA.bit.PRESCALER = 0; // 1:1 + while(timer->COUNT8.SYNCBUSY.bit.STATUS); + + timer->COUNT8.CTRLBCLR.bit.DIR = 1; // Count UP + while(timer->COUNT8.SYNCBUSY.bit.CTRLB); + timer->COUNT8.CTRLBSET.bit.ONESHOT = 1; // One-shot + while(timer->COUNT8.SYNCBUSY.bit.CTRLB); + timer->COUNT8.PER.reg = 6; // PWM top + while(timer->COUNT8.SYNCBUSY.bit.PER); + timer->COUNT8.CC[0].reg = 2; // Compare + while(timer->COUNT8.SYNCBUSY.bit.CC0); + // Enable async input events, + // event action = restart. + timer->COUNT8.EVCTRL.bit.TCEI = 1; + timer->COUNT8.EVCTRL.bit.EVACT = 1; + + // Enable timer + timer->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE; + while(timer->COUNT8.SYNCBUSY.bit.STATUS); + +#if(wrPeripheral == PIO_CCL) + // CONFIGURE CCL (inverts timer/counter output) + + MCLK->APBCMASK.bit.CCL_ = 1; // Enable CCL clock + CCL->CTRL.bit.ENABLE = 0; // Disable to config + CCL->CTRL.bit.SWRST = 1; // Reset CCL registers + CCL->LUTCTRL[tcNum].bit.ENABLE = 0; // Disable LUT + CCL->LUTCTRL[tcNum].bit.FILTSEL = 0; // No filter + CCL->LUTCTRL[tcNum].bit.INSEL0 = 6; // TC input + CCL->LUTCTRL[tcNum].bit.INSEL1 = 0; // MASK + CCL->LUTCTRL[tcNum].bit.INSEL2 = 0; // MASK + CCL->LUTCTRL[tcNum].bit.TRUTH = 1; // Invert in 0 + CCL->LUTCTRL[tcNum].bit.ENABLE = 1; // Enable LUT + CCL->CTRL.bit.ENABLE = 1; // Enable CCL +#endif + + // CONFIGURE EVENT SYSTEM + + // Set up event system clock source from GCLK... + // Disable EVSYS, wait for disable + GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN = 0; + while(GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN); + pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK0_Val; + pchctrl.bit.CHEN = 1; // Re-enable + GCLK->PCHCTRL[EVSYS_GCLK_ID_0].reg = pchctrl.reg; + // Wait for it, then enable EVSYS clock + while(!GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN); + MCLK->APBBMASK.bit.EVSYS_ = 1; + + // Connect Timer EVU to ch 0 + EVSYS->USER[tcList[tcNum].evu].reg = 1; + // Datasheet recommends single write operation; + // reg instead of bit. Also datasheet: PATH bits + // must be zero when using async! + EVSYS_CHANNEL_Type ev; + ev.reg = 0; + ev.bit.PATH = 2; // Asynchronous + ev.bit.EVGEN = 0x22 + dmaChannel; // DMA channel 0+ + EVSYS->Channel[0].CHANNEL.reg = ev.reg; + + // Initialize descriptor list. + for(int d=0; d= 0) SPI_CS_LOW(); +} + +/*! + @brief Call after issuing command(s) or data to display. Performs + chip-deselect (if required) and ends an SPI transaction (if + using hardware SPI and transactions are supported). Required + for all display types; not an SPI-specific function. +*/ +void Adafruit_SPITFT::endWrite(void) { + if(_cs >= 0) SPI_CS_HIGH(); + SPI_END_TRANSACTION(); +} + + +// ------------------------------------------------------------------------- +// Lower-level graphics operations. These functions require a chip-select +// and/or SPI transaction around them (via startWrite(), endWrite() above). +// Higher-level graphics primitives might start a single transaction and +// then make multiple calls to these functions (e.g. circle or text +// rendering might make repeated lines or rects) before ending the +// transaction. It's more efficient than starting a transaction every time. + +/*! + @brief Draw a single pixel to the display at requested coordinates. + Not self-contained; should follow a startWrite() call. + @param x Horizontal position (0 = left). + @param y Vertical position (0 = top). + @param color 16-bit pixel color in '565' RGB format. +*/ +void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { + if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { + setAddrWindow(x, y, 1, 1); + SPI_WRITE16(color); + } +} + +/*! + @brief Issue a series of pixels from memory to the display. Not self- + contained; should follow startWrite() and setAddrWindow() calls. + @param colors Pointer to array of 16-bit pixel values in '565' RGB + format. + @param len Number of elements in 'colors' array. + @param block If true (default case if unspecified), function blocks + until DMA transfer is complete. This is simply IGNORED + if DMA is not enabled. If false, the function returns + immediately after the last DMA transfer is started, + and one should use the dmaWait() function before + doing ANY other display-related activities (or even + any SPI-related activities, if using an SPI display + that shares the bus with other devices). + @param bigEndian If using DMA, and if set true, bitmap in memory is in + big-endian order (most significant byte first). By + default this is false, as most microcontrollers seem + to be little-endian and 16-bit pixel values must be + byte-swapped before issuing to the display (which tend + to be big-endian when using SPI or 8-bit parallel). + If an application can optimize around this -- for + example, a bitmap in a uint16_t array having the byte + values already reordered big-endian, this can save + some processing time here, ESPECIALLY if using this + function's non-blocking DMA mode. Not all cases are + covered...this is really here only for SAMD DMA and + much forethought on the application side. +*/ +void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len, + bool block, bool bigEndian) { + + if(!len) return; // Avoid 0-byte transfers + +#if defined(ESP32) // ESP32 has a special SPI pixel-writing function... + if(connection == TFT_HARD_SPI) { + hwspi._spi->writePixels(colors, len * 2); + return; + } +#elif defined(USE_SPI_DMA) + if((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) { + int maxSpan = maxFillLen / 2; // One scanline max + uint8_t pixelBufIdx = 0; // Active pixel buffer number + #if defined(__SAMD51__) + if(connection == TFT_PARALLEL) { + // Switch WR pin to PWM or CCL + pinPeripheral(tft8._wr, wrPeripheral); + } + #endif // end __SAMD51__ + if(!bigEndian) { // Normal little-endian situation... + while(len) { + int count = (len < maxSpan) ? len : maxSpan; + + // Because TFT and SAMD endianisms are different, must swap + // bytes from the 'colors' array passed into a DMA working + // buffer. This can take place while the prior DMA transfer + // is in progress, hence the need for two pixelBufs. + for(int i=0; isetDataMode(hwspi._mode); + } else { + pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO + } + #endif // end __SAMD51__ || _SAMD21_ + } + return; + } +#endif // end USE_SPI_DMA + + // All other cases (bitbang SPI or non-DMA hard SPI or parallel), + // use a loop with the normal 16-bit data write function: + while(len--) { + SPI_WRITE16(*colors++); + } +} + +/*! + @brief Wait for the last DMA transfer in a prior non-blocking + writePixels() call to complete. This does nothing if DMA + is not enabled, and is not needed if blocking writePixels() + was used (as is the default case). +*/ +void Adafruit_SPITFT::dmaWait(void) { +#if defined(USE_SPI_DMA) + while(dma_busy); + #if defined(__SAMD51__) || defined(_SAMD21_) + if(connection == TFT_HARD_SPI) { + // See SAMD51/21 note in writeColor() + hwspi._spi->setDataMode(hwspi._mode); + } else { + pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO + } + #endif // end __SAMD51__ || _SAMD21_ +#endif +} + +/*! + @brief Issue a series of pixels, all the same color. Not self- + contained; should follow startWrite() and setAddrWindow() calls. + @param color 16-bit pixel color in '565' RGB format. + @param len Number of pixels to draw. +*/ +void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) { + + if(!len) return; // Avoid 0-byte transfers + + uint8_t hi = color >> 8, lo = color; + +#if defined(ESP32) // ESP32 has a special SPI pixel-writing function... + if(connection == TFT_HARD_SPI) { + #define SPI_MAX_PIXELS_AT_ONCE 32 + #define TMPBUF_LONGWORDS (SPI_MAX_PIXELS_AT_ONCE + 1) / 2 + #define TMPBUF_PIXELS (TMPBUF_LONGWORDS * 2) + static uint32_t temp[TMPBUF_LONGWORDS]; + uint32_t c32 = color * 0x00010001; + uint16_t bufLen = (len < TMPBUF_PIXELS) ? len : TMPBUF_PIXELS, + xferLen, fillLen; + // Fill temp buffer 32 bits at a time + fillLen = (bufLen + 1) / 2; // Round up to next 32-bit boundary + for(uint32_t t=0; t= 16)) { // Don't bother with DMA on short pixel runs + int i, d, numDescriptors; + if(hi == lo) { // If high & low bytes are same... + onePixelBuf = color; + // Can do this with a relatively short descriptor list, + // each transferring a max of 32,767 (not 32,768) pixels. + // This won't run off the end of the allocated descriptor list, + // since we're using much larger chunks per descriptor here. + numDescriptors = (len + 32766) / 32767; + for(d=0; d lastFillLen) { + int fillStart = lastFillLen / 2, + fillEnd = (((len < maxFillLen) ? + len : maxFillLen) + 1) / 2; + for(i=fillStart; isetDataMode(hwspi._mode); + } else { + pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO + } + #endif // end __SAMD51__ + return; + } + #endif // end USE_SPI_DMA +#endif // end !ESP32 + + // All other cases (non-DMA hard SPI, bitbang SPI, parallel)... + + if(connection == TFT_HARD_SPI) { +#if defined(ESP8266) + do { + uint32_t pixelsThisPass = len; + if(pixelsThisPass > 50000) pixelsThisPass = 50000; + len -= pixelsThisPass; + yield(); // Periodic yield() on long fills + while(pixelsThisPass--) { + hwspi._spi->write(hi); + hwspi._spi->write(lo); + } + } while(len); +#else // !ESP8266 + while(len--) { + #if defined(__AVR__) + AVR_WRITESPI(hi); + AVR_WRITESPI(lo); + #elif defined(ESP32) + hwspi._spi->write(hi); + hwspi._spi->write(lo); + #else + hwspi._spi->transfer(hi); + hwspi._spi->transfer(lo); + #endif + } +#endif // end !ESP8266 + } else if(connection == TFT_SOFT_SPI) { +#if defined(ESP8266) + do { + uint32_t pixelsThisPass = len; + if(pixelsThisPass > 20000) pixelsThisPass = 20000; + len -= pixelsThisPass; + yield(); // Periodic yield() on long fills + while(pixelsThisPass--) { + for(uint16_t bit=0, x=color; bit<16; bit++) { + if(x & 0x8000) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + SPI_SCK_LOW(); + x <<= 1; + } + } + } while(len); +#else // !ESP8266 + while(len--) { + #if defined(__AVR__) + for(uint8_t bit=0, x=hi; bit<8; bit++) { + if(x & 0x80) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + SPI_SCK_LOW(); + x <<= 1; + } + for(uint8_t bit=0, x=lo; bit<8; bit++) { + if(x & 0x80) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + SPI_SCK_LOW(); + x <<= 1; + } + #else // !__AVR__ + for(uint16_t bit=0, x=color; bit<16; bit++) { + if(x & 0x8000) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + x <<= 1; + SPI_SCK_LOW(); + } + #endif // end !__AVR__ + } +#endif // end !ESP8266 + } else { // PARALLEL + if(hi == lo) { +#if defined(__AVR__) + len *= 2; + *tft8.writePort = hi; + while(len--) { + TFT_WR_STROBE(); + } +#elif defined(USE_FAST_PINIO) + if(!tft8.wide) { + len *= 2; + *tft8.writePort = hi; + } else { + *(volatile uint16_t *)tft8.writePort = color; + } + while(len--) { + TFT_WR_STROBE(); + } +#endif + } else { + while(len--) { +#if defined(__AVR__) + *tft8.writePort = hi; + TFT_WR_STROBE(); + *tft8.writePort = lo; +#elif defined(USE_FAST_PINIO) + if(!tft8.wide) { + *tft8.writePort = hi; + TFT_WR_STROBE(); + *tft8.writePort = lo; + } else { + *(volatile uint16_t *)tft8.writePort = color; + } +#endif + TFT_WR_STROBE(); + } + } + } +} + +/*! + @brief Draw a filled rectangle to the display. Not self-contained; + should follow startWrite(). Typically used by higher-level + graphics primitives; user code shouldn't need to call this and + is likely to use the self-contained fillRect() instead. + writeFillRect() performs its own edge clipping and rejection; + see writeFillRectPreclipped() for a more 'raw' implementation. + @param x Horizontal position of first corner. + @param y Vertical position of first corner. + @param w Rectangle width in pixels (positive = right of first + corner, negative = left of first corner). + @param h Rectangle height in pixels (positive = below first + corner, negative = above first corner). + @param color 16-bit fill color in '565' RGB format. + @note Written in this deep-nested way because C by definition will + optimize for the 'if' case, not the 'else' -- avoids branches + and rejects clipped rectangles at the least-work possibility. +*/ +void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y, + int16_t w, int16_t h, uint16_t color) { + if(w && h) { // Nonzero width and height? + if(w < 0) { // If negative width... + x += w + 1; // Move X to left edge + w = -w; // Use positive width + } + if(x < _width) { // Not off right + if(h < 0) { // If negative height... + y += h + 1; // Move Y to top edge + h = -h; // Use positive height + } + if(y < _height) { // Not off bottom + int16_t x2 = x + w - 1; + if(x2 >= 0) { // Not off left + int16_t y2 = y + h - 1; + if(y2 >= 0) { // Not off top + // Rectangle partly or fully overlaps screen + if(x < 0) { x = 0; w = x2 + 1; } // Clip left + if(y < 0) { y = 0; h = y2 + 1; } // Clip top + if(x2 >= _width) { w = _width - x; } // Clip right + if(y2 >= _height) { h = _height - y; } // Clip bottom + writeFillRectPreclipped(x, y, w, h, color); + } + } + } + } + } +} + +/*! + @brief Draw a horizontal line on the display. Performs edge clipping + and rejection. Not self-contained; should follow startWrite(). + Typically used by higher-level graphics primitives; user code + shouldn't need to call this and is likely to use the self- + contained drawFastHLine() instead. + @param x Horizontal position of first point. + @param y Vertical position of first point. + @param w Line width in pixels (positive = right of first point, + negative = point of first corner). + @param color 16-bit line color in '565' RGB format. +*/ +void inline Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w, + uint16_t color) { + if((y >= 0) && (y < _height) && w) { // Y on screen, nonzero width + if(w < 0) { // If negative width... + x += w + 1; // Move X to left edge + w = -w; // Use positive width + } + if(x < _width) { // Not off right + int16_t x2 = x + w - 1; + if(x2 >= 0) { // Not off left + // Line partly or fully overlaps screen + if(x < 0) { x = 0; w = x2 + 1; } // Clip left + if(x2 >= _width) { w = _width - x; } // Clip right + writeFillRectPreclipped(x, y, w, 1, color); + } + } + } +} + +/*! + @brief Draw a vertical line on the display. Performs edge clipping and + rejection. Not self-contained; should follow startWrite(). + Typically used by higher-level graphics primitives; user code + shouldn't need to call this and is likely to use the self- + contained drawFastVLine() instead. + @param x Horizontal position of first point. + @param y Vertical position of first point. + @param h Line height in pixels (positive = below first point, + negative = above first point). + @param color 16-bit line color in '565' RGB format. +*/ +void inline Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h, + uint16_t color) { + if((x >= 0) && (x < _width) && h) { // X on screen, nonzero height + if(h < 0) { // If negative height... + y += h + 1; // Move Y to top edge + h = -h; // Use positive height + } + if(y < _height) { // Not off bottom + int16_t y2 = y + h - 1; + if(y2 >= 0) { // Not off top + // Line partly or fully overlaps screen + if(y < 0) { y = 0; h = y2 + 1; } // Clip top + if(y2 >= _height) { h = _height - y; } // Clip bottom + writeFillRectPreclipped(x, y, 1, h, color); + } + } + } +} + +/*! + @brief A lower-level version of writeFillRect(). This version requires + all inputs are in-bounds, that width and height are positive, + and no part extends offscreen. NO EDGE CLIPPING OR REJECTION IS + PERFORMED. If higher-level graphics primitives are written to + handle their own clipping earlier in the drawing process, this + can avoid unnecessary function calls and repeated clipping + operations in the lower-level functions. + @param x Horizontal position of first corner. MUST BE WITHIN + SCREEN BOUNDS. + @param y Vertical position of first corner. MUST BE WITHIN SCREEN + BOUNDS. + @param w Rectangle width in pixels. MUST BE POSITIVE AND NOT + EXTEND OFF SCREEN. + @param h Rectangle height in pixels. MUST BE POSITIVE AND NOT + EXTEND OFF SCREEN. + @param color 16-bit fill color in '565' RGB format. + @note This is a new function, no graphics primitives besides rects + and horizontal/vertical lines are written to best use this yet. +*/ +inline void Adafruit_SPITFT::writeFillRectPreclipped(int16_t x, int16_t y, + int16_t w, int16_t h, uint16_t color) { + setAddrWindow(x, y, w, h); + writeColor(color, (uint32_t)w * h); +} + + +// ------------------------------------------------------------------------- +// Ever-so-slightly higher-level graphics operations. Similar to the 'write' +// functions above, but these contain their own chip-select and SPI +// transactions as needed (via startWrite(), endWrite()). They're typically +// used solo -- as graphics primitives in themselves, not invoked by higher- +// level primitives (which should use the functions above for better +// performance). + +/*! + @brief Draw a single pixel to the display at requested coordinates. + Self-contained and provides its own transaction as needed + (see writePixel(x,y,color) for a lower-level variant). + Edge clipping is performed here. + @param x Horizontal position (0 = left). + @param y Vertical position (0 = top). + @param color 16-bit pixel color in '565' RGB format. +*/ +void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color) { + // Clip first... + if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { + // THEN set up transaction (if needed) and draw... + startWrite(); + setAddrWindow(x, y, 1, 1); + SPI_WRITE16(color); + endWrite(); + } +} + +/*! + @brief Draw a filled rectangle to the display. Self-contained and + provides its own transaction as needed (see writeFillRect() or + writeFillRectPreclipped() for lower-level variants). Edge + clipping and rejection is performed here. + @param x Horizontal position of first corner. + @param y Vertical position of first corner. + @param w Rectangle width in pixels (positive = right of first + corner, negative = left of first corner). + @param h Rectangle height in pixels (positive = below first + corner, negative = above first corner). + @param color 16-bit fill color in '565' RGB format. + @note This repeats the writeFillRect() function almost in its entirety, + with the addition of a transaction start/end. It's done this way + (rather than starting the transaction and calling writeFillRect() + to handle clipping and so forth) so that the transaction isn't + performed at all if the rectangle is rejected. It's really not + that much code. +*/ +void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, + uint16_t color) { + if(w && h) { // Nonzero width and height? + if(w < 0) { // If negative width... + x += w + 1; // Move X to left edge + w = -w; // Use positive width + } + if(x < _width) { // Not off right + if(h < 0) { // If negative height... + y += h + 1; // Move Y to top edge + h = -h; // Use positive height + } + if(y < _height) { // Not off bottom + int16_t x2 = x + w - 1; + if(x2 >= 0) { // Not off left + int16_t y2 = y + h - 1; + if(y2 >= 0) { // Not off top + // Rectangle partly or fully overlaps screen + if(x < 0) { x = 0; w = x2 + 1; } // Clip left + if(y < 0) { y = 0; h = y2 + 1; } // Clip top + if(x2 >= _width) { w = _width - x; } // Clip right + if(y2 >= _height) { h = _height - y; } // Clip bottom + startWrite(); + writeFillRectPreclipped(x, y, w, h, color); + endWrite(); + } + } + } + } + } +} + +/*! + @brief Draw a horizontal line on the display. Self-contained and + provides its own transaction as needed (see writeFastHLine() for + a lower-level variant). Edge clipping and rejection is performed + here. + @param x Horizontal position of first point. + @param y Vertical position of first point. + @param w Line width in pixels (positive = right of first point, + negative = point of first corner). + @param color 16-bit line color in '565' RGB format. + @note This repeats the writeFastHLine() function almost in its + entirety, with the addition of a transaction start/end. It's + done this way (rather than starting the transaction and calling + writeFastHLine() to handle clipping and so forth) so that the + transaction isn't performed at all if the line is rejected. +*/ +void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y, int16_t w, + uint16_t color) { + if((y >= 0) && (y < _height) && w) { // Y on screen, nonzero width + if(w < 0) { // If negative width... + x += w + 1; // Move X to left edge + w = -w; // Use positive width + } + if(x < _width) { // Not off right + int16_t x2 = x + w - 1; + if(x2 >= 0) { // Not off left + // Line partly or fully overlaps screen + if(x < 0) { x = 0; w = x2 + 1; } // Clip left + if(x2 >= _width) { w = _width - x; } // Clip right + startWrite(); + writeFillRectPreclipped(x, y, w, 1, color); + endWrite(); + } + } + } +} + +/*! + @brief Draw a vertical line on the display. Self-contained and provides + its own transaction as needed (see writeFastHLine() for a lower- + level variant). Edge clipping and rejection is performed here. + @param x Horizontal position of first point. + @param y Vertical position of first point. + @param h Line height in pixels (positive = below first point, + negative = above first point). + @param color 16-bit line color in '565' RGB format. + @note This repeats the writeFastVLine() function almost in its + entirety, with the addition of a transaction start/end. It's + done this way (rather than starting the transaction and calling + writeFastVLine() to handle clipping and so forth) so that the + transaction isn't performed at all if the line is rejected. +*/ +void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y, int16_t h, + uint16_t color) { + if((x >= 0) && (x < _width) && h) { // X on screen, nonzero height + if(h < 0) { // If negative height... + y += h + 1; // Move Y to top edge + h = -h; // Use positive height + } + if(y < _height) { // Not off bottom + int16_t y2 = y + h - 1; + if(y2 >= 0) { // Not off top + // Line partly or fully overlaps screen + if(y < 0) { y = 0; h = y2 + 1; } // Clip top + if(y2 >= _height) { h = _height - y; } // Clip bottom + startWrite(); + writeFillRectPreclipped(x, y, 1, h, color); + endWrite(); + } + } + } +} + +/*! + @brief Essentially writePixel() with a transaction around it. I don't + think this is in use by any of our code anymore (believe it was + for some older BMP-reading examples), but is kept here in case + any user code relies on it. Consider it DEPRECATED. + @param color 16-bit pixel color in '565' RGB format. +*/ +void Adafruit_SPITFT::pushColor(uint16_t color) { + startWrite(); + SPI_WRITE16(color); + endWrite(); +} + +/*! + @brief Draw a 16-bit image (565 RGB) at the specified (x,y) position. + For 16-bit display devices; no color reduction performed. + Adapted from https://github.com/PaulStoffregen/ILI9341_t3 + by Marc MERLIN. See examples/pictureEmbed to use this. + 5/6/2017: function name and arguments have changed for + compatibility with current GFX library and to avoid naming + problems in prior implementation. Formerly drawBitmap() with + arguments in different order. Handles its own transaction and + edge clipping/rejection. + @param x Top left corner horizontal coordinate. + @param y Top left corner vertical coordinate. + @param pcolors Pointer to 16-bit array of pixel values. + @param w Width of bitmap in pixels. + @param h Height of bitmap in pixels. +*/ +void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y, + uint16_t *pcolors, int16_t w, int16_t h) { + + int16_t x2, y2; // Lower-right coord + if(( x >= _width ) || // Off-edge right + ( y >= _height) || // " top + ((x2 = (x+w-1)) < 0 ) || // " left + ((y2 = (y+h-1)) < 0) ) return; // " bottom + + int16_t bx1=0, by1=0, // Clipped top-left within bitmap + saveW=w; // Save original bitmap width value + if(x < 0) { // Clip left + w += x; + bx1 = -x; + x = 0; + } + if(y < 0) { // Clip top + h += y; + by1 = -y; + y = 0; + } + if(x2 >= _width ) w = _width - x; // Clip right + if(y2 >= _height) h = _height - y; // Clip bottom + + pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left + startWrite(); + setAddrWindow(x, y, w, h); // Clipped area + while(h--) { // For each (clipped) scanline... + writePixels(pcolors, w); // Push one (clipped) row + pcolors += saveW; // Advance pointer by one full (unclipped) line + } + endWrite(); +} + + +// ------------------------------------------------------------------------- +// Miscellaneous class member functions that don't draw anything. + +/*! + @brief Invert the colors of the display (if supported by hardware). + Self-contained, no transaction setup required. + @param i true = inverted display, false = normal display. +*/ +void Adafruit_SPITFT::invertDisplay(bool i) { + startWrite(); + writeCommand(i ? invertOnCommand : invertOffCommand); + endWrite(); +} + +/*! + @brief Given 8-bit red, green and blue values, return a 'packed' + 16-bit color value in '565' RGB format (5 bits red, 6 bits + green, 5 bits blue). This is just a mathematical operation, + no hardware is touched. + @param red 8-bit red brightnesss (0 = off, 255 = max). + @param green 8-bit green brightnesss (0 = off, 255 = max). + @param blue 8-bit blue brightnesss (0 = off, 255 = max). + @return 'Packed' 16-bit color value (565 format). +*/ +uint16_t Adafruit_SPITFT::color565(uint8_t red, uint8_t green, uint8_t blue) { + return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3); +} + +/*! + @brief Adafruit_SPITFT Send Command handles complete sending of commands and data + @param commandByte The Command Byte + @param dataBytes A pointer to the Data bytes to send + @param numDataBytes The number of bytes we should send + */ +void Adafruit_SPITFT::sendCommand(uint8_t commandByte, uint8_t *dataBytes, uint8_t numDataBytes) { + SPI_BEGIN_TRANSACTION(); + if(_cs >= 0) SPI_CS_LOW(); + + SPI_DC_LOW(); // Command mode + spiWrite(commandByte); // Send the command byte + + SPI_DC_HIGH(); + for (int i=0; i= 0) SPI_CS_HIGH(); + SPI_END_TRANSACTION(); +} + +/*! + @brief Adafruit_SPITFT Send Command handles complete sending of commands and const data + @param commandByte The Command Byte + @param dataBytes A pointer to the Data bytes to send + @param numDataBytes The number of bytes we should send + */ +void Adafruit_SPITFT::sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes) { + SPI_BEGIN_TRANSACTION(); + if(_cs >= 0) SPI_CS_LOW(); + + SPI_DC_LOW(); // Command mode + spiWrite(commandByte); // Send the command byte + + SPI_DC_HIGH(); + for (int i=0; i= 0) SPI_CS_HIGH(); + SPI_END_TRANSACTION(); +} + +/*! + @brief Read 8 bits of data from display configuration memory (not RAM). + This is highly undocumented/supported and should be avoided, + function is only included because some of the examples use it. + @param commandByte + The command register to read data from. + @param index + The byte index into the command to read from. + @return Unsigned 8-bit data read from display register. + */ +/**************************************************************************/ +uint8_t Adafruit_SPITFT::readcommand8(uint8_t commandByte, uint8_t index) { + uint8_t result; + startWrite(); + SPI_DC_LOW(); // Command mode + spiWrite(commandByte); + SPI_DC_HIGH(); // Data mode + do { + result = spiRead(); + } while(index--); // Discard bytes up to index'th + endWrite(); + return result; +} + +// ------------------------------------------------------------------------- +// Lowest-level hardware-interfacing functions. Many of these are inline and +// compile to different things based on #defines -- typically just a few +// instructions. Others, not so much, those are not inlined. + +/*! + @brief Start an SPI transaction if using the hardware SPI interface to + the display. If using an earlier version of the Arduino platform + (before the addition of SPI transactions), this instead attempts + to set up the SPI clock and mode. No action is taken if the + connection is not hardware SPI-based. This does NOT include a + chip-select operation -- see startWrite() for a function that + encapsulated both actions. +*/ +inline void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION(void) { + if(connection == TFT_HARD_SPI) { +#if defined(SPI_HAS_TRANSACTION) + hwspi._spi->beginTransaction(hwspi.settings); +#else // No transactions, configure SPI manually... + #if defined(__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1) + hwspi._spi->setClockDivider(SPI_CLOCK_DIV2); + #elif defined(__arm__) + hwspi._spi->setClockDivider(11); + #elif defined(ESP8266) || defined(ESP32) + hwspi._spi->setFrequency(hwspi._freq); + #elif defined(RASPI) || defined(ARDUINO_ARCH_STM32F1) + hwspi._spi->setClock(hwspi._freq); + #endif + hwspi._spi->setBitOrder(MSBFIRST); + hwspi._spi->setDataMode(hwspi._mode); +#endif // end !SPI_HAS_TRANSACTION + } +} + +/*! + @brief End an SPI transaction if using the hardware SPI interface to + the display. No action is taken if the connection is not + hardware SPI-based or if using an earlier version of the Arduino + platform (before the addition of SPI transactions). This does + NOT include a chip-deselect operation -- see endWrite() for a + function that encapsulated both actions. +*/ +inline void Adafruit_SPITFT::SPI_END_TRANSACTION(void) { +#if defined(SPI_HAS_TRANSACTION) + if(connection == TFT_HARD_SPI) { + hwspi._spi->endTransaction(); + } +#endif +} + +/*! + @brief Issue a single 8-bit value to the display. Chip-select, + transaction and data/command selection must have been + previously set -- this ONLY issues the byte. This is another of + those functions in the library with a now-not-accurate name + that's being maintained for compatibility with outside code. + This function is used even if display connection is parallel. + @param b 8-bit value to write. +*/ +void Adafruit_SPITFT::spiWrite(uint8_t b) { + if(connection == TFT_HARD_SPI) { +#if defined(__AVR__) + AVR_WRITESPI(b); +#elif defined(ESP8266) || defined(ESP32) + hwspi._spi->write(b); +#else + hwspi._spi->transfer(b); +#endif + } else if(connection == TFT_SOFT_SPI) { + for(uint8_t bit=0; bit<8; bit++) { + if(b & 0x80) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + b <<= 1; + SPI_SCK_LOW(); + } + } else { // TFT_PARALLEL +#if defined(__AVR__) + *tft8.writePort = b; +#elif defined(USE_FAST_PINIO) + if(!tft8.wide) *tft8.writePort = b; + else *(volatile uint16_t *)tft8.writePort = b; +#endif + TFT_WR_STROBE(); + } +} + +/*! + @brief Write a single command byte to the display. Chip-select and + transaction must have been previously set -- this ONLY sets + the device to COMMAND mode, issues the byte and then restores + DATA mode. There is no corresponding explicit writeData() + function -- just use spiWrite(). + @param cmd 8-bit command to write. +*/ +void Adafruit_SPITFT::writeCommand(uint8_t cmd) { + SPI_DC_LOW(); + spiWrite(cmd); + SPI_DC_HIGH(); +} + +/*! + @brief Read a single 8-bit value from the display. Chip-select and + transaction must have been previously set -- this ONLY reads + the byte. This is another of those functions in the library + with a now-not-accurate name that's being maintained for + compatibility with outside code. This function is used even if + display connection is parallel. + @return Unsigned 8-bit value read (always zero if USE_FAST_PINIO is + not supported by the MCU architecture). +*/ +uint8_t Adafruit_SPITFT::spiRead(void) { + uint8_t b = 0; + uint16_t w = 0; + if(connection == TFT_HARD_SPI) { + return hwspi._spi->transfer((uint8_t)0); + } else if(connection == TFT_SOFT_SPI) { + if(swspi._miso >= 0) { + for(uint8_t i=0; i<8; i++) { + SPI_SCK_HIGH(); + b <<= 1; + if(SPI_MISO_READ()) b++; + SPI_SCK_LOW(); + } + } + return b; + } else { // TFT_PARALLEL + if(tft8._rd >= 0) { +#if defined(USE_FAST_PINIO) + TFT_RD_LOW(); // Read line LOW + #if defined(__AVR__) + *tft8.portDir = 0x00; // Set port to input state + w = *tft8.readPort; // Read value from port + *tft8.portDir = 0xFF; // Restore port to output + #else // !__AVR__ + if(!tft8.wide) { // 8-bit TFT connection + #if defined(HAS_PORT_SET_CLR) + *tft8.dirClr = 0xFF; // Set port to input state + w = *tft8.readPort; // Read value from port + *tft8.dirSet = 0xFF; // Restore port to output + #else // !HAS_PORT_SET_CLR + *tft8.portDir = 0x00; // Set port to input state + w = *tft8.readPort; // Read value from port + *tft8.portDir = 0xFF; // Restore port to output + #endif // end HAS_PORT_SET_CLR + } else { // 16-bit TFT connection + #if defined(HAS_PORT_SET_CLR) + *(volatile uint16_t *)tft8.dirClr = 0xFFFF; // Input state + w = *(volatile uint16_t *)tft8.readPort; // 16-bit read + *(volatile uint16_t *)tft8.dirSet = 0xFFFF; // Output state + #else // !HAS_PORT_SET_CLR + *(volatile uint16_t *)tft8.portDir = 0x0000; // Input state + w = *(volatile uint16_t *)tft8.readPort; // 16-bit read + *(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state + #endif // end !HAS_PORT_SET_CLR + } + TFT_RD_HIGH(); // Read line HIGH + #endif // end !__AVR__ +#else // !USE_FAST_PINIO + w = 0; // Parallel TFT is NOT SUPPORTED without USE_FAST_PINIO +#endif // end !USE_FAST_PINIO + } + return w; + } +} + +/*! + @brief Set the software (bitbang) SPI MOSI line HIGH. +*/ +inline void Adafruit_SPITFT::SPI_MOSI_HIGH(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *swspi.mosiPortSet = 1; + #else // !KINETISK + *swspi.mosiPortSet = swspi.mosiPinMask; + #endif + #else // !HAS_PORT_SET_CLR + *swspi.mosiPort |= swspi.mosiPinMaskSet; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(swspi._mosi, HIGH); + #if defined(ESP32) + for(volatile uint8_t i=0; i<1; i++); + #endif // end ESP32 +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Set the software (bitbang) SPI MOSI line LOW. +*/ +inline void Adafruit_SPITFT::SPI_MOSI_LOW(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *swspi.mosiPortClr = 1; + #else // !KINETISK + *swspi.mosiPortClr = swspi.mosiPinMask; + #endif + #else // !HAS_PORT_SET_CLR + *swspi.mosiPort &= swspi.mosiPinMaskClr; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(swspi._mosi, LOW); + #if defined(ESP32) + for(volatile uint8_t i=0; i<1; i++); + #endif // end ESP32 +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Set the software (bitbang) SPI SCK line HIGH. +*/ +inline void Adafruit_SPITFT::SPI_SCK_HIGH(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *swspi.sckPortSet = 1; + #else // !KINETISK + *swspi.sckPortSet = swspi.sckPinMask; + #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x + for(volatile uint8_t i=0; i<1; i++); + #endif + #endif + #else // !HAS_PORT_SET_CLR + *swspi.sckPort |= swspi.sckPinMaskSet; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(swspi._sck, HIGH); + #if defined(ESP32) + for(volatile uint8_t i=0; i<1; i++); + #endif // end ESP32 +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Set the software (bitbang) SPI SCK line LOW. +*/ +inline void Adafruit_SPITFT::SPI_SCK_LOW(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *swspi.sckPortClr = 1; + #else // !KINETISK + *swspi.sckPortClr = swspi.sckPinMask; + #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x + for(volatile uint8_t i=0; i<1; i++); + #endif + #endif + #else // !HAS_PORT_SET_CLR + *swspi.sckPort &= swspi.sckPinMaskClr; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(swspi._sck, LOW); + #if defined(ESP32) + for(volatile uint8_t i=0; i<1; i++); + #endif // end ESP32 +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Read the state of the software (bitbang) SPI MISO line. + @return true if HIGH, false if LOW. +*/ +inline bool Adafruit_SPITFT::SPI_MISO_READ(void) { +#if defined(USE_FAST_PINIO) + #if defined(KINETISK) + return *swspi.misoPort; + #else // !KINETISK + return *swspi.misoPort & swspi.misoPinMask; + #endif // end !KINETISK +#else // !USE_FAST_PINIO + return digitalRead(swspi._miso); +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Issue a single 16-bit value to the display. Chip-select, + transaction and data/command selection must have been + previously set -- this ONLY issues the word. Despite the name, + this function is used even if display connection is parallel; + name was maintaned for backward compatibility. Naming is also + not consistent with the 8-bit version, spiWrite(). Sorry about + that. Again, staying compatible with outside code. + @param w 16-bit value to write. +*/ +void Adafruit_SPITFT::SPI_WRITE16(uint16_t w) { + if(connection == TFT_HARD_SPI) { +#if defined(__AVR__) + AVR_WRITESPI(w >> 8); + AVR_WRITESPI(w); +#elif defined(ESP8266) || defined(ESP32) + hwspi._spi->write16(w); +#else + hwspi._spi->transfer(w >> 8); + hwspi._spi->transfer(w); +#endif + } else if(connection == TFT_SOFT_SPI) { + for(uint8_t bit=0; bit<16; bit++) { + if(w & 0x8000) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + SPI_SCK_LOW(); + w <<= 1; + } + } else { // TFT_PARALLEL +#if defined(__AVR__) + *tft8.writePort = w >> 8; + TFT_WR_STROBE(); + *tft8.writePort = w; +#elif defined(USE_FAST_PINIO) + if(!tft8.wide) { + *tft8.writePort = w >> 8; + TFT_WR_STROBE(); + *tft8.writePort = w; + } else { + *(volatile uint16_t *)tft8.writePort = w; + } +#endif + TFT_WR_STROBE(); + } +} + +/*! + @brief Issue a single 32-bit value to the display. Chip-select, + transaction and data/command selection must have been + previously set -- this ONLY issues the longword. Despite the + name, this function is used even if display connection is + parallel; name was maintaned for backward compatibility. Naming + is also not consistent with the 8-bit version, spiWrite(). + Sorry about that. Again, staying compatible with outside code. + @param l 32-bit value to write. +*/ +void Adafruit_SPITFT::SPI_WRITE32(uint32_t l) { + if(connection == TFT_HARD_SPI) { +#if defined(__AVR__) + AVR_WRITESPI(l >> 24); + AVR_WRITESPI(l >> 16); + AVR_WRITESPI(l >> 8); + AVR_WRITESPI(l ); +#elif defined(ESP8266) || defined(ESP32) + hwspi._spi->write32(l); +#else + hwspi._spi->transfer(l >> 24); + hwspi._spi->transfer(l >> 16); + hwspi._spi->transfer(l >> 8); + hwspi._spi->transfer(l); +#endif + } else if(connection == TFT_SOFT_SPI) { + for(uint8_t bit=0; bit<32; bit++) { + if(l & 0x80000000) SPI_MOSI_HIGH(); + else SPI_MOSI_LOW(); + SPI_SCK_HIGH(); + SPI_SCK_LOW(); + l <<= 1; + } + } else { // TFT_PARALLEL +#if defined(__AVR__) + *tft8.writePort = l >> 24; + TFT_WR_STROBE(); + *tft8.writePort = l >> 16; + TFT_WR_STROBE(); + *tft8.writePort = l >> 8; + TFT_WR_STROBE(); + *tft8.writePort = l; +#elif defined(USE_FAST_PINIO) + if(!tft8.wide) { + *tft8.writePort = l >> 24; + TFT_WR_STROBE(); + *tft8.writePort = l >> 16; + TFT_WR_STROBE(); + *tft8.writePort = l >> 8; + TFT_WR_STROBE(); + *tft8.writePort = l; + } else { + *(volatile uint16_t *)tft8.writePort = l >> 16; + TFT_WR_STROBE(); + *(volatile uint16_t *)tft8.writePort = l; + } +#endif + TFT_WR_STROBE(); + } +} + +/*! + @brief Set the WR line LOW, then HIGH. Used for parallel-connected + interfaces when writing data. +*/ +inline void Adafruit_SPITFT::TFT_WR_STROBE(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *tft8.wrPortClr = 1; + *tft8.wrPortSet = 1; + #else // !KINETISK + *tft8.wrPortClr = tft8.wrPinMask; + *tft8.wrPortSet = tft8.wrPinMask; + #endif // end !KINETISK + #else // !HAS_PORT_SET_CLR + *tft8.wrPort &= tft8.wrPinMaskClr; + *tft8.wrPort |= tft8.wrPinMaskSet; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(tft8._wr, LOW); + digitalWrite(tft8._wr, HIGH); +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Set the RD line HIGH. Used for parallel-connected interfaces + when reading data. +*/ +inline void Adafruit_SPITFT::TFT_RD_HIGH(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + *tft8.rdPortSet = tft8.rdPinMask; + #else // !HAS_PORT_SET_CLR + *tft8.rdPort |= tft8.rdPinMaskSet; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(tft8._rd, HIGH); +#endif // end !USE_FAST_PINIO +} + +/*! + @brief Set the RD line LOW. Used for parallel-connected interfaces + when reading data. +*/ +inline void Adafruit_SPITFT::TFT_RD_LOW(void) { +#if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + *tft8.rdPortClr = tft8.rdPinMask; + #else // !HAS_PORT_SET_CLR + *tft8.rdPort &= tft8.rdPinMaskClr; + #endif // end !HAS_PORT_SET_CLR +#else // !USE_FAST_PINIO + digitalWrite(tft8._rd, LOW); +#endif // end !USE_FAST_PINIO +} + +#endif // end __AVR_ATtiny85__ diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h new file mode 100644 index 000000000..dcfc1646b --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h @@ -0,0 +1,520 @@ +/*! + * @file Adafruit_SPITFT.h + * + * Part of Adafruit's GFX graphics library. Originally this class was + * written to handle a range of color TFT displays connected via SPI, + * but over time this library and some display-specific subclasses have + * mutated to include some color OLEDs as well as parallel-interfaced + * displays. The name's been kept for the sake of older code. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Written by Limor "ladyada" Fried for Adafruit Industries, + * with contributions from the open source community. + * + * BSD license, all text here must be included in any redistribution. + */ + +#ifndef _ADAFRUIT_SPITFT_H_ +#define _ADAFRUIT_SPITFT_H_ + +#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all + +#include +#include "Adafruit_GFX.h" +#include "renderer.h" + +// HARDWARE CONFIG --------------------------------------------------------- + +#if defined(__AVR__) + typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit + #define USE_FAST_PINIO ///< Use direct PORT register access +#elif defined(ARDUINO_STM32_FEATHER) // WICED + typedef class HardwareSPI SPIClass; ///< SPI is a bit odd on WICED + typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit +#elif defined(__arm__) + #if defined(ARDUINO_ARCH_SAMD) + // Adafruit M0, M4 + typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit + #define USE_FAST_PINIO ///< Use direct PORT register access + #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers + #elif defined(CORE_TEENSY) + // PJRC Teensy 4.x + #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x + typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit + // PJRC Teensy 3.x + #else + typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit + #endif + #define USE_FAST_PINIO ///< Use direct PORT register access + #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers + #else + // Arduino Due? + typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit + // USE_FAST_PINIO not available here (yet)...Due has a totally different + // GPIO register set and will require some changes elsewhere (e.g. in + // constructors especially). + #endif +#else // !ARM + // Probably ESP8266 or ESP32. USE_FAST_PINIO is not available here (yet) + // but don't worry about it too much...the digitalWrite() implementation + // on these platforms is reasonably efficient and already RAM-resident, + // only gotcha then is no parallel connection support for now. + typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit +#endif // end !ARM +typedef volatile ADAGFX_PORT_t* PORTreg_t; ///< PORT register type + +#if defined(__AVR__) + #define DEFAULT_SPI_FREQ 8000000L ///< Hardware SPI default speed +#else + #define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed +#endif + +#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || defined(ADAFRUIT_PYGAMER_M4_EXPRESS) + #define USE_SPI_DMA ///< Auto DMA if using PyPortal +#else + //#define USE_SPI_DMA ///< If set, use DMA if available +#endif +// Another "oops" name -- this now also handles parallel DMA. +// If DMA is enabled, Arduino sketch MUST #include +// Estimated RAM usage: +// 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis, +// e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes. + +#if !defined(ARDUINO_ARCH_SAMD) + #undef USE_SPI_DMA ///< DMA currently for SAMD chips only +#endif + +#if defined(USE_SPI_DMA) + #pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.") + #include +#endif + +// This is kind of a kludge. Needed a way to disambiguate the software SPI +// and parallel constructors via their argument lists. Originally tried a +// bool as the first argument to the parallel constructor (specifying 8-bit +// vs 16-bit interface) but the compiler regards this as equivalent to an +// integer and thus still ambiguous. SO...the parallel constructor requires +// an enumerated type as the first argument: tft8 (for 8-bit parallel) or +// tft16 (for 16-bit)...even though 16-bit isn't fully implemented or tested +// and might never be, still needed that disambiguation from soft SPI. +enum tftBusWidth { tft8bitbus, tft16bitbus }; ///< For first arg to parallel constructor + +// CLASS DEFINITION -------------------------------------------------------- + +/*! + @brief Adafruit_SPITFT is an intermediary class between Adafruit_GFX + and various hardware-specific subclasses for different displays. + It handles certain operations that are common to a range of + displays (address window, area fills, etc.). Originally these were + all color TFT displays interfaced via SPI, but it's since expanded + to include color OLEDs and parallel-interfaced TFTs. THE NAME HAS + BEEN KEPT TO AVOID BREAKING A LOT OF SUBCLASSES AND EXAMPLE CODE. + Many of the class member functions similarly live on with names + that don't necessarily accurately describe what they're doing, + again to avoid breaking a lot of other code. If in doubt, read + the comments. +*/ +class Adafruit_SPITFT : public Renderer { + + public: + + // CONSTRUCTORS -------------------------------------------------------- + + // Software SPI constructor: expects width & height (at default rotation + // setting 0), 4 signal pins (cs, dc, mosi, sclk), 2 optional pins + // (reset, miso). cs argument is required but can be -1 if unused -- + // rather than moving it to the optional arguments, it was done this way + // to avoid breaking existing code (-1 option was a later addition). + Adafruit_SPITFT(uint16_t w, uint16_t h, + int8_t cs, int8_t dc, int8_t mosi, int8_t sck, + int8_t rst = -1, int8_t miso = -1); + + // Hardware SPI constructor using the default SPI port: expects width & + // height (at default rotation setting 0), 2 signal pins (cs, dc), + // optional reset pin. cs is required but can be -1 if unused -- rather + // than moving it to the optional arguments, it was done this way to + // avoid breaking existing code (-1 option was a later addition). + Adafruit_SPITFT(uint16_t w, uint16_t h, + int8_t cs, int8_t dc, int8_t rst = -1); + +#if !defined(ESP8266) // See notes in .cpp + // Hardware SPI constructor using an arbitrary SPI peripheral: expects + // width & height (rotation 0), SPIClass pointer, 2 signal pins (cs, dc) + // and optional reset pin. cs is required but can be -1 if unused. + Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, + int8_t cs, int8_t dc, int8_t rst = -1); +#endif // end !ESP8266 + + // Parallel constructor: expects width & height (rotation 0), flag + // indicating whether 16-bit (true) or 8-bit (false) interface, 3 signal + // pins (d0, wr, dc), 3 optional pins (cs, rst, rd). 16-bit parallel + // isn't even fully implemented but the 'wide' flag was added as a + // required argument to avoid ambiguity with other constructors. + Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth, + int8_t d0, int8_t wr, int8_t dc, + int8_t cs = -1, int8_t rst = -1, int8_t rd = -1); + + // CLASS MEMBER FUNCTIONS ---------------------------------------------- + + // These first two functions MUST be declared by subclasses: + + /*! + @brief Display-specific initialization function. + @param freq SPI frequency, in hz (or 0 for default or unused). + */ + virtual void begin(uint32_t freq) = 0; + + /*! + @brief Set up the specific display hardware's "address window" + for subsequent pixel-pushing operations. + @param x Leftmost pixel of area to be drawn (MUST be within + display bounds at current rotation setting). + @param y Topmost pixel of area to be drawn (MUST be within + display bounds at current rotation setting). + @param w Width of area to be drawn, in pixels (MUST be >0 and, + added to x, within display bounds at current rotation). + @param h Height of area to be drawn, in pixels (MUST be >0 and, + added to x, within display bounds at current rotation). + */ + virtual void setAddrWindow( + uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0; + + // Remaining functions do not need to be declared in subclasses + // unless they wish to provide hardware-specific optimizations. + // Brief comments here...documented more thoroughly in .cpp file. + + // Subclass' begin() function invokes this to initialize hardware. + // freq=0 to use default SPI speed. spiMode must be one of the SPI_MODEn + // values defined in SPI.h, which are NOT the same as 0 for SPI_MODE0, + // 1 for SPI_MODE1, etc...use ONLY the SPI_MODEn defines! Only! + // Name is outdated (interface may be parallel) but for compatibility: + void initSPI(uint32_t freq = 0, uint8_t spiMode = SPI_MODE0); + // Chip select and/or hardware SPI transaction start as needed: + void startWrite(void); + // Chip deselect and/or hardware SPI transaction end as needed: + void endWrite(void); + void sendCommand(uint8_t commandByte, uint8_t *dataBytes = NULL, uint8_t numDataBytes = 0); + void sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes); + uint8_t readcommand8(uint8_t commandByte, uint8_t index = 0); + + // These functions require a chip-select and/or SPI transaction + // around them. Higher-level graphics primitives might start a + // single transaction and then make multiple calls to these functions + // (e.g. circle or text rendering might make repeated lines or rects) + // before ending the transaction. It's more efficient than starting a + // transaction every time. + void writePixel(int16_t x, int16_t y, uint16_t color); + void writePixels(uint16_t *colors, uint32_t len, + bool block=true, bool bigEndian=false); + void writeColor(uint16_t color, uint32_t len); + void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, + uint16_t color); + void writeFastHLine(int16_t x, int16_t y, int16_t w, + uint16_t color); + void writeFastVLine(int16_t x, int16_t y, int16_t h, + uint16_t color); + // This is a new function, similar to writeFillRect() except that + // all arguments MUST be onscreen, sorted and clipped. If higher-level + // primitives can handle their own sorting/clipping, it avoids repeating + // such operations in the low-level code, making it potentially faster. + // CALLING THIS WITH UNCLIPPED OR NEGATIVE VALUES COULD BE DISASTROUS. + inline void writeFillRectPreclipped(int16_t x, int16_t y, + int16_t w, int16_t h, uint16_t color); + // Another new function, companion to the new non-blocking + // writePixels() variant. + void dmaWait(void); + + + // These functions are similar to the 'write' functions above, but with + // a chip-select and/or SPI transaction built-in. They're typically used + // solo -- that is, as graphics primitives in themselves, not invoked by + // higher-level primitives (which should use the functions above). + void drawPixel(int16_t x, int16_t y, uint16_t color); + void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, + uint16_t color); + void drawFastHLine(int16_t x, int16_t y, int16_t w, + uint16_t color); + void drawFastVLine(int16_t x, int16_t y, int16_t h, + uint16_t color); + // A single-pixel push encapsulated in a transaction. I don't think + // this is used anymore (BMP demos might've used it?) but is provided + // for backward compatibility, consider it deprecated: + void pushColor(uint16_t color); + + using Adafruit_GFX::drawRGBBitmap; // Check base class first + void drawRGBBitmap(int16_t x, int16_t y, + uint16_t *pcolors, int16_t w, int16_t h); + + void invertDisplay(bool i); + uint16_t color565(uint8_t r, uint8_t g, uint8_t b); + + // Despite parallel additions, function names kept for compatibility: + void spiWrite(uint8_t b); // Write single byte as DATA + void writeCommand(uint8_t cmd); // Write single byte as COMMAND + uint8_t spiRead(void); // Read single byte of data + + // Most of these low-level functions were formerly macros in + // Adafruit_SPITFT_Macros.h. Some have been made into inline functions + // to avoid macro mishaps. Despite the addition of code for a parallel + // display interface, the names have been kept for backward + // compatibility (some subclasses may be invoking these): + void SPI_WRITE16(uint16_t w); // Not inline + void SPI_WRITE32(uint32_t l); // Not inline + // Old code had both a spiWrite16() function and SPI_WRITE16 macro + // in addition to the SPI_WRITE32 macro. The latter two have been + // made into functions here, and spiWrite16() removed (use SPI_WRITE16() + // instead). It looks like most subclasses had gotten comfortable with + // SPI_WRITE16 and SPI_WRITE32 anyway so those names were kept rather + // than the less-obnoxious camelcase variants, oh well. + + // Placing these functions entirely in the class definition inlines + // them implicitly them while allowing their use in other code: + + /*! + @brief Set the chip-select line HIGH. Does NOT check whether CS pin + is set (>=0), that should be handled in calling function. + Despite function name, this is used even if the display + connection is parallel. + */ + void SPI_CS_HIGH(void) { + #if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *csPortSet = 1; + #else // !KINETISK + *csPortSet = csPinMask; + #endif // end !KINETISK + #else // !HAS_PORT_SET_CLR + *csPort |= csPinMaskSet; + #endif // end !HAS_PORT_SET_CLR + #else // !USE_FAST_PINIO + digitalWrite(_cs, HIGH); + #endif // end !USE_FAST_PINIO + } + + /*! + @brief Set the chip-select line LOW. Does NOT check whether CS pin + is set (>=0), that should be handled in calling function. + Despite function name, this is used even if the display + connection is parallel. + */ + void SPI_CS_LOW(void) { + #if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *csPortClr = 1; + #else // !KINETISK + *csPortClr = csPinMask; + #endif // end !KINETISK + #else // !HAS_PORT_SET_CLR + *csPort &= csPinMaskClr; + #endif // end !HAS_PORT_SET_CLR + #else // !USE_FAST_PINIO + digitalWrite(_cs, LOW); + #endif // end !USE_FAST_PINIO + } + + /*! + @brief Set the data/command line HIGH (data mode). + */ + void SPI_DC_HIGH(void) { + #if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *dcPortSet = 1; + #else // !KINETISK + *dcPortSet = dcPinMask; + #endif // end !KINETISK + #else // !HAS_PORT_SET_CLR + *dcPort |= dcPinMaskSet; + #endif // end !HAS_PORT_SET_CLR + #else // !USE_FAST_PINIO + digitalWrite(_dc, HIGH); + #endif // end !USE_FAST_PINIO + } + + /*! + @brief Set the data/command line LOW (command mode). + */ + void SPI_DC_LOW(void) { + #if defined(USE_FAST_PINIO) + #if defined(HAS_PORT_SET_CLR) + #if defined(KINETISK) + *dcPortClr = 1; + #else // !KINETISK + *dcPortClr = dcPinMask; + #endif // end !KINETISK + #else // !HAS_PORT_SET_CLR + *dcPort &= dcPinMaskClr; + #endif // end !HAS_PORT_SET_CLR + #else // !USE_FAST_PINIO + digitalWrite(_dc, LOW); + #endif // end !USE_FAST_PINIO + } + + protected: + + // A few more low-level member functions -- some may have previously + // been macros. Shouldn't have a need to access these externally, so + // they've been moved to the protected section. Additionally, they're + // declared inline here and the code is in the .cpp file, since outside + // code doesn't need to see these. + inline void SPI_MOSI_HIGH(void); + inline void SPI_MOSI_LOW(void); + inline void SPI_SCK_HIGH(void); + inline void SPI_SCK_LOW(void); + inline bool SPI_MISO_READ(void); + inline void SPI_BEGIN_TRANSACTION(void); + inline void SPI_END_TRANSACTION(void); + inline void TFT_WR_STROBE(void); // Parallel interface write strobe + inline void TFT_RD_HIGH(void); // Parallel interface read high + inline void TFT_RD_LOW(void); // Parallel interface read low + + // CLASS INSTANCE VARIABLES -------------------------------------------- + + // Here be dragons! There's a big union of three structures here -- + // one each for hardware SPI, software (bitbang) SPI, and parallel + // interfaces. This is to save some memory, since a display's connection + // will be only one of these. The order of some things is a little weird + // in an attempt to get values to align and pack better in RAM. + +#if defined(USE_FAST_PINIO) +#if defined(HAS_PORT_SET_CLR) + PORTreg_t csPortSet; ///< PORT register for chip select SET + PORTreg_t csPortClr; ///< PORT register for chip select CLEAR + PORTreg_t dcPortSet; ///< PORT register for data/command SET + PORTreg_t dcPortClr; ///< PORT register for data/command CLEAR +#else // !HAS_PORT_SET_CLR + PORTreg_t csPort; ///< PORT register for chip select + PORTreg_t dcPort; ///< PORT register for data/command +#endif // end HAS_PORT_SET_CLR +#endif // end USE_FAST_PINIO +#if defined(__cplusplus) && (__cplusplus >= 201100) + union { +#endif + struct { // Values specific to HARDWARE SPI: + SPIClass *_spi; ///< SPI class pointer +#if defined(SPI_HAS_TRANSACTION) + SPISettings settings; ///< SPI transaction settings +#else + uint32_t _freq; ///< SPI bitrate (if no SPI transactions) +#endif + uint32_t _mode; ///< SPI data mode (transactions or no) + } hwspi; ///< Hardware SPI values + struct { // Values specific to SOFTWARE SPI: +#if defined(USE_FAST_PINIO) + PORTreg_t misoPort; ///< PORT (PIN) register for MISO +#if defined(HAS_PORT_SET_CLR) + PORTreg_t mosiPortSet; ///< PORT register for MOSI SET + PORTreg_t mosiPortClr; ///< PORT register for MOSI CLEAR + PORTreg_t sckPortSet; ///< PORT register for SCK SET + PORTreg_t sckPortClr; ///< PORT register for SCK CLEAR + #if !defined(KINETISK) + ADAGFX_PORT_t mosiPinMask; ///< Bitmask for MOSI + ADAGFX_PORT_t sckPinMask; ///< Bitmask for SCK + #endif // end !KINETISK +#else // !HAS_PORT_SET_CLR + PORTreg_t mosiPort; ///< PORT register for MOSI + PORTreg_t sckPort; ///< PORT register for SCK + ADAGFX_PORT_t mosiPinMaskSet; ///< Bitmask for MOSI SET (OR) + ADAGFX_PORT_t mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND) + ADAGFX_PORT_t sckPinMaskSet; ///< Bitmask for SCK SET (OR bitmask) + ADAGFX_PORT_t sckPinMaskClr; ///< Bitmask for SCK CLEAR (AND) +#endif // end HAS_PORT_SET_CLR + #if !defined(KINETISK) + ADAGFX_PORT_t misoPinMask; ///< Bitmask for MISO + #endif // end !KINETISK +#endif // end USE_FAST_PINIO + int8_t _mosi; ///< MOSI pin # + int8_t _miso; ///< MISO pin # + int8_t _sck; ///< SCK pin # + } swspi; ///< Software SPI values + struct { // Values specific to 8-bit parallel: +#if defined(USE_FAST_PINIO) + + #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x + volatile uint32_t *writePort; ///< PORT register for DATA WRITE + volatile uint32_t *readPort; ///< PORT (PIN) register for DATA READ + #else + volatile uint8_t *writePort; ///< PORT register for DATA WRITE + volatile uint8_t *readPort; ///< PORT (PIN) register for DATA READ + #endif +#if defined(HAS_PORT_SET_CLR) + // Port direction register pointers are always 8-bit regardless of + // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits. + #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x + volatile uint32_t *dirSet; ///< PORT byte data direction SET + volatile uint32_t *dirClr; ///< PORT byte data direction CLEAR + #else + volatile uint8_t *dirSet; ///< PORT byte data direction SET + volatile uint8_t *dirClr; ///< PORT byte data direction CLEAR + #endif + PORTreg_t wrPortSet; ///< PORT register for write strobe SET + PORTreg_t wrPortClr; ///< PORT register for write strobe CLEAR + PORTreg_t rdPortSet; ///< PORT register for read strobe SET + PORTreg_t rdPortClr; ///< PORT register for read strobe CLEAR + #if !defined(KINETISK) + ADAGFX_PORT_t wrPinMask; ///< Bitmask for write strobe + #endif // end !KINETISK + ADAGFX_PORT_t rdPinMask; ///< Bitmask for read strobe +#else // !HAS_PORT_SET_CLR + // Port direction register pointer is always 8-bit regardless of + // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits. + volatile uint8_t *portDir; ///< PORT direction register + PORTreg_t wrPort; ///< PORT register for write strobe + PORTreg_t rdPort; ///< PORT register for read strobe + ADAGFX_PORT_t wrPinMaskSet; ///< Bitmask for write strobe SET (OR) + ADAGFX_PORT_t wrPinMaskClr; ///< Bitmask for write strobe CLEAR (AND) + ADAGFX_PORT_t rdPinMaskSet; ///< Bitmask for read strobe SET (OR) + ADAGFX_PORT_t rdPinMaskClr; ///< Bitmask for read strobe CLEAR (AND) +#endif // end HAS_PORT_SET_CLR +#endif // end USE_FAST_PINIO + int8_t _d0; ///< Data pin 0 # + int8_t _wr; ///< Write strobe pin # + int8_t _rd; ///< Read strobe pin # (or -1) + bool wide = 0; ///< If true, is 16-bit interface + } tft8; ///< Parallel interface settings +#if defined(__cplusplus) && (__cplusplus >= 201100) + }; ///< Only one interface is active +#endif +#if defined(USE_SPI_DMA) // Used by hardware SPI and tft8 + Adafruit_ZeroDMA dma; ///< DMA instance + DmacDescriptor *dptr = NULL; ///< 1st descriptor + DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list + uint16_t *pixelBuf[2]; ///< Working buffers + uint16_t maxFillLen; ///< Max pixels per DMA xfer + uint16_t lastFillColor = 0; ///< Last color used w/fill + uint32_t lastFillLen = 0; ///< # of pixels w/last fill + uint8_t onePixelBuf; ///< For hi==lo fill +#endif +#if defined(USE_FAST_PINIO) +#if defined(HAS_PORT_SET_CLR) + #if !defined(KINETISK) + ADAGFX_PORT_t csPinMask; ///< Bitmask for chip select + ADAGFX_PORT_t dcPinMask; ///< Bitmask for data/command + #endif // end !KINETISK +#else // !HAS_PORT_SET_CLR + ADAGFX_PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR) + ADAGFX_PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND) + ADAGFX_PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR) + ADAGFX_PORT_t dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND) +#endif // end HAS_PORT_SET_CLR +#endif // end USE_FAST_PINIO + uint8_t connection; ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc. + int8_t _rst; ///< Reset pin # (or -1) + int8_t _cs; ///< Chip select pin # (or -1) + int8_t _dc; ///< Data/command pin # + + int16_t _xstart = 0; ///< Internal framebuffer X offset + int16_t _ystart = 0; ///< Internal framebuffer Y offset + uint8_t invertOnCommand = 0; ///< Command to enable invert mode + uint8_t invertOffCommand = 0; ///< Command to disable invert mode + + uint32_t _freq = 0; ///< Dummy var to keep subclasses happy +}; + +#endif // end __AVR_ATtiny85__ +#endif // end _ADAFRUIT_SPITFT_H_ diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp new file mode 100644 index 000000000..78d9901d6 --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp @@ -0,0 +1,190 @@ +/*! + * @file Adafruit_SSD1331.cpp + * + * @mainpage Adafruit SSD1331 Arduino Library + * + * @section intro_sec Introduction + * + * This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip + * + * Pick one up today in the adafruit shop! + * ------> http://www.adafruit.com/products/684 + * + * These displays use SPI to communicate, 4 or 5 pins are required to + * interface + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * @section author Author + * + * Written by Limor Fried/Ladyada for Adafruit Industries. + * + * @section license License + * + * BSD license, all text above must be included in any redistribution + */ + +#include "Adafruit_SSD1331.h" +#include "pins_arduino.h" +#include "wiring_private.h" + +/***********************************/ + +/*! + @brief SPI displays set an address window rectangle for blitting pixels + @param x Top left corner x coordinate + @param y Top left corner x coordinate + @param w Width of window + @param h Height of window +*/ +void Adafruit_SSD1331::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, + uint16_t h) { + + uint8_t x1 = x; + uint8_t y1 = y; + if (x1 > 95) + x1 = 95; + if (y1 > 63) + y1 = 63; + + uint8_t x2 = (x + w - 1); + uint8_t y2 = (y + h - 1); + if (x2 > 95) + x2 = 95; + if (y2 > 63) + y2 = 63; + + if (x1 > x2) { + uint8_t t = x2; + x2 = x1; + x1 = t; + } + if (y1 > y2) { + uint8_t t = y2; + y2 = y1; + y1 = t; + } + + sendCommand(0x15); // Column addr set + sendCommand(x1); + sendCommand(x2); + + sendCommand(0x75); // Column addr set + sendCommand(y1); + sendCommand(y2); + + startWrite(); +} + +/**************************************************************************/ +/*! + @brief Initialize SSD1331 chip + Connects to the SSD1331 over SPI and sends initialization procedure commands + @param freq Desired SPI clock frequency +*/ +/**************************************************************************/ +void Adafruit_SSD1331::begin(uint32_t freq) { + initSPI(freq); + + // Initialization Sequence + sendCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE + sendCommand(SSD1331_CMD_SETREMAP); // 0xA0 +#if defined SSD1331_COLORORDER_RGB + sendCommand(0x72); // RGB Color +#else + sendCommand(0x76); // BGR Color +#endif + sendCommand(SSD1331_CMD_STARTLINE); // 0xA1 + sendCommand(0x0); + sendCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2 + sendCommand(0x0); + sendCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4 + sendCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8 + sendCommand(0x3F); // 0x3F 1/64 duty + sendCommand(SSD1331_CMD_SETMASTER); // 0xAD + sendCommand(0x8E); + sendCommand(SSD1331_CMD_POWERMODE); // 0xB0 + sendCommand(0x0B); + sendCommand(SSD1331_CMD_PRECHARGE); // 0xB1 + sendCommand(0x31); + sendCommand(SSD1331_CMD_CLOCKDIV); // 0xB3 + sendCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio + // (A[3:0]+1 = 1..16) + sendCommand(SSD1331_CMD_PRECHARGEA); // 0x8A + sendCommand(0x64); + sendCommand(SSD1331_CMD_PRECHARGEB); // 0x8B + sendCommand(0x78); + sendCommand(SSD1331_CMD_PRECHARGEC); // 0x8C + sendCommand(0x64); + sendCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB + sendCommand(0x3A); + sendCommand(SSD1331_CMD_VCOMH); // 0xBE + sendCommand(0x3E); + sendCommand(SSD1331_CMD_MASTERCURRENT); // 0x87 + sendCommand(0x06); + sendCommand(SSD1331_CMD_CONTRASTA); // 0x81 + sendCommand(0x91); + sendCommand(SSD1331_CMD_CONTRASTB); // 0x82 + sendCommand(0x50); + sendCommand(SSD1331_CMD_CONTRASTC); // 0x83 + sendCommand(0x7D); + sendCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel + _width = TFTWIDTH; + _height = TFTHEIGHT; +} + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit SSD1331 driver with software SPI + @param cs Chip select pin # + @param dc Data/Command pin # + @param mosi SPI MOSI pin # + @param sclk SPI Clock pin # + @param rst Reset pin # (optional, pass -1 if unused) +*/ +/**************************************************************************/ +Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi, + int8_t sclk, int8_t rst) + : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, mosi, sclk, rst, -1) {} + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit SSD1331 driver with hardware SPI + @param cs Chip select pin # + @param dc Data/Command pin # + @param rst Reset pin # (optional, pass -1 if unused) +*/ +/**************************************************************************/ +Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst) + : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {} + +/**************************************************************************/ +/*! + @brief Instantiate Adafruit SSD1331 driver with hardware SPI + @param spi Pointer to an existing SPIClass instance (e.g. &SPI, the + microcontroller's primary SPI bus). + @param cs Chip select pin # + @param dc Data/Command pin # + @param rst Reset pin # (optional, pass -1 if unused) +*/ +/**************************************************************************/ +Adafruit_SSD1331::Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc, + int8_t rst) + : +#if defined(ESP8266) + Adafruit_SPITFT(TFTWIDTH, TFTWIDTH, cs, dc, rst) { +#else + Adafruit_SPITFT(TFTWIDTH, TFTWIDTH, spi, cs, dc, rst) { +#endif +} + +/**************************************************************************/ +/*! + @brief Change whether display is on or off + @param enable True if you want the display ON, false OFF +*/ +/**************************************************************************/ +void Adafruit_SSD1331::enableDisplay(boolean enable) { + sendCommand(enable ? SSD1331_CMD_DISPLAYON : SSD1331_CMD_DISPLAYOFF); +} diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h new file mode 100644 index 000000000..7d9bc85a0 --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h @@ -0,0 +1,76 @@ +/*! + * @file Adafruit_SSD1331.h + */ + +#include "Arduino.h" +#include +// Tasmota change: use custom version of Adafruit_SPITFT which extends Renderer instead of Adafruit_GFX +#include +#include +#include + +/*! + * @brief Select one of these defines to set the pixel color order + */ +#define SSD1331_COLORORDER_RGB +// #define SSD1331_COLORORDER_BGR + +#if defined SSD1331_COLORORDER_RGB && defined SSD1331_COLORORDER_BGR +#error "RGB and BGR can not both be defined for SSD1331_COLORODER." +#endif + +// Timing Delays +#define SSD1331_DELAYS_HWFILL (3) //!< Fill delay +#define SSD1331_DELAYS_HWLINE (1) //!< Line delay + +// SSD1331 Commands +#define SSD1331_CMD_DRAWLINE 0x21 //!< Draw line +#define SSD1331_CMD_DRAWRECT 0x22 //!< Draw rectangle +#define SSD1331_CMD_FILL 0x26 //!< Fill enable/disable +#define SSD1331_CMD_SETCOLUMN 0x15 //!< Set column address +#define SSD1331_CMD_SETROW 0x75 //!< Set row adress +#define SSD1331_CMD_CONTRASTA 0x81 //!< Set contrast for color A +#define SSD1331_CMD_CONTRASTB 0x82 //!< Set contrast for color B +#define SSD1331_CMD_CONTRASTC 0x83 //!< Set contrast for color C +#define SSD1331_CMD_MASTERCURRENT 0x87 //!< Master current control +#define SSD1331_CMD_SETREMAP 0xA0 //!< Set re-map & data format +#define SSD1331_CMD_STARTLINE 0xA1 //!< Set display start line +#define SSD1331_CMD_DISPLAYOFFSET 0xA2 //!< Set display offset +#define SSD1331_CMD_NORMALDISPLAY 0xA4 //!< Set display to normal mode +#define SSD1331_CMD_DISPLAYALLON 0xA5 //!< Set entire display ON +#define SSD1331_CMD_DISPLAYALLOFF 0xA6 //!< Set entire display OFF +#define SSD1331_CMD_INVERTDISPLAY 0xA7 //!< Invert display +#define SSD1331_CMD_SETMULTIPLEX 0xA8 //!< Set multiplex ratio +#define SSD1331_CMD_SETMASTER 0xAD //!< Set master configuration +#define SSD1331_CMD_DISPLAYOFF 0xAE //!< Display OFF (sleep mode) +#define SSD1331_CMD_DISPLAYON 0xAF //!< Normal Brightness Display ON +#define SSD1331_CMD_POWERMODE 0xB0 //!< Power save mode +#define SSD1331_CMD_PRECHARGE 0xB1 //!< Phase 1 and 2 period adjustment +#define SSD1331_CMD_CLOCKDIV \ + 0xB3 //!< Set display clock divide ratio/oscillator frequency +#define SSD1331_CMD_PRECHARGEA 0x8A //!< Set second pre-charge speed for color A +#define SSD1331_CMD_PRECHARGEB 0x8B //!< Set second pre-charge speed for color B +#define SSD1331_CMD_PRECHARGEC 0x8C //!< Set second pre-charge speed for color C +#define SSD1331_CMD_PRECHARGELEVEL 0xBB //!< Set pre-charge voltage +#define SSD1331_CMD_VCOMH 0xBE //!< Set Vcomh voltge + +/// Class to manage hardware interface with SSD1331 chipset +class Adafruit_SSD1331 : public Adafruit_SPITFT { +public: + Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk, int8_t rst); + Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst); + // 3-4 args using hardware SPI (must specify peripheral) (reset optional) + Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc, int8_t rst = -1); + + // commands + void begin(uint32_t begin = 8000000); + + void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h); + + void enableDisplay(boolean enable); + + static const int16_t TFTWIDTH = 96; ///< The width of the display + static const int16_t TFTHEIGHT = 64; ///< The height of the display + +private: +}; diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/README.md b/lib/lib_display/Adafruit_SSD1331-1.2.0/README.md new file mode 100644 index 000000000..24c404c59 --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/README.md @@ -0,0 +1,24 @@ +# Adafruit SSD1331 Arduino Library [![Build Status](https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/html/index.html) +This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip + + Pick one up today in the adafruit shop! + ------> http://www.adafruit.com/products/684 + +These displays use SPI to communicate, 4 or 5 pins are required to +interface + +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Written by Limor Fried/Ladyada for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution + +To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_SSD1131. Check that the Adafruit_SSD1331 folder contains Adafruit_SSD1331.cpp and Adafruit_SSD1331.h + +Place the Adafruit_SSD1331 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. + +You will also have to download the Adafruit GFX Graphics core which does all the circles, text, rectangles, etc. You can get it from +https://github.com/adafruit/Adafruit-GFX-Library +and download/install that library as well diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties b/lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties new file mode 100644 index 000000000..931f1aa38 --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties @@ -0,0 +1,10 @@ +name=Adafruit SSD1331 OLED Driver Library for Arduino +version=1.2.0 +author=Adafruit +maintainer=Adafruit +sentence=For 0.96" OLEDs in the Adafruit shop +paragraph=For 0.96" OLEDs in the Adafruit shop +category=Display +url=https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino +architectures=* +depends=Adafruit GFX Library diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt b/lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt @@ -0,0 +1,26 @@ +Software License Agreement (BSD License) + +Copyright (c) 2012, Adafruit Industries +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino new file mode 100644 index 000000000..031115beb --- /dev/null +++ b/tasmota/xdsp_14_SSD1331.ino @@ -0,0 +1,182 @@ +/* + xdsp_14_SSD1331.ino - Display SSD1331 support for Tasmota + + Copyright (C) 2020 Jeroen Vermeulen, Gerhard Mutz and 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 . +*/ + +#ifdef USE_SPI +#ifdef USE_DISPLAY +#ifdef USE_DISPLAY_SSD1331 + +#define XDSP_14 14 + +#define COLORED 1 +#define UNCOLORED 0 +#define USE_TINY_FONT + +#define SSD1331_BLACK 0x0000 // 0, 0, 0 +#define SSD1331_RED 0xF800 // 255, 0, 0 +#define SSD1331_WHITE 0xFFFF // 255, 255, 255 + +#include + +extern uint8_t *buffer; +extern uint8_t color_type; +Adafruit_SSD1331 *ssd1331; + +/*********************************************************************************************/ + +void SSD1331_InitDriver() { + if (!Settings.display_model) { + Settings.display_model = XDSP_14; + } + + if (XDSP_14 == Settings.display_model) { + + if (Settings.display_width != Adafruit_SSD1331::TFTWIDTH) { + Settings.display_width = Adafruit_SSD1331::TFTWIDTH; + } + if (Settings.display_height != Adafruit_SSD1331::TFTHEIGHT) { + Settings.display_height = Adafruit_SSD1331::TFTHEIGHT; + } + + buffer=0; + + // default colors + fg_color = SSD1331_WHITE; + bg_color = SSD1331_BLACK; + + // init renderer + if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)){ + ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_DC),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),OLED_RESET); + } else { + if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { + ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK),OLED_RESET); + } else { + return; + } + } + + delay(100); + ssd1331->begin(); + renderer = ssd1331; + // Rotation is currently broken, https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/issues/26 + renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); + renderer->dim(Settings.display_dimmer); + +#ifdef SHOW_SPLASH + // Welcome text + renderer->clearDisplay(); + renderer->setTextFont(1); + renderer->DrawStringAt(24, 27, "SSD1331", SSD1331_RED, 0); + delay(1000); +#endif + + color_type = COLOR_COLOR; + } +} + +#ifdef USE_DISPLAY_MODES1TO5 + +void SSD1331PrintLog(void) +{ + disp_refresh--; + if (!disp_refresh) { + disp_refresh = Settings.display_refresh; + if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); } + + char* txt = DisplayLogBuffer('\370'); + if (txt != NULL) { + uint8_t last_row = Settings.display_rows -1; + + renderer->clearDisplay(); + renderer->setTextSize(Settings.display_size); + renderer->setCursor(0,0); + for (byte i = 0; i < last_row; i++) { + strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); + renderer->println(disp_screen_buffer[i]); + } + strlcpy(disp_screen_buffer[last_row], txt, disp_screen_buffer_cols); + DisplayFillScreen(last_row); + + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "[%s]"), disp_screen_buffer[last_row]); + + renderer->println(disp_screen_buffer[last_row]); + renderer->Updateframe(); + } + } +} + +void SSD1331Time(void) +{ + char line[12]; + + renderer->clearDisplay(); + renderer->setTextSize(2); + renderer->setCursor(0, 0); + snprintf_P(line, sizeof(line), PSTR(" %02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); // [ 12:34:56 ] + renderer->println(line); + snprintf_P(line, sizeof(line), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); // [01-02-2018] + renderer->println(line); + renderer->Updateframe(); +} + +void SSD1331Refresh(void) // Every second +{ + if (Settings.display_mode) { // Mode 0 is User text + switch (Settings.display_mode) { + case 1: // Time + SSD1331Time(); + break; + case 2: // Local + case 3: // Local + case 4: // Mqtt + case 5: // Mqtt + SSD1331PrintLog(); + break; + } + } +} + +#endif // USE_DISPLAY_MODES1TO5 +/*********************************************************************************************/ +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ +bool Xdsp14(uint8_t function) +{ + bool result = false; + + if (FUNC_DISPLAY_INIT_DRIVER == function) { + SSD1331_InitDriver(); + } + else if (XDSP_14 == Settings.display_model) { + switch (function) { + case FUNC_DISPLAY_MODEL: + result = true; + break; +#ifdef USE_DISPLAY_MODES1TO5 + case FUNC_DISPLAY_EVERY_SECOND: + SSD1331Refresh(); + break; +#endif // USE_DISPLAY_MODES1TO5 + } + } + return result; +} +#endif // USE_DISPLAY_SSD1331 +#endif // USE_DISPLAY +#endif // USE_SPI From d69be912e9e0a87dfc761506c8cd9dd6865f9c34 Mon Sep 17 00:00:00 2001 From: Mike Harris Date: Mon, 28 Dec 2020 15:43:59 -0800 Subject: [PATCH 053/105] Make all initial tabs two spaces for consistency. Also clean up some trailing comments spacing. This seems to be the common style. --- tasmota/WiFiClientSecureLightBearSSL.cpp | 410 +++++++++++------------ 1 file changed, 205 insertions(+), 205 deletions(-) diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp index d7b53cf25..98cd5f4d6 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.cpp +++ b/tasmota/WiFiClientSecureLightBearSSL.cpp @@ -57,8 +57,8 @@ extern "C" { #include "coredecls.h" #define LOG_HEAP_SIZE(a) _Log_heap_size(a) void _Log_heap_size(const char *msg) { - register uint32_t *sp asm("a1"); - int freestack = 4 * (sp - g_pcont->stack); + register uint32_t *sp asm("a1"); + int freestack = 4 * (sp - g_pcont->stack); Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n", msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(), freestack, ESP.getFreeContStack()); @@ -98,60 +98,60 @@ make_stack_thunk_light(br_ssl_engine_sendrec_buf); // unless the Thunk was initialized. Thanks to AES128 GCM, we can keep // symetric processing on the stack void min_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvapp_ack(cc, len); - } else { - return br_ssl_engine_recvapp_ack(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvapp_ack(cc, len); + } else { + return br_ssl_engine_recvapp_ack(cc, len); + } } unsigned char *min_br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvapp_buf(cc, len); - } else { - return br_ssl_engine_recvapp_buf(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvapp_buf(cc, len); + } else { + return br_ssl_engine_recvapp_buf(cc, len); + } } void min_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvrec_ack(cc, len); - } else { - return br_ssl_engine_recvrec_ack(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvrec_ack(cc, len); + } else { + return br_ssl_engine_recvrec_ack(cc, len); + } } unsigned char *min_br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvrec_buf(cc, len); - } else { - return br_ssl_engine_recvrec_buf(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvrec_buf(cc, len); + } else { + return br_ssl_engine_recvrec_buf(cc, len); + } } void min_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendapp_ack(cc, len); - } else { - return br_ssl_engine_sendapp_ack(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendapp_ack(cc, len); + } else { + return br_ssl_engine_sendapp_ack(cc, len); + } } unsigned char *min_br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendapp_buf(cc, len); - } else { - return br_ssl_engine_sendapp_buf(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendapp_buf(cc, len); + } else { + return br_ssl_engine_sendapp_buf(cc, len); + } } void min_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendrec_ack(cc, len); - } else { - return br_ssl_engine_sendrec_ack(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendrec_ack(cc, len); + } else { + return br_ssl_engine_sendrec_ack(cc, len); + } } unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendrec_buf(cc, len); - } else { - return br_ssl_engine_sendrec_buf(cc, len); - } + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendrec_buf(cc, len); + } else { + return br_ssl_engine_sendrec_buf(cc, len); + } } // Use min_ instead of original thunk_ @@ -176,7 +176,7 @@ namespace BearSSL { void WiFiClientSecure_light::_clear() { // TLS handshake may take more than the 5 second default timeout - _timeout = 10000; // 10 seconds max, it should never go over 6 seconds + _timeout = 10000; // 10 seconds max, it should never go over 6 seconds _sc = nullptr; _ctx_present = false; @@ -185,17 +185,17 @@ void WiFiClientSecure_light::_clear() { _iobuf_out = nullptr; setBufferSizes(1024, 1024); // reasonable minimum _handshake_done = false; - _last_error = 0; + _last_error = 0; _recvapp_buf = nullptr; _recvapp_len = 0; - _fingerprint_any = true; // by default accept all fingerprints - _fingerprint1 = nullptr; - _fingerprint2 = nullptr; - _chain_P = nullptr; - _sk_ec_P = nullptr; - _ta_P = nullptr; + _fingerprint_any = true; // by default accept all fingerprints + _fingerprint1 = nullptr; + _fingerprint2 = nullptr; + _chain_P = nullptr; + _sk_ec_P = nullptr; + _ta_P = nullptr; _ta_size = 0; - _max_thunkstack_use = 0; + _max_thunkstack_use = 0; } // Constructor @@ -221,24 +221,24 @@ WiFiClientSecure_light::~WiFiClientSecure_light() { void WiFiClientSecure_light::allocateBuffers(void) { // We prefer to allocate all buffers at start, rather than lazy allocation and deallocation // in the long run it avoids heap fragmentation and improves stability - LOG_HEAP_SIZE("allocateBuffers before"); + LOG_HEAP_SIZE("allocateBuffers before"); _sc = std::make_shared(); - LOG_HEAP_SIZE("allocateBuffers ClientContext"); + LOG_HEAP_SIZE("allocateBuffers ClientContext"); _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); - LOG_HEAP_SIZE("allocateBuffers after"); + LOG_HEAP_SIZE("allocateBuffers after"); } void WiFiClientSecure_light::setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, - unsigned allowed_usages, unsigned cert_issuer_key_type) { - _chain_P = cert; - _sk_ec_P = sk; + unsigned allowed_usages, unsigned cert_issuer_key_type) { + _chain_P = cert; + _sk_ec_P = sk; _allowed_usages = allowed_usages; _cert_issuer_key_type = cert_issuer_key_type; } void WiFiClientSecure_light::setTrustAnchor(const br_x509_trust_anchor *ta, size_t ta_size) { - _ta_P = ta; + _ta_P = ta; _ta_size = ta_size; } @@ -271,9 +271,9 @@ bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) { int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port); - clearLastError(); + clearLastError(); if (!WiFiClient::connect(ip, port)) { - setLastError(ERR_TCP_CONNECT); + setLastError(ERR_TCP_CONNECT); return 0; } return _connectSSL(nullptr); @@ -282,19 +282,19 @@ int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { int WiFiClientSecure_light::connect(const char* name, uint16_t port) { DEBUG_BSSL("connect(%s,%d)\n", name, port); IPAddress remote_addr; - clearLastError(); + clearLastError(); if (!WiFi.hostByName(name, remote_addr)) { DEBUG_BSSL("connect: Name loopup failure\n"); - setLastError(ERR_CANT_RESOLVE_IP); + setLastError(ERR_CANT_RESOLVE_IP); return 0; } DEBUG_BSSL("connect(%s,%d)\n", remote_addr.toString().c_str(), port); if (!WiFiClient::connect(remote_addr, port)) { DEBUG_BSSL("connect: Unable to connect TCP socket\n"); - _last_error = ERR_TCP_CONNECT; + _last_error = ERR_TCP_CONNECT; return 0; } - LOG_HEAP_SIZE("Before calling _connectSSL"); + LOG_HEAP_SIZE("Before calling _connectSSL"); return _connectSSL(name); } @@ -355,7 +355,7 @@ size_t WiFiClientSecure_light::_write(const uint8_t *buf, size_t size, bool pmem } } while (size); - LOG_HEAP_SIZE("_write"); + LOG_HEAP_SIZE("_write"); return sent_bytes; } @@ -399,7 +399,7 @@ int WiFiClientSecure_light::read(uint8_t *buf, size_t size) { int avail = available(); bool conn = connected(); if (!avail && conn) { - return 0; // We're still connected, but nothing to read + return 0; // We're still connected, but nothing to read } if (!avail && !conn) { DEBUG_BSSL("read: Not connected, none left available\n"); @@ -434,7 +434,7 @@ int WiFiClientSecure_light::read() { int WiFiClientSecure_light::available() { if (_recvapp_buf) { - return _recvapp_len; // Anything from last call? + return _recvapp_len; // Anything from last call? } _recvapp_buf = nullptr; _recvapp_len = 0; @@ -443,7 +443,7 @@ int WiFiClientSecure_light::available() { } int st = br_ssl_engine_current_state(_eng); if (st == BR_SSL_CLOSED) { - return 0; // Nothing leftover, SSL is closed + return 0; // Nothing leftover, SSL is closed } if (st & BR_SSL_RECVAPP) { _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); @@ -620,24 +620,24 @@ static uint8_t htoi (unsigned char c) extern "C" { - // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c - void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) { - unsigned char * pin = in; - static const char * hex = "0123456789ABCDEF"; - char * pout = out; - for(; pin < in+insz; pout +=3, pin++){ - pout[0] = hex[(*pin>>4) & 0xF]; - pout[1] = hex[ *pin & 0xF]; - pout[2] = ':'; - if (pout + 3 - out > outsz){ - /* Better to truncate output string than overflow buffer */ - /* it would be still better to either return a status */ - /* or ensure the target buffer is large enough and it never happen */ - break; - } - } - pout[-1] = 0; - } + // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c + void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) { + unsigned char * pin = in; + static const char * hex = "0123456789ABCDEF"; + char * pout = out; + for(; pin < in+insz; pout +=3, pin++){ + pout[0] = hex[(*pin>>4) & 0xF]; + pout[1] = hex[ *pin & 0xF]; + pout[2] = ':'; + if (pout + 3 - out > outsz){ + /* Better to truncate output string than overflow buffer */ + /* it would be still better to either return a status */ + /* or ensure the target buffer is large enough and it never happen */ + break; + } + } + pout[-1] = 0; + } // BearSSL doesn't define a true insecure decoder, so we make one ourselves @@ -648,12 +648,12 @@ extern "C" { // Private x509 decoder state struct br_x509_pubkeyfingerprint_context { const br_x509_class *vtable; - bool done_cert; // did we parse the first cert already? - bool fingerprint_all; - uint8_t *pubkey_recv_fingerprint; + bool done_cert; // did we parse the first cert already? + bool fingerprint_all; + uint8_t *pubkey_recv_fingerprint; const uint8_t *fingerprint1; const uint8_t *fingerprint2; - unsigned usages; // pubkey usage + unsigned usages; // pubkey usage br_x509_decoder_context ctx; // defined in BearSSL }; @@ -662,15 +662,15 @@ extern "C" { br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; // Don't process anything but the first certificate in the chain if (!xc->done_cert) { - br_x509_decoder_init(&xc->ctx, nullptr, nullptr, nullptr, nullptr); - } - (void)server_name; // ignore server name + br_x509_decoder_init(&xc->ctx, nullptr, nullptr, nullptr, nullptr); + } + (void)server_name; // ignore server name } // Callback for each certificate present in the chain (but only operates // on the first one by design). static void pubkeyfingerprint_start_cert(const br_x509_class **ctx, uint32_t length) { - (void) ctx; // do nothing + (void) ctx; // do nothing (void) length; } @@ -686,7 +686,7 @@ extern "C" { // Callback on individual cert end. static void pubkeyfingerprint_end_cert(const br_x509_class **ctx) { br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - xc->done_cert = true; // first cert already processed + xc->done_cert = true; // first cert already processed } // **** Start patch Castellucci @@ -743,18 +743,18 @@ extern "C" { pubkeyfingerprint_pubkey_fingerprint(&sha1_context, xc->ctx.pkey.key.rsa); br_sha1_out(&sha1_context, xc->pubkey_recv_fingerprint); // copy to fingerprint - if (!xc->fingerprint_all) { - if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { - return 0; - } - if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { - return 0; - } - return 1; // no match, error - } else { - // Default (no validation at all) or no errors in prior checks = success. - return 0; - } + if (!xc->fingerprint_all) { + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { + return 0; + } + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { + return 0; + } + return 1; // no match, error + } else { + // Default (no validation at all) or no errors in prior checks = success. + return 0; + } */ // set fingerprint status byte to zero // FIXME: find a better way to pass this information @@ -796,7 +796,7 @@ extern "C" { xc->pubkey_recv_fingerprint[20] |= 2; // mark for update } if (!xc->pubkey_recv_fingerprint[20]) { - return 1; // not marked for update because no match, error + return 1; // not marked for update because no match, error } // the old fingerprint format matched, recompute new one for update @@ -822,9 +822,9 @@ extern "C" { // Set up the x509 insecure data structures for BearSSL core to use. void br_x509_pubkeyfingerprint_init(br_x509_pubkeyfingerprint_context *ctx, - const uint8_t *fingerprint1, const uint8_t *fingerprint2, - uint8_t *recv_fingerprint, - bool fingerprint_all) { + const uint8_t *fingerprint1, const uint8_t *fingerprint2, + uint8_t *recv_fingerprint, + bool fingerprint_all) { static const br_x509_class br_x509_pubkeyfingerprint_vtable PROGMEM = { sizeof(br_x509_pubkeyfingerprint_context), pubkeyfingerprint_start_chain, @@ -838,19 +838,19 @@ extern "C" { memset(ctx, 0, sizeof * ctx); ctx->vtable = &br_x509_pubkeyfingerprint_vtable; ctx->done_cert = false; - ctx->fingerprint1 = fingerprint1; - ctx->fingerprint2 = fingerprint2; - ctx->pubkey_recv_fingerprint = recv_fingerprint; - ctx->fingerprint_all = fingerprint_all; + ctx->fingerprint1 = fingerprint1; + ctx->fingerprint2 = fingerprint2; + ctx->pubkey_recv_fingerprint = recv_fingerprint; + ctx->fingerprint_all = fingerprint_all; } - // We limit to a single cipher to reduce footprint + // We limit to a single cipher to reduce footprint // we reference it, don't put in PROGMEM static const uint16_t suites[] = { #ifdef USE_MQTT_TLS_FORCE_EC_CIPHER - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 #else - BR_TLS_RSA_WITH_AES_128_GCM_SHA256 + BR_TLS_RSA_WITH_AES_128_GCM_SHA256 #endif }; @@ -869,14 +869,14 @@ extern "C" { br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - // AES CTR/GCM small version, not contstant time (we don't really care here as there is no TPM anyways) - br_ssl_engine_set_gcm(&cc->eng, &br_sslrec_in_gcm_vtable, &br_sslrec_out_gcm_vtable); - br_ssl_engine_set_aes_ctr(&cc->eng, &br_aes_small_ctr_vtable); - br_ssl_engine_set_ghash(&cc->eng, &br_ghash_ctmul32); + // AES CTR/GCM small version, not contstant time (we don't really care here as there is no TPM anyways) + br_ssl_engine_set_gcm(&cc->eng, &br_sslrec_in_gcm_vtable, &br_sslrec_out_gcm_vtable); + br_ssl_engine_set_aes_ctr(&cc->eng, &br_aes_small_ctr_vtable); + br_ssl_engine_set_ghash(&cc->eng, &br_ghash_ctmul32); #ifdef USE_MQTT_TLS_FORCE_EC_CIPHER - // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced - br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); // TODO + // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced + br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); // TODO #endif static const char * alpn_mqtt = "mqtt"; br_ssl_engine_set_protocol_names(&cc->eng, &alpn_mqtt, 1); @@ -886,110 +886,110 @@ extern "C" { // Called by connect() to do the actual SSL setup and handshake. // Returns if the SSL handshake succeeded. bool WiFiClientSecure_light::_connectSSL(const char* hostName) { - // Validation context, either full CA validation or checking only fingerprints + // Validation context, either full CA validation or checking only fingerprints #ifdef USE_MQTT_TLS_CA_CERT - br_x509_minimal_context *x509_minimal; + br_x509_minimal_context *x509_minimal; #else br_x509_pubkeyfingerprint_context *x509_insecure; #endif - LOG_HEAP_SIZE("_connectSSL.start"); + LOG_HEAP_SIZE("_connectSSL.start"); - do { // used to exit on Out of Memory error and keep all cleanup code at the same place - // ============================================================ - // allocate Thunk stack, move to alternate stack and initialize - stack_thunk_light_add_ref(); - LOG_HEAP_SIZE("Thunk allocated"); - DEBUG_BSSL("_connectSSL: start connection\n"); - _freeSSL(); - clearLastError(); - if (!stack_thunk_light_get_stack_bot()) break; + do { // used to exit on Out of Memory error and keep all cleanup code at the same place + // ============================================================ + // allocate Thunk stack, move to alternate stack and initialize + stack_thunk_light_add_ref(); + LOG_HEAP_SIZE("Thunk allocated"); + DEBUG_BSSL("_connectSSL: start connection\n"); + _freeSSL(); + clearLastError(); + if (!stack_thunk_light_get_stack_bot()) break; - _ctx_present = true; - _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr + _ctx_present = true; + _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - br_ssl_client_base_init(_sc.get()); + br_ssl_client_base_init(_sc.get()); - // ============================================================ - // Allocatte and initialize Decoder Context - LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation"); - // Only failure possible in the installation is OOM - #ifdef USE_MQTT_TLS_CA_CERT - x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context)); - if (!x509_minimal) break; - br_x509_minimal_init(x509_minimal, &br_sha256_vtable, _ta_P, _ta_size); - br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng)); - br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable); - br_ssl_engine_set_x509(_eng, &x509_minimal->vtable); + // ============================================================ + // Allocatte and initialize Decoder Context + LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation"); + // Only failure possible in the installation is OOM + #ifdef USE_MQTT_TLS_CA_CERT + x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context)); + if (!x509_minimal) break; + br_x509_minimal_init(x509_minimal, &br_sha256_vtable, _ta_P, _ta_size); + br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng)); + br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable); + br_ssl_engine_set_x509(_eng, &x509_minimal->vtable); uint32_t now = UtcTime(); uint32_t cfg_time = CfgTime(); if (cfg_time > now) { now = cfg_time; } br_x509_minimal_set_time(x509_minimal, now / 86400 + 719528, now % 86400); - #else - x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context)); - //x509_insecure = std::unique_ptr(new br_x509_pubkeyfingerprint_context); - if (!x509_insecure) break; - br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any); - br_ssl_engine_set_x509(_eng, &x509_insecure->vtable); - #endif - LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation"); + #else + x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context)); + //x509_insecure = std::unique_ptr(new br_x509_pubkeyfingerprint_context); + if (!x509_insecure) break; + br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any); + br_ssl_engine_set_x509(_eng, &x509_insecure->vtable); + #endif + LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation"); - // ============================================================ - // Set send/receive buffers - br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); + // ============================================================ + // Set send/receive buffers + br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); - // ============================================================ - // allocate Private key if needed, only if USE_MQTT_AWS_IOT - LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); - #ifdef USE_MQTT_AWS_IOT - // ============================================================ - // Set the EC Private Key, only USE_MQTT_AWS_IOT - // limited to P256 curve - br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, - _sk_ec_P, _allowed_usages, - _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); - #endif // USE_MQTT_AWS_IOT + // ============================================================ + // allocate Private key if needed, only if USE_MQTT_AWS_IOT + LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); + #ifdef USE_MQTT_AWS_IOT + // ============================================================ + // Set the EC Private Key, only USE_MQTT_AWS_IOT + // limited to P256 curve + br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, + _sk_ec_P, _allowed_usages, + _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); + #endif // USE_MQTT_AWS_IOT - // ============================================================ - // Start TLS connection, ALL - if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break; + // ============================================================ + // Start TLS connection, ALL + if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break; - auto ret = _wait_for_handshake(); - #ifdef DEBUG_ESP_SSL - if (!ret) { - DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError()); - } else { - DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus()); - } - #endif - LOG_HEAP_SIZE("_connectSSL.end"); - _max_thunkstack_use = stack_thunk_light_get_max_usage(); - stack_thunk_light_del_ref(); - //stack_thunk_light_repaint(); - LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk"); + auto ret = _wait_for_handshake(); + #ifdef DEBUG_ESP_SSL + if (!ret) { + DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError()); + } else { + DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus()); + } + #endif + LOG_HEAP_SIZE("_connectSSL.end"); + _max_thunkstack_use = stack_thunk_light_get_max_usage(); + stack_thunk_light_del_ref(); + //stack_thunk_light_repaint(); + LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk"); - #ifdef USE_MQTT_TLS_CA_CERT - free(x509_minimal); - #else - free(x509_insecure); - #endif - LOG_HEAP_SIZE("_connectSSL after release of Priv Key"); - return ret; - } while (0); + #ifdef USE_MQTT_TLS_CA_CERT + free(x509_minimal); + #else + free(x509_insecure); + #endif + LOG_HEAP_SIZE("_connectSSL after release of Priv Key"); + return ret; + } while (0); - // ============================================================ - // if we arrived here, this means we had an OOM error, cleaning up - setLastError(ERR_OOM); - DEBUG_BSSL("_connectSSL: Out of memory\n"); - stack_thunk_light_del_ref(); + // ============================================================ + // if we arrived here, this means we had an OOM error, cleaning up + setLastError(ERR_OOM); + DEBUG_BSSL("_connectSSL: Out of memory\n"); + stack_thunk_light_del_ref(); #ifdef USE_MQTT_TLS_CA_CERT - free(x509_minimal); + free(x509_minimal); #else - free(x509_insecure); + free(x509_insecure); #endif - LOG_HEAP_SIZE("_connectSSL clean_on_error"); - return false; + LOG_HEAP_SIZE("_connectSSL clean_on_error"); + return false; } }; From 00b3a9180a9de44af57a7954ee22d6edca5d0f2a Mon Sep 17 00:00:00 2001 From: Mike Harris Date: Mon, 28 Dec 2020 15:54:28 -0800 Subject: [PATCH 054/105] Fix typo s/renegociation/renegotiation. --- tasmota/WiFiClientSecureLightBearSSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp index d7b53cf25..91f433c50 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.cpp +++ b/tasmota/WiFiClientSecureLightBearSSL.cpp @@ -857,7 +857,7 @@ extern "C" { // Default initializion for our SSL clients static void br_ssl_client_base_init(br_ssl_client_context *cc) { br_ssl_client_zero(cc); - // forbid SSL renegociation, as we free the Private Key after handshake + // forbid SSL renegotiation, as we free the Private Key after handshake br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); From 525e55ff6ef86bf608cb19daf66ff50d7affb3a7 Mon Sep 17 00:00:00 2001 From: Mike Harris Date: Tue, 29 Dec 2020 16:01:12 -0800 Subject: [PATCH 055/105] Change the pull pull request template branch to development. This was 'dev', I think it's supposed to be 'development'. This is similar to PR #10297. --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1cb3f42cd..e542181b9 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ **Related issue (if applicable):** fixes # ## Checklist: - - [ ] The pull request is done against the latest dev branch + - [ ] The pull request is done against the latest development branch - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR and the code change compiles without warnings - [ ] The code change is tested and works on Tasmota core ESP8266 V.2.7.4.9 From a328f0e4de4d54bed62703d937911a64e66c2f98 Mon Sep 17 00:00:00 2001 From: Leon Wright Date: Tue, 29 Dec 2020 15:35:43 +0800 Subject: [PATCH 056/105] Only apply mcp230xx_oldoutpincount when USE_MCP230xx_OUTPUT set --- tasmota/xsns_29_mcp230xx.ino | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasmota/xsns_29_mcp230xx.ino b/tasmota/xsns_29_mcp230xx.ino index 6a960968a..27c91773b 100644 --- a/tasmota/xsns_29_mcp230xx.ino +++ b/tasmota/xsns_29_mcp230xx.ino @@ -196,6 +196,7 @@ void MCP230xx_ApplySettings(void) I2cWrite8(USE_MCP230xx_ADDR, MCP230xx_GPIO+mcp230xx_port, reg_portpins); #endif // USE_MCP230xx_OUTPUT } +#ifdef USE_MCP230xx_OUTPUT TasmotaGlobal.devices_present -= mcp230xx_oldoutpincount; mcp230xx_oldoutpincount = 0; for (uint32_t idx=0;idx Date: Wed, 30 Dec 2020 12:52:16 +0000 Subject: [PATCH 057/105] Allow up to 20s for an XHR request to succeed - only cancel & retry after that. Move refresh timer inside successful response. Applied to main menu and Console menu. Fixes times when commands are issued from Web Console, but get the XHR gets cancelled after the default 2.345s webrefresh time. --- tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h | 67 ++++++------- .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 42 ++++---- .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 54 +++++------ .../html_uncompressed/HTTP_SCRIPT_CONSOL.h | 97 ++++++++++--------- .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 16 +-- .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 27 +++--- 6 files changed, 156 insertions(+), 147 deletions(-) diff --git a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h index 91e1fab76..9138c4e8a 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h @@ -2,38 +2,39 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_CONSOL_SIZE = 853; -const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x82\x30\x2F\x83\xAD\xCE\x41\x1D" - "\xD1\x87\x78\xF6\x99\xDF\xD0\x67\x56\x1F\x0F\xB3\xEC\xEA\xA3\xC0\x61\x3B\xF9\x56" - "\x8D\x78\x2E\x8E\xE8\x54\x77\x8F\x14\x7C\x63\x8E\xE9\xF7\x47\x21\xF6\x77\x8F\x05" - "\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7\x74\xFB\x0C\xE4\x3E\xCE" - "\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0\x78\x23\x21\x65\xF2\xD2" - "\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3\xC0\x21\x45\x3E\x1F\x67" - "\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD\x2A\x01\xF1\xEE\x3E\x02" - "\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE\x3D\xBA\x60\xEE\x9B\x0F" - "\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD\x3B\xC7\x83\xDC\x6C\x3E" - "\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F\xD4\x77\x4E\xF1\xE0\xD8" - "\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08\x7C\x28\x1D\xD0\x41\xCA" - "\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F" - "\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\x03\x69\xD4\x21\xE0\x43\xE1\xB0\xE9\xF7\xE1\x99" - "\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4\x3B\x0E\xF1\xE0\xB4\x43" - "\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44\x92\x7C\x3E\x1C\x67\x78" - "\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13\xE1\xEA\x14\x7E\x02\x2E" - "\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xDE\x1E\x4F\x71\xE0\xD8\x74\xC1\x8F\x8E\xE9\xF6" - "\x43\xC4\xCA\x8F\xB3\xA8\xFB\x0F\xC7\x68\x33\x94\x7C\x3E\xCE\xD9\x68\x87\x6F\x0E" - "\xAA\xF8\xB6\x77\x8F\x06\xC3\xA7\x9F\x08\x77\x4E\xF1\xE0\xF7\x05\x47\xCF\x3A\x04" - "\x4E\x4A\x4E\xA3\xE8\x43\xBC\x78\xFB\xA1\x7F\xE4\x62\xC2\xF3\x3C\x1E\xE1\xF0\x8E" - "\xE8\x47\x78\xF0\x67\x7F\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF0\x23\xF2\xF4\x28\xEE" - "\x9D\xE3\xDA\x08\x7C\xA2\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F\xCE\xE9\xF6" - "\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE2\xDD\x82\x0F\x12\xA3\x81\x13\x97\xB3\xA8" - "\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2\x0C\xFF\x1F" - "\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13\xA6\x7C\x3E" - "\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76\xC3\xE3\xF0" - "\x50\x60\x85\xC4\x31\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E\x04\x2E\x2E" - "\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C\x67\xC3\xE1" - "\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78\x41\xC9\x67" - "\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28\x33\xA0\xCC" - "\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x44\x01\x0B\x1C\x3B\xC7\x50\x7C\x7C" - "\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; +const size_t HTTP_SCRIPT_CONSOL_SIZE = 913; +const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x3D\xA1\x3A\x5E\xE3\xE1\xC6\x75\x16\x88\x7C\x38\xCE\xA2\x31\x47\x83\x02\xF8\x3A" + "\xDC\xE4\x11\xDD\x18\x77\x8F\x68\x4E\x90\x67\x56\x1F\x0F\xB3\xEC\xF0\x18\x4E\xFE" + "\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE0\x49\x9A\x62\x8E\xF1\xE2\x8F\x8C\x71\xDD\x3E" + "\xE8\xE4\x3E\xCE\xF1\xE0\xB4\xC1\xDD\x18\x7C\x3E\x1C\x87\x78\xF6\x90\x67\xC6\x38" + "\xEE\x9F\x61\x9C\x87\xD9\xDE\x3C\x16\x1F\x0F\xB3\xF4\x19\xC8\x7C\x3E\xCE\xD9\x3E" + "\x0F\x04\x64\x2C\xBE\x5A\x41\xE0\xD1\x99\xCF\xA8\xEE\x86\x74\x33\xB0\x85\xB3\xBC" + "\x78\x04\x28\xA7\xC3\xEC\xFB\x3C\x51\xD3\xC1\xFF\x02\x08\xAB\x06\x1F\x0E\x22\x37" + "\xA0\x1E\x3D\xC7\xC0\x46\xA2\x78\x3D\xDA\x60\xEE\x82\x34\xC3\xF0\xF9\xEE\x3B\xC7" + "\xB7\x4C\x1D\xD3\x61\xFC\x3E\x70\xB0\x82\x3B\xC7\xB4\xD8\x74\xB1\xD9\xFA\x3B\xA7" + "\x78\xF0\x7B\x8D\x87\xCE\x63\xE8\x8D\x84\x34\x82\x21\x55\x43\x0B\xEC\xD4\x2D\xFA" + "\x8E\xE9\xDE\x3C\x1B\x0E\x99\xDF\x76\x21\x97\xAA\xE9\x86\x2A\x2B\xF8\x79\x9F\x01" + "\x0F\x85\xF3\xBA\x08\x39\x51\xD3\xEE\xC4\x32\x2F\x55\xD3\x3E\x1F\x0E\x61\xFA\x3F" + "\x44\x6C\x3A\x7A\xAE\x85\xF8\xF8\x7C\x39\x4D\x90\x20\xF0\xFE\x6D\x3A\x84\x3C\x08" + "\x7C\x36\x1D\x3E\xFC\x33\x3B\xCC\xA9\x9B\x28\xE9\xE1\x81\x6D\x1D\xD3\xB0\xF7\x1C" + "\x87\x61\xDE\x3C\x16\x88\x7C\x10\xE9\xE1\x5A\x62\x8E\xE9\xDE\x3C\x69\x83\xBA\x08" + "\x92\x4F\x87\xC3\x8C\xEF\x1E\xD2\xA0\x45\xE1\x44\xF7\x1B\x41\x27\x05\x36\x9D\x02" + "\x7C\x3D\x42\x8F\xC0\x45\xC0\xCE\xD9\xF0\xDA\x78\x3D\xC0\xB9\xC3\xC8\x26\x71\xF4" + "\x15\x1F\x3C\xE8\x11\x39\x1D\x3A\x8F\xA1\x0E\xF1\xE0\xF7\x1E\xE3\xC1\xB0\xE9\x83" + "\x1F\x1D\xD3\xEC\x87\x89\x95\x1F\x67\x51\xF6\x1F\x8E\xD0\x67\x28\xF8\x7D\x9D\xB2" + "\xD1\x0E\xDE\x1D\x55\xF1\x6C\xEF\x1E\x0D\x87\x4F\x3E\x10\xEE\x9D\xE3\xC1\x80\x4A" + "\xC7\x4E\x53\x6D\x9D\xE3\xC1\xEE\x2F\xBA\x17\xFE\x46\x2C\x2F\x33\xC1\xEE\x1F\x08" + "\xEE\x84\x77\x8F\x01\x3A\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF1\xF0\xE3\x20\x45\xE6" + "\xC4\x51\xDD\x3B\xC7\xB4\x10\xF9\x6D\x3A\x58\x82\x13\x33\x7D\x44\x16\xFA\x9F\x3F" + "\x9D\xD3\xEC\xD1\x99\x09\x83\xFC\x7D\x9D\x40\x89\xC6\xFB\x04\x1E\x2F\x47\x02\x27" + "\x34\x67\x50\x67\xC6\x74\x34\x66\x44\x1E\x08\xCF\x1A\x60\xEE\x9C\xBF\x9F\x0F\x84" + "\x19\xFE\x3F\xC7\x31\x9F\x0F\x84\x19\xDE\x3D\xA3\x8E\x96\x2E\xB0\x3C\x1A\x30\x27" + "\x4C\xF8\x7D\xE1\x83\x07\xD9\xE0\xF7\x1C\xBF\x9F\x0F\x84\x19\xDA\x3B\xA7\x6C\xED" + "\x87\xC7\xE0\xA0\xC1\x0B\x8A\xE3\xF4\x7E\x8E\xE8\x7C\x7C\x04\x49\x67\x78\xEA\x1C" + "\x08\x5C\x71\x0A\x0C\xF7\x83\xE3\xAC\xE4\x3D\xF3\xFC\x7F\x8F\xB3\xEC\xEF\x1E\x78" + "\xCF\x87\xC2\x0C\xED\x1D\xD3\x8C\xFC\x3A\xCE\xB2\x0F\x81\x07\x10\x38\xC8\x14\xF0" + "\x83\x92\xCF\x87\xC2\x0C\xFD\x1F\xA3\xBA\x08\x99\x89\xF8\x72\x23\xF4\x7E\x88\x50" + "\x67\x41\x98\x30\xEE\x9D\xE3\xA8\x50\x67\x41\x7C\x08\x3C\x9C\x02\x16\x38\x77\x8E" + "\xA0\xF8\xF8\x71\x9D\xE3\xDC\x77\x8F\x07\xB8\x87\xC2\x3B\xA2\x8E\xF1\xE0\xF7\x1B"; #define HTTP_SCRIPT_CONSOL Decompress(HTTP_SCRIPT_CONSOL_COMPRESSED,HTTP_SCRIPT_CONSOL_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h index 2f61ce116..d7a530b43 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -2,26 +2,26 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_ROOT_SIZE = 524; -const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x69\x9D\xFD\x59\xF0\xFB\x3E\xCF\x1A" - "\x60\xEE\x85\x67\x4B\xF8\xF0\xB1\xAF\xAB\xC7\x40\x9F\x0F\x50\xA3\xE1\xF0\xE4\x3B" - "\xC7\xB4\xAC\xF8\x30\xF0\x18\x4E\xFE\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE3\xC1\xEE" - "\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE" - "\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3" - "\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xDA" - "\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F" - "\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x80\x7F\x1F\x0D\x87" - "\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B" - "\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C" - "\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2" - "\x85\x02\x4D\x71\xA0\x83\x5C\xEC\xA1\x47\xE1\xE9\x42\x02\x4E\x4E\x72\x99\x0C\x36" - "\x1E\x07\xC5\x6D\x33\xAF\xC3\x2C\x36\x79\xF6\x0F\xFE\xC6\x02\x56\x72\xC1\x0F\x1E" - "\x10\xFC\x3D\x0E\xCA\xF8\x24\xD9\x0C\xF7\x1D\x83\xC7\x51\xEC\x3E\x8F\xA3\xEC\xFC" - "\x3D\x04\xD3\x30\x43\xCE\xE9\x9B\x28\xEB\xB0\xB4\x7B\x8F\x30\xDF\x53\xF9\xE0\xC6" - "\x75\x1D\x63\xEF\x47\x85\x51\xE6\x7B\x0E\xF1\xE1\x8E\x3B\xA7\xD8\x47\x21\xF6\x77" - "\x8E\x85\xBD\xCF\xE4\x28\xA8\x86\x90\x47\xCF\x1E\x0F\x71\xEE\x3C\x1B\x0E\x98\x31" - "\xF1\xDD\x3E\xC8\x78\x99\x51\xF6\x75\x1F\x67\x43\xB4\x34\xF8\x72\x1F\x67\x6C\xAC" - "\xEA\xAF\x8B\x67\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x02\xA3\xE7\x9D\x02\x27" - "\x23\x96\x75\x1F\x42\x1D\xE3\xC1\xEE"; +const size_t HTTP_SCRIPT_ROOT_SIZE = 574; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x3D\xA1\x3A\x46\x28\xF0\x60\x5F\x07\x5B\x9C\x82\xB3\xBA\x30\xEF\x1E\xDB\x3E\x0C" + "\x3F\xC7\xF8\xFB\x3E\xCF\x01\x84\xEF\xE5\x5A\x35\xE0\xBA\x3B\xA6\x28\xEF\x02\x4C" + "\xD0\xA8\xEF\x1E\x34\xC1\xDD\x36\x1F\xC3\xE7\x0B\x08\x23\xBC\x7B\x4D\x87\x4B\x1D" + "\x9F\xA3\xBA\x77\x8F\x71\xB0\xF9\xCC\x7D\x11\xB0\x86\x90\x44\x2A\x2B\xA8\x61\x7D" + "\x9A\x85\xBF\x51\xDD\x3B\xC7\x83\x61\xD3\x3B\xEE\xC4\x32\xF5\x5D\x30\xC5\x5F\x0F" + "\x33\xE0\x21\xEA\xE7\x74\xEF\x1E\xDD\x30\x77\x4D\x87\x4F\xBB\x10\xC8\xBD\x57\x4C" + "\xF8\x7C\x39\x87\xE8\xFD\x11\xB0\xE9\xEA\xBA\x17\xE3\xE1\xF0\xE5\x36\x77\x8F\x69" + "\x19\xDF\xD7\x8F\x86\xC3\xA7\xDF\x86\x67\x79\x95\x33\x65\x1D\x3E\xC6\x05\x61\xB3" + "\xBA\x76\x1E\xDA\x3D\xC7\x60\xF1\xD4\x7B\x0F\x4A\xB1\xC1\x35\xEA\x32\x09\x9F\x0F" + "\xB1\xFD\x12\x85\x1E\x67\x23\x67\xD1\xF4\x7D\x9F\x87\xB0\xEF\x10\x23\x61\x5E\x04" + "\x2C\x2B\xE7\xE1\xE9\x42\x81\x26\xB8\xD0\x41\xAE\x76\x50\xA3\xF0\xF4\xA1\x01\x27" + "\x27\x39\x4C\x86\x1B\x0F\x03\xE2\xB6\x99\xD7\xE1\x96\x1B\x3C\xFB\x07\xFF\x63\x01" + "\x2B\x39\x60\x87\x8F\x08\x7E\x1E\x87\x65\x7C\x12\x6C\x86\x7B\x8E\xC1\xE3\xA8\xF6" + "\x1F\x47\xD1\xF6\x7E\x1E\x82\x69\x98\x21\xE7\x74\xCD\x94\x75\xD8\x5A\x3D\xC7\x98" + "\x6F\xA9\xFC\xF0\x63\x3A\x8E\xB1\xF7\xA3\xC2\xA8\xF3\x3D\x87\x78\xF0\xC7\x1D\xD3" + "\xEC\x23\x90\xFB\x3B\xC7\x42\xDE\xE7\xF2\x14\x54\x43\x48\x23\xE7\x81\x7B\x90\x10" + "\xA8\xF9\xE7\x40\x89\x3A\xCE\xA3\xE8\x43\xBC\x78\x3D\xC7\xB8\xF0\x6C\x3A\x60\xC7" + "\xC7\x74\xFB\x21\xE2\x65\x47\xD9\xD4\x7D\x9D\x0E\xD0\xD3\xE1\xC8\x7D\x9D\xB2\xB3" + "\xAA\xBE\x2D\x9D\xE3\xC1\xB0\xE9\xE7\xC2\x1D\xD3\xBC\x78\x30\x09\x78\xD1\xCA\x6D" + "\xB3\xBC\x78\x3D\xC7\xB8"; #define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h index bb52fbbcd..1481a609c 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -2,32 +2,32 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_ROOT_SIZE = 744; -const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x78\x23\x02\xF8\x3A\xDC\xE4\x15\x9D\xD1\x87\x78" - "\xF6\x99\xDF\xD5\x9F\x0F\xB3\xEC\xF1\xA6\x0E\xE8\x56\x74\xBF\x8F\x0B\x1A\xFA\xBC" - "\x74\x09\xF0\xF5\x0A\x3E\x1F\x0E\x43\xBC\x7B\x4A\xCF\x83\x0F\x01\x84\xEF\xE5\x5A" - "\x35\xE0\xBA\x3B\xA1\x51\xDE\x3C\x1E\xED\x30\x77\x4D\x87\xF0\xF9\xC2\xC2\x08\xEF" - "\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36\x10\xD2" - "\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8\x86\x5E" - "\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\xA0\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0\xE9\xF7" - "\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC\x7C\x3E" - "\x1C\xA6\xC8\x10\x78\x07\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\xD8" - "\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56\x38\x26\xBD\x46" - "\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0\xF6\x1D\xE2\x04" - "\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE\xCA\x14\x7E\x1E" - "\x94\x20\x24\xE4\xE7\x29\x90\xC3\x61\xE0\x7C\x56\xD3\x3A\xFC\x32\xC3\x67\x9F\x60" - "\xFF\xEC\x60\x25\x67\x2C\x10\xF1\xE1\x0F\xC3\xD0\xEC\xAF\x82\x4D\x90\xCF\x71\xD8" - "\x3C\x75\x1E\xC3\xE8\xFA\x3E\xCF\xC3\xD0\x4D\x33\x04\x3C\xEE\x99\xB2\x8E\xBB\x0B" - "\x47\xB8\xF3\x0D\xF5\x3F\x9E\x0C\x67\x51\xD6\x3E\xF4\x78\x55\x1E\x67\xB0\xEF\x1E" - "\x18\xE3\xBA\x7D\x84\x72\x1F\x67\x78\xE8\x5B\xDC\xFE\x42\x8A\x88\x69\x04\x7C\xF1" - "\xE0\xF7\x1E\xE3\xC6\x98\x47\x77\xE6\x3C\x28\xEF\x23\xDA\x6C\x3A\x60\xC7\xC7\x74" - "\xFB\x21\xE2\x65\x47\xD9\xD4\x7D\x9D\x0E\xD0\xD3\xE1\xC8\x7D\x9D\xB2\xB3\xAA\xBE" - "\x2D\x9D\xE3\xC1\xB0\xE9\xE7\xC2\x1D\xD3\xBC\x78\x0A\x8F\x9E\x74\x08\x9C\x93\xD9" - "\xD4\x7D\x08\x77\x8F\x07\xB8\xF7\x02\x27\x2E\x9E\x66\x76\x77\x46\x5F\xCE\xAD\x33" - "\xBF\x9D\xE3\xDA\x15\x9D\xD3\xEC\xFD\x78\xCC\xF8\x7D\x9D\xBD\x33\xBF\x9D\xB3\xEC" - "\xFD\x9F\x67\x6C\x65\xFC\xEF\x1E\x01\x1B\x0D\xD0\x48\xC3\x41\x0B\x9C\x40\x53\xC5" - "\x3E\x63\xC2\x8F\x87\x19\x02\x36\x36\x33\xE7\x74\xC1\xDE\x3D\xBA\x61\x1D\xD3\x07" - "\x79\x1E\xD0\x50\xDE\x81\x0B\x2F\x3D\xC9\x85\xE6\x8F\x68\x26\x73\xD0\x08\x79\x81" - "\xEE"; +const size_t HTTP_SCRIPT_ROOT_SIZE = 844; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x09\xD2\xF9\x8F\x0A\x3E\x1C\x87\x51\x18\xA3\xC1\x81\x7C\x1D\x6E\x72\x0A\xCE\xE8" + "\xC3\xBC\x7B\x6C\xF8\x30\xFF\x1F\xE3\xEC\xFB\x3C\x06\x13\xBF\x95\x68\xD7\x82\xE8" + "\xEE\x98\xA3\xBC\x09\x33\x42\xA3\xBC\x78\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E" + "\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D" + "\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65" + "\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xD6\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F" + "\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3" + "\xE1\xCA\x6C\xEF\x1E\xD2\x33\xBF\xAF\x1F\x0D\x87\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66" + "\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63" + "\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F" + "\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2\x85\x02\x4D\x71\xA0\x83\x5C\xEC" + "\xA1\x47\xE1\xE9\x42\x02\x4E\x4E\x72\x99\x0C\x36\x1E\x07\xC5\x6D\x33\xAF\xC3\x2C" + "\x36\x79\xF6\x0F\xFE\xC6\x02\x56\x72\xC1\x0F\x1E\x10\xFC\x3D\x0E\xCA\xF8\x24\xD9" + "\x0C\xF7\x1D\x83\xC7\x51\xEC\x3E\x8F\xA3\xEC\xFC\x3D\x04\xD3\x30\x43\xCE\xE9\x9B" + "\x28\xEB\xB0\xB4\x7B\x8F\x30\xDF\x53\xF9\xE0\xC6\x75\x1D\x63\xEF\x47\x85\x51\xE6" + "\x7B\x0E\xF1\xE1\x8E\x3B\xA7\xD8\x47\x21\xF6\x77\x8E\x85\xBD\xCF\xE4\x28\xA8\x86" + "\x90\x47\xCF\x03\x01\xE4\x0B\xE6\x3C\x28\xEF\x1E\xD0\xA8\xF9\xE7\x40\x89\x5E\xCE" + "\xA3\xE8\x43\xBC\x78\x3D\xC7\xB8\xF7\x02\x2D\xE3\x61\xD3\x06\x3E\x3B\xA7\xD9\x0F" + "\x13\x2A\x2B\x3E\xCE\xA3\xEC\xE8\x76\x86\x9F\x0E\x43\xEC\xED\x95\x9D\x55\xF1\x6C" + "\xEF\x1E\x0D\x87\x4F\x3E\x10\xEE\x9D\xE3\xC1\x80\x4B\xC9\x0E\x53\x6D\x9D\xE3\xC1" + "\xEE\x3D\xC4\x08\x9C\xD3\x79\x99\xD9\xDD\x19\x7F\x3A\xB4\xCE\xFE\x77\x8F\x68\x56" + "\x77\x4F\xB3\xF5\xE3\x33\xE1\xF6\x76\xF4\xCE\xFE\x76\xCF\xB3\xF6\x7D\x9D\xB1\x97" + "\xF3\xBC\x78\x04\x6C\x37\x41\x23\x0D\x04\x1E\x7E\x4F\x2A\x01\xA7\x8A\x7C\xC7\x85" + "\x1F\x0E\x32\x04\x6C\x6C\x67\xCE\xE9\x83\xBC\x7B\x74\xC1\xDD\x30\x77\x8F\x68\x26" + "\x70\xBA\x09\x9C\x3F\x82\x87\x0C\xA0\x85\xA7\x9E\xE6\x17\x98\x2F\x64\x2A\x01\x87" + "\xAF\x9E\xE3"; #define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h index 51cfb66a3..0351e828e 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h @@ -1,49 +1,54 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = - "var sn=0,id=0;" // Scroll position, Get most of weblog initially - "function l(p){" // Console log and command service - "var c,o='',t;" - "clearTimeout(lt);" - "t=eb('t1');" - "if(p==1){" - "c=eb('c1');" // Console command id - "o='&c1='+encodeURIComponent(c.value);" - "c.value='';" - "t.scrollTop=99999;" - "sn=t.scrollTop;" + "{" + "let sn=0,id=0,ft;" // Scroll position, Get most of weblog initially + "function l(p){" // Console log and command service + "let c,o='';" + "clearTimeout(lt);" + "clearTimeout(ft);" + "t=eb('t1');" + "if(p==1){" + "c=eb('c1');" // Console command id + "o='&c1='+encodeURIComponent(c.value);" + "c.value='';" + "t.scrollTop=99999;" + "sn=t.scrollTop;" + "}" + "if(t.scrollTop>=sn){" // User scrolled back so no updates + "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) + "x=new XMLHttpRequest();" + "x.onreadystatechange=function(){" + "if(x.readyState==4&&x.status==200){" + "let z,d;" + "d=x.responseText.split(/}1/);" // Field separator + "id=d.shift();" + "if(d.shift()==0){t.value='';}" + "z=d.shift();" + "if(z.length>0){t.value+=z;}" + "t.scrollTop=99999;" + "sn=t.scrollTop;" + "clearTimeout(ft);" + "lt=setTimeout(l,%d);" // webrefresh timer.... + "}" + "};" + "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) + "x.send();" + "ft=setTimeout(l,20000);" // fail timeout, triggered 20s after asking for XHR + "}" + "return false;" "}" - "if(t.scrollTop>=sn){" // User scrolled back so no updates - "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) - "x=new XMLHttpRequest();" - "x.onreadystatechange=function(){" - "if(x.readyState==4&&x.status==200){" - "var z,d;" - "d=x.responseText.split(/}1/);" // Field separator - "id=d.shift();" - "if(d.shift()==0){t.value='';}" - "z=d.shift();" - "if(z.length>0){t.value+=z;}" - "t.scrollTop=99999;" - "sn=t.scrollTop;" - "}" - "};" - "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) - "x.send();" - "}" - "lt=setTimeout(l,%d);" - "return false;" - "}" - "wl(l);" // Load initial console text + "wl(l);" // Load initial console text - // Console command history - "var hc=[],cn=0;" // hc = History commands, cn = Number of history being shown - "function h(){" -// "if(!(navigator.maxTouchPoints||'ontouchstart'in document.documentElement)){eb('c1').autocomplete='off';}" // No touch so stop browser autocomplete - "eb('c1').addEventListener('keydown',function(e){" - "var b=eb('c1'),c=e.keyCode;" // c1 = Console command id - "if(38==c||40==c){b.autocomplete='off';}" // ArrowUp or ArrowDown must be a keyboard so stop browser autocomplete - "38==c?(++cn>hc.length&&(cn=hc.length),b.value=hc[cn-1]||''):" // ArrowUp - "40==c?(0>--cn&&(cn=0),b.value=hc[cn-1]||''):" // ArrowDown - "13==c&&(hc.length>19&&hc.pop(),hc.unshift(b.value),cn=0)" // Enter, 19 = Max number -1 of commands in history - "});" - "}" - "wl(h);"; // Add console command key eventlistener after name has been synced with id (= wl(jd)) + // Console command history + "let hc=[],cn=0;" // hc = History commands, cn = Number of history being shown + "function h(){" + // "if(!(navigator.maxTouchPoints||'ontouchstart'in document.documentElement)){eb('c1').autocomplete='off';}" // No touch so stop browser autocomplete + "eb('c1').addEventListener('keydown',function(e){" + "let b=eb('c1'),c=e.keyCode;" // c1 = Console command id + "if(38==c||40==c){b.autocomplete='off';}" // ArrowUp or ArrowDown must be a keyboard so stop browser autocomplete + "38==c?(++cn>hc.length&&(cn=hc.length),b.value=hc[cn-1]||''):" // ArrowUp + "40==c?(0>--cn&&(cn=0),b.value=hc[cn-1]||''):" // ArrowDown + "13==c&&(hc.length>19&&hc.pop(),hc.unshift(b.value),cn=0)" // Enter, 19 = Max number -1 of commands in history + "});" + "}" + "wl(h);" // Add console command key eventlistener after name has been synced with id (= wl(jd)) + "}"; diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h index 729bb54a5..dd2cdc796 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -1,11 +1,9 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = + "{let ft;" "function la(p){" - "var a='';" - "if(la.arguments.length==1){" - "a=p;" - "clearTimeout(lt);" - "}" - "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) + "a=p||'';" + "clearTimeout(ft);clearTimeout(lt);" + "if(x!=null){x.abort()}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" "if(x.readyState==4&&x.status==200){" @@ -16,9 +14,11 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = ".replace(/{e}/g,\"\")" ".replace(/{c}/g,\"%%'>
hasArg("m") "x.send();" - "lt=setTimeout(la,%d);" // Settings.web_refresh - "}"; + "ft=setTimeout(la,20000);" // 20s failure timeout + "}}"; diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h index 2d76a8c91..ddb5e6941 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -1,11 +1,8 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = - "var rfsh=1;" + "let rfsh=1,ft;" "function la(p){" - "var a='';" - "if(la.arguments.length==1){" - "a=p;" - "clearTimeout(lt);" - "}" + "a=p||'';" + "clearTimeout(ft);clearTimeout(lt);" "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" @@ -17,12 +14,16 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = ".replace(/{e}/g,\"\")" ".replace(/{c}/g,\"%%'>
hasArg("m") "x.send();" - "lt=setTimeout(la,%d);" // Settings.web_refresh + "ft=setTimeout(la,20000);" // 20s failure timeout "}" "}" "function seva(par,ivar){" @@ -34,11 +35,13 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "rfsh=0;" "}" "function pr(f){" - "if (f) {" + "if(f){" + "clearTimeout(lt);clearTimeout(ft);" "lt=setTimeout(la,%d);" "rfsh=1;" - "} else {" - "clearTimeout(lt);" + "}else{" + "clearTimeout(lt);clearTimeout(ft);" "rfsh=0;" "}" - "}"; + "}" + ; From ebbfc900e11b00577b582dbae6b68594885c6fee Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:27:04 +0100 Subject: [PATCH 058/105] Create Odroid_flash.bat --- tools/Esptool/odroid_go/Odroid_flash.bat | 1 + 1 file changed, 1 insertion(+) create mode 100644 tools/Esptool/odroid_go/Odroid_flash.bat diff --git a/tools/Esptool/odroid_go/Odroid_flash.bat b/tools/Esptool/odroid_go/Odroid_flash.bat new file mode 100644 index 000000000..eb1f160b3 --- /dev/null +++ b/tools/Esptool/odroid_go/Odroid_flash.bat @@ -0,0 +1 @@ +esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions_ffat_12M.bin 0xe000 boot_app0.bin 0x10000 tasmota32.bin From 8f40741feb7f293c0b8dcc1154b1c094a56b1d11 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:28:28 +0100 Subject: [PATCH 059/105] Add files via upload --- tools/Esptool/odroid_go/boot_app0.bin | Bin 0 -> 8192 bytes tools/Esptool/odroid_go/bootloader_dout_40m.bin | Bin 0 -> 17072 bytes tools/Esptool/odroid_go/partitions_ffat_12M.bin | Bin 0 -> 3072 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/Esptool/odroid_go/boot_app0.bin create mode 100644 tools/Esptool/odroid_go/bootloader_dout_40m.bin create mode 100644 tools/Esptool/odroid_go/partitions_ffat_12M.bin diff --git a/tools/Esptool/odroid_go/boot_app0.bin b/tools/Esptool/odroid_go/boot_app0.bin new file mode 100644 index 0000000000000000000000000000000000000000..13562cabb9648287fdf70d2a22789fdf1e4156b4 GIT binary patch literal 8192 zcmeI#u?+wq2n0Z!&B7Ip%ZdwNPjZydJlFk*h+E9ra}_6R0t5&UAV7cs0RjXF5FkLH gk-)3}W&dyVhNuJx5FkK+009C72oNAZfWSu}0Te{nn*aa+ literal 0 HcmV?d00001 diff --git a/tools/Esptool/odroid_go/bootloader_dout_40m.bin b/tools/Esptool/odroid_go/bootloader_dout_40m.bin new file mode 100644 index 0000000000000000000000000000000000000000..267abf3dac6673a45831d387e0c66b6b754d62cb GIT binary patch literal 17072 zcmd73eOy%4_AtKBnPE809CHSc6!3OtbYM`(;YC5y%RpSz^xivBqM4hv-etit-aS?d+ql%->6kwi-xiNK(6_tCK54Q4JZ-*;vpT4fc(cp(aoSXsPj)5=ZdMH|bxx$`&~bgWwgS!71(`uiO-Hf~*&4|HA9GUHt|^(Zdj0(y)~|D{E8jGuc>VhFvh_v4w{p|w z4I9>PET6Gyu+IqO!lHEZiQEzn#g64p&_E-G8SxvZ!hXiJMWm6G3W-QZX~ z1`$$Pv~EqAgEP+K{;*{6;{U6<+EiL3sftLAE_1Bo%v=UHZyslbc5NtHv$FWXa>u5t zkkFNDHm$^FLF>$1?&3e*ylCapKNjTOhFr6(GcpMIpJ}XwhqC|w{9UDQkUwqatd%98 zcThC^{d*p^4Dg#vN*o*ipV0Y6=>GNhgW9i>wPbBs*-AMB?67S8mepnVtz7-!>M~IN zTrNE=b5`d6K|9&BeziOZXKXBAy|R4m{SL_}5Rl|3DqFdBUAbf9x}q|v-}rD_c_Jb4 z*8c2h2=N@m5LoZ!>{agmZ1HhXBzl-feip?w022;u9^%^}EQ7ED!iMuh*)gk*5yBF( ztcuv!XNm38XNZll_GfbtUdzK*+IfXg9V2 z+P(NKO#hUf2l*>dUgGzQ*lhCi8={y75`(_$K(|0&;SaNIpv3H6Xd@4?8sbJP@IY`w zcmhH@;3h)Y03jKI9YQ_eX%00i5;c@#2i{c}Kn}o-C#3%kkkJp7wtpZH+XxB(_VK`r z;Wofgt#(4b`%V-qJ_)lmLWuuIm`xA1LLjsoHMRi60qAcv#L0+YN&qS*@E`tqJ zM~1PcDrf_nCd5h=GJMU{5{p%sh)@gTxn6X)>OC={dl#10AeZKe0$9JwWZ;qzn*_y{ zEU*eXg-0v#MEr_J^Y1*%tU@Rx*Aon3JtLuO>lp<2+IoQD9776YuV=@d7{}hp9u$TV zAwhBMLqb4;SQgX2jO9#cw+lZhIhg)&EN2nhDtxEpVEUV}oSWEP!k0=8rq5$~??;ln zI^k4^2YKHIsUkA-)D>tI@Kt`5Le-PebTQ*LYT|f$_p> zt0=rCDlStA-*?$3q8Qc9);a zI?uVf{r-M3#lYt|xn6GmVZ-rv=O3o`AJ*txKuL)6SctS5_-P!g&EE=eZw4D@JJjtS zw)OtKJ>3sgwx8^0V>MFQEXY(L3-Dl0Lnu!0ii zIo(UR%-5n0F4;em&YY>y-;Z-ovnA+H#$GyS$!E`{NCp6AjfCD<;Xyv^y}21^u_=gLP}Bt3wZOkB?_vUDGv zp8+eI?bGdPUh2u2w0922M(#gMu{1Y@3-V+=hE~@ zEZ5|l-$5^p(xfmjAZVhqu-YCR94Xp)S~NklU3T#ix@nInycdLdCk4=e!?j~PDI6kc zrtmhpIVirklVKx)gQX{5!Z53d#GIzuXme0(${|hNT=NJdC^r5GBCnImsrZ*vR^J@P z>D9n&QerVWy%YIX&gor+Ump)&77=|57?=|Gpa4(@jweqLMz)0(UJAn4F}BK(XLrzD zr#J3KsD<|K2|L$na6hs6QiB0zbN+E0lL=W730t)Z6LpfHCJ;6a0!l8mwT@<;^f=yS z0MgzpRt57z#m{;J*B1~?^mT~`sfwRdR7eamxab5%XDLod)0X7wu!ymM?av`LTRA(C z)jqA|>MO0=cS4CT*5^1?OkymB1jt!LW>aif{v>E0 z=kTUFg4S7jVNKA*R7YjAT1bITAzm%TH!QyHtg7qoAggQB2`dp*dmJ+F#uU~|h)@`u z4YnfOfhg-Nf6;Bhd(%s)Ra?ASs@dUjOKfR5e-6u>xl^(M=y)#?79lAnZo!1@E$)a4 zOlBRGqJ?tiBd(2h{4AnnNqWt>Ihd;^g&CTh++b!#QBGFSmaFIZ{_W|)Z-d*@t=7xH zHw*b7o{4c#1#+vqvShha5mnm?nO2Di^aAM=DLpYYIq1BZ*i3#%%rQX@=0X5n3g#ea zI%X@4vi?RQ*9w!B*d)afLVU1p0jU@iqJv|57`wfk@cfRmJ6~FC#;W8DJRhXsfn@c&q5HEh) z7J9s|Y3saHHKp2~w_c(t~;tt``synO8yy+#SUp*gVDX?|;XatryNY+FMA4n+1 z^Zp3#y5M`w?(XCmEWC$=^$hGk8<4eu*?U~V=oDB7$WEs2718~ayup;=wlP@nk9gid zmYRsM_`enSh!P*hxHCdHGy+qlOnN{;bzVWeuAp8ULkasN6vHlbKP5{i)$Z9d;y$FW zYa*lAu9qY_7B>q|>De9aa$8uSKEryNN8D%i_xA7xh^7nd`cq9PyvkcQ+GdCw`qwxDyCvM!_QyG8Gp`S%Kmhb5*&= z81KtSt8CfZ4u(fR}!8!s{*$H*WY5gtF2`LD`RQZ~S z6PC#rCQtP8ybS$deL2V6B^Dkewhy>u_6XgkG9Q#?g;@gm>(6Qs3a7VHb+?!6@QQjL zC&XikX>U@nLQI)m)JB;FarXnM6Hs^;%s~#8%~z4|(r|W?yVvUXm-9kS;e}8q4U~hT zGsH=gA z+v47Fz$w#ktbxuuRK-iz$gRU&J%I`M3z09Tc&? zy+y;m>fye}#Ch77dzljy8`sxJ3bjm6EXdQo-LSo~j-hK8CQQ1eX9B5XRJC^`yfeNh zjF9??E=z-{CQSn(O6lC10?jy5p=&>&FFBO#c4tg)0Kq$f>_Ae@Y^Nz9&gCplkopPA zDQtjcfO1;s2D&CPuGK|VPjk1a`f5dKzcadic9D6sg^o!JhYg;}aT*M-@DmLiAqc~; zV75_xWn%5UOksI*x>A>}fF zGuer$8-`)Uo_q;NnwN_ST2p(g!RzBq(}>QLHYLGoIxmj{LQH#}R+3|50+;gpu-m{+ z)?(cB+y!AWCOnzL!W!)421WySMYD?NiZAEyT(DzrQ@0+(kGX~H@b!Hy!rrfWShT$= zE#JUiL=G5ShQ^jQs+lE?b9U^7#NWi))+1^dneT`@e9d2qx;$9>ey{pU{dU~V`EXw- zbDP6t?kq#&bHK!ma=)u^Hy;J=zH?&kTU44UAv5DxM;8OKG`}OuV*Xt0_Q8s}!zbK` z@|*u9f=!fwvP_n=*;JB2!;*>%)jPFWxt0P6hDHZ6vnD`yR__}>J)KK$cTKUR*8pig z9DV5|NLZ*WgEWq%af@@g3ClL#Fw8PF(6iEBq3|?0HF>ye^6-j9zRAOmrHqY>jsaZU zaM#4)6?gh34x0-Z+s2&yIIu&bVYrlDwJIY%Y}FFKed%gr6zbSQ7v_ppVT7yVbH)$b z7I>{rZM#*0mBNStYDS|1SQ(8Ct>G;@-Ad5L|C-#XJ<@_Kwp$9Oi{sKzoD($d+R z08GhnVfY}5h-0HLk~-Bt)HOWR;T3%SL%3sK%*6atm-GG50=13LIOj6Vt>An8AFUwW z-Yt;0v)9i@H!`O#4R!qhOi%c}MyBS4%-)MbusgjZ3ZD(ZhKJ8!2cMjH-Kh&hU0(uO zz3=RhV?NXVyrEeof-S(&2#zz&-;2ighb%PQWYwNN_1RF@CqVj)@AOb}9s?Ot`x7Gj zLGUvOEToMmt{~|uH91#j*mbk;&d~On7RDS3?N-N`UUz;2q;lW<`Vdj@V)X4jFqV(w z$)I*NtHZ6w;X|bj$uu#FcX}rajYqi<>Kb?wo74|Y;|9@cILPnt?dm~>ujslS`HU%5ho(N@9wm^ z{PQCCn|AusxhHqVJsHU$e;eKRzGza%)kYQ^osr? zqtJji46$*J8^qdJ<2oP%+k)W>7ch=lBAo7fTYDyx4lmA6XefY@+YeRVB=6b4iH>{_^9bj8fo3M1qHSwg& zTBB`@@$*mg9`nEDcRo+}-qmdy$1!n{=>$DLtpnEaS<;d(ofp0!&>PMi8?5472L}`D zSy+i-3c$Xq*8pZ&NkjC>4!+JXrlQkaV6FmZQ(ai>*S+P-16F$!(U@ z=|gkUgs`E^&KpvvK{B)R`qZSMIi`6`V&^!x4}!%Kt`n)qHByh($9vSfIF}js`>9?;kOaXjCNae?d>tG zaCn}4srL02gZUS+b{9LL2l@_O#LrJypC67g#0Z+9 z>O_jwtXfqLrtG1H<|mk~%NNFWl)g659elTneqqTOH{7 zo(6gFY!~hTEiAt!-B#lND&{>jD-=jRa~aRUykz`Lnw*ShA(GK#mX8#4hl;%v8~#|h zy{eM8m){}i3P#gT?~gS(kA>T+Dy{eIU; zMOyn&uG7<^cAP}wZ=(y;Ve!n;PP)fVmZ=MlPQ1gzhV_gi-A8F#Z+mf+T68F?ebumHxc_X zKMXl@d#LyL33X=<=&TD%xOZH^)XcOg6x^OwrICWEB-J>WIU%xfzoRYm>AheR;pX>& zu7@Tu)iBn`h8MX$pO~hOi>ahxZb+M&Ij1#Q2WD&zhF~i+6b_qRZIkz0>+`}I)C}0M zN-X?HlVDne{bGXFnA%My6^@7Z#lzaiXqJ|&fiL!EX~K)cANbSY)^He(50npXz22H> zovn#8O`mB?Z_m2fnwFE9_EFpt$*@f7utf77ERzi{_R+96X2a3GD}Dj{1_k%V6cr7Q z$=v)`dBKJb%SEwLG&oL8J`~AENnnDtvev3fw95%K`4YI&hmL;r&HhRbZfXEw|VCL_vkj4Gdpt@Q48{F9Kp=5R=g60gRH}XE9QCKYY3sS3U`gN0C1LsB$t8Kd4G8~K z3jJcNP&*&pyUbotjy7j6Fvcx`n|5HUvv%X@(UYJ1l{7qUtq%EG*e@qRo z4b9((p3?#0xKhorv1*`rP%rA{3lV0&>r0j88g&dJ6fPK7pX;tXzx`2AQ%@SIsqag% zCmHS+fn`W6Jg#$kZ&=zgS9mtS@6-!-2jCgT^C}kaTnmRLly{#jZ;Kj`yCW3Eyzcs{ z;OM!uH@W;sFl{$7^N&)<+>FdM5&z%qfA&9>2kkHL63?!H;6Z+{PvO5LDJ(?pd&l2J zP*2sVD;6M~XuuLAd-6RNaC|IwcxS@uF9-oJROb`|SHm@`(fJ(q548D1QP_&bf|+?{ z2ZTS3*0t%Hx|&bRwZQl>ZVABV=#(gJ9S6liEu4Z(O@y1GPojJq0_KxqYFWUz2H9uR zLNUgYO{K04z|{7hD3l_qo-y7N7=01zgfo|U049;zktA0an%?ND$-G+km_ND%%uSTC$<9z6w5rCda(Z(#-U?uhsIqRFa*YPC<`aTv5 zcd6}b{2NNT*TO0eZ*%tUoDCmy)?P378t>x*%^!*v4?eUct^^i%IH}J19P;fS_#uDV zYraVV*bPD>j$hpfxglWNoIS7bQMC=e4z&=4{mp9b(&R_L;rew$`$oQf9}i2BFb;F> z(tbJzmL1p!^!+H_rR}{puEe%EXUnV)gmBDGfxDT}IwV^qw-HYcqAo=E>IS^8U{CGF*Ia-<2N>(y9kC@qYo-z5k67Z! zRzSgp?PCM7?bJm0-c_W@lcafXOd8M00ijo^Zxzmci3kAiO5l~OE5dhJ;hib*zA?rN zg!NjbC8=1i?&_BKURT&=A)C{CXjB0`uqc!HTgQ1i281@bYFO64E**1@#%1?yl?iabR>@oca6cT=#^=rK5 zI@HN|q{qQHNvRzN?g!Ht9l;w1gnKa$ z4Ck(azB;iM9>1l%1-zM+VTOx_ErZQvFs>b#=JKo^aJ!m#=ZD790nXxti4Vqsu|%db zI)H+u*-3oTPMi`k&r>uY+%1mp8I9A+dYLy0H`Hn;>-2?lKXo{ zP~+X#)MXzyWgqZ9=j_vm3cHE%56I9|EWK!zM6$+32=9hn8}OBwSmT1LU}OFjK-yc$ za>CyJmt5S~!?_jHw@GQf9Q0J!!hHHKAr;wR4$U0klHkH|sx6(erlFm}>y}hcBqvxD zni&es2B0w^O_D-m;)EL%nnZ=h`zspZdWC>f2u@yG(N!`#@UCF0+Y5CD{b0rV?Ge>3#RD+m8Bz^{TZ z5rPI-i5`6mZ2<8Q;NFo~3CXg757|BeE+N5z4E{C%Uj+m)+Yd!kA@mT-I|t=}`=a

%d6q!o_?tm$Z^8S(_XFKtFPuT~cxA^j;KF5C#A0{ReWwEO zNJE)F2p}Kaoi3Ce*RVJV&X?WL>U`AbV(y0#%~X6dIzoXG_zLUP!d#hExJilUDDiA1 z&QfC8J&zG)Dez1s&XD8Dmju~ej}g+8oKz*YD)9^@zEO!&lsH+5r^~UTD{$+BMhnxV zuNkxI8DXkeUGr1(=|O+1K`@E@!KU_he3Ca^rQ;?q5mX4nn{yL9vk**obPurcEHjU3 zpIceiJ?O5jF#xab2`?xxBV zRo(GH_YP$4y^yfoz;-0Y8rai`yP|uLYm}9Zhf_JgF)yR@0nDgutoa+!@zvO!7P@_H z%Sfj*LLzEsR+gzzaLG z9!#}xS9lxccxJ#nnZQEO_nio3e2Qf_{DXZT4zdrkTJxtE#rFMUkX?jLdS`I&dm%u- zIcNr&{~i>2CI2_Z^Df2>j7N6zixA#HUp+w8MD(p6G-n6En)^Nw;ac!VPzK&AD(@u% ziC?_;jS!s6-;-Lwz%f=|@2yJ$4UYGIW4Cg|yVg$N5OIupec6}7>mhJ-x`1e|6wzE! zR0`$k2np?>>I36W?G1J94Xx1m_J;a&lxOcKx;@nOQfNh-@1>AK3lDIi>a=mEUJiA= z5Lz+a_d>`VF^X#mb@@UoZu0p;ec_a^G1S!<^7i^!ov=<(@eV1D6>1b%j$?&t1%3u& zqwG9L3x6GT2c+RG=t;~1jnvbE2k??|XrEispSCOjn<~g`&`K1e*^YnW*+Dz@wgmO? z|22VgQRmtX?HxJ%A+F=ypsz9{RAS+d&Vkxkn3v#j3C>7Dq1-jXk`Rm?;bDYa%)o^x z;UPH*9ux@{?Ft6Z_AAgA#Ob}{DG$MBv3}BSs=-hP_mMe-uQv$mLoF0^C%6+ii-_4v zyx!=O+bPd|fQC16aF*IlnVSKtJ_p#6tFWC0^Q_T1P$@JurW0UIE6FSY+GvNkGwhS2TD4l|7_nd@d1hk8XDvn)W=a zApa4Bq2+Fj2JxJ)Ji?pwAQLQFAIX(VH7A3ck)CDPSoiiytmpu`#hN(Q0v}0NoL}wz zl;ZZP^@pgF?{eI8(biVVe~{z;5^Zmw+IMqYb@T=o<*ny9r`qkJz=Vu11i_iuxDTrt zd)IWVA$<-~xQnoHZ8}`+?||E8xJafPSwz?ugmtZ}BX|lDtxoeJ1J*+Z?{i1Jhq(BH z#GCZVk^4KslTYvOKzGUbCiz7x84gfz$Dbt3_CSSD6+8(}pHLF1VdIjwo1Y=6O^9@< zj6RS?Z=$AfChR1@C8<2Sq`U~@Q*z$aOD0Om!y`I4Q~w1sECOdX+s4=;WIsq3o$3x+ zvn1<9YXkT(fFchyKrLwyF!6~)6L8nWvIFs2K!K$h#BKb(NQN26+z7;hTlmqGz zVvzxM3X_5`+rb-L4e{L<^fo!owXlJ5@FXj>qf6f+cw3$@KS+9G%`b^fUHZP~h^bo? zijdb-N)`uW{%LdocMs-yeg0K9VyBt6HG8 zEl}5WgR?gqc7K?=w9@wI&U=_BAzf}xfsfelKqVKHl9I@1a4Cc|c*qqrUBL_U5D7Or zbAvD&bM9!X5kq@X68kS;n1m#YwyU_NYJNLO?)pTZvL ziVXU6K{#o%WThy-RDpoAhdvw}U66x25~VnRJzr+&WHbXqceKu?r&9gu$mi zO!)hVa={P=PDwg+g~YuPA-Z%}OT!TsM9FIimNfdSsIO&*!Fs0P714eN%)JKi?uL>U zG9{6Q-($O%F{U;VrdCKMF^wwYW#oq8l9&UXga>d8FyF}zkKj|`J;WS~mG+fh zL^G21_q|Hp@BXT+V@g@0NARPV&vDUy6XmYMN~8=6`u5eq-9z-rbc1{6Rrrbqz}sxm zm-4`S`6|5UnUPWcQ5nF+5ZfE!Y_^Twx4@OmOC#_Y(JBkPWowk@1(^u^?qnjkc2dTI z=UFAo3t3W+N8nP_;Z-+zON2&jdGa{ew8MV0M5ssbw09S~SX!z|geMTej$>bz^W6&A zD}%KND)oRbe9U>$?S&au1(z5XrA@d{ft6brPbIW#Y)AmikHMqu1b%qykBQV6C3nAi z+PUYA(S4b5GZq6ox$+TMITphYhfrrVbmQvOJj`*aOnV;TERwCMV0RA_n(PgzGI@E< zg2YLxxzmItvb@GjWXhtUph~$Q<6TMxE3g7*Ga0P`q{B6Nx>O6jn1%^jzAvjBmD@N~ z&cm9n$pk)OGUkEp&PV50uI}nnVm;%0MT7>HM24As1b0U?@8pbnfj%C}EnmN*blcs1bON*24$Ofn;EKR6frLy3)Wc)91s`|M2@1 zD=ZhXN+O!PDnWl$9~ys>U3oaX-G)7FuFp0V;#7x1kBwlDxfmUbk1LSm@8_u5{YFjct@|?ni{-{+c}SHp)~Qp7YbNtwf)52_cx? z^Cz&IZNKx|^Yr#SgDqbYGn}0xe1v=`ZZ?V=j^dg%a0VQcHooW2Vc=nPwJ2_Oe^vPZ zD6E@(`?U8>_OLA5F%+Oc~lOOsTG$#wM{7n|$X`V+%25!_p<3twyyws$oh}y7U~POzd(Usdq`TsrVfe5+<5z z7bIA+s#ua*jo7p)#AO$hz35 zHik`t-%_k#*qcEDc9KQ|^?;P@6ba0y@l1ulId)P5y*qL?xI~WXNywFCVLWSx!Lj(s zdNus)#KduYKaqZoCCtHW{COdaH!eBnO2*xz8FHK8-FgLfg0B$q@T&1LzR&0?dHxCI zB%}3NhG8cp+zJD(gLkHSvs1xyN#{zPf*kNZeZ9oVq%It`&c-{>zOw_%tv&Se&N1rKdjKucJ&?uWH9A$$=4V0%WO5jW< zSD}_@HCL*5XQ&Uabf8@GDKYgJlA-b3G$E!E78|PhE3x^{Vo4NjeoRa=k;3;$hlzfD zx}_z}+=q)$N!0btkBg3nMe_*}+_0NF#3qvpgmx2BGKDr@Mj9v^T|`I!)(C>dwr=h8 hxEBr_KDJl)LCo^Evu{8Auy(%Y{auIVtXf$AzX6zD7<~W$ literal 0 HcmV?d00001 diff --git a/tools/Esptool/odroid_go/partitions_ffat_12M.bin b/tools/Esptool/odroid_go/partitions_ffat_12M.bin new file mode 100644 index 0000000000000000000000000000000000000000..4389fdc62b75f3347aea8a05b5dcfe4effe8a70e GIT binary patch literal 3072 zcmZ1#z{tcffq{V`fPo>etQg2Z1*-xW85kY_#S|DA@=Fp^5=#cs$r04 zNGvEYK#>G;fbxQ1%@BD*OnJse1_pbe@Ii*Ow8Rp0`PZ-iqk#IL9ZU2Uo#PUTtDWo2 m_dy6na+EU~0;3@?8UmvsFd71*Aut*OqaiRF0;3^-Hv|CwXI*0e literal 0 HcmV?d00001 From 0fac4044c3c4145c44dd8b877b0e6d0c5351a445 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:37:14 +0100 Subject: [PATCH 060/105] Odroid-go files --- .github/workflows/Tasmota_build.yml | 2 ++ .github/workflows/Tasmota_build_master.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index fe06a70d2..8bf360bcc 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1560,6 +1560,7 @@ jobs: mkdir -p ./firmware/tasmota/languages mkdir -p ./firmware/tasmota32/languages mkdir -p ./firmware/tasmota32/ESP32_needed_files/ + mkdir -p ./firmware/tasmota32/Odroid_go_needed_files/ [ ! -f ./mv_firmware/tasmota.* ] || mv ./mv_firmware/tasmota.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-sensors.* ] || mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-minimal.* ] || mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ @@ -1581,6 +1582,7 @@ jobs: rm ./firmware/tasmota32/*.gz rm ./firmware/tasmota32/languages/*.gz [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ + [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ [ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index 4169bd028..cdf6ccc99 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -1560,6 +1560,7 @@ jobs: mkdir -p ./firmware/tasmota/languages mkdir -p ./firmware/tasmota32/languages mkdir -p ./firmware/tasmota32/ESP32_needed_files/ + mkdir -p ./firmware/tasmota32/Odroid_go_needed_files/ [ ! -f ./mv_firmware/tasmota.* ] || mv ./mv_firmware/tasmota.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-sensors.* ] || mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ [ ! -f ./mv_firmware/tasmota-minimal.* ] || mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ @@ -1581,6 +1582,7 @@ jobs: rm ./firmware/tasmota32/*.gz rm ./firmware/tasmota32/languages/*.gz [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ + [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ [ ! -f ./FIRMWARE.md ] || mv -f ./RELEASENOTES.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | From 8d9541320a215e77229f67ae0ca9b4d54f335ccf Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:38:35 +0100 Subject: [PATCH 061/105] Delete Odroid_flash.bat --- tools/Esptool/odroid_go/Odroid_flash.bat | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tools/Esptool/odroid_go/Odroid_flash.bat diff --git a/tools/Esptool/odroid_go/Odroid_flash.bat b/tools/Esptool/odroid_go/Odroid_flash.bat deleted file mode 100644 index eb1f160b3..000000000 --- a/tools/Esptool/odroid_go/Odroid_flash.bat +++ /dev/null @@ -1 +0,0 @@ -esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions_ffat_12M.bin 0xe000 boot_app0.bin 0x10000 tasmota32.bin From b83c5abbe957d9e95e83b55bd546dac50e83929e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:38:44 +0100 Subject: [PATCH 062/105] Delete boot_app0.bin --- tools/Esptool/odroid_go/boot_app0.bin | Bin 8192 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/Esptool/odroid_go/boot_app0.bin diff --git a/tools/Esptool/odroid_go/boot_app0.bin b/tools/Esptool/odroid_go/boot_app0.bin deleted file mode 100644 index 13562cabb9648287fdf70d2a22789fdf1e4156b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI#u?+wq2n0Z!&B7Ip%ZdwNPjZydJlFk*h+E9ra}_6R0t5&UAV7cs0RjXF5FkLH gk-)3}W&dyVhNuJx5FkK+009C72oNAZfWSu}0Te{nn*aa+ From 190276f5c7eef13be43c698abf7cbd09eb1b0e4a Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:38:53 +0100 Subject: [PATCH 063/105] Delete bootloader_dout_40m.bin --- tools/Esptool/odroid_go/bootloader_dout_40m.bin | Bin 17072 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/Esptool/odroid_go/bootloader_dout_40m.bin diff --git a/tools/Esptool/odroid_go/bootloader_dout_40m.bin b/tools/Esptool/odroid_go/bootloader_dout_40m.bin deleted file mode 100644 index 267abf3dac6673a45831d387e0c66b6b754d62cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17072 zcmd73eOy%4_AtKBnPE809CHSc6!3OtbYM`(;YC5y%RpSz^xivBqM4hv-etit-aS?d+ql%->6kwi-xiNK(6_tCK54Q4JZ-*;vpT4fc(cp(aoSXsPj)5=ZdMH|bxx$`&~bgWwgS!71(`uiO-Hf~*&4|HA9GUHt|^(Zdj0(y)~|D{E8jGuc>VhFvh_v4w{p|w z4I9>PET6Gyu+IqO!lHEZiQEzn#g64p&_E-G8SxvZ!hXiJMWm6G3W-QZX~ z1`$$Pv~EqAgEP+K{;*{6;{U6<+EiL3sftLAE_1Bo%v=UHZyslbc5NtHv$FWXa>u5t zkkFNDHm$^FLF>$1?&3e*ylCapKNjTOhFr6(GcpMIpJ}XwhqC|w{9UDQkUwqatd%98 zcThC^{d*p^4Dg#vN*o*ipV0Y6=>GNhgW9i>wPbBs*-AMB?67S8mepnVtz7-!>M~IN zTrNE=b5`d6K|9&BeziOZXKXBAy|R4m{SL_}5Rl|3DqFdBUAbf9x}q|v-}rD_c_Jb4 z*8c2h2=N@m5LoZ!>{agmZ1HhXBzl-feip?w022;u9^%^}EQ7ED!iMuh*)gk*5yBF( ztcuv!XNm38XNZll_GfbtUdzK*+IfXg9V2 z+P(NKO#hUf2l*>dUgGzQ*lhCi8={y75`(_$K(|0&;SaNIpv3H6Xd@4?8sbJP@IY`w zcmhH@;3h)Y03jKI9YQ_eX%00i5;c@#2i{c}Kn}o-C#3%kkkJp7wtpZH+XxB(_VK`r z;Wofgt#(4b`%V-qJ_)lmLWuuIm`xA1LLjsoHMRi60qAcv#L0+YN&qS*@E`tqJ zM~1PcDrf_nCd5h=GJMU{5{p%sh)@gTxn6X)>OC={dl#10AeZKe0$9JwWZ;qzn*_y{ zEU*eXg-0v#MEr_J^Y1*%tU@Rx*Aon3JtLuO>lp<2+IoQD9776YuV=@d7{}hp9u$TV zAwhBMLqb4;SQgX2jO9#cw+lZhIhg)&EN2nhDtxEpVEUV}oSWEP!k0=8rq5$~??;ln zI^k4^2YKHIsUkA-)D>tI@Kt`5Le-PebTQ*LYT|f$_p> zt0=rCDlStA-*?$3q8Qc9);a zI?uVf{r-M3#lYt|xn6GmVZ-rv=O3o`AJ*txKuL)6SctS5_-P!g&EE=eZw4D@JJjtS zw)OtKJ>3sgwx8^0V>MFQEXY(L3-Dl0Lnu!0ii zIo(UR%-5n0F4;em&YY>y-;Z-ovnA+H#$GyS$!E`{NCp6AjfCD<;Xyv^y}21^u_=gLP}Bt3wZOkB?_vUDGv zp8+eI?bGdPUh2u2w0922M(#gMu{1Y@3-V+=hE~@ zEZ5|l-$5^p(xfmjAZVhqu-YCR94Xp)S~NklU3T#ix@nInycdLdCk4=e!?j~PDI6kc zrtmhpIVirklVKx)gQX{5!Z53d#GIzuXme0(${|hNT=NJdC^r5GBCnImsrZ*vR^J@P z>D9n&QerVWy%YIX&gor+Ump)&77=|57?=|Gpa4(@jweqLMz)0(UJAn4F}BK(XLrzD zr#J3KsD<|K2|L$na6hs6QiB0zbN+E0lL=W730t)Z6LpfHCJ;6a0!l8mwT@<;^f=yS z0MgzpRt57z#m{;J*B1~?^mT~`sfwRdR7eamxab5%XDLod)0X7wu!ymM?av`LTRA(C z)jqA|>MO0=cS4CT*5^1?OkymB1jt!LW>aif{v>E0 z=kTUFg4S7jVNKA*R7YjAT1bITAzm%TH!QyHtg7qoAggQB2`dp*dmJ+F#uU~|h)@`u z4YnfOfhg-Nf6;Bhd(%s)Ra?ASs@dUjOKfR5e-6u>xl^(M=y)#?79lAnZo!1@E$)a4 zOlBRGqJ?tiBd(2h{4AnnNqWt>Ihd;^g&CTh++b!#QBGFSmaFIZ{_W|)Z-d*@t=7xH zHw*b7o{4c#1#+vqvShha5mnm?nO2Di^aAM=DLpYYIq1BZ*i3#%%rQX@=0X5n3g#ea zI%X@4vi?RQ*9w!B*d)afLVU1p0jU@iqJv|57`wfk@cfRmJ6~FC#;W8DJRhXsfn@c&q5HEh) z7J9s|Y3saHHKp2~w_c(t~;tt``synO8yy+#SUp*gVDX?|;XatryNY+FMA4n+1 z^Zp3#y5M`w?(XCmEWC$=^$hGk8<4eu*?U~V=oDB7$WEs2718~ayup;=wlP@nk9gid zmYRsM_`enSh!P*hxHCdHGy+qlOnN{;bzVWeuAp8ULkasN6vHlbKP5{i)$Z9d;y$FW zYa*lAu9qY_7B>q|>De9aa$8uSKEryNN8D%i_xA7xh^7nd`cq9PyvkcQ+GdCw`qwxDyCvM!_QyG8Gp`S%Kmhb5*&= z81KtSt8CfZ4u(fR}!8!s{*$H*WY5gtF2`LD`RQZ~S z6PC#rCQtP8ybS$deL2V6B^Dkewhy>u_6XgkG9Q#?g;@gm>(6Qs3a7VHb+?!6@QQjL zC&XikX>U@nLQI)m)JB;FarXnM6Hs^;%s~#8%~z4|(r|W?yVvUXm-9kS;e}8q4U~hT zGsH=gA z+v47Fz$w#ktbxuuRK-iz$gRU&J%I`M3z09Tc&? zy+y;m>fye}#Ch77dzljy8`sxJ3bjm6EXdQo-LSo~j-hK8CQQ1eX9B5XRJC^`yfeNh zjF9??E=z-{CQSn(O6lC10?jy5p=&>&FFBO#c4tg)0Kq$f>_Ae@Y^Nz9&gCplkopPA zDQtjcfO1;s2D&CPuGK|VPjk1a`f5dKzcadic9D6sg^o!JhYg;}aT*M-@DmLiAqc~; zV75_xWn%5UOksI*x>A>}fF zGuer$8-`)Uo_q;NnwN_ST2p(g!RzBq(}>QLHYLGoIxmj{LQH#}R+3|50+;gpu-m{+ z)?(cB+y!AWCOnzL!W!)421WySMYD?NiZAEyT(DzrQ@0+(kGX~H@b!Hy!rrfWShT$= zE#JUiL=G5ShQ^jQs+lE?b9U^7#NWi))+1^dneT`@e9d2qx;$9>ey{pU{dU~V`EXw- zbDP6t?kq#&bHK!ma=)u^Hy;J=zH?&kTU44UAv5DxM;8OKG`}OuV*Xt0_Q8s}!zbK` z@|*u9f=!fwvP_n=*;JB2!;*>%)jPFWxt0P6hDHZ6vnD`yR__}>J)KK$cTKUR*8pig z9DV5|NLZ*WgEWq%af@@g3ClL#Fw8PF(6iEBq3|?0HF>ye^6-j9zRAOmrHqY>jsaZU zaM#4)6?gh34x0-Z+s2&yIIu&bVYrlDwJIY%Y}FFKed%gr6zbSQ7v_ppVT7yVbH)$b z7I>{rZM#*0mBNStYDS|1SQ(8Ct>G;@-Ad5L|C-#XJ<@_Kwp$9Oi{sKzoD($d+R z08GhnVfY}5h-0HLk~-Bt)HOWR;T3%SL%3sK%*6atm-GG50=13LIOj6Vt>An8AFUwW z-Yt;0v)9i@H!`O#4R!qhOi%c}MyBS4%-)MbusgjZ3ZD(ZhKJ8!2cMjH-Kh&hU0(uO zz3=RhV?NXVyrEeof-S(&2#zz&-;2ighb%PQWYwNN_1RF@CqVj)@AOb}9s?Ot`x7Gj zLGUvOEToMmt{~|uH91#j*mbk;&d~On7RDS3?N-N`UUz;2q;lW<`Vdj@V)X4jFqV(w z$)I*NtHZ6w;X|bj$uu#FcX}rajYqi<>Kb?wo74|Y;|9@cILPnt?dm~>ujslS`HU%5ho(N@9wm^ z{PQCCn|AusxhHqVJsHU$e;eKRzGza%)kYQ^osr? zqtJji46$*J8^qdJ<2oP%+k)W>7ch=lBAo7fTYDyx4lmA6XefY@+YeRVB=6b4iH>{_^9bj8fo3M1qHSwg& zTBB`@@$*mg9`nEDcRo+}-qmdy$1!n{=>$DLtpnEaS<;d(ofp0!&>PMi8?5472L}`D zSy+i-3c$Xq*8pZ&NkjC>4!+JXrlQkaV6FmZQ(ai>*S+P-16F$!(U@ z=|gkUgs`E^&KpvvK{B)R`qZSMIi`6`V&^!x4}!%Kt`n)qHByh($9vSfIF}js`>9?;kOaXjCNae?d>tG zaCn}4srL02gZUS+b{9LL2l@_O#LrJypC67g#0Z+9 z>O_jwtXfqLrtG1H<|mk~%NNFWl)g659elTneqqTOH{7 zo(6gFY!~hTEiAt!-B#lND&{>jD-=jRa~aRUykz`Lnw*ShA(GK#mX8#4hl;%v8~#|h zy{eM8m){}i3P#gT?~gS(kA>T+Dy{eIU; zMOyn&uG7<^cAP}wZ=(y;Ve!n;PP)fVmZ=MlPQ1gzhV_gi-A8F#Z+mf+T68F?ebumHxc_X zKMXl@d#LyL33X=<=&TD%xOZH^)XcOg6x^OwrICWEB-J>WIU%xfzoRYm>AheR;pX>& zu7@Tu)iBn`h8MX$pO~hOi>ahxZb+M&Ij1#Q2WD&zhF~i+6b_qRZIkz0>+`}I)C}0M zN-X?HlVDne{bGXFnA%My6^@7Z#lzaiXqJ|&fiL!EX~K)cANbSY)^He(50npXz22H> zovn#8O`mB?Z_m2fnwFE9_EFpt$*@f7utf77ERzi{_R+96X2a3GD}Dj{1_k%V6cr7Q z$=v)`dBKJb%SEwLG&oL8J`~AENnnDtvev3fw95%K`4YI&hmL;r&HhRbZfXEw|VCL_vkj4Gdpt@Q48{F9Kp=5R=g60gRH}XE9QCKYY3sS3U`gN0C1LsB$t8Kd4G8~K z3jJcNP&*&pyUbotjy7j6Fvcx`n|5HUvv%X@(UYJ1l{7qUtq%EG*e@qRo z4b9((p3?#0xKhorv1*`rP%rA{3lV0&>r0j88g&dJ6fPK7pX;tXzx`2AQ%@SIsqag% zCmHS+fn`W6Jg#$kZ&=zgS9mtS@6-!-2jCgT^C}kaTnmRLly{#jZ;Kj`yCW3Eyzcs{ z;OM!uH@W;sFl{$7^N&)<+>FdM5&z%qfA&9>2kkHL63?!H;6Z+{PvO5LDJ(?pd&l2J zP*2sVD;6M~XuuLAd-6RNaC|IwcxS@uF9-oJROb`|SHm@`(fJ(q548D1QP_&bf|+?{ z2ZTS3*0t%Hx|&bRwZQl>ZVABV=#(gJ9S6liEu4Z(O@y1GPojJq0_KxqYFWUz2H9uR zLNUgYO{K04z|{7hD3l_qo-y7N7=01zgfo|U049;zktA0an%?ND$-G+km_ND%%uSTC$<9z6w5rCda(Z(#-U?uhsIqRFa*YPC<`aTv5 zcd6}b{2NNT*TO0eZ*%tUoDCmy)?P378t>x*%^!*v4?eUct^^i%IH}J19P;fS_#uDV zYraVV*bPD>j$hpfxglWNoIS7bQMC=e4z&=4{mp9b(&R_L;rew$`$oQf9}i2BFb;F> z(tbJzmL1p!^!+H_rR}{puEe%EXUnV)gmBDGfxDT}IwV^qw-HYcqAo=E>IS^8U{CGF*Ia-<2N>(y9kC@qYo-z5k67Z! zRzSgp?PCM7?bJm0-c_W@lcafXOd8M00ijo^Zxzmci3kAiO5l~OE5dhJ;hib*zA?rN zg!NjbC8=1i?&_BKURT&=A)C{CXjB0`uqc!HTgQ1i281@bYFO64E**1@#%1?yl?iabR>@oca6cT=#^=rK5 zI@HN|q{qQHNvRzN?g!Ht9l;w1gnKa$ z4Ck(azB;iM9>1l%1-zM+VTOx_ErZQvFs>b#=JKo^aJ!m#=ZD790nXxti4Vqsu|%db zI)H+u*-3oTPMi`k&r>uY+%1mp8I9A+dYLy0H`Hn;>-2?lKXo{ zP~+X#)MXzyWgqZ9=j_vm3cHE%56I9|EWK!zM6$+32=9hn8}OBwSmT1LU}OFjK-yc$ za>CyJmt5S~!?_jHw@GQf9Q0J!!hHHKAr;wR4$U0klHkH|sx6(erlFm}>y}hcBqvxD zni&es2B0w^O_D-m;)EL%nnZ=h`zspZdWC>f2u@yG(N!`#@UCF0+Y5CD{b0rV?Ge>3#RD+m8Bz^{TZ z5rPI-i5`6mZ2<8Q;NFo~3CXg757|BeE+N5z4E{C%Uj+m)+Yd!kA@mT-I|t=}`=a

%d6q!o_?tm$Z^8S(_XFKtFPuT~cxA^j;KF5C#A0{ReWwEO zNJE)F2p}Kaoi3Ce*RVJV&X?WL>U`AbV(y0#%~X6dIzoXG_zLUP!d#hExJilUDDiA1 z&QfC8J&zG)Dez1s&XD8Dmju~ej}g+8oKz*YD)9^@zEO!&lsH+5r^~UTD{$+BMhnxV zuNkxI8DXkeUGr1(=|O+1K`@E@!KU_he3Ca^rQ;?q5mX4nn{yL9vk**obPurcEHjU3 zpIceiJ?O5jF#xab2`?xxBV zRo(GH_YP$4y^yfoz;-0Y8rai`yP|uLYm}9Zhf_JgF)yR@0nDgutoa+!@zvO!7P@_H z%Sfj*LLzEsR+gzzaLG z9!#}xS9lxccxJ#nnZQEO_nio3e2Qf_{DXZT4zdrkTJxtE#rFMUkX?jLdS`I&dm%u- zIcNr&{~i>2CI2_Z^Df2>j7N6zixA#HUp+w8MD(p6G-n6En)^Nw;ac!VPzK&AD(@u% ziC?_;jS!s6-;-Lwz%f=|@2yJ$4UYGIW4Cg|yVg$N5OIupec6}7>mhJ-x`1e|6wzE! zR0`$k2np?>>I36W?G1J94Xx1m_J;a&lxOcKx;@nOQfNh-@1>AK3lDIi>a=mEUJiA= z5Lz+a_d>`VF^X#mb@@UoZu0p;ec_a^G1S!<^7i^!ov=<(@eV1D6>1b%j$?&t1%3u& zqwG9L3x6GT2c+RG=t;~1jnvbE2k??|XrEispSCOjn<~g`&`K1e*^YnW*+Dz@wgmO? z|22VgQRmtX?HxJ%A+F=ypsz9{RAS+d&Vkxkn3v#j3C>7Dq1-jXk`Rm?;bDYa%)o^x z;UPH*9ux@{?Ft6Z_AAgA#Ob}{DG$MBv3}BSs=-hP_mMe-uQv$mLoF0^C%6+ii-_4v zyx!=O+bPd|fQC16aF*IlnVSKtJ_p#6tFWC0^Q_T1P$@JurW0UIE6FSY+GvNkGwhS2TD4l|7_nd@d1hk8XDvn)W=a zApa4Bq2+Fj2JxJ)Ji?pwAQLQFAIX(VH7A3ck)CDPSoiiytmpu`#hN(Q0v}0NoL}wz zl;ZZP^@pgF?{eI8(biVVe~{z;5^Zmw+IMqYb@T=o<*ny9r`qkJz=Vu11i_iuxDTrt zd)IWVA$<-~xQnoHZ8}`+?||E8xJafPSwz?ugmtZ}BX|lDtxoeJ1J*+Z?{i1Jhq(BH z#GCZVk^4KslTYvOKzGUbCiz7x84gfz$Dbt3_CSSD6+8(}pHLF1VdIjwo1Y=6O^9@< zj6RS?Z=$AfChR1@C8<2Sq`U~@Q*z$aOD0Om!y`I4Q~w1sECOdX+s4=;WIsq3o$3x+ zvn1<9YXkT(fFchyKrLwyF!6~)6L8nWvIFs2K!K$h#BKb(NQN26+z7;hTlmqGz zVvzxM3X_5`+rb-L4e{L<^fo!owXlJ5@FXj>qf6f+cw3$@KS+9G%`b^fUHZP~h^bo? zijdb-N)`uW{%LdocMs-yeg0K9VyBt6HG8 zEl}5WgR?gqc7K?=w9@wI&U=_BAzf}xfsfelKqVKHl9I@1a4Cc|c*qqrUBL_U5D7Or zbAvD&bM9!X5kq@X68kS;n1m#YwyU_NYJNLO?)pTZvL ziVXU6K{#o%WThy-RDpoAhdvw}U66x25~VnRJzr+&WHbXqceKu?r&9gu$mi zO!)hVa={P=PDwg+g~YuPA-Z%}OT!TsM9FIimNfdSsIO&*!Fs0P714eN%)JKi?uL>U zG9{6Q-($O%F{U;VrdCKMF^wwYW#oq8l9&UXga>d8FyF}zkKj|`J;WS~mG+fh zL^G21_q|Hp@BXT+V@g@0NARPV&vDUy6XmYMN~8=6`u5eq-9z-rbc1{6Rrrbqz}sxm zm-4`S`6|5UnUPWcQ5nF+5ZfE!Y_^Twx4@OmOC#_Y(JBkPWowk@1(^u^?qnjkc2dTI z=UFAo3t3W+N8nP_;Z-+zON2&jdGa{ew8MV0M5ssbw09S~SX!z|geMTej$>bz^W6&A zD}%KND)oRbe9U>$?S&au1(z5XrA@d{ft6brPbIW#Y)AmikHMqu1b%qykBQV6C3nAi z+PUYA(S4b5GZq6ox$+TMITphYhfrrVbmQvOJj`*aOnV;TERwCMV0RA_n(PgzGI@E< zg2YLxxzmItvb@GjWXhtUph~$Q<6TMxE3g7*Ga0P`q{B6Nx>O6jn1%^jzAvjBmD@N~ z&cm9n$pk)OGUkEp&PV50uI}nnVm;%0MT7>HM24As1b0U?@8pbnfj%C}EnmN*blcs1bON*24$Ofn;EKR6frLy3)Wc)91s`|M2@1 zD=ZhXN+O!PDnWl$9~ys>U3oaX-G)7FuFp0V;#7x1kBwlDxfmUbk1LSm@8_u5{YFjct@|?ni{-{+c}SHp)~Qp7YbNtwf)52_cx? z^Cz&IZNKx|^Yr#SgDqbYGn}0xe1v=`ZZ?V=j^dg%a0VQcHooW2Vc=nPwJ2_Oe^vPZ zD6E@(`?U8>_OLA5F%+Oc~lOOsTG$#wM{7n|$X`V+%25!_p<3twyyws$oh}y7U~POzd(Usdq`TsrVfe5+<5z z7bIA+s#ua*jo7p)#AO$hz35 zHik`t-%_k#*qcEDc9KQ|^?;P@6ba0y@l1ulId)P5y*qL?xI~WXNywFCVLWSx!Lj(s zdNus)#KduYKaqZoCCtHW{COdaH!eBnO2*xz8FHK8-FgLfg0B$q@T&1LzR&0?dHxCI zB%}3NhG8cp+zJD(gLkHSvs1xyN#{zPf*kNZeZ9oVq%It`&c-{>zOw_%tv&Se&N1rKdjKucJ&?uWH9A$$=4V0%WO5jW< zSD}_@HCL*5XQ&Uabf8@GDKYgJlA-b3G$E!E78|PhE3x^{Vo4NjeoRa=k;3;$hlzfD zx}_z}+=q)$N!0btkBg3nMe_*}+_0NF#3qvpgmx2BGKDr@Mj9v^T|`I!)(C>dwr=h8 hxEBr_KDJl)LCo^Evu{8Auy(%Y{auIVtXf$AzX6zD7<~W$ From bf4b7b3b1e9673a1417b52596a17efaef5a672b4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:39:03 +0100 Subject: [PATCH 064/105] Delete partitions_ffat_12M.bin --- tools/Esptool/odroid_go/partitions_ffat_12M.bin | Bin 3072 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tools/Esptool/odroid_go/partitions_ffat_12M.bin diff --git a/tools/Esptool/odroid_go/partitions_ffat_12M.bin b/tools/Esptool/odroid_go/partitions_ffat_12M.bin deleted file mode 100644 index 4389fdc62b75f3347aea8a05b5dcfe4effe8a70e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 zcmZ1#z{tcffq{V`fPo>etQg2Z1*-xW85kY_#S|DA@=Fp^5=#cs$r04 zNGvEYK#>G;fbxQ1%@BD*OnJse1_pbe@Ii*Ow8Rp0`PZ-iqk#IL9ZU2Uo#PUTtDWo2 m_dy6na+EU~0;3@?8UmvsFd71*Aut*OqaiRF0;3^-Hv|CwXI*0e From 6c0ec48a6c0b36a9d02fc95496998d5707b31362 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:40:42 +0100 Subject: [PATCH 065/105] Odroid files --- tools/Esptool/Odroid_go/Odroid_flash.bat | 1 + tools/Esptool/Odroid_go/boot_app0.bin | Bin 0 -> 8192 bytes tools/Esptool/Odroid_go/bootloader_dout_40m.bin | Bin 0 -> 17072 bytes tools/Esptool/Odroid_go/partitions_ffat_12M.bin | Bin 0 -> 3072 bytes 4 files changed, 1 insertion(+) create mode 100644 tools/Esptool/Odroid_go/Odroid_flash.bat create mode 100644 tools/Esptool/Odroid_go/boot_app0.bin create mode 100644 tools/Esptool/Odroid_go/bootloader_dout_40m.bin create mode 100644 tools/Esptool/Odroid_go/partitions_ffat_12M.bin diff --git a/tools/Esptool/Odroid_go/Odroid_flash.bat b/tools/Esptool/Odroid_go/Odroid_flash.bat new file mode 100644 index 000000000..053742d27 --- /dev/null +++ b/tools/Esptool/Odroid_go/Odroid_flash.bat @@ -0,0 +1 @@ +esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions_ffat_12M.bin 0xe000 boot_app0.bin 0x10000 tasmota32.bin \ No newline at end of file diff --git a/tools/Esptool/Odroid_go/boot_app0.bin b/tools/Esptool/Odroid_go/boot_app0.bin new file mode 100644 index 0000000000000000000000000000000000000000..13562cabb9648287fdf70d2a22789fdf1e4156b4 GIT binary patch literal 8192 zcmeI#u?+wq2n0Z!&B7Ip%ZdwNPjZydJlFk*h+E9ra}_6R0t5&UAV7cs0RjXF5FkLH gk-)3}W&dyVhNuJx5FkK+009C72oNAZfWSu}0Te{nn*aa+ literal 0 HcmV?d00001 diff --git a/tools/Esptool/Odroid_go/bootloader_dout_40m.bin b/tools/Esptool/Odroid_go/bootloader_dout_40m.bin new file mode 100644 index 0000000000000000000000000000000000000000..267abf3dac6673a45831d387e0c66b6b754d62cb GIT binary patch literal 17072 zcmd73eOy%4_AtKBnPE809CHSc6!3OtbYM`(;YC5y%RpSz^xivBqM4hv-etit-aS?d+ql%->6kwi-xiNK(6_tCK54Q4JZ-*;vpT4fc(cp(aoSXsPj)5=ZdMH|bxx$`&~bgWwgS!71(`uiO-Hf~*&4|HA9GUHt|^(Zdj0(y)~|D{E8jGuc>VhFvh_v4w{p|w z4I9>PET6Gyu+IqO!lHEZiQEzn#g64p&_E-G8SxvZ!hXiJMWm6G3W-QZX~ z1`$$Pv~EqAgEP+K{;*{6;{U6<+EiL3sftLAE_1Bo%v=UHZyslbc5NtHv$FWXa>u5t zkkFNDHm$^FLF>$1?&3e*ylCapKNjTOhFr6(GcpMIpJ}XwhqC|w{9UDQkUwqatd%98 zcThC^{d*p^4Dg#vN*o*ipV0Y6=>GNhgW9i>wPbBs*-AMB?67S8mepnVtz7-!>M~IN zTrNE=b5`d6K|9&BeziOZXKXBAy|R4m{SL_}5Rl|3DqFdBUAbf9x}q|v-}rD_c_Jb4 z*8c2h2=N@m5LoZ!>{agmZ1HhXBzl-feip?w022;u9^%^}EQ7ED!iMuh*)gk*5yBF( ztcuv!XNm38XNZll_GfbtUdzK*+IfXg9V2 z+P(NKO#hUf2l*>dUgGzQ*lhCi8={y75`(_$K(|0&;SaNIpv3H6Xd@4?8sbJP@IY`w zcmhH@;3h)Y03jKI9YQ_eX%00i5;c@#2i{c}Kn}o-C#3%kkkJp7wtpZH+XxB(_VK`r z;Wofgt#(4b`%V-qJ_)lmLWuuIm`xA1LLjsoHMRi60qAcv#L0+YN&qS*@E`tqJ zM~1PcDrf_nCd5h=GJMU{5{p%sh)@gTxn6X)>OC={dl#10AeZKe0$9JwWZ;qzn*_y{ zEU*eXg-0v#MEr_J^Y1*%tU@Rx*Aon3JtLuO>lp<2+IoQD9776YuV=@d7{}hp9u$TV zAwhBMLqb4;SQgX2jO9#cw+lZhIhg)&EN2nhDtxEpVEUV}oSWEP!k0=8rq5$~??;ln zI^k4^2YKHIsUkA-)D>tI@Kt`5Le-PebTQ*LYT|f$_p> zt0=rCDlStA-*?$3q8Qc9);a zI?uVf{r-M3#lYt|xn6GmVZ-rv=O3o`AJ*txKuL)6SctS5_-P!g&EE=eZw4D@JJjtS zw)OtKJ>3sgwx8^0V>MFQEXY(L3-Dl0Lnu!0ii zIo(UR%-5n0F4;em&YY>y-;Z-ovnA+H#$GyS$!E`{NCp6AjfCD<;Xyv^y}21^u_=gLP}Bt3wZOkB?_vUDGv zp8+eI?bGdPUh2u2w0922M(#gMu{1Y@3-V+=hE~@ zEZ5|l-$5^p(xfmjAZVhqu-YCR94Xp)S~NklU3T#ix@nInycdLdCk4=e!?j~PDI6kc zrtmhpIVirklVKx)gQX{5!Z53d#GIzuXme0(${|hNT=NJdC^r5GBCnImsrZ*vR^J@P z>D9n&QerVWy%YIX&gor+Ump)&77=|57?=|Gpa4(@jweqLMz)0(UJAn4F}BK(XLrzD zr#J3KsD<|K2|L$na6hs6QiB0zbN+E0lL=W730t)Z6LpfHCJ;6a0!l8mwT@<;^f=yS z0MgzpRt57z#m{;J*B1~?^mT~`sfwRdR7eamxab5%XDLod)0X7wu!ymM?av`LTRA(C z)jqA|>MO0=cS4CT*5^1?OkymB1jt!LW>aif{v>E0 z=kTUFg4S7jVNKA*R7YjAT1bITAzm%TH!QyHtg7qoAggQB2`dp*dmJ+F#uU~|h)@`u z4YnfOfhg-Nf6;Bhd(%s)Ra?ASs@dUjOKfR5e-6u>xl^(M=y)#?79lAnZo!1@E$)a4 zOlBRGqJ?tiBd(2h{4AnnNqWt>Ihd;^g&CTh++b!#QBGFSmaFIZ{_W|)Z-d*@t=7xH zHw*b7o{4c#1#+vqvShha5mnm?nO2Di^aAM=DLpYYIq1BZ*i3#%%rQX@=0X5n3g#ea zI%X@4vi?RQ*9w!B*d)afLVU1p0jU@iqJv|57`wfk@cfRmJ6~FC#;W8DJRhXsfn@c&q5HEh) z7J9s|Y3saHHKp2~w_c(t~;tt``synO8yy+#SUp*gVDX?|;XatryNY+FMA4n+1 z^Zp3#y5M`w?(XCmEWC$=^$hGk8<4eu*?U~V=oDB7$WEs2718~ayup;=wlP@nk9gid zmYRsM_`enSh!P*hxHCdHGy+qlOnN{;bzVWeuAp8ULkasN6vHlbKP5{i)$Z9d;y$FW zYa*lAu9qY_7B>q|>De9aa$8uSKEryNN8D%i_xA7xh^7nd`cq9PyvkcQ+GdCw`qwxDyCvM!_QyG8Gp`S%Kmhb5*&= z81KtSt8CfZ4u(fR}!8!s{*$H*WY5gtF2`LD`RQZ~S z6PC#rCQtP8ybS$deL2V6B^Dkewhy>u_6XgkG9Q#?g;@gm>(6Qs3a7VHb+?!6@QQjL zC&XikX>U@nLQI)m)JB;FarXnM6Hs^;%s~#8%~z4|(r|W?yVvUXm-9kS;e}8q4U~hT zGsH=gA z+v47Fz$w#ktbxuuRK-iz$gRU&J%I`M3z09Tc&? zy+y;m>fye}#Ch77dzljy8`sxJ3bjm6EXdQo-LSo~j-hK8CQQ1eX9B5XRJC^`yfeNh zjF9??E=z-{CQSn(O6lC10?jy5p=&>&FFBO#c4tg)0Kq$f>_Ae@Y^Nz9&gCplkopPA zDQtjcfO1;s2D&CPuGK|VPjk1a`f5dKzcadic9D6sg^o!JhYg;}aT*M-@DmLiAqc~; zV75_xWn%5UOksI*x>A>}fF zGuer$8-`)Uo_q;NnwN_ST2p(g!RzBq(}>QLHYLGoIxmj{LQH#}R+3|50+;gpu-m{+ z)?(cB+y!AWCOnzL!W!)421WySMYD?NiZAEyT(DzrQ@0+(kGX~H@b!Hy!rrfWShT$= zE#JUiL=G5ShQ^jQs+lE?b9U^7#NWi))+1^dneT`@e9d2qx;$9>ey{pU{dU~V`EXw- zbDP6t?kq#&bHK!ma=)u^Hy;J=zH?&kTU44UAv5DxM;8OKG`}OuV*Xt0_Q8s}!zbK` z@|*u9f=!fwvP_n=*;JB2!;*>%)jPFWxt0P6hDHZ6vnD`yR__}>J)KK$cTKUR*8pig z9DV5|NLZ*WgEWq%af@@g3ClL#Fw8PF(6iEBq3|?0HF>ye^6-j9zRAOmrHqY>jsaZU zaM#4)6?gh34x0-Z+s2&yIIu&bVYrlDwJIY%Y}FFKed%gr6zbSQ7v_ppVT7yVbH)$b z7I>{rZM#*0mBNStYDS|1SQ(8Ct>G;@-Ad5L|C-#XJ<@_Kwp$9Oi{sKzoD($d+R z08GhnVfY}5h-0HLk~-Bt)HOWR;T3%SL%3sK%*6atm-GG50=13LIOj6Vt>An8AFUwW z-Yt;0v)9i@H!`O#4R!qhOi%c}MyBS4%-)MbusgjZ3ZD(ZhKJ8!2cMjH-Kh&hU0(uO zz3=RhV?NXVyrEeof-S(&2#zz&-;2ighb%PQWYwNN_1RF@CqVj)@AOb}9s?Ot`x7Gj zLGUvOEToMmt{~|uH91#j*mbk;&d~On7RDS3?N-N`UUz;2q;lW<`Vdj@V)X4jFqV(w z$)I*NtHZ6w;X|bj$uu#FcX}rajYqi<>Kb?wo74|Y;|9@cILPnt?dm~>ujslS`HU%5ho(N@9wm^ z{PQCCn|AusxhHqVJsHU$e;eKRzGza%)kYQ^osr? zqtJji46$*J8^qdJ<2oP%+k)W>7ch=lBAo7fTYDyx4lmA6XefY@+YeRVB=6b4iH>{_^9bj8fo3M1qHSwg& zTBB`@@$*mg9`nEDcRo+}-qmdy$1!n{=>$DLtpnEaS<;d(ofp0!&>PMi8?5472L}`D zSy+i-3c$Xq*8pZ&NkjC>4!+JXrlQkaV6FmZQ(ai>*S+P-16F$!(U@ z=|gkUgs`E^&KpvvK{B)R`qZSMIi`6`V&^!x4}!%Kt`n)qHByh($9vSfIF}js`>9?;kOaXjCNae?d>tG zaCn}4srL02gZUS+b{9LL2l@_O#LrJypC67g#0Z+9 z>O_jwtXfqLrtG1H<|mk~%NNFWl)g659elTneqqTOH{7 zo(6gFY!~hTEiAt!-B#lND&{>jD-=jRa~aRUykz`Lnw*ShA(GK#mX8#4hl;%v8~#|h zy{eM8m){}i3P#gT?~gS(kA>T+Dy{eIU; zMOyn&uG7<^cAP}wZ=(y;Ve!n;PP)fVmZ=MlPQ1gzhV_gi-A8F#Z+mf+T68F?ebumHxc_X zKMXl@d#LyL33X=<=&TD%xOZH^)XcOg6x^OwrICWEB-J>WIU%xfzoRYm>AheR;pX>& zu7@Tu)iBn`h8MX$pO~hOi>ahxZb+M&Ij1#Q2WD&zhF~i+6b_qRZIkz0>+`}I)C}0M zN-X?HlVDne{bGXFnA%My6^@7Z#lzaiXqJ|&fiL!EX~K)cANbSY)^He(50npXz22H> zovn#8O`mB?Z_m2fnwFE9_EFpt$*@f7utf77ERzi{_R+96X2a3GD}Dj{1_k%V6cr7Q z$=v)`dBKJb%SEwLG&oL8J`~AENnnDtvev3fw95%K`4YI&hmL;r&HhRbZfXEw|VCL_vkj4Gdpt@Q48{F9Kp=5R=g60gRH}XE9QCKYY3sS3U`gN0C1LsB$t8Kd4G8~K z3jJcNP&*&pyUbotjy7j6Fvcx`n|5HUvv%X@(UYJ1l{7qUtq%EG*e@qRo z4b9((p3?#0xKhorv1*`rP%rA{3lV0&>r0j88g&dJ6fPK7pX;tXzx`2AQ%@SIsqag% zCmHS+fn`W6Jg#$kZ&=zgS9mtS@6-!-2jCgT^C}kaTnmRLly{#jZ;Kj`yCW3Eyzcs{ z;OM!uH@W;sFl{$7^N&)<+>FdM5&z%qfA&9>2kkHL63?!H;6Z+{PvO5LDJ(?pd&l2J zP*2sVD;6M~XuuLAd-6RNaC|IwcxS@uF9-oJROb`|SHm@`(fJ(q548D1QP_&bf|+?{ z2ZTS3*0t%Hx|&bRwZQl>ZVABV=#(gJ9S6liEu4Z(O@y1GPojJq0_KxqYFWUz2H9uR zLNUgYO{K04z|{7hD3l_qo-y7N7=01zgfo|U049;zktA0an%?ND$-G+km_ND%%uSTC$<9z6w5rCda(Z(#-U?uhsIqRFa*YPC<`aTv5 zcd6}b{2NNT*TO0eZ*%tUoDCmy)?P378t>x*%^!*v4?eUct^^i%IH}J19P;fS_#uDV zYraVV*bPD>j$hpfxglWNoIS7bQMC=e4z&=4{mp9b(&R_L;rew$`$oQf9}i2BFb;F> z(tbJzmL1p!^!+H_rR}{puEe%EXUnV)gmBDGfxDT}IwV^qw-HYcqAo=E>IS^8U{CGF*Ia-<2N>(y9kC@qYo-z5k67Z! zRzSgp?PCM7?bJm0-c_W@lcafXOd8M00ijo^Zxzmci3kAiO5l~OE5dhJ;hib*zA?rN zg!NjbC8=1i?&_BKURT&=A)C{CXjB0`uqc!HTgQ1i281@bYFO64E**1@#%1?yl?iabR>@oca6cT=#^=rK5 zI@HN|q{qQHNvRzN?g!Ht9l;w1gnKa$ z4Ck(azB;iM9>1l%1-zM+VTOx_ErZQvFs>b#=JKo^aJ!m#=ZD790nXxti4Vqsu|%db zI)H+u*-3oTPMi`k&r>uY+%1mp8I9A+dYLy0H`Hn;>-2?lKXo{ zP~+X#)MXzyWgqZ9=j_vm3cHE%56I9|EWK!zM6$+32=9hn8}OBwSmT1LU}OFjK-yc$ za>CyJmt5S~!?_jHw@GQf9Q0J!!hHHKAr;wR4$U0klHkH|sx6(erlFm}>y}hcBqvxD zni&es2B0w^O_D-m;)EL%nnZ=h`zspZdWC>f2u@yG(N!`#@UCF0+Y5CD{b0rV?Ge>3#RD+m8Bz^{TZ z5rPI-i5`6mZ2<8Q;NFo~3CXg757|BeE+N5z4E{C%Uj+m)+Yd!kA@mT-I|t=}`=a

%d6q!o_?tm$Z^8S(_XFKtFPuT~cxA^j;KF5C#A0{ReWwEO zNJE)F2p}Kaoi3Ce*RVJV&X?WL>U`AbV(y0#%~X6dIzoXG_zLUP!d#hExJilUDDiA1 z&QfC8J&zG)Dez1s&XD8Dmju~ej}g+8oKz*YD)9^@zEO!&lsH+5r^~UTD{$+BMhnxV zuNkxI8DXkeUGr1(=|O+1K`@E@!KU_he3Ca^rQ;?q5mX4nn{yL9vk**obPurcEHjU3 zpIceiJ?O5jF#xab2`?xxBV zRo(GH_YP$4y^yfoz;-0Y8rai`yP|uLYm}9Zhf_JgF)yR@0nDgutoa+!@zvO!7P@_H z%Sfj*LLzEsR+gzzaLG z9!#}xS9lxccxJ#nnZQEO_nio3e2Qf_{DXZT4zdrkTJxtE#rFMUkX?jLdS`I&dm%u- zIcNr&{~i>2CI2_Z^Df2>j7N6zixA#HUp+w8MD(p6G-n6En)^Nw;ac!VPzK&AD(@u% ziC?_;jS!s6-;-Lwz%f=|@2yJ$4UYGIW4Cg|yVg$N5OIupec6}7>mhJ-x`1e|6wzE! zR0`$k2np?>>I36W?G1J94Xx1m_J;a&lxOcKx;@nOQfNh-@1>AK3lDIi>a=mEUJiA= z5Lz+a_d>`VF^X#mb@@UoZu0p;ec_a^G1S!<^7i^!ov=<(@eV1D6>1b%j$?&t1%3u& zqwG9L3x6GT2c+RG=t;~1jnvbE2k??|XrEispSCOjn<~g`&`K1e*^YnW*+Dz@wgmO? z|22VgQRmtX?HxJ%A+F=ypsz9{RAS+d&Vkxkn3v#j3C>7Dq1-jXk`Rm?;bDYa%)o^x z;UPH*9ux@{?Ft6Z_AAgA#Ob}{DG$MBv3}BSs=-hP_mMe-uQv$mLoF0^C%6+ii-_4v zyx!=O+bPd|fQC16aF*IlnVSKtJ_p#6tFWC0^Q_T1P$@JurW0UIE6FSY+GvNkGwhS2TD4l|7_nd@d1hk8XDvn)W=a zApa4Bq2+Fj2JxJ)Ji?pwAQLQFAIX(VH7A3ck)CDPSoiiytmpu`#hN(Q0v}0NoL}wz zl;ZZP^@pgF?{eI8(biVVe~{z;5^Zmw+IMqYb@T=o<*ny9r`qkJz=Vu11i_iuxDTrt zd)IWVA$<-~xQnoHZ8}`+?||E8xJafPSwz?ugmtZ}BX|lDtxoeJ1J*+Z?{i1Jhq(BH z#GCZVk^4KslTYvOKzGUbCiz7x84gfz$Dbt3_CSSD6+8(}pHLF1VdIjwo1Y=6O^9@< zj6RS?Z=$AfChR1@C8<2Sq`U~@Q*z$aOD0Om!y`I4Q~w1sECOdX+s4=;WIsq3o$3x+ zvn1<9YXkT(fFchyKrLwyF!6~)6L8nWvIFs2K!K$h#BKb(NQN26+z7;hTlmqGz zVvzxM3X_5`+rb-L4e{L<^fo!owXlJ5@FXj>qf6f+cw3$@KS+9G%`b^fUHZP~h^bo? zijdb-N)`uW{%LdocMs-yeg0K9VyBt6HG8 zEl}5WgR?gqc7K?=w9@wI&U=_BAzf}xfsfelKqVKHl9I@1a4Cc|c*qqrUBL_U5D7Or zbAvD&bM9!X5kq@X68kS;n1m#YwyU_NYJNLO?)pTZvL ziVXU6K{#o%WThy-RDpoAhdvw}U66x25~VnRJzr+&WHbXqceKu?r&9gu$mi zO!)hVa={P=PDwg+g~YuPA-Z%}OT!TsM9FIimNfdSsIO&*!Fs0P714eN%)JKi?uL>U zG9{6Q-($O%F{U;VrdCKMF^wwYW#oq8l9&UXga>d8FyF}zkKj|`J;WS~mG+fh zL^G21_q|Hp@BXT+V@g@0NARPV&vDUy6XmYMN~8=6`u5eq-9z-rbc1{6Rrrbqz}sxm zm-4`S`6|5UnUPWcQ5nF+5ZfE!Y_^Twx4@OmOC#_Y(JBkPWowk@1(^u^?qnjkc2dTI z=UFAo3t3W+N8nP_;Z-+zON2&jdGa{ew8MV0M5ssbw09S~SX!z|geMTej$>bz^W6&A zD}%KND)oRbe9U>$?S&au1(z5XrA@d{ft6brPbIW#Y)AmikHMqu1b%qykBQV6C3nAi z+PUYA(S4b5GZq6ox$+TMITphYhfrrVbmQvOJj`*aOnV;TERwCMV0RA_n(PgzGI@E< zg2YLxxzmItvb@GjWXhtUph~$Q<6TMxE3g7*Ga0P`q{B6Nx>O6jn1%^jzAvjBmD@N~ z&cm9n$pk)OGUkEp&PV50uI}nnVm;%0MT7>HM24As1b0U?@8pbnfj%C}EnmN*blcs1bON*24$Ofn;EKR6frLy3)Wc)91s`|M2@1 zD=ZhXN+O!PDnWl$9~ys>U3oaX-G)7FuFp0V;#7x1kBwlDxfmUbk1LSm@8_u5{YFjct@|?ni{-{+c}SHp)~Qp7YbNtwf)52_cx? z^Cz&IZNKx|^Yr#SgDqbYGn}0xe1v=`ZZ?V=j^dg%a0VQcHooW2Vc=nPwJ2_Oe^vPZ zD6E@(`?U8>_OLA5F%+Oc~lOOsTG$#wM{7n|$X`V+%25!_p<3twyyws$oh}y7U~POzd(Usdq`TsrVfe5+<5z z7bIA+s#ua*jo7p)#AO$hz35 zHik`t-%_k#*qcEDc9KQ|^?;P@6ba0y@l1ulId)P5y*qL?xI~WXNywFCVLWSx!Lj(s zdNus)#KduYKaqZoCCtHW{COdaH!eBnO2*xz8FHK8-FgLfg0B$q@T&1LzR&0?dHxCI zB%}3NhG8cp+zJD(gLkHSvs1xyN#{zPf*kNZeZ9oVq%It`&c-{>zOw_%tv&Se&N1rKdjKucJ&?uWH9A$$=4V0%WO5jW< zSD}_@HCL*5XQ&Uabf8@GDKYgJlA-b3G$E!E78|PhE3x^{Vo4NjeoRa=k;3;$hlzfD zx}_z}+=q)$N!0btkBg3nMe_*}+_0NF#3qvpgmx2BGKDr@Mj9v^T|`I!)(C>dwr=h8 hxEBr_KDJl)LCo^Evu{8Auy(%Y{auIVtXf$AzX6zD7<~W$ literal 0 HcmV?d00001 diff --git a/tools/Esptool/Odroid_go/partitions_ffat_12M.bin b/tools/Esptool/Odroid_go/partitions_ffat_12M.bin new file mode 100644 index 0000000000000000000000000000000000000000..4389fdc62b75f3347aea8a05b5dcfe4effe8a70e GIT binary patch literal 3072 zcmZ1#z{tcffq{V`fPo>etQg2Z1*-xW85kY_#S|DA@=Fp^5=#cs$r04 zNGvEYK#>G;fbxQ1%@BD*OnJse1_pbe@Ii*Ow8Rp0`PZ-iqk#IL9ZU2Uo#PUTtDWo2 m_dy6na+EU~0;3@?8UmvsFd71*Aut*OqaiRF0;3^-Hv|CwXI*0e literal 0 HcmV?d00001 From b68d8c65f34a788b6cf54c761f710ca2e0162b2c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:44:54 +0100 Subject: [PATCH 066/105] tasmota32-odroid.bin --- tools/Esptool/Odroid_go/Odroid_flash.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Esptool/Odroid_go/Odroid_flash.bat b/tools/Esptool/Odroid_go/Odroid_flash.bat index 053742d27..2ce84284f 100644 --- a/tools/Esptool/Odroid_go/Odroid_flash.bat +++ b/tools/Esptool/Odroid_go/Odroid_flash.bat @@ -1 +1 @@ -esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions_ffat_12M.bin 0xe000 boot_app0.bin 0x10000 tasmota32.bin \ No newline at end of file +esptool.py --chip esp32 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions_ffat_12M.bin 0xe000 boot_app0.bin 0x10000 tasmota32-odroid.bin \ No newline at end of file From 0703e5899b7d5251c4018c3706ae988798ec2f7b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:45:40 +0100 Subject: [PATCH 067/105] Update workflows --- .github/workflows/Tasmota_build.yml | 24 ++++++++++++++++++++++ .github/workflows/Tasmota_build_master.yml | 24 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index fe06a70d2..ba32bbe74 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1013,6 +1013,29 @@ jobs: path: ./build_output/firmware + tasmota32-AF: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota32-BG: needs: tasmota_pull runs-on: ubuntu-latest @@ -1575,6 +1598,7 @@ jobs: [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/tasmota32-odroidgo.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index 4169bd028..1bc598370 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -1013,6 +1013,29 @@ jobs: path: ./build_output/firmware + tasmota32-AF: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota32-BG: needs: tasmota_pull runs-on: ubuntu-latest @@ -1575,6 +1598,7 @@ jobs: [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/tasmota32-odroidgo.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ From 8117d25f41f4b4250f9b28035a71a4f918a8aa15 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 14:56:52 +0100 Subject: [PATCH 068/105] Plus changes Theo --- .github/workflows/Tasmota_build.yml | 24 ++++++++++++++++++++++ .github/workflows/Tasmota_build_master.yml | 24 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 8bf360bcc..708a6b56b 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1013,6 +1013,29 @@ jobs: path: ./build_output/firmware + tasmota32-AF: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota32-BG: needs: tasmota_pull runs-on: ubuntu-latest @@ -1576,6 +1599,7 @@ jobs: [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/tasmota32-odroidgo.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index cdf6ccc99..e97ac181c 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -1013,6 +1013,29 @@ jobs: path: ./build_output/firmware + tasmota32-AF: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota32-AF + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + tasmota32-BG: needs: tasmota_pull runs-on: ubuntu-latest @@ -1576,6 +1599,7 @@ jobs: [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-odroidgo.* ] || mv ./mv_firmware/tasmota32-odroidgo.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ From 8f90ad733da4bf05c9077765b771b90f1540ac8f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 16:37:22 +0100 Subject: [PATCH 069/105] Overlooked a needed change --- .github/workflows/Tasmota_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml index 708a6b56b..9e8f61219 100644 --- a/.github/workflows/Tasmota_build.yml +++ b/.github/workflows/Tasmota_build.yml @@ -1606,7 +1606,7 @@ jobs: rm ./firmware/tasmota32/*.gz rm ./firmware/tasmota32/languages/*.gz [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ - [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ + [ ! -f ./tools/Esptool/Odroid_go/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ [ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | From 1cbc6bc80bd2926e8b49244eb85e9561cef641b9 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 30 Dec 2020 16:41:34 +0100 Subject: [PATCH 070/105] Forgot Odroid_go change --- .github/workflows/Tasmota_build_master.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index e97ac181c..8c00d25e3 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -1606,7 +1606,7 @@ jobs: rm ./firmware/tasmota32/*.gz rm ./firmware/tasmota32/languages/*.gz [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ - [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ + [ ! -f ./tools/Esptool/Odroid_go/*.* ] || mv ./tools/Esptool/Odroid_go/*.* ./firmware/tasmota32/Odroid_go_needed_files/ [ ! -f ./FIRMWARE.md ] || mv -f ./RELEASENOTES.md ./README.md - name: Commit files # transfer the new binaries back into the repository run: | From 01f3a7da19cec91b62b4453852d6bb7cbebf0457 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 30 Dec 2020 17:49:52 +0100 Subject: [PATCH 071/105] Breaking change replaced NRF24L01 GPIO selection Breaking change replaced NRF24L01 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_NRF24_CS`` and ``GPIO_SPI_DC`` by ``GPIO_NRF24_DC`` --- CHANGELOG.md | 5 +- RELEASENOTES.md | 3 + tasmota/support.ino | 17 +++-- tasmota/support_tasmota.ino | 97 ++++++++------------------ tasmota/tasmota_configurations_ESP32.h | 5 ++ tasmota/xdrv_33_nrf24l01.ino | 35 +++++----- tasmota/xdsp_04_ili9341.ino | 43 +++--------- 7 files changed, 82 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d542934fa..c39ba0abf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,13 @@ All notable changes to this project will be documented in this file. ## [9.2.0.2] ### Added - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) -- Command ``CTRange`` to specify the visible CT range the bulb is capable of -- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels +- Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311) +- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels (#10311) ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` - Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` +- Replaced NRF24L01 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_NRF24_CS`` and ``GPIO_SPI_DC`` by ``GPIO_NRF24_DC`` ## [9.2.0.1] 20201229 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6f02fa36f..f7d6c073d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,6 +58,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ## Changelog v9.2.0.2 ### Added +- Command ``CTRange`` to specify the visible CT range the bulb is capable of [#10311](https://github.com/arendst/Tasmota/issues/10311) +- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels [#10311](https://github.com/arendst/Tasmota/issues/10311) - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253) @@ -73,6 +75,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` - Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` +- Replaced NRF24L01 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_NRF24_CS`` and ``GPIO_SPI_DC`` by ``GPIO_NRF24_DC`` ### Changed - Logging from heap to stack freeing 700 bytes RAM diff --git a/tasmota/support.ino b/tasmota/support.ino index fcf21a014..81e826365 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1479,8 +1479,7 @@ bool FlashPin(uint32_t pin) return (((pin > 5) && (pin < 9)) || (11 == pin)); } -uint32_t ValidPin(uint32_t pin, uint32_t gpio) -{ +uint32_t ValidPin(uint32_t pin, uint32_t gpio) { if (FlashPin(pin)) { return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11 } @@ -1495,8 +1494,7 @@ uint32_t ValidPin(uint32_t pin, uint32_t gpio) return gpio; } -bool ValidGPIO(uint32_t pin, uint32_t gpio) -{ +bool ValidGPIO(uint32_t pin, uint32_t gpio) { #ifdef ESP8266 #ifdef USE_ADC_VCC if (ADC0_PIN == pin) { return false; } // ADC0 = GPIO17 @@ -1505,6 +1503,17 @@ bool ValidGPIO(uint32_t pin, uint32_t gpio) return (GPIO_USER == ValidPin(pin, BGPIO(gpio))); // Only allow GPIO_USER pins } +bool ValidSpiGPIO(uint32_t gpio) { + // ESP8266: If SPI pin selected chk if it's not one of the three Hardware SPI pins (12..14) + bool result = true; // Not used and therefore valid + uint32_t pin; + if (PinUsed(gpio)) { + pin = Pin(gpio); + result = ((pin < 12) || (pin > 14)); + } + return result; +} + bool JsonTemplate(char* dataBuf) { // Old: {"NAME":"Shelly 2.5","GPIO":[56,0,17,0,21,83,0,0,6,82,5,22,156],"FLAG":2,"BASE":18} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 58b79e905..325ad3b2e 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1599,26 +1599,20 @@ void GpioInit(void) TasmotaGlobal.soft_spi_enabled = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); #ifdef USE_SPI - uint32_t pin_cs = Pin(GPIO_SPI_CS); - uint32_t pin_dc = Pin(GPIO_SPI_DC); - if (PinUsed(GPIO_RC522_CS)) { - pin_cs = Pin(GPIO_RC522_CS); - } - if (PinUsed(GPIO_ILI9341_CS)) { - pin_cs = Pin(GPIO_ILI9341_CS); - if (PinUsed(GPIO_ILI9341_DC)) { - pin_dc = Pin(GPIO_ILI9341_DC); - } - } - #ifdef ESP8266 if (!TasmotaGlobal.soft_spi_enabled) { - // If SPI_CS is used it must be valid - TasmotaGlobal.spi_enabled = ((pin_cs < 99) && ((pin_cs > 14) || (pin_cs < 12))); - if (TasmotaGlobal.spi_enabled && (pin_dc < 99)) { - // If SPI_DC is used it must be valid - TasmotaGlobal.spi_enabled = ((pin_dc > 14) || (pin_dc < 12)); - } + bool valid_cs = (ValidSpiGPIO(GPIO_SPI_CS) && + ValidSpiGPIO(GPIO_RC522_CS) && + ValidSpiGPIO(GPIO_NRF24_CS) && + ValidSpiGPIO(GPIO_ILI9341_CS) + ); + bool valid_dc = (ValidSpiGPIO(GPIO_SPI_DC) && + ValidSpiGPIO(GPIO_NRF24_DC) && + ValidSpiGPIO(GPIO_ILI9341_DC) + ); + + // If SPI_CS and/or SPI_DC is used they must be valid + TasmotaGlobal.spi_enabled = (valid_cs && valid_dc); if (TasmotaGlobal.spi_enabled) { TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); SetPin(12, AGPIO(GPIO_SPI_MISO)); @@ -1631,57 +1625,26 @@ void GpioInit(void) } #endif // ESP8266 #ifdef ESP32 - if (pin_cs < 99) { -/* - // Do not do this as ESP32 can have SPI_CS everywhere - if ((15 == pin_cs) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI - TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); - SetPin(12, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); - SetPin(13, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); - SetPin(14, AGPIO(GPIO_SPI_CLK)); + if (PinUsed(GPIO_SPI_CS) || + PinUsed(GPIO_RC522_CS) || + PinUsed(GPIO_NRF24_CS) || + PinUsed(GPIO_ILI9341_CS) + ) { + TasmotaGlobal.spi_enabled = true; + if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); } - else if ((5 == pin_cs) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI - TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); - SetPin(19, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); - SetPin(23, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[18] = AGPIO(GPIO_SPI_CLK); - SetPin(18, AGPIO(GPIO_SPI_CLK)); + else if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); } - else if ((12 == Pin(GPIO_SPI_MISO)) || (13 == Pin(GPIO_SPI_MOSI)) || (14 == Pin(GPIO_SPI_CLK))) { // HSPI - TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); - SetPin(12, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); - SetPin(13, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); - SetPin(14, AGPIO(GPIO_SPI_CLK)); - } - else if ((19 == Pin(GPIO_SPI_MISO)) || (23 == Pin(GPIO_SPI_MOSI)) || (18 == Pin(GPIO_SPI_CLK))) { // VSPI - TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); - SetPin(19, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); - SetPin(23, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[18] = AGPIO(GPIO_SPI_CLK); - SetPin(18, AGPIO(GPIO_SPI_CLK)); - } - TasmotaGlobal.spi_enabled = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); -*/ - TasmotaGlobal.spi_enabled = (pin_cs < 99); - if (TasmotaGlobal.spi_enabled) { - if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); - } - else if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); - } - else if (PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); - } + else if (PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Failed as no CLK and MISO and/or MOSI GPIO defined")); + TasmotaGlobal.spi_enabled = false; } } #endif // ESP32 diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index c3bb7044b..2f21ed0aa 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -46,6 +46,11 @@ #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "odroid-go" +#undef MODULE +#define MODULE ODROID_GO // [Module] Select default module from tasmota_template.h +#undef FALLBACK_MODULE +#define FALLBACK_MODULE ODROID_GO // [Module2] Select default module on fast reboot where USER_MODULE is user template + #define USE_ODROID_GO // Add support for Odroid Go #define USE_ADC #define USE_SPI diff --git a/tasmota/xdrv_33_nrf24l01.ino b/tasmota/xdrv_33_nrf24l01.ino index 7c4d1b843..1b3c5b8c8 100644 --- a/tasmota/xdrv_33_nrf24l01.ino +++ b/tasmota/xdrv_33_nrf24l01.ino @@ -34,7 +34,7 @@ /*********************************************************************************************\ * NRF24l01(+) * -* Usage: 5 SPI-data-wires plus VVC/ground, use hardware SPI, select GPIO_SPI_CS/GPIO_SPI_DC +* Usage: 5 SPI-data-wires plus VVC/ground, use hardware SPI, select GPIO_NRF24_CS/GPIO_NRF24_DC \*********************************************************************************************/ #define XDRV_33 33 @@ -51,28 +51,26 @@ struct { RF24 NRF24radio; -bool NRF24initRadio() -{ - NRF24radio.begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); +bool NRF24initRadio() { + NRF24radio.begin(Pin(GPIO_NRF24_CS), Pin(GPIO_NRF24_DC)); NRF24radio.powerUp(); - if(NRF24radio.isChipConnected()){ - DEBUG_DRIVER_LOG(PSTR("NRF24 chip connected")); + if (NRF24radio.isChipConnected()) { + DEBUG_DRIVER_LOG(PSTR("NRF: Chip connected")); return true; } - DEBUG_DRIVER_LOG(PSTR("NRF24 chip NOT !!!! connected")); + DEBUG_DRIVER_LOG(PSTR("NRF: Chip NOT !!!! connected")); return false; } -bool NRF24Detect(void) -{ - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { - if(NRF24initRadio()){ +bool NRF24Detect(void) { + if (PinUsed(GPIO_NRF24_CS) && PinUsed(GPIO_NRF24_DC)) { + if (NRF24initRadio()) { NRF24.chipType = 32; // SPACE - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF24L01 initialized")); - if(NRF24radio.isPVariant()){ + AddLog_P(LOG_LEVEL_INFO,PSTR("NRF: Model 24L01 initialized")); + if (NRF24radio.isPVariant()) { NRF24.chipType = 43; // + - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF24L01+ detected")); + AddLog_P(LOG_LEVEL_INFO,PSTR("NRF: Model 24L01+ detected")); } return true; } @@ -84,12 +82,13 @@ bool NRF24Detect(void) * Interface \*********************************************************************************************/ -bool Xdrv33(uint8_t function) -{ +bool Xdrv33(uint8_t function) { bool result = false; - if (FUNC_INIT == function) { - result = NRF24Detect(); + if (TasmotaGlobal.spi_enabled) { + if (FUNC_INIT == function) { + result = NRF24Detect(); + } } return result; } diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index adabfe6b0..005f048eb 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -57,8 +57,7 @@ bool Ili9341Header(void) { return (tft_cols > 17); } -void Ili9341InitMode(void) -{ +void Ili9341InitMode(void) { tft->setRotation(Settings.display_rotate); // 0 tft->invertDisplay(0); tft->fillScreen(ILI9341_BLACK); @@ -78,8 +77,7 @@ void Ili9341InitMode(void) } } -void Ili9341Init(uint8_t mode) -{ +void Ili9341Init(uint8_t mode) { switch(mode) { case DISPLAY_INIT_MODE: Ili9341InitMode(); @@ -95,24 +93,11 @@ void Ili9341Init(uint8_t mode) } } -void Ili9341InitDriver(void) -{ - uint32_t pin_cs = Pin(GPIO_SPI_CS); - uint32_t pin_dc = Pin(GPIO_SPI_DC); - if (!Settings.display_model) { - if (PinUsed(GPIO_ILI9341_CS)) { - pin_cs = Pin(GPIO_ILI9341_CS); - if (PinUsed(GPIO_ILI9341_DC)) { - pin_dc = Pin(GPIO_ILI9341_DC); - } - Settings.display_model = XDSP_04; - } +void Ili9341InitDriver(void) { + if (PinUsed(GPIO_ILI9341_CS) && PinUsed(GPIO_ILI9341_DC)) { - // Legacy Settings.display_model = XDSP_04; - } - if (XDSP_04 == Settings.display_model) { if (Settings.display_width != ILI9341_TFTWIDTH) { Settings.display_width = ILI9341_TFTWIDTH; } @@ -120,7 +105,7 @@ void Ili9341InitDriver(void) Settings.display_height = ILI9341_TFTHEIGHT; } - tft = new Adafruit_ILI9341(pin_cs, pin_dc); + tft = new Adafruit_ILI9341(Pin(GPIO_ILI9341_CS), Pin(GPIO_ILI9341_DC)); tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 @@ -135,14 +120,12 @@ void Ili9341InitDriver(void) } } -void Ili9341Clear(void) -{ +void Ili9341Clear(void) { tft->fillScreen(ILI9341_BLACK); tft->setCursor(0, 0); } -void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) -{ +void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) { uint16_t active_color = ILI9341_WHITE; tft->setTextSize(Settings.display_size); @@ -156,8 +139,7 @@ void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint tft->println(str); } -void Ili9341DisplayOnOff() -{ +void Ili9341DisplayOnOff() { // tft->showDisplay(disp_power); // tft->invertDisplay(disp_power); if (PinUsed(GPIO_BACKLIGHT)) { @@ -170,8 +152,7 @@ void Ili9341DisplayOnOff() #ifdef USE_DISPLAY_MODES1TO5 -void Ili9341PrintLog(void) -{ +void Ili9341PrintLog(void) { disp_refresh--; if (!disp_refresh) { disp_refresh = Settings.display_refresh; @@ -217,8 +198,7 @@ void Ili9341PrintLog(void) } } -void Ili9341Refresh(void) // Every second -{ +void Ili9341Refresh(void) { // Every second if (Settings.display_mode) { // Mode 0 is User text // 24-04-2017 13:45:43 = 19 + 1 ('\0') = 20 // 24-04-2017 13:45 = 16 + 1 ('\0') = 17 @@ -263,8 +243,7 @@ void Ili9341Refresh(void) // Every second * Interface \*********************************************************************************************/ -bool Xdsp04(uint8_t function) -{ +bool Xdsp04(uint8_t function) { bool result = false; if (TasmotaGlobal.spi_enabled) { From 9c2b8040f185164d9e2e1cad320fa01275caa996 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 30 Dec 2020 17:52:05 +0100 Subject: [PATCH 072/105] Revert "Breaking change replaced NRF24L01 GPIO selection" This reverts commit 01f3a7da19cec91b62b4453852d6bb7cbebf0457. --- CHANGELOG.md | 5 +- RELEASENOTES.md | 3 - tasmota/support.ino | 17 ++--- tasmota/support_tasmota.ino | 97 ++++++++++++++++++-------- tasmota/tasmota_configurations_ESP32.h | 5 -- tasmota/xdrv_33_nrf24l01.ino | 35 +++++----- tasmota/xdsp_04_ili9341.ino | 43 +++++++++--- 7 files changed, 123 insertions(+), 82 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c39ba0abf..d542934fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,12 @@ All notable changes to this project will be documented in this file. ## [9.2.0.2] ### Added - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) -- Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311) -- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels (#10311) +- Command ``CTRange`` to specify the visible CT range the bulb is capable of +- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` - Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` -- Replaced NRF24L01 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_NRF24_CS`` and ``GPIO_SPI_DC`` by ``GPIO_NRF24_DC`` ## [9.2.0.1] 20201229 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index f7d6c073d..6f02fa36f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,8 +58,6 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ## Changelog v9.2.0.2 ### Added -- Command ``CTRange`` to specify the visible CT range the bulb is capable of [#10311](https://github.com/arendst/Tasmota/issues/10311) -- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels [#10311](https://github.com/arendst/Tasmota/issues/10311) - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253) @@ -75,7 +73,6 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` - Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` -- Replaced NRF24L01 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_NRF24_CS`` and ``GPIO_SPI_DC`` by ``GPIO_NRF24_DC`` ### Changed - Logging from heap to stack freeing 700 bytes RAM diff --git a/tasmota/support.ino b/tasmota/support.ino index 81e826365..fcf21a014 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1479,7 +1479,8 @@ bool FlashPin(uint32_t pin) return (((pin > 5) && (pin < 9)) || (11 == pin)); } -uint32_t ValidPin(uint32_t pin, uint32_t gpio) { +uint32_t ValidPin(uint32_t pin, uint32_t gpio) +{ if (FlashPin(pin)) { return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11 } @@ -1494,7 +1495,8 @@ uint32_t ValidPin(uint32_t pin, uint32_t gpio) { return gpio; } -bool ValidGPIO(uint32_t pin, uint32_t gpio) { +bool ValidGPIO(uint32_t pin, uint32_t gpio) +{ #ifdef ESP8266 #ifdef USE_ADC_VCC if (ADC0_PIN == pin) { return false; } // ADC0 = GPIO17 @@ -1503,17 +1505,6 @@ bool ValidGPIO(uint32_t pin, uint32_t gpio) { return (GPIO_USER == ValidPin(pin, BGPIO(gpio))); // Only allow GPIO_USER pins } -bool ValidSpiGPIO(uint32_t gpio) { - // ESP8266: If SPI pin selected chk if it's not one of the three Hardware SPI pins (12..14) - bool result = true; // Not used and therefore valid - uint32_t pin; - if (PinUsed(gpio)) { - pin = Pin(gpio); - result = ((pin < 12) || (pin > 14)); - } - return result; -} - bool JsonTemplate(char* dataBuf) { // Old: {"NAME":"Shelly 2.5","GPIO":[56,0,17,0,21,83,0,0,6,82,5,22,156],"FLAG":2,"BASE":18} diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 325ad3b2e..58b79e905 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1599,20 +1599,26 @@ void GpioInit(void) TasmotaGlobal.soft_spi_enabled = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); #ifdef USE_SPI + uint32_t pin_cs = Pin(GPIO_SPI_CS); + uint32_t pin_dc = Pin(GPIO_SPI_DC); + if (PinUsed(GPIO_RC522_CS)) { + pin_cs = Pin(GPIO_RC522_CS); + } + if (PinUsed(GPIO_ILI9341_CS)) { + pin_cs = Pin(GPIO_ILI9341_CS); + if (PinUsed(GPIO_ILI9341_DC)) { + pin_dc = Pin(GPIO_ILI9341_DC); + } + } + #ifdef ESP8266 if (!TasmotaGlobal.soft_spi_enabled) { - bool valid_cs = (ValidSpiGPIO(GPIO_SPI_CS) && - ValidSpiGPIO(GPIO_RC522_CS) && - ValidSpiGPIO(GPIO_NRF24_CS) && - ValidSpiGPIO(GPIO_ILI9341_CS) - ); - bool valid_dc = (ValidSpiGPIO(GPIO_SPI_DC) && - ValidSpiGPIO(GPIO_NRF24_DC) && - ValidSpiGPIO(GPIO_ILI9341_DC) - ); - - // If SPI_CS and/or SPI_DC is used they must be valid - TasmotaGlobal.spi_enabled = (valid_cs && valid_dc); + // If SPI_CS is used it must be valid + TasmotaGlobal.spi_enabled = ((pin_cs < 99) && ((pin_cs > 14) || (pin_cs < 12))); + if (TasmotaGlobal.spi_enabled && (pin_dc < 99)) { + // If SPI_DC is used it must be valid + TasmotaGlobal.spi_enabled = ((pin_dc > 14) || (pin_dc < 12)); + } if (TasmotaGlobal.spi_enabled) { TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); SetPin(12, AGPIO(GPIO_SPI_MISO)); @@ -1625,26 +1631,57 @@ void GpioInit(void) } #endif // ESP8266 #ifdef ESP32 - if (PinUsed(GPIO_SPI_CS) || - PinUsed(GPIO_RC522_CS) || - PinUsed(GPIO_NRF24_CS) || - PinUsed(GPIO_ILI9341_CS) - ) { - TasmotaGlobal.spi_enabled = true; - if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + if (pin_cs < 99) { +/* + // Do not do this as ESP32 can have SPI_CS everywhere + if ((15 == pin_cs) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI + TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); } - else if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + else if ((5 == pin_cs) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI + TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); + SetPin(19, AGPIO(GPIO_SPI_MISO)); + TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); + SetPin(23, AGPIO(GPIO_SPI_MOSI)); + TasmotaGlobal.my_module.io[18] = AGPIO(GPIO_SPI_CLK); + SetPin(18, AGPIO(GPIO_SPI_CLK)); } - else if (PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); - } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Failed as no CLK and MISO and/or MOSI GPIO defined")); - TasmotaGlobal.spi_enabled = false; + else if ((12 == Pin(GPIO_SPI_MISO)) || (13 == Pin(GPIO_SPI_MOSI)) || (14 == Pin(GPIO_SPI_CLK))) { // HSPI + TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); + } + else if ((19 == Pin(GPIO_SPI_MISO)) || (23 == Pin(GPIO_SPI_MOSI)) || (18 == Pin(GPIO_SPI_CLK))) { // VSPI + TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); + SetPin(19, AGPIO(GPIO_SPI_MISO)); + TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); + SetPin(23, AGPIO(GPIO_SPI_MOSI)); + TasmotaGlobal.my_module.io[18] = AGPIO(GPIO_SPI_CLK); + SetPin(18, AGPIO(GPIO_SPI_CLK)); + } + TasmotaGlobal.spi_enabled = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); +*/ + TasmotaGlobal.spi_enabled = (pin_cs < 99); + if (TasmotaGlobal.spi_enabled) { + if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } + else if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } + else if (PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); + } } } #endif // ESP32 diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index 2f21ed0aa..c3bb7044b 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -46,11 +46,6 @@ #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "odroid-go" -#undef MODULE -#define MODULE ODROID_GO // [Module] Select default module from tasmota_template.h -#undef FALLBACK_MODULE -#define FALLBACK_MODULE ODROID_GO // [Module2] Select default module on fast reboot where USER_MODULE is user template - #define USE_ODROID_GO // Add support for Odroid Go #define USE_ADC #define USE_SPI diff --git a/tasmota/xdrv_33_nrf24l01.ino b/tasmota/xdrv_33_nrf24l01.ino index 1b3c5b8c8..7c4d1b843 100644 --- a/tasmota/xdrv_33_nrf24l01.ino +++ b/tasmota/xdrv_33_nrf24l01.ino @@ -34,7 +34,7 @@ /*********************************************************************************************\ * NRF24l01(+) * -* Usage: 5 SPI-data-wires plus VVC/ground, use hardware SPI, select GPIO_NRF24_CS/GPIO_NRF24_DC +* Usage: 5 SPI-data-wires plus VVC/ground, use hardware SPI, select GPIO_SPI_CS/GPIO_SPI_DC \*********************************************************************************************/ #define XDRV_33 33 @@ -51,26 +51,28 @@ struct { RF24 NRF24radio; -bool NRF24initRadio() { - NRF24radio.begin(Pin(GPIO_NRF24_CS), Pin(GPIO_NRF24_DC)); +bool NRF24initRadio() +{ + NRF24radio.begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); NRF24radio.powerUp(); - if (NRF24radio.isChipConnected()) { - DEBUG_DRIVER_LOG(PSTR("NRF: Chip connected")); + if(NRF24radio.isChipConnected()){ + DEBUG_DRIVER_LOG(PSTR("NRF24 chip connected")); return true; } - DEBUG_DRIVER_LOG(PSTR("NRF: Chip NOT !!!! connected")); + DEBUG_DRIVER_LOG(PSTR("NRF24 chip NOT !!!! connected")); return false; } -bool NRF24Detect(void) { - if (PinUsed(GPIO_NRF24_CS) && PinUsed(GPIO_NRF24_DC)) { - if (NRF24initRadio()) { +bool NRF24Detect(void) +{ + if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { + if(NRF24initRadio()){ NRF24.chipType = 32; // SPACE - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF: Model 24L01 initialized")); - if (NRF24radio.isPVariant()) { + AddLog_P(LOG_LEVEL_INFO,PSTR("NRF24L01 initialized")); + if(NRF24radio.isPVariant()){ NRF24.chipType = 43; // + - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF: Model 24L01+ detected")); + AddLog_P(LOG_LEVEL_INFO,PSTR("NRF24L01+ detected")); } return true; } @@ -82,13 +84,12 @@ bool NRF24Detect(void) { * Interface \*********************************************************************************************/ -bool Xdrv33(uint8_t function) { +bool Xdrv33(uint8_t function) +{ bool result = false; - if (TasmotaGlobal.spi_enabled) { - if (FUNC_INIT == function) { - result = NRF24Detect(); - } + if (FUNC_INIT == function) { + result = NRF24Detect(); } return result; } diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index 005f048eb..adabfe6b0 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -57,7 +57,8 @@ bool Ili9341Header(void) { return (tft_cols > 17); } -void Ili9341InitMode(void) { +void Ili9341InitMode(void) +{ tft->setRotation(Settings.display_rotate); // 0 tft->invertDisplay(0); tft->fillScreen(ILI9341_BLACK); @@ -77,7 +78,8 @@ void Ili9341InitMode(void) { } } -void Ili9341Init(uint8_t mode) { +void Ili9341Init(uint8_t mode) +{ switch(mode) { case DISPLAY_INIT_MODE: Ili9341InitMode(); @@ -93,11 +95,24 @@ void Ili9341Init(uint8_t mode) { } } -void Ili9341InitDriver(void) { - if (PinUsed(GPIO_ILI9341_CS) && PinUsed(GPIO_ILI9341_DC)) { +void Ili9341InitDriver(void) +{ + uint32_t pin_cs = Pin(GPIO_SPI_CS); + uint32_t pin_dc = Pin(GPIO_SPI_DC); + if (!Settings.display_model) { + if (PinUsed(GPIO_ILI9341_CS)) { + pin_cs = Pin(GPIO_ILI9341_CS); + if (PinUsed(GPIO_ILI9341_DC)) { + pin_dc = Pin(GPIO_ILI9341_DC); + } + Settings.display_model = XDSP_04; + } + // Legacy Settings.display_model = XDSP_04; + } + if (XDSP_04 == Settings.display_model) { if (Settings.display_width != ILI9341_TFTWIDTH) { Settings.display_width = ILI9341_TFTWIDTH; } @@ -105,7 +120,7 @@ void Ili9341InitDriver(void) { Settings.display_height = ILI9341_TFTHEIGHT; } - tft = new Adafruit_ILI9341(Pin(GPIO_ILI9341_CS), Pin(GPIO_ILI9341_DC)); + tft = new Adafruit_ILI9341(pin_cs, pin_dc); tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 @@ -120,12 +135,14 @@ void Ili9341InitDriver(void) { } } -void Ili9341Clear(void) { +void Ili9341Clear(void) +{ tft->fillScreen(ILI9341_BLACK); tft->setCursor(0, 0); } -void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) { +void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) +{ uint16_t active_color = ILI9341_WHITE; tft->setTextSize(Settings.display_size); @@ -139,7 +156,8 @@ void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint tft->println(str); } -void Ili9341DisplayOnOff() { +void Ili9341DisplayOnOff() +{ // tft->showDisplay(disp_power); // tft->invertDisplay(disp_power); if (PinUsed(GPIO_BACKLIGHT)) { @@ -152,7 +170,8 @@ void Ili9341DisplayOnOff() { #ifdef USE_DISPLAY_MODES1TO5 -void Ili9341PrintLog(void) { +void Ili9341PrintLog(void) +{ disp_refresh--; if (!disp_refresh) { disp_refresh = Settings.display_refresh; @@ -198,7 +217,8 @@ void Ili9341PrintLog(void) { } } -void Ili9341Refresh(void) { // Every second +void Ili9341Refresh(void) // Every second +{ if (Settings.display_mode) { // Mode 0 is User text // 24-04-2017 13:45:43 = 19 + 1 ('\0') = 20 // 24-04-2017 13:45 = 16 + 1 ('\0') = 17 @@ -243,7 +263,8 @@ void Ili9341Refresh(void) { // Every second * Interface \*********************************************************************************************/ -bool Xdsp04(uint8_t function) { +bool Xdsp04(uint8_t function) +{ bool result = false; if (TasmotaGlobal.spi_enabled) { From db7e0ff97adcc0460e76f698f0432dd7d8a39bc7 Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Wed, 30 Dec 2020 23:51:02 +0100 Subject: [PATCH 073/105] SSD1331: fixed hardware SPI --- tasmota/xdsp_14_SSD1331.ino | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino index 031115beb..f2f15e9d5 100644 --- a/tasmota/xdsp_14_SSD1331.ino +++ b/tasmota/xdsp_14_SSD1331.ino @@ -32,6 +32,7 @@ #define SSD1331_WHITE 0xFFFF // 255, 255, 255 #include +#include extern uint8_t *buffer; extern uint8_t color_type; @@ -60,14 +61,14 @@ void SSD1331_InitDriver() { bg_color = SSD1331_BLACK; // init renderer - if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)){ - ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_DC),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),OLED_RESET); + if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_DC) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_OLED_RESET)) { + ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_DC),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),Pin(GPIO_OLED_RESET)); + } else if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC) && PinUsed(GPIO_OLED_RESET)) { + ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC),Pin(GPIO_OLED_RESET)); + } else if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { + ssd1331 = new Adafruit_SSD1331(&SPI,Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); } else { - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { - ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK),OLED_RESET); - } else { - return; - } + return; } delay(100); From 3676ad3eb8548fe644e50d1fb0d2f81606debd14 Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Thu, 31 Dec 2020 09:06:21 +0100 Subject: [PATCH 074/105] Removed font setting in DisplayMode 1 The user can choose it using DisplayFont. --- tasmota/xdsp_14_SSD1331.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino index f2f15e9d5..a34890b48 100644 --- a/tasmota/xdsp_14_SSD1331.ino +++ b/tasmota/xdsp_14_SSD1331.ino @@ -126,7 +126,6 @@ void SSD1331Time(void) char line[12]; renderer->clearDisplay(); - renderer->setTextSize(2); renderer->setCursor(0, 0); snprintf_P(line, sizeof(line), PSTR(" %02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); // [ 12:34:56 ] renderer->println(line); From 8f63663c1e3ec0dc4968adc9c635699acc81cb44 Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Thu, 31 Dec 2020 10:17:30 +0100 Subject: [PATCH 075/105] Improved hardware SPI. Removed unnecessary setTextSize in PrintLog. --- tasmota/xdsp_14_SSD1331.ino | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino index a34890b48..ac6e3e994 100644 --- a/tasmota/xdsp_14_SSD1331.ino +++ b/tasmota/xdsp_14_SSD1331.ino @@ -63,10 +63,8 @@ void SSD1331_InitDriver() { // init renderer if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_DC) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_OLED_RESET)) { ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_DC),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),Pin(GPIO_OLED_RESET)); - } else if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC) && PinUsed(GPIO_OLED_RESET)) { - ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC),Pin(GPIO_OLED_RESET)); } else if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { - ssd1331 = new Adafruit_SSD1331(&SPI,Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); + ssd1331 = new Adafruit_SSD1331(&SPI,Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC),Pin(GPIO_OLED_RESET)); } else { return; } @@ -104,7 +102,6 @@ void SSD1331PrintLog(void) uint8_t last_row = Settings.display_rows -1; renderer->clearDisplay(); - renderer->setTextSize(Settings.display_size); renderer->setCursor(0,0); for (byte i = 0; i < last_row; i++) { strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); From 89e697fab64eb7e12ff678f26b1f92889eb657d8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 31 Dec 2020 11:47:37 +0100 Subject: [PATCH 076/105] Revert "Merge pull request #10318 from btsimonh/webtimeouts" This reverts commit c7ff3f39db49a5668839d63fe1eeb77f7e58f9d9, reversing changes made to 0703e5899b7d5251c4018c3706ae988798ec2f7b. --- tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h | 67 +++++++------ .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 42 ++++---- .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 54 +++++------ .../html_uncompressed/HTTP_SCRIPT_CONSOL.h | 97 +++++++++---------- .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 16 +-- .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 27 +++--- 6 files changed, 147 insertions(+), 156 deletions(-) diff --git a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h index 9138c4e8a..91e1fab76 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h @@ -2,39 +2,38 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_CONSOL_SIZE = 913; -const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x3D\xA1\x3A\x5E\xE3\xE1\xC6\x75\x16\x88\x7C\x38\xCE\xA2\x31\x47\x83\x02\xF8\x3A" - "\xDC\xE4\x11\xDD\x18\x77\x8F\x68\x4E\x90\x67\x56\x1F\x0F\xB3\xEC\xF0\x18\x4E\xFE" - "\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE0\x49\x9A\x62\x8E\xF1\xE2\x8F\x8C\x71\xDD\x3E" - "\xE8\xE4\x3E\xCE\xF1\xE0\xB4\xC1\xDD\x18\x7C\x3E\x1C\x87\x78\xF6\x90\x67\xC6\x38" - "\xEE\x9F\x61\x9C\x87\xD9\xDE\x3C\x16\x1F\x0F\xB3\xF4\x19\xC8\x7C\x3E\xCE\xD9\x3E" - "\x0F\x04\x64\x2C\xBE\x5A\x41\xE0\xD1\x99\xCF\xA8\xEE\x86\x74\x33\xB0\x85\xB3\xBC" - "\x78\x04\x28\xA7\xC3\xEC\xFB\x3C\x51\xD3\xC1\xFF\x02\x08\xAB\x06\x1F\x0E\x22\x37" - "\xA0\x1E\x3D\xC7\xC0\x46\xA2\x78\x3D\xDA\x60\xEE\x82\x34\xC3\xF0\xF9\xEE\x3B\xC7" - "\xB7\x4C\x1D\xD3\x61\xFC\x3E\x70\xB0\x82\x3B\xC7\xB4\xD8\x74\xB1\xD9\xFA\x3B\xA7" - "\x78\xF0\x7B\x8D\x87\xCE\x63\xE8\x8D\x84\x34\x82\x21\x55\x43\x0B\xEC\xD4\x2D\xFA" - "\x8E\xE9\xDE\x3C\x1B\x0E\x99\xDF\x76\x21\x97\xAA\xE9\x86\x2A\x2B\xF8\x79\x9F\x01" - "\x0F\x85\xF3\xBA\x08\x39\x51\xD3\xEE\xC4\x32\x2F\x55\xD3\x3E\x1F\x0E\x61\xFA\x3F" - "\x44\x6C\x3A\x7A\xAE\x85\xF8\xF8\x7C\x39\x4D\x90\x20\xF0\xFE\x6D\x3A\x84\x3C\x08" - "\x7C\x36\x1D\x3E\xFC\x33\x3B\xCC\xA9\x9B\x28\xE9\xE1\x81\x6D\x1D\xD3\xB0\xF7\x1C" - "\x87\x61\xDE\x3C\x16\x88\x7C\x10\xE9\xE1\x5A\x62\x8E\xE9\xDE\x3C\x69\x83\xBA\x08" - "\x92\x4F\x87\xC3\x8C\xEF\x1E\xD2\xA0\x45\xE1\x44\xF7\x1B\x41\x27\x05\x36\x9D\x02" - "\x7C\x3D\x42\x8F\xC0\x45\xC0\xCE\xD9\xF0\xDA\x78\x3D\xC0\xB9\xC3\xC8\x26\x71\xF4" - "\x15\x1F\x3C\xE8\x11\x39\x1D\x3A\x8F\xA1\x0E\xF1\xE0\xF7\x1E\xE3\xC1\xB0\xE9\x83" - "\x1F\x1D\xD3\xEC\x87\x89\x95\x1F\x67\x51\xF6\x1F\x8E\xD0\x67\x28\xF8\x7D\x9D\xB2" - "\xD1\x0E\xDE\x1D\x55\xF1\x6C\xEF\x1E\x0D\x87\x4F\x3E\x10\xEE\x9D\xE3\xC1\x80\x4A" - "\xC7\x4E\x53\x6D\x9D\xE3\xC1\xEE\x2F\xBA\x17\xFE\x46\x2C\x2F\x33\xC1\xEE\x1F\x08" - "\xEE\x84\x77\x8F\x01\x3A\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF1\xF0\xE3\x20\x45\xE6" - "\xC4\x51\xDD\x3B\xC7\xB4\x10\xF9\x6D\x3A\x58\x82\x13\x33\x7D\x44\x16\xFA\x9F\x3F" - "\x9D\xD3\xEC\xD1\x99\x09\x83\xFC\x7D\x9D\x40\x89\xC6\xFB\x04\x1E\x2F\x47\x02\x27" - "\x34\x67\x50\x67\xC6\x74\x34\x66\x44\x1E\x08\xCF\x1A\x60\xEE\x9C\xBF\x9F\x0F\x84" - "\x19\xFE\x3F\xC7\x31\x9F\x0F\x84\x19\xDE\x3D\xA3\x8E\x96\x2E\xB0\x3C\x1A\x30\x27" - "\x4C\xF8\x7D\xE1\x83\x07\xD9\xE0\xF7\x1C\xBF\x9F\x0F\x84\x19\xDA\x3B\xA7\x6C\xED" - "\x87\xC7\xE0\xA0\xC1\x0B\x8A\xE3\xF4\x7E\x8E\xE8\x7C\x7C\x04\x49\x67\x78\xEA\x1C" - "\x08\x5C\x71\x0A\x0C\xF7\x83\xE3\xAC\xE4\x3D\xF3\xFC\x7F\x8F\xB3\xEC\xEF\x1E\x78" - "\xCF\x87\xC2\x0C\xED\x1D\xD3\x8C\xFC\x3A\xCE\xB2\x0F\x81\x07\x10\x38\xC8\x14\xF0" - "\x83\x92\xCF\x87\xC2\x0C\xFD\x1F\xA3\xBA\x08\x99\x89\xF8\x72\x23\xF4\x7E\x88\x50" - "\x67\x41\x98\x30\xEE\x9D\xE3\xA8\x50\x67\x41\x7C\x08\x3C\x9C\x02\x16\x38\x77\x8E" - "\xA0\xF8\xF8\x71\x9D\xE3\xDC\x77\x8F\x07\xB8\x87\xC2\x3B\xA2\x8E\xF1\xE0\xF7\x1B"; +const size_t HTTP_SCRIPT_CONSOL_SIZE = 853; +const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x82\x30\x2F\x83\xAD\xCE\x41\x1D" + "\xD1\x87\x78\xF6\x99\xDF\xD0\x67\x56\x1F\x0F\xB3\xEC\xEA\xA3\xC0\x61\x3B\xF9\x56" + "\x8D\x78\x2E\x8E\xE8\x54\x77\x8F\x14\x7C\x63\x8E\xE9\xF7\x47\x21\xF6\x77\x8F\x05" + "\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7\x74\xFB\x0C\xE4\x3E\xCE" + "\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0\x78\x23\x21\x65\xF2\xD2" + "\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3\xC0\x21\x45\x3E\x1F\x67" + "\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD\x2A\x01\xF1\xEE\x3E\x02" + "\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE\x3D\xBA\x60\xEE\x9B\x0F" + "\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD\x3B\xC7\x83\xDC\x6C\x3E" + "\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F\xD4\x77\x4E\xF1\xE0\xD8" + "\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08\x7C\x28\x1D\xD0\x41\xCA" + "\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F" + "\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\x03\x69\xD4\x21\xE0\x43\xE1\xB0\xE9\xF7\xE1\x99" + "\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4\x3B\x0E\xF1\xE0\xB4\x43" + "\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44\x92\x7C\x3E\x1C\x67\x78" + "\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13\xE1\xEA\x14\x7E\x02\x2E" + "\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xDE\x1E\x4F\x71\xE0\xD8\x74\xC1\x8F\x8E\xE9\xF6" + "\x43\xC4\xCA\x8F\xB3\xA8\xFB\x0F\xC7\x68\x33\x94\x7C\x3E\xCE\xD9\x68\x87\x6F\x0E" + "\xAA\xF8\xB6\x77\x8F\x06\xC3\xA7\x9F\x08\x77\x4E\xF1\xE0\xF7\x05\x47\xCF\x3A\x04" + "\x4E\x4A\x4E\xA3\xE8\x43\xBC\x78\xFB\xA1\x7F\xE4\x62\xC2\xF3\x3C\x1E\xE1\xF0\x8E" + "\xE8\x47\x78\xF0\x67\x7F\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF0\x23\xF2\xF4\x28\xEE" + "\x9D\xE3\xDA\x08\x7C\xA2\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F\xCE\xE9\xF6" + "\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE2\xDD\x82\x0F\x12\xA3\x81\x13\x97\xB3\xA8" + "\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2\x0C\xFF\x1F" + "\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13\xA6\x7C\x3E" + "\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76\xC3\xE3\xF0" + "\x50\x60\x85\xC4\x31\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E\x04\x2E\x2E" + "\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C\x67\xC3\xE1" + "\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78\x41\xC9\x67" + "\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28\x33\xA0\xCC" + "\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x44\x01\x0B\x1C\x3B\xC7\x50\x7C\x7C" + "\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; #define HTTP_SCRIPT_CONSOL Decompress(HTTP_SCRIPT_CONSOL_COMPRESSED,HTTP_SCRIPT_CONSOL_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h index d7a530b43..2f61ce116 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -2,26 +2,26 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_ROOT_SIZE = 574; -const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x3D\xA1\x3A\x46\x28\xF0\x60\x5F\x07\x5B\x9C\x82\xB3\xBA\x30\xEF\x1E\xDB\x3E\x0C" - "\x3F\xC7\xF8\xFB\x3E\xCF\x01\x84\xEF\xE5\x5A\x35\xE0\xBA\x3B\xA6\x28\xEF\x02\x4C" - "\xD0\xA8\xEF\x1E\x34\xC1\xDD\x36\x1F\xC3\xE7\x0B\x08\x23\xBC\x7B\x4D\x87\x4B\x1D" - "\x9F\xA3\xBA\x77\x8F\x71\xB0\xF9\xCC\x7D\x11\xB0\x86\x90\x44\x2A\x2B\xA8\x61\x7D" - "\x9A\x85\xBF\x51\xDD\x3B\xC7\x83\x61\xD3\x3B\xEE\xC4\x32\xF5\x5D\x30\xC5\x5F\x0F" - "\x33\xE0\x21\xEA\xE7\x74\xEF\x1E\xDD\x30\x77\x4D\x87\x4F\xBB\x10\xC8\xBD\x57\x4C" - "\xF8\x7C\x39\x87\xE8\xFD\x11\xB0\xE9\xEA\xBA\x17\xE3\xE1\xF0\xE5\x36\x77\x8F\x69" - "\x19\xDF\xD7\x8F\x86\xC3\xA7\xDF\x86\x67\x79\x95\x33\x65\x1D\x3E\xC6\x05\x61\xB3" - "\xBA\x76\x1E\xDA\x3D\xC7\x60\xF1\xD4\x7B\x0F\x4A\xB1\xC1\x35\xEA\x32\x09\x9F\x0F" - "\xB1\xFD\x12\x85\x1E\x67\x23\x67\xD1\xF4\x7D\x9F\x87\xB0\xEF\x10\x23\x61\x5E\x04" - "\x2C\x2B\xE7\xE1\xE9\x42\x81\x26\xB8\xD0\x41\xAE\x76\x50\xA3\xF0\xF4\xA1\x01\x27" - "\x27\x39\x4C\x86\x1B\x0F\x03\xE2\xB6\x99\xD7\xE1\x96\x1B\x3C\xFB\x07\xFF\x63\x01" - "\x2B\x39\x60\x87\x8F\x08\x7E\x1E\x87\x65\x7C\x12\x6C\x86\x7B\x8E\xC1\xE3\xA8\xF6" - "\x1F\x47\xD1\xF6\x7E\x1E\x82\x69\x98\x21\xE7\x74\xCD\x94\x75\xD8\x5A\x3D\xC7\x98" - "\x6F\xA9\xFC\xF0\x63\x3A\x8E\xB1\xF7\xA3\xC2\xA8\xF3\x3D\x87\x78\xF0\xC7\x1D\xD3" - "\xEC\x23\x90\xFB\x3B\xC7\x42\xDE\xE7\xF2\x14\x54\x43\x48\x23\xE7\x81\x7B\x90\x10" - "\xA8\xF9\xE7\x40\x89\x3A\xCE\xA3\xE8\x43\xBC\x78\x3D\xC7\xB8\xF0\x6C\x3A\x60\xC7" - "\xC7\x74\xFB\x21\xE2\x65\x47\xD9\xD4\x7D\x9D\x0E\xD0\xD3\xE1\xC8\x7D\x9D\xB2\xB3" - "\xAA\xBE\x2D\x9D\xE3\xC1\xB0\xE9\xE7\xC2\x1D\xD3\xBC\x78\x30\x09\x78\xD1\xCA\x6D" - "\xB3\xBC\x78\x3D\xC7\xB8"; +const size_t HTTP_SCRIPT_ROOT_SIZE = 524; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x69\x9D\xFD\x59\xF0\xFB\x3E\xCF\x1A" + "\x60\xEE\x85\x67\x4B\xF8\xF0\xB1\xAF\xAB\xC7\x40\x9F\x0F\x50\xA3\xE1\xF0\xE4\x3B" + "\xC7\xB4\xAC\xF8\x30\xF0\x18\x4E\xFE\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE3\xC1\xEE" + "\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE" + "\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3" + "\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xDA" + "\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F" + "\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x80\x7F\x1F\x0D\x87" + "\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B" + "\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C" + "\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2" + "\x85\x02\x4D\x71\xA0\x83\x5C\xEC\xA1\x47\xE1\xE9\x42\x02\x4E\x4E\x72\x99\x0C\x36" + "\x1E\x07\xC5\x6D\x33\xAF\xC3\x2C\x36\x79\xF6\x0F\xFE\xC6\x02\x56\x72\xC1\x0F\x1E" + "\x10\xFC\x3D\x0E\xCA\xF8\x24\xD9\x0C\xF7\x1D\x83\xC7\x51\xEC\x3E\x8F\xA3\xEC\xFC" + "\x3D\x04\xD3\x30\x43\xCE\xE9\x9B\x28\xEB\xB0\xB4\x7B\x8F\x30\xDF\x53\xF9\xE0\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE6\x7B\x0E\xF1\xE1\x8E\x3B\xA7\xD8\x47\x21\xF6\x77" + "\x8E\x85\xBD\xCF\xE4\x28\xA8\x86\x90\x47\xCF\x1E\x0F\x71\xEE\x3C\x1B\x0E\x98\x31" + "\xF1\xDD\x3E\xC8\x78\x99\x51\xF6\x75\x1F\x67\x43\xB4\x34\xF8\x72\x1F\x67\x6C\xAC" + "\xEA\xAF\x8B\x67\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x02\xA3\xE7\x9D\x02\x27" + "\x23\x96\x75\x1F\x42\x1D\xE3\xC1\xEE"; #define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h index 1481a609c..bb52fbbcd 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -2,32 +2,32 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_ROOT_SIZE = 844; -const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x09\xD2\xF9\x8F\x0A\x3E\x1C\x87\x51\x18\xA3\xC1\x81\x7C\x1D\x6E\x72\x0A\xCE\xE8" - "\xC3\xBC\x7B\x6C\xF8\x30\xFF\x1F\xE3\xEC\xFB\x3C\x06\x13\xBF\x95\x68\xD7\x82\xE8" - "\xEE\x98\xA3\xBC\x09\x33\x42\xA3\xBC\x78\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E" - "\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D" - "\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65" - "\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xD6\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F" - "\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3" - "\xE1\xCA\x6C\xEF\x1E\xD2\x33\xBF\xAF\x1F\x0D\x87\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66" - "\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63" - "\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F" - "\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2\x85\x02\x4D\x71\xA0\x83\x5C\xEC" - "\xA1\x47\xE1\xE9\x42\x02\x4E\x4E\x72\x99\x0C\x36\x1E\x07\xC5\x6D\x33\xAF\xC3\x2C" - "\x36\x79\xF6\x0F\xFE\xC6\x02\x56\x72\xC1\x0F\x1E\x10\xFC\x3D\x0E\xCA\xF8\x24\xD9" - "\x0C\xF7\x1D\x83\xC7\x51\xEC\x3E\x8F\xA3\xEC\xFC\x3D\x04\xD3\x30\x43\xCE\xE9\x9B" - "\x28\xEB\xB0\xB4\x7B\x8F\x30\xDF\x53\xF9\xE0\xC6\x75\x1D\x63\xEF\x47\x85\x51\xE6" - "\x7B\x0E\xF1\xE1\x8E\x3B\xA7\xD8\x47\x21\xF6\x77\x8E\x85\xBD\xCF\xE4\x28\xA8\x86" - "\x90\x47\xCF\x03\x01\xE4\x0B\xE6\x3C\x28\xEF\x1E\xD0\xA8\xF9\xE7\x40\x89\x5E\xCE" - "\xA3\xE8\x43\xBC\x78\x3D\xC7\xB8\xF7\x02\x2D\xE3\x61\xD3\x06\x3E\x3B\xA7\xD9\x0F" - "\x13\x2A\x2B\x3E\xCE\xA3\xEC\xE8\x76\x86\x9F\x0E\x43\xEC\xED\x95\x9D\x55\xF1\x6C" - "\xEF\x1E\x0D\x87\x4F\x3E\x10\xEE\x9D\xE3\xC1\x80\x4B\xC9\x0E\x53\x6D\x9D\xE3\xC1" - "\xEE\x3D\xC4\x08\x9C\xD3\x79\x99\xD9\xDD\x19\x7F\x3A\xB4\xCE\xFE\x77\x8F\x68\x56" - "\x77\x4F\xB3\xF5\xE3\x33\xE1\xF6\x76\xF4\xCE\xFE\x76\xCF\xB3\xF6\x7D\x9D\xB1\x97" - "\xF3\xBC\x78\x04\x6C\x37\x41\x23\x0D\x04\x1E\x7E\x4F\x2A\x01\xA7\x8A\x7C\xC7\x85" - "\x1F\x0E\x32\x04\x6C\x6C\x67\xCE\xE9\x83\xBC\x7B\x74\xC1\xDD\x30\x77\x8F\x68\x26" - "\x70\xBA\x09\x9C\x3F\x82\x87\x0C\xA0\x85\xA7\x9E\xE6\x17\x98\x2F\x64\x2A\x01\x87" - "\xAF\x9E\xE3"; +const size_t HTTP_SCRIPT_ROOT_SIZE = 744; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x78\x23\x02\xF8\x3A\xDC\xE4\x15\x9D\xD1\x87\x78" + "\xF6\x99\xDF\xD5\x9F\x0F\xB3\xEC\xF1\xA6\x0E\xE8\x56\x74\xBF\x8F\x0B\x1A\xFA\xBC" + "\x74\x09\xF0\xF5\x0A\x3E\x1F\x0E\x43\xBC\x7B\x4A\xCF\x83\x0F\x01\x84\xEF\xE5\x5A" + "\x35\xE0\xBA\x3B\xA1\x51\xDE\x3C\x1E\xED\x30\x77\x4D\x87\xF0\xF9\xC2\xC2\x08\xEF" + "\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36\x10\xD2" + "\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8\x86\x5E" + "\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\xA0\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0\xE9\xF7" + "\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC\x7C\x3E" + "\x1C\xA6\xC8\x10\x78\x07\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\xD8" + "\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56\x38\x26\xBD\x46" + "\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0\xF6\x1D\xE2\x04" + "\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE\xCA\x14\x7E\x1E" + "\x94\x20\x24\xE4\xE7\x29\x90\xC3\x61\xE0\x7C\x56\xD3\x3A\xFC\x32\xC3\x67\x9F\x60" + "\xFF\xEC\x60\x25\x67\x2C\x10\xF1\xE1\x0F\xC3\xD0\xEC\xAF\x82\x4D\x90\xCF\x71\xD8" + "\x3C\x75\x1E\xC3\xE8\xFA\x3E\xCF\xC3\xD0\x4D\x33\x04\x3C\xEE\x99\xB2\x8E\xBB\x0B" + "\x47\xB8\xF3\x0D\xF5\x3F\x9E\x0C\x67\x51\xD6\x3E\xF4\x78\x55\x1E\x67\xB0\xEF\x1E" + "\x18\xE3\xBA\x7D\x84\x72\x1F\x67\x78\xE8\x5B\xDC\xFE\x42\x8A\x88\x69\x04\x7C\xF1" + "\xE0\xF7\x1E\xE3\xC6\x98\x47\x77\xE6\x3C\x28\xEF\x23\xDA\x6C\x3A\x60\xC7\xC7\x74" + "\xFB\x21\xE2\x65\x47\xD9\xD4\x7D\x9D\x0E\xD0\xD3\xE1\xC8\x7D\x9D\xB2\xB3\xAA\xBE" + "\x2D\x9D\xE3\xC1\xB0\xE9\xE7\xC2\x1D\xD3\xBC\x78\x0A\x8F\x9E\x74\x08\x9C\x93\xD9" + "\xD4\x7D\x08\x77\x8F\x07\xB8\xF7\x02\x27\x2E\x9E\x66\x76\x77\x46\x5F\xCE\xAD\x33" + "\xBF\x9D\xE3\xDA\x15\x9D\xD3\xEC\xFD\x78\xCC\xF8\x7D\x9D\xBD\x33\xBF\x9D\xB3\xEC" + "\xFD\x9F\x67\x6C\x65\xFC\xEF\x1E\x01\x1B\x0D\xD0\x48\xC3\x41\x0B\x9C\x40\x53\xC5" + "\x3E\x63\xC2\x8F\x87\x19\x02\x36\x36\x33\xE7\x74\xC1\xDE\x3D\xBA\x61\x1D\xD3\x07" + "\x79\x1E\xD0\x50\xDE\x81\x0B\x2F\x3D\xC9\x85\xE6\x8F\x68\x26\x73\xD0\x08\x79\x81" + "\xEE"; #define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h index 0351e828e..51cfb66a3 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h @@ -1,54 +1,49 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = - "{" - "let sn=0,id=0,ft;" // Scroll position, Get most of weblog initially - "function l(p){" // Console log and command service - "let c,o='';" - "clearTimeout(lt);" - "clearTimeout(ft);" - "t=eb('t1');" - "if(p==1){" - "c=eb('c1');" // Console command id - "o='&c1='+encodeURIComponent(c.value);" - "c.value='';" - "t.scrollTop=99999;" - "sn=t.scrollTop;" - "}" - "if(t.scrollTop>=sn){" // User scrolled back so no updates - "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) - "x=new XMLHttpRequest();" - "x.onreadystatechange=function(){" - "if(x.readyState==4&&x.status==200){" - "let z,d;" - "d=x.responseText.split(/}1/);" // Field separator - "id=d.shift();" - "if(d.shift()==0){t.value='';}" - "z=d.shift();" - "if(z.length>0){t.value+=z;}" - "t.scrollTop=99999;" - "sn=t.scrollTop;" - "clearTimeout(ft);" - "lt=setTimeout(l,%d);" // webrefresh timer.... - "}" - "};" - "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) - "x.send();" - "ft=setTimeout(l,20000);" // fail timeout, triggered 20s after asking for XHR - "}" - "return false;" + "var sn=0,id=0;" // Scroll position, Get most of weblog initially + "function l(p){" // Console log and command service + "var c,o='',t;" + "clearTimeout(lt);" + "t=eb('t1');" + "if(p==1){" + "c=eb('c1');" // Console command id + "o='&c1='+encodeURIComponent(c.value);" + "c.value='';" + "t.scrollTop=99999;" + "sn=t.scrollTop;" "}" - "wl(l);" // Load initial console text + "if(t.scrollTop>=sn){" // User scrolled back so no updates + "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) + "x=new XMLHttpRequest();" + "x.onreadystatechange=function(){" + "if(x.readyState==4&&x.status==200){" + "var z,d;" + "d=x.responseText.split(/}1/);" // Field separator + "id=d.shift();" + "if(d.shift()==0){t.value='';}" + "z=d.shift();" + "if(z.length>0){t.value+=z;}" + "t.scrollTop=99999;" + "sn=t.scrollTop;" + "}" + "};" + "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) + "x.send();" + "}" + "lt=setTimeout(l,%d);" + "return false;" + "}" + "wl(l);" // Load initial console text - // Console command history - "let hc=[],cn=0;" // hc = History commands, cn = Number of history being shown - "function h(){" - // "if(!(navigator.maxTouchPoints||'ontouchstart'in document.documentElement)){eb('c1').autocomplete='off';}" // No touch so stop browser autocomplete - "eb('c1').addEventListener('keydown',function(e){" - "let b=eb('c1'),c=e.keyCode;" // c1 = Console command id - "if(38==c||40==c){b.autocomplete='off';}" // ArrowUp or ArrowDown must be a keyboard so stop browser autocomplete - "38==c?(++cn>hc.length&&(cn=hc.length),b.value=hc[cn-1]||''):" // ArrowUp - "40==c?(0>--cn&&(cn=0),b.value=hc[cn-1]||''):" // ArrowDown - "13==c&&(hc.length>19&&hc.pop(),hc.unshift(b.value),cn=0)" // Enter, 19 = Max number -1 of commands in history - "});" - "}" - "wl(h);" // Add console command key eventlistener after name has been synced with id (= wl(jd)) - "}"; + // Console command history + "var hc=[],cn=0;" // hc = History commands, cn = Number of history being shown + "function h(){" +// "if(!(navigator.maxTouchPoints||'ontouchstart'in document.documentElement)){eb('c1').autocomplete='off';}" // No touch so stop browser autocomplete + "eb('c1').addEventListener('keydown',function(e){" + "var b=eb('c1'),c=e.keyCode;" // c1 = Console command id + "if(38==c||40==c){b.autocomplete='off';}" // ArrowUp or ArrowDown must be a keyboard so stop browser autocomplete + "38==c?(++cn>hc.length&&(cn=hc.length),b.value=hc[cn-1]||''):" // ArrowUp + "40==c?(0>--cn&&(cn=0),b.value=hc[cn-1]||''):" // ArrowDown + "13==c&&(hc.length>19&&hc.pop(),hc.unshift(b.value),cn=0)" // Enter, 19 = Max number -1 of commands in history + "});" + "}" + "wl(h);"; // Add console command key eventlistener after name has been synced with id (= wl(jd)) diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h index dd2cdc796..729bb54a5 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -1,9 +1,11 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = - "{let ft;" "function la(p){" - "a=p||'';" - "clearTimeout(ft);clearTimeout(lt);" - "if(x!=null){x.abort()}" // Abort if no response within 2 seconds (happens on restart 1) + "var a='';" + "if(la.arguments.length==1){" + "a=p;" + "clearTimeout(lt);" + "}" + "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" "if(x.readyState==4&&x.status==200){" @@ -14,11 +16,9 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = ".replace(/{e}/g,\"\")" ".replace(/{c}/g,\"%%'>

hasArg("m") "x.send();" - "ft=setTimeout(la,20000);" // 20s failure timeout - "}}"; + "lt=setTimeout(la,%d);" // Settings.web_refresh + "}"; diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h index ddb5e6941..2d76a8c91 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -1,8 +1,11 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = - "let rfsh=1,ft;" + "var rfsh=1;" "function la(p){" - "a=p||'';" - "clearTimeout(ft);clearTimeout(lt);" + "var a='';" + "if(la.arguments.length==1){" + "a=p;" + "clearTimeout(lt);" + "}" "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" @@ -14,16 +17,12 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = ".replace(/{e}/g,\"\")" ".replace(/{c}/g,\"%%'>
hasArg("m") "x.send();" - "ft=setTimeout(la,20000);" // 20s failure timeout + "lt=setTimeout(la,%d);" // Settings.web_refresh "}" "}" "function seva(par,ivar){" @@ -35,13 +34,11 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "rfsh=0;" "}" "function pr(f){" - "if(f){" - "clearTimeout(lt);clearTimeout(ft);" + "if (f) {" "lt=setTimeout(la,%d);" "rfsh=1;" - "}else{" - "clearTimeout(lt);clearTimeout(ft);" + "} else {" + "clearTimeout(lt);" "rfsh=0;" "}" - "}" - ; + "}"; From 6b2daa14d02c5e9689642c38824fc4390ab06724 Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Thu, 31 Dec 2020 11:36:35 +0000 Subject: [PATCH 077/105] Add mutex/semaphore for logging - protects new logging_buffer --- tasmota/support.ino | 105 ++++++++++++++++++++++++++++++++++++++++++++ tasmota/tasmota.ino | 1 + 2 files changed, 106 insertions(+) diff --git a/tasmota/support.ino b/tasmota/support.ino index fcf21a014..f12c6b007 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -111,6 +111,94 @@ String GetResetReason(void) } } + +/*********************************************************************************************\ + * ESP32 AutoMutex +\*********************************************************************************************/ + +////////////////////////////////////////// +// automutex. +// create a mute in your driver with: +// void *mutex = nullptr; +// TasAutoMutex::init(&mutex); +// +// then protect any function with +// TasAutoMutex m(mutex); +// - it will be automagically released when the function is over. +// - the same thread can take multiple times (recursive). +// - advanced options m.give() and m.take() allow you fine control within a function. +class TasAutoMutex { +#ifdef ESP32 + SemaphoreHandle_t mutex; +#endif + bool taken; + public: + TasAutoMutex(void * mutex, bool take=true); + ~TasAutoMutex(); + void give(); + void take(); + static void init(void ** ptr); +}; +////////////////////////////////////////// + +TasAutoMutex::TasAutoMutex(void * mutex, bool take){ +#ifdef ESP32 + if(mutex){ + if (take){ + xSemaphoreTakeRecursive(mutex, portMAX_DELAY); + this->taken = true; + } + this->mutex = (SemaphoreHandle_t ) mutex; + } else { + this->mutex = (SemaphoreHandle_t )nullptr; + } +#endif +} + +TasAutoMutex::~TasAutoMutex(){ +#ifdef ESP32 + if (this->mutex){ + if (this->taken){ + xSemaphoreGiveRecursive(this->mutex); + this->taken = false; + } + } +#endif +} + +void TasAutoMutex::init(void ** ptr){ +#ifdef ESP32 + SemaphoreHandle_t mutex = xSemaphoreCreateRecursiveMutex(); + (*ptr) = (void *) mutex; +#else + // needed, else we will initialis more than once in logging + (*ptr) = (void *) 1; +#endif +} + +void TasAutoMutex::give(){ +#ifdef ESP32 + if (this->mutex){ + if (this->taken){ + xSemaphoreGiveRecursive(this->mutex); + this->taken= false; + } + } +#endif +} +void TasAutoMutex::take(){ +#ifdef ESP32 + if (this->mutex){ + if (!this->taken){ + xSemaphoreTakeRecursive(this->mutex, portMAX_DELAY); + this->taken = true; + } + } +#endif +} + + + /*********************************************************************************************\ * Miscellaneous \*********************************************************************************************/ @@ -1958,6 +2046,10 @@ void SyslogAsync(bool refresh) { } bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) { + // this takes the mutex, and will be release when the class is destroyed - + // i.e. when the functon leaves You CAN call mutex.give() to leave early. + TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + // Skip initial buffer fill if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - LOGSZ) { return false; } @@ -1973,6 +2065,10 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l if (TasmotaGlobal.uptime < 3) { return false; } // Allow time to setup correct log level if (!req_loglevel || (index == TasmotaGlobal.log_buffer_pointer)) { return false; } + // this takes the mutex, and will be release when the class is destroyed - + // i.e. when the functon leaves You CAN call mutex.give() to leave early. + TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + if (!index) { // Dump all index = TasmotaGlobal.log_buffer_pointer +1; if (index > 255) { index = 1; } @@ -2011,9 +2107,18 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l } void AddLogData(uint32_t loglevel, const char* log_data) { + + if (!TasmotaGlobal.log_buffer_mutex){ + TasAutoMutex::init(&TasmotaGlobal.log_buffer_mutex); + } + char mxtime[14]; // "13:45:21.999 " snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d.%03d "), RtcTime.hour, RtcTime.minute, RtcTime.second, RtcMillis()); + // this takes the mutex, and will be release when the class is destroyed - + // i.e. when the functon leaves You CAN call mutex.give() to leave early. + TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + if ((loglevel <= TasmotaGlobal.seriallog_level) && (TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) { Serial.printf("%s%s\r\n", mxtime, log_data); diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b70bd4637..cf35a1fa7 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -171,6 +171,7 @@ struct { char mqtt_topic[TOPSZ]; // Composed MQTT topic char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer char log_buffer[LOG_BUFFER_SIZE]; // Web log buffer + void *log_buffer_mutex; // control, access to log buffer } TasmotaGlobal; #ifdef SUPPORT_IF_STATEMENT From 0c38aca915e2bf620d880e79892138dc232d0a4a Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Thu, 31 Dec 2020 12:31:22 +0000 Subject: [PATCH 078/105] MAC compatible httm webtimout changes --- tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h | 67 ++++++++++--------- .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 42 ++++++------ .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 53 +++++++-------- .../html_uncompressed/HTTP_SCRIPT_CONSOL.h | 10 ++- .../HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h | 14 ++-- .../HTTP_SCRIPT_ROOT_WEB_DISPLAY.h | 27 ++++---- 6 files changed, 110 insertions(+), 103 deletions(-) diff --git a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h index 91e1fab76..ba7f0677d 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_CONSOL.h @@ -2,38 +2,39 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_CONSOL_SIZE = 853; -const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x82\x30\x2F\x83\xAD\xCE\x41\x1D" - "\xD1\x87\x78\xF6\x99\xDF\xD0\x67\x56\x1F\x0F\xB3\xEC\xEA\xA3\xC0\x61\x3B\xF9\x56" - "\x8D\x78\x2E\x8E\xE8\x54\x77\x8F\x14\x7C\x63\x8E\xE9\xF7\x47\x21\xF6\x77\x8F\x05" - "\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7\x74\xFB\x0C\xE4\x3E\xCE" - "\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0\x78\x23\x21\x65\xF2\xD2" - "\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3\xC0\x21\x45\x3E\x1F\x67" - "\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD\x2A\x01\xF1\xEE\x3E\x02" - "\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE\x3D\xBA\x60\xEE\x9B\x0F" - "\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD\x3B\xC7\x83\xDC\x6C\x3E" - "\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F\xD4\x77\x4E\xF1\xE0\xD8" - "\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08\x7C\x28\x1D\xD0\x41\xCA" - "\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F" - "\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\x03\x69\xD4\x21\xE0\x43\xE1\xB0\xE9\xF7\xE1\x99" - "\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4\x3B\x0E\xF1\xE0\xB4\x43" - "\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44\x92\x7C\x3E\x1C\x67\x78" - "\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13\xE1\xEA\x14\x7E\x02\x2E" - "\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xDE\x1E\x4F\x71\xE0\xD8\x74\xC1\x8F\x8E\xE9\xF6" - "\x43\xC4\xCA\x8F\xB3\xA8\xFB\x0F\xC7\x68\x33\x94\x7C\x3E\xCE\xD9\x68\x87\x6F\x0E" - "\xAA\xF8\xB6\x77\x8F\x06\xC3\xA7\x9F\x08\x77\x4E\xF1\xE0\xF7\x05\x47\xCF\x3A\x04" - "\x4E\x4A\x4E\xA3\xE8\x43\xBC\x78\xFB\xA1\x7F\xE4\x62\xC2\xF3\x3C\x1E\xE1\xF0\x8E" - "\xE8\x47\x78\xF0\x67\x7F\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF0\x23\xF2\xF4\x28\xEE" - "\x9D\xE3\xDA\x08\x7C\xA2\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F\xCE\xE9\xF6" - "\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE2\xDD\x82\x0F\x12\xA3\x81\x13\x97\xB3\xA8" - "\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2\x0C\xFF\x1F" - "\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13\xA6\x7C\x3E" - "\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76\xC3\xE3\xF0" - "\x50\x60\x85\xC4\x31\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E\x04\x2E\x2E" - "\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C\x67\xC3\xE1" - "\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78\x41\xC9\x67" - "\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28\x33\xA0\xCC" - "\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x44\x01\x0B\x1C\x3B\xC7\x50\x7C\x7C" - "\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; +const size_t HTTP_SCRIPT_CONSOL_SIZE = 911; +const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x51\x18\xA3\xC1\x81\x7C\x1D\x6E" + "\x72\x08\xEE\x8C\x3B\xC7\xB4\xCE\xFE\x83\x3A\xB0\xF8\x7D\x9F\x67\x80\xC2\x77\xF2" + "\xAD\x1A\xF0\x5D\x1D\xD0\xA8\xEF\x02\x4C\xD3\x14\x77\x8F\x14\x7C\x63\x8E\xE9\xF7" + "\x47\x21\xF6\x77\x8F\x05\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7" + "\x74\xFB\x0C\xE4\x3E\xCE\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0" + "\x78\x23\x21\x65\xF2\xD2\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3" + "\xC0\x21\x45\x3E\x1F\x67\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD" + "\x2A\x01\xF1\xEE\x3E\x02\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE" + "\x3D\xBA\x60\xEE\x9B\x0F\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD" + "\x3B\xC7\x83\xDC\x6C\x3E\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F" + "\xD4\x77\x4E\xF1\xE0\xD8\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08" + "\x7C\x2F\x9D\xD0\x41\xCA\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA" + "\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\xF3\x69\xD4\x21\xE0\x43" + "\xE1\xB0\xE9\xF7\xE1\x99\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4" + "\x3B\x0E\xF1\xE0\xB4\x43\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44" + "\x92\x7C\x3E\x1C\x67\x78\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13" + "\xE1\xEA\x14\x7E\x02\x2E\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xCE\x1E\x41\x33\x8F\xA0" + "\xA8\xF9\xE7\x40\x89\xC8\xE9\xD4\x7D\x08\x77\x8F\x07\xB8\xF7\x1E\x0D\x87\x4C\x18" + "\xF8\xEE\x9F\x64\x3C\x4C\xA8\xFB\x3A\x8F\xB0\xFC\x76\x83\x39\x47\xC3\xEC\xED\x96" + "\x88\x76\xF0\xEA\xAF\x8B\x67\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x0C\x02\x56" + "\x3A\x72\x9B\x6C\xEF\x1E\x0F\x71\x7D\xD0\xBF\xF2\x31\x61\x79\x9E\x0F\x70\xF8\x47" + "\x74\x23\xBC\x78\x33\xBF\xA1\x41\x9F\x0F\x78\xF7\xCE\xA0\xF8\xF8\x71\x90\x22\xF3" + "\x62\x28\xEE\x9D\xE3\xDA\x08\x7C\xB6\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F" + "\xCE\xE9\xF6\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE3\x7D\x82\x0F\x17\xA3\x81\x13" + "\x9A\x33\xA8\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2" + "\x0C\xFF\x1F\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13" + "\xA6\x7C\x3E\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76" + "\xC3\xE3\xF0\x50\x60\x85\xC5\x71\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E" + "\x04\x2E\x38\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C" + "\x67\xC3\xE1\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78" + "\x41\xC9\x67\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28" + "\x33\xA0\xCC\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x4E\x01\x0B\x1C\x3B\xC7" + "\x50\x7C\x7C\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; #define HTTP_SCRIPT_CONSOL Decompress(HTTP_SCRIPT_CONSOL_COMPRESSED,HTTP_SCRIPT_CONSOL_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h index 2f61ce116..862ecf0f6 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -2,26 +2,26 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_ROOT_SIZE = 524; -const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x69\x9D\xFD\x59\xF0\xFB\x3E\xCF\x1A" - "\x60\xEE\x85\x67\x4B\xF8\xF0\xB1\xAF\xAB\xC7\x40\x9F\x0F\x50\xA3\xE1\xF0\xE4\x3B" - "\xC7\xB4\xAC\xF8\x30\xF0\x18\x4E\xFE\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE3\xC1\xEE" - "\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE" - "\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3" - "\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xDA" - "\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F" - "\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x80\x7F\x1F\x0D\x87" - "\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B" - "\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C" - "\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2" - "\x85\x02\x4D\x71\xA0\x83\x5C\xEC\xA1\x47\xE1\xE9\x42\x02\x4E\x4E\x72\x99\x0C\x36" - "\x1E\x07\xC5\x6D\x33\xAF\xC3\x2C\x36\x79\xF6\x0F\xFE\xC6\x02\x56\x72\xC1\x0F\x1E" - "\x10\xFC\x3D\x0E\xCA\xF8\x24\xD9\x0C\xF7\x1D\x83\xC7\x51\xEC\x3E\x8F\xA3\xEC\xFC" - "\x3D\x04\xD3\x30\x43\xCE\xE9\x9B\x28\xEB\xB0\xB4\x7B\x8F\x30\xDF\x53\xF9\xE0\xC6" - "\x75\x1D\x63\xEF\x47\x85\x51\xE6\x7B\x0E\xF1\xE1\x8E\x3B\xA7\xD8\x47\x21\xF6\x77" - "\x8E\x85\xBD\xCF\xE4\x28\xA8\x86\x90\x47\xCF\x1E\x0F\x71\xEE\x3C\x1B\x0E\x98\x31" - "\xF1\xDD\x3E\xC8\x78\x99\x51\xF6\x75\x1F\x67\x43\xB4\x34\xF8\x72\x1F\x67\x6C\xAC" - "\xEA\xAF\x8B\x67\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x02\xA3\xE7\x9D\x02\x27" - "\x23\x96\x75\x1F\x42\x1D\xE3\xC1\xEE"; +const size_t HTTP_SCRIPT_ROOT_SIZE = 572; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xA3\x14\x78\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x6D\x9F\x06\x1F" + "\xE3\xFC\x7D\x9F\x67\x80\xC2\x77\xF2\xAD\x1A\xF0\x5D\x1D\xD3\x14\x77\x81\x26\x68" + "\x54\x77\x8F\x1A\x60\xEE\x9B\x0F\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF" + "\xD1\xDD\x3B\xC7\xB8\xD8\x7C\xE6\x3E\x88\xD8\x43\x48\x22\x15\x54\x30\xBE\xCD\x42" + "\xDF\xA8\xEE\x9D\xE3\xC1\xB0\xE9\x9D\xF7\x62\x19\x7A\xAE\x98\x62\xAF\x87\x99\xF0" + "\x10\xF5\x73\xBA\x77\x8F\x6E\x98\x3B\xA6\xC3\xA7\xDD\x88\x64\x5E\xAB\xA6\x7C\x3E" + "\x1C\xC3\xF4\x7E\x88\xD8\x74\xF5\x5D\x0B\xF1\xF0\xF8\x72\x9B\x3B\xC7\xB4\x8C\xEF" + "\xEB\xC7\xC3\x61\xD3\xEF\xC3\x33\xBC\xCA\x99\xB2\x8E\x9F\x63\x02\xB0\xD9\xDD\x3B" + "\x0F\x6D\x1E\xE3\xB0\x78\xEA\x3D\x87\xA5\x58\xE0\x9A\xF5\x19\x04\xCF\x87\xD8\xFE" + "\x89\x42\x8F\x33\x91\xB3\xE8\xFA\x3E\xCF\xC3\xD8\x77\x88\x11\xB0\xAF\x02\x16\x15" + "\xF3\xF0\xF4\xA1\x40\x93\x5C\x68\x20\xD7\x3B\x28\x51\xF8\x7A\x50\x80\x93\x93\x9C" + "\xA6\x43\x0D\x87\x81\xF1\x5B\x4C\xEB\xF0\xCB\x0D\x9E\x7D\x83\xFF\xB1\x80\x95\x9C" + "\xB0\x43\xC7\x84\x3F\x0F\x43\xB2\xBE\x09\x36\x43\x3D\xC7\x60\xF1\xD4\x7B\x0F\xA3" + "\xE8\xFB\x3F\x0F\x41\x34\xCC\x10\xF3\xBA\x66\xCA\x3A\xEC\x2D\x1E\xE3\xCC\x37\xD4" + "\xFE\x78\x31\x9D\x47\x58\xFB\xD1\xE1\x54\x79\x9E\xC3\xBC\x78\x63\x8E\xE9\xF6\x11" + "\xC8\x7D\x9D\xE3\xA1\x6F\x73\xF9\x0A\x2A\x2B\x21\xA4\x11\xF3\xC0\xBD\xC8\x08\x54" + "\x7C\xF3\xA0\x44\x9D\x67\x51\xF4\x21\xDE\x3C\x1E\xE3\xDC\x78\x36\x1D\x30\x63\xE3" + "\xBA\x7D\x90\xF1\x32\xA3\xEC\xEA\x3E\xCE\x87\x68\x69\xF0\xE4\x3E\xCE\xD9\x59\xD5" + "\x5F\x16\xCE\xF1\xE0\xD8\x74\xF3\xE1\x0E\xE9\xDE\x3C\x18\x04\xBC\x68\xE5\x36\xD9" + "\xDE\x3C\x1E\xE3"; #define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h index bb52fbbcd..d211338a1 100644 --- a/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h +++ b/tasmota/html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -2,32 +2,31 @@ // compressed by tools/unishox/compress-html-uncompressed.py ///////////////////////////////////////////////////////////////////// -const size_t HTTP_SCRIPT_ROOT_SIZE = 744; -const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x78\x23\x02\xF8\x3A\xDC\xE4\x15\x9D\xD1\x87\x78" - "\xF6\x99\xDF\xD5\x9F\x0F\xB3\xEC\xF1\xA6\x0E\xE8\x56\x74\xBF\x8F\x0B\x1A\xFA\xBC" - "\x74\x09\xF0\xF5\x0A\x3E\x1F\x0E\x43\xBC\x7B\x4A\xCF\x83\x0F\x01\x84\xEF\xE5\x5A" - "\x35\xE0\xBA\x3B\xA1\x51\xDE\x3C\x1E\xED\x30\x77\x4D\x87\xF0\xF9\xC2\xC2\x08\xEF" - "\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36\x10\xD2" - "\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8\x86\x5E" - "\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\xA0\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0\xE9\xF7" - "\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC\x7C\x3E" - "\x1C\xA6\xC8\x10\x78\x07\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\xD8" - "\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56\x38\x26\xBD\x46" - "\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0\xF6\x1D\xE2\x04" - "\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE\xCA\x14\x7E\x1E" - "\x94\x20\x24\xE4\xE7\x29\x90\xC3\x61\xE0\x7C\x56\xD3\x3A\xFC\x32\xC3\x67\x9F\x60" - "\xFF\xEC\x60\x25\x67\x2C\x10\xF1\xE1\x0F\xC3\xD0\xEC\xAF\x82\x4D\x90\xCF\x71\xD8" - "\x3C\x75\x1E\xC3\xE8\xFA\x3E\xCF\xC3\xD0\x4D\x33\x04\x3C\xEE\x99\xB2\x8E\xBB\x0B" - "\x47\xB8\xF3\x0D\xF5\x3F\x9E\x0C\x67\x51\xD6\x3E\xF4\x78\x55\x1E\x67\xB0\xEF\x1E" - "\x18\xE3\xBA\x7D\x84\x72\x1F\x67\x78\xE8\x5B\xDC\xFE\x42\x8A\x88\x69\x04\x7C\xF1" - "\xE0\xF7\x1E\xE3\xC6\x98\x47\x77\xE6\x3C\x28\xEF\x23\xDA\x6C\x3A\x60\xC7\xC7\x74" - "\xFB\x21\xE2\x65\x47\xD9\xD4\x7D\x9D\x0E\xD0\xD3\xE1\xC8\x7D\x9D\xB2\xB3\xAA\xBE" - "\x2D\x9D\xE3\xC1\xB0\xE9\xE7\xC2\x1D\xD3\xBC\x78\x0A\x8F\x9E\x74\x08\x9C\x93\xD9" - "\xD4\x7D\x08\x77\x8F\x07\xB8\xF7\x02\x27\x2E\x9E\x66\x76\x77\x46\x5F\xCE\xAD\x33" - "\xBF\x9D\xE3\xDA\x15\x9D\xD3\xEC\xFD\x78\xCC\xF8\x7D\x9D\xBD\x33\xBF\x9D\xB3\xEC" - "\xFD\x9F\x67\x6C\x65\xFC\xEF\x1E\x01\x1B\x0D\xD0\x48\xC3\x41\x0B\x9C\x40\x53\xC5" - "\x3E\x63\xC2\x8F\x87\x19\x02\x36\x36\x33\xE7\x74\xC1\xDE\x3D\xBA\x61\x1D\xD3\x07" - "\x79\x1E\xD0\x50\xDE\x81\x0B\x2F\x3D\xC9\x85\xE6\x8F\x68\x26\x73\xD0\x08\x79\x81" - "\xEE"; +const size_t HTTP_SCRIPT_ROOT_SIZE = 844; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x75\x11\x8A\x3C\x18\x17\xC1\xD6\xE7\x20\xAC\xEE" + "\x8C\x3B\xC7\xB6\xCF\x83\x0F\xF1\xFE\x3E\xCF\xB3\xC0\x61\x3B\xF9\x56\x8D\x78\x2E" + "\x8E\xE9\x8A\x3B\xC0\x93\x34\x2A\x2B\x3B\xC7\x8D\x30\x77\x4D\x87\xF0\xF9\xC2\xC2" + "\x08\xEF\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36" + "\x10\xD2\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8" + "\x86\x5E\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\x60\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0" + "\xE9\xF7\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC" + "\x7C\x3E\x1C\xA6\xCE\xF1\xED\x23\x3B\xFA\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6" + "\x6C\xA3\xA7\xD8\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56" + "\x38\x26\xBD\x46\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0" + "\xF6\x1D\xE2\x04\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE" + "\xCA\x14\x7E\x1E\x94\x20\x24\xE4\xE7\x29\x90\xC3\x61\xE0\x7C\x56\xD3\x3A\xFC\x32" + "\xC3\x67\x9F\x60\xFF\xEC\x60\x25\x67\x2C\x10\xF1\xE1\x0F\xC3\xD0\xEC\xAF\x82\x4D" + "\x90\xCF\x71\xD8\x3C\x75\x1E\xC3\xE8\xFA\x3E\xCF\xC3\xD0\x4D\x33\x04\x3C\xEE\x99" + "\xB2\x8E\xBB\x0B\x47\xB8\xF3\x0D\xF5\x3F\x9E\x0C\x67\x51\xD6\x3E\xF4\x78\x55\x1E" + "\x67\xB0\xEF\x1E\x18\xE3\xBA\x7D\x84\x72\x1F\x67\x78\xE8\x5B\xDC\xFE\x42\x8A\x88" + "\x69\x04\x7C\xF0\x30\x1E\x40\xBE\x63\xC2\x8E\xF1\xED\x0A\x8F\x9E\x74\x08\x95\xEC" + "\xEA\x3E\x84\x3B\xC7\x83\xDC\x7B\x8F\x70\x22\xDE\x36\x1D\x30\x63\xE3\xBA\x7D\x90" + "\xF1\x32\xA3\xEC\xEA\x3E\xCE\x87\x68\x69\xF0\xE4\x3E\xCE\xD9\x59\xD5\x5F\x16\xCE" + "\xF1\xE0\xD8\x74\xF3\xE1\x0E\xE9\xDE\x3C\x18\x04\xBC\x90\xE5\x36\xD9\xDE\x3C\x1E" + "\xE3\xDC\x40\x89\xCD\x37\x99\x9D\x9D\xD1\x97\xF3\xAB\x4C\xEF\xE7\x78\xF6\x85\x67" + "\x74\xFB\x3F\x5E\x33\x3E\x1F\x67\x6F\x4C\xEF\xE7\x6C\xFB\x3F\x67\xD9\xDB\x19\x7F" + "\x3B\xC7\x80\x46\xC3\x74\x12\x30\xD0\x41\xE7\xE4\xF0\x0A\x78\xA7\xCC\x78\x51\xF0" + "\xE3\x20\x46\xC6\xC6\x7C\xEE\x98\x3B\xC7\xB7\x4C\x1D\xD3\x07\x78\xF6\x82\x67\x0B" + "\xA0\x99\xC3\xF8\x28\x70\xCA\x08\x5A\x79\xEE\x61\x79\x82\xF6\x40\x08\x7A\xF9\xEE"; #define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() \ No newline at end of file diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h b/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h index 51cfb66a3..451bc7a7f 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_CONSOL.h @@ -1,8 +1,9 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = - "var sn=0,id=0;" // Scroll position, Get most of weblog initially + "var sn=0,id=0,ft;" // Scroll position, Get most of weblog initially "function l(p){" // Console log and command service - "var c,o='',t;" + "var c,o='';" "clearTimeout(lt);" + "clearTimeout(ft);" "t=eb('t1');" "if(p==1){" "c=eb('c1');" // Console command id @@ -24,12 +25,14 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "if(z.length>0){t.value+=z;}" "t.scrollTop=99999;" "sn=t.scrollTop;" + "clearTimeout(ft);" + "lt=setTimeout(l,%d);" // webrefresh timer.... "}" "};" "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) "x.send();" + "ft=setTimeout(l,20000);" // fail timeout, triggered 20s after asking for XHR "}" - "lt=setTimeout(l,%d);" "return false;" "}" "wl(l);" // Load initial console text @@ -47,3 +50,4 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "});" "}" "wl(h);"; // Add console command key eventlistener after name has been synced with id (= wl(jd)) + diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h index 729bb54a5..41e519502 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h @@ -1,11 +1,9 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = + "var ft;" "function la(p){" - "var a='';" - "if(la.arguments.length==1){" - "a=p;" - "clearTimeout(lt);" - "}" - "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) + "a=p||'';" + "clearTimeout(ft);clearTimeout(lt);" + "if(x!=null){x.abort()}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" "if(x.readyState==4&&x.status==200){" @@ -16,9 +14,11 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = ".replace(/{e}/g,\"\")" ".replace(/{c}/g,\"%%'>
hasArg("m") "x.send();" - "lt=setTimeout(la,%d);" // Settings.web_refresh + "ft=setTimeout(la,20000);" // 20s failure timeout "}"; diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h index 2d76a8c91..5bd8a4ec7 100644 --- a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h +++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h @@ -1,11 +1,8 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = - "var rfsh=1;" + "var rfsh=1,ft;" "function la(p){" - "var a='';" - "if(la.arguments.length==1){" - "a=p;" - "clearTimeout(lt);" - "}" + "a=p||'';" + "clearTimeout(ft);clearTimeout(lt);" "if(x!=null){x.abort();}" // Abort if no response within 2 seconds (happens on restart 1) "x=new XMLHttpRequest();" "x.onreadystatechange=function(){" @@ -17,12 +14,16 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = ".replace(/{e}/g,\"\")" ".replace(/{c}/g,\"%%'>
hasArg("m") "x.send();" - "lt=setTimeout(la,%d);" // Settings.web_refresh + "ft=setTimeout(la,20000);" // 20s failure timeout "}" "}" "function seva(par,ivar){" @@ -34,11 +35,13 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "rfsh=0;" "}" "function pr(f){" - "if (f) {" + "if(f){" + "clearTimeout(lt);clearTimeout(ft);" "lt=setTimeout(la,%d);" "rfsh=1;" - "} else {" - "clearTimeout(lt);" + "}else{" + "clearTimeout(lt);clearTimeout(ft);" "rfsh=0;" "}" - "}"; + "}" + ; From 58e6ec55f1a4b4390ee85efdaf0cc9ed78a4e5c9 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 31 Dec 2020 16:17:30 +0100 Subject: [PATCH 079/105] Breaking change replacing SPI CS and SPI DC Breaking change replacing SPI CS and SPI DC by device specific CS and DC --- CHANGELOG.md | 15 ++- RELEASENOTES.md | 13 ++- tasmota/support.ino | 36 +++++- tasmota/support_tasmota.ino | 110 ++++++------------ tasmota/tasmota.h | 2 + tasmota/tasmota.ino | 4 +- tasmota/tasmota_configurations_ESP32.h | 5 + tasmota/tasmota_template.h | 18 +-- tasmota/xdrv_33_nrf24l01.ino | 33 +++--- tasmota/xdsp_04_ili9341.ino | 153 +++++++++++-------------- tasmota/xdsp_05_epaper_29.ino | 54 +++++---- tasmota/xdsp_06_epaper_42.ino | 63 +++++----- tasmota/xdsp_08_ILI9488.ino | 78 +++++-------- tasmota/xdsp_09_SSD1351.ino | 28 ++--- tasmota/xdsp_10_RA8876.ino | 44 ++----- tasmota/xdsp_12_ST7789.ino | 66 ++++------- tasmota/xsns_61_MI_NRF24.ino | 21 ++-- tasmota/xsns_80_mfrc522.ino | 2 +- 18 files changed, 325 insertions(+), 420 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d542934fa..3f1a34e5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,19 @@ All notable changes to this project will be documented in this file. ## [9.2.0.2] ### Added - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) -- Command ``CTRange`` to specify the visible CT range the bulb is capable of -- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels +- Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311) +- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels (#10311) ### Breaking Changed -- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` -- Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` +- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``SPI CS`` by ``RC522 CS`` +- Replaced NRF24L01 GPIO selection from ``SPI CS`` by ``NRF24 CS`` and ``SPI DC`` by ``NRF24 DC`` +- Replaced ILI9341 GPIO selection from ``SPI CS`` by ``ILI9341 CS`` and ``SPI DC`` by ``ILI9341 DC`` +- Replaced ST7789 GPIO selection from ``SPI CS`` by ``ST7789 CS`` and ``SPI DC`` by ``ST7789 DC`` +- Replaced ILI9488 GPIO selection from ``SPI CS`` by ``ILI9488_CS`` +- Replaced EPaper29 GPIO selection from ``SPI CS`` by ``EPaper29 CS`` +- Replaced EPaper42 GPIO selection from ``SPI CS`` by ``EPaper42 CS`` +- Replaced SSD1351 GPIO selection from ``SPI CS`` by ``SSD1351 CS`` +- Replaced RA8876 GPIO selection from ``SPI CS`` by ``RA8876 CS`` ## [9.2.0.1] 20201229 ### Added diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6f02fa36f..83cfe63c7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,6 +58,8 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota ## Changelog v9.2.0.2 ### Added +- Command ``CTRange`` to specify the visible CT range the bulb is capable of [#10311](https://github.com/arendst/Tasmota/issues/10311) +- Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels [#10311](https://github.com/arendst/Tasmota/issues/10311) - Milliseconds to console output [#10152](https://github.com/arendst/Tasmota/issues/10152) - Gpio ``Option_a1`` enabling PWM2 high impedance if powered off as used by Wyze bulbs [#10196](https://github.com/arendst/Tasmota/issues/10196) - BSSID and Signal Strength Indicator to GUI wifi scan result [#10253](https://github.com/arendst/Tasmota/issues/10253) @@ -71,8 +73,15 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630) ### Breaking Changed -- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_RC522_CS`` -- Replaced ILI9341 GPIO selection from ``GPIO_SPI_CS`` by ``GPIO_ILI9341_CS`` and ``GPIO_SPI_DC`` by ``GPIO_ILI9341_DC`` +- Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``SPI CS`` by ``RC522 CS`` +- Replaced NRF24L01 GPIO selection from ``SPI CS`` by ``NRF24 CS`` and ``SPI DC`` by ``NRF24 DC`` +- Replaced ILI9341 GPIO selection from ``SPI CS`` by ``ILI9341 CS`` and ``SPI DC`` by ``ILI9341 DC`` +- Replaced ST7789 GPIO selection from ``SPI CS`` by ``ST7789 CS`` and ``SPI DC`` by ``ST7789 DC`` +- Replaced ILI9488 GPIO selection from ``SPI CS`` by ``ILI9488_CS`` +- Replaced EPaper29 GPIO selection from ``SPI CS`` by ``EPaper29 CS`` +- Replaced EPaper42 GPIO selection from ``SPI CS`` by ``EPaper42 CS`` +- Replaced SSD1351 GPIO selection from ``SPI CS`` by ``SSD1351 CS`` +- Replaced RA8876 GPIO selection from ``SPI CS`` by ``RA8876 CS`` ### Changed - Logging from heap to stack freeing 700 bytes RAM diff --git a/tasmota/support.ino b/tasmota/support.ino index fcf21a014..215c8ea1d 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1479,8 +1479,7 @@ bool FlashPin(uint32_t pin) return (((pin > 5) && (pin < 9)) || (11 == pin)); } -uint32_t ValidPin(uint32_t pin, uint32_t gpio) -{ +uint32_t ValidPin(uint32_t pin, uint32_t gpio) { if (FlashPin(pin)) { return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11 } @@ -1495,8 +1494,7 @@ uint32_t ValidPin(uint32_t pin, uint32_t gpio) return gpio; } -bool ValidGPIO(uint32_t pin, uint32_t gpio) -{ +bool ValidGPIO(uint32_t pin, uint32_t gpio) { #ifdef ESP8266 #ifdef USE_ADC_VCC if (ADC0_PIN == pin) { return false; } // ADC0 = GPIO17 @@ -1505,6 +1503,17 @@ bool ValidGPIO(uint32_t pin, uint32_t gpio) return (GPIO_USER == ValidPin(pin, BGPIO(gpio))); // Only allow GPIO_USER pins } +bool ValidSpiGPIO(uint32_t gpio) { + // ESP8266: If SPI pin selected chk if it's not one of the three Hardware SPI pins (12..14) + bool result = true; // Not used and therefore valid + uint32_t pin; + if (PinUsed(gpio)) { + pin = Pin(gpio); + result = ((pin < 12) || (pin > 14)); + } + return result; +} + bool JsonTemplate(char* dataBuf) { // Old: {"NAME":"Shelly 2.5","GPIO":[56,0,17,0,21,83,0,0,6,82,5,22,156],"FLAG":2,"BASE":18} @@ -2106,6 +2115,25 @@ void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32 AddLogData(loglevel, log_data); } +void AddLogSpi(bool hardware, uint32_t clk, uint32_t mosi, uint32_t miso) { + // Needs optimization + uint32_t enabled = (hardware) ? TasmotaGlobal.spi_enabled : TasmotaGlobal.soft_spi_enabled; + switch(enabled) { + case SPI_MOSI: + AddLog_P(LOG_LEVEL_INFO, PSTR("SPI: %s using GPIO%02d(CLK) and GPIO%02d(MOSI)"), + (hardware) ? PSTR("Hardware") : PSTR("Software"), clk, mosi); + break; + case SPI_MISO: + AddLog_P(LOG_LEVEL_INFO, PSTR("SPI: %s using GPIO%02d(CLK) and GPIO%02d(MISO)"), + (hardware) ? PSTR("Hardware") : PSTR("Software"), clk, miso); + break; + case SPI_MOSI_MISO: + AddLog_P(LOG_LEVEL_INFO, PSTR("SPI: %s using GPIO%02d(CLK), GPIO%02d(MOSI) and GPIO%02d(MISO)"), + (hardware) ? PSTR("Hardware") : PSTR("Software"), clk, mosi, miso); + break; + } +} + /*********************************************************************************************\ * Uncompress static PROGMEM strings \*********************************************************************************************/ diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 58b79e905..b6178f4bc 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1596,29 +1596,33 @@ void GpioInit(void) if ((2 == Pin(GPIO_TXD)) || (H801 == TasmotaGlobal.module_type)) { Serial.set_tx(2); } #endif - TasmotaGlobal.soft_spi_enabled = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); + uint32_t sspi_mosi = (PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_MOSI)) ? SPI_MOSI : SPI_NONE; + uint32_t sspi_miso = (PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_MISO)) ? SPI_MISO : SPI_NONE; + TasmotaGlobal.soft_spi_enabled = sspi_mosi + sspi_miso; + AddLogSpi(0, Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI), PinUsed(GPIO_SSPI_MISO)); #ifdef USE_SPI - uint32_t pin_cs = Pin(GPIO_SPI_CS); - uint32_t pin_dc = Pin(GPIO_SPI_DC); - if (PinUsed(GPIO_RC522_CS)) { - pin_cs = Pin(GPIO_RC522_CS); - } - if (PinUsed(GPIO_ILI9341_CS)) { - pin_cs = Pin(GPIO_ILI9341_CS); - if (PinUsed(GPIO_ILI9341_DC)) { - pin_dc = Pin(GPIO_ILI9341_DC); - } - } - #ifdef ESP8266 if (!TasmotaGlobal.soft_spi_enabled) { - // If SPI_CS is used it must be valid - TasmotaGlobal.spi_enabled = ((pin_cs < 99) && ((pin_cs > 14) || (pin_cs < 12))); - if (TasmotaGlobal.spi_enabled && (pin_dc < 99)) { - // If SPI_DC is used it must be valid - TasmotaGlobal.spi_enabled = ((pin_dc > 14) || (pin_dc < 12)); - } + bool valid_cs = (ValidSpiGPIO(GPIO_SPI_CS) && + ValidSpiGPIO(GPIO_RC522_CS) && + ValidSpiGPIO(GPIO_NRF24_CS) && + ValidSpiGPIO(GPIO_ILI9341_CS) && + ValidSpiGPIO(GPIO_EPAPER29_CS) && + ValidSpiGPIO(GPIO_EPAPER42_CS) && + ValidSpiGPIO(GPIO_ILI9488_CS) && + ValidSpiGPIO(GPIO_SSD1351_CS) && + ValidSpiGPIO(GPIO_RA8876_CS) && + ValidSpiGPIO(GPIO_ST7789_CS) + ); + bool valid_dc = (ValidSpiGPIO(GPIO_SPI_DC) && + ValidSpiGPIO(GPIO_NRF24_DC) && + ValidSpiGPIO(GPIO_ILI9341_DC) && + ValidSpiGPIO(GPIO_ST7789_DC) + ); + + // If SPI_CS and/or SPI_DC is used they must be valid + TasmotaGlobal.spi_enabled = (valid_cs && valid_dc) ? SPI_MOSI_MISO : SPI_NONE; if (TasmotaGlobal.spi_enabled) { TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); SetPin(12, AGPIO(GPIO_SPI_MISO)); @@ -1626,65 +1630,27 @@ void GpioInit(void) SetPin(13, AGPIO(GPIO_SPI_MOSI)); TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); SetPin(14, AGPIO(GPIO_SPI_CLK)); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK)")); } } #endif // ESP8266 #ifdef ESP32 - if (pin_cs < 99) { -/* - // Do not do this as ESP32 can have SPI_CS everywhere - if ((15 == pin_cs) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI - TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); - SetPin(12, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); - SetPin(13, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); - SetPin(14, AGPIO(GPIO_SPI_CLK)); - } - else if ((5 == pin_cs) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI - TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); - SetPin(19, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); - SetPin(23, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[18] = AGPIO(GPIO_SPI_CLK); - SetPin(18, AGPIO(GPIO_SPI_CLK)); - } - else if ((12 == Pin(GPIO_SPI_MISO)) || (13 == Pin(GPIO_SPI_MOSI)) || (14 == Pin(GPIO_SPI_CLK))) { // HSPI - TasmotaGlobal.my_module.io[12] = AGPIO(GPIO_SPI_MISO); - SetPin(12, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[13] = AGPIO(GPIO_SPI_MOSI); - SetPin(13, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[14] = AGPIO(GPIO_SPI_CLK); - SetPin(14, AGPIO(GPIO_SPI_CLK)); - } - else if ((19 == Pin(GPIO_SPI_MISO)) || (23 == Pin(GPIO_SPI_MOSI)) || (18 == Pin(GPIO_SPI_CLK))) { // VSPI - TasmotaGlobal.my_module.io[19] = AGPIO(GPIO_SPI_MISO); - SetPin(19, AGPIO(GPIO_SPI_MISO)); - TasmotaGlobal.my_module.io[23] = AGPIO(GPIO_SPI_MOSI); - SetPin(23, AGPIO(GPIO_SPI_MOSI)); - TasmotaGlobal.my_module.io[18] = AGPIO(GPIO_SPI_CLK); - SetPin(18, AGPIO(GPIO_SPI_CLK)); - } - TasmotaGlobal.spi_enabled = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); -*/ - TasmotaGlobal.spi_enabled = (pin_cs < 99); - if (TasmotaGlobal.spi_enabled) { - if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); - } - else if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); - } - else if (PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), - Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); - } - } + if (PinUsed(GPIO_SPI_CS) || + PinUsed(GPIO_RC522_CS) || + PinUsed(GPIO_NRF24_CS) || + PinUsed(GPIO_ILI9341_CS) || + PinUsed(GPIO_EPAPER29_CS) || + PinUsed(GPIO_EPAPER42_CS) || + PinUsed(GPIO_ILI9488_CS) || + PinUsed(GPIO_SSD1351_CS) || + PinUsed(GPIO_RA8876_CS) || + PinUsed(GPIO_ST7789_CS) + ) { + uint32_t spi_mosi = (PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MOSI)) ? SPI_MOSI : SPI_NONE; + uint32_t spi_miso = (PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MISO)) ? SPI_MISO : SPI_NONE; + TasmotaGlobal.spi_enabled = spi_mosi + spi_miso; } #endif // ESP32 + AddLogSpi(1, Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO)); #endif // USE_SPI for (uint32_t i = 0; i < ARRAY_SIZE(TasmotaGlobal.my_module.io); i++) { diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 759655956..20f150f69 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -313,6 +313,8 @@ enum SettingsTextIndex { SET_OTAURL, SET_SHD_PARAM, SET_MAX }; +enum SpiInterfaces { SPI_NONE, SPI_MOSI, SPI_MISO, SPI_MOSI_MISO }; + enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND, DGR_MSGTYPFLAG_WITH_LOCAL = 128 }; enum DevGroupMessageFlag { DGR_FLAG_RESET = 1, DGR_FLAG_STATUS_REQUEST = 2, DGR_FLAG_FULL_STATUS = 4, DGR_FLAG_ACK = 8, DGR_FLAG_MORE_TO_COME = 16, DGR_FLAG_DIRECT = 32, DGR_FLAG_ANNOUNCEMENT = 64, DGR_FLAG_LOCAL = 128 }; diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b70bd4637..183606909 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -119,8 +119,6 @@ struct { bool blinkstate; // LED state bool pwm_present; // Any PWM channel configured with SetOption15 0 bool i2c_enabled; // I2C configured - bool spi_enabled; // SPI configured - bool soft_spi_enabled; // Software SPI configured bool ntp_force_sync; // Force NTP sync bool is_8285; // Hardware device ESP8266EX (0) or ESP8285 (1) bool skip_light_fade; // Temporarily skip light fading @@ -128,6 +126,8 @@ struct { bool module_changed; // Indicate module changed since last restart StateBitfield global_state; // Global states (currently Wifi and Mqtt) (8 bits) + uint8_t spi_enabled; // SPI configured + uint8_t soft_spi_enabled; // Software SPI configured uint8_t blinks; // Number of LED blinks uint8_t restart_flag; // Tasmota restart flag uint8_t ota_state_flag; // OTA state flag diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index c3bb7044b..2f21ed0aa 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -46,6 +46,11 @@ #undef CODE_IMAGE_STR #define CODE_IMAGE_STR "odroid-go" +#undef MODULE +#define MODULE ODROID_GO // [Module] Select default module from tasmota_template.h +#undef FALLBACK_MODULE +#define FALLBACK_MODULE ODROID_GO // [Module2] Select default module on fast reboot where USER_MODULE is user template + #define USE_ODROID_GO // Add support for Odroid Go #define USE_ADC #define USE_SPI diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 46915f280..786eeed08 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -365,8 +365,8 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SPI_CS), // SPI Chip Select AGPIO(GPIO_SPI_DC), // SPI Data Direction #ifdef USE_NRF24 -// AGPIO(GPIO_NRF24_CS), -// AGPIO(GPIO_NRF24_DC), + AGPIO(GPIO_NRF24_CS), + AGPIO(GPIO_NRF24_DC), #endif #ifdef USE_RC522 AGPIO(GPIO_RC522_CS), // RC522 Rfid Chip Select @@ -386,23 +386,23 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command #ifdef USE_DISPLAY #ifdef USE_DISPLAY_ILI9488 -// AGPIO(GPIO_ILI9488_CS), + AGPIO(GPIO_ILI9488_CS), #endif // USE_DISPLAY_ILI9488 #ifdef USE_DISPLAY_EPAPER_29 -// AGPIO(GPIO_EPAPER29_CS), + AGPIO(GPIO_EPAPER29_CS), #endif // USE_DISPLAY_EPAPER_29 #ifdef USE_DISPLAY_EPAPER_42 -// AGPIO(GPIO_EPAPER42_CS), + AGPIO(GPIO_EPAPER42_CS), #endif // USE_DISPLAY_EPAPER_42 #ifdef USE_DISPLAY_SSD1351 -// AGPIO(GPIO_SSD1351_CS), + AGPIO(GPIO_SSD1351_CS), #endif // USE_DISPLAY_SSD1351 #ifdef USE_DISPLAY_RA8876 -// AGPIO(GPIO_RA8876_CS), + AGPIO(GPIO_RA8876_CS), #endif // USE_DISPLAY_RA8876 #ifdef USE_DISPLAY_ST7789 -// AGPIO(GPIO_ST7789_CS), -// AGPIO(GPIO_ST7789_DC), + AGPIO(GPIO_ST7789_CS), + AGPIO(GPIO_ST7789_DC), #endif //f USE_DISPLAY_ST7789 AGPIO(GPIO_BACKLIGHT), // Display backlight control AGPIO(GPIO_OLED_RESET), // OLED Display Reset diff --git a/tasmota/xdrv_33_nrf24l01.ino b/tasmota/xdrv_33_nrf24l01.ino index 7c4d1b843..b1e8d43c4 100644 --- a/tasmota/xdrv_33_nrf24l01.ino +++ b/tasmota/xdrv_33_nrf24l01.ino @@ -34,7 +34,7 @@ /*********************************************************************************************\ * NRF24l01(+) * -* Usage: 5 SPI-data-wires plus VVC/ground, use hardware SPI, select GPIO_SPI_CS/GPIO_SPI_DC +* Usage: 5 SPI-data-wires plus VVC/ground, use hardware SPI, select GPIO_NRF24_CS/GPIO_NRF24_DC \*********************************************************************************************/ #define XDRV_33 33 @@ -51,45 +51,40 @@ struct { RF24 NRF24radio; -bool NRF24initRadio() -{ - NRF24radio.begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); +bool NRF24initRadio() { + NRF24radio.begin(Pin(GPIO_NRF24_CS), Pin(GPIO_NRF24_DC)); NRF24radio.powerUp(); - if(NRF24radio.isChipConnected()){ - DEBUG_DRIVER_LOG(PSTR("NRF24 chip connected")); + if (NRF24radio.isChipConnected()) { + DEBUG_DRIVER_LOG(PSTR("NRF: Chip connected")); return true; } - DEBUG_DRIVER_LOG(PSTR("NRF24 chip NOT !!!! connected")); + DEBUG_DRIVER_LOG(PSTR("NRF: Chip NOT !!!! connected")); return false; } -bool NRF24Detect(void) -{ - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { - if(NRF24initRadio()){ +void NRF24Detect(void) { + if (PinUsed(GPIO_NRF24_CS) && PinUsed(GPIO_NRF24_DC) && TasmotaGlobal.spi_enabled) { + if (NRF24initRadio()) { NRF24.chipType = 32; // SPACE - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF24L01 initialized")); - if(NRF24radio.isPVariant()){ + AddLog_P(LOG_LEVEL_INFO, PSTR("NRF: Model 24L01 initialized")); + if (NRF24radio.isPVariant()) { NRF24.chipType = 43; // + - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF24L01+ detected")); + AddLog_P(LOG_LEVEL_INFO, PSTR("NRF: Model 24L01+ detected")); } - return true; } } - return false; } /*********************************************************************************************\ * Interface \*********************************************************************************************/ -bool Xdrv33(uint8_t function) -{ +bool Xdrv33(uint8_t function) { bool result = false; if (FUNC_INIT == function) { - result = NRF24Detect(); + NRF24Detect(); } return result; } diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index adabfe6b0..50f19ac02 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -38,6 +38,7 @@ uint16_t tft_top = TFT_TOP; uint16_t tft_bottom = TFT_BOTTOM; uint16_t tft_scroll = TFT_TOP; uint16_t tft_cols = 0; +bool tft_init_done = false; /*********************************************************************************************/ @@ -57,8 +58,7 @@ bool Ili9341Header(void) { return (tft_cols > 17); } -void Ili9341InitMode(void) -{ +void Ili9341InitMode(void) { tft->setRotation(Settings.display_rotate); // 0 tft->invertDisplay(0); tft->fillScreen(ILI9341_BLACK); @@ -78,8 +78,7 @@ void Ili9341InitMode(void) } } -void Ili9341Init(uint8_t mode) -{ +void Ili9341Init(uint8_t mode) { switch(mode) { case DISPLAY_INIT_MODE: Ili9341InitMode(); @@ -95,24 +94,11 @@ void Ili9341Init(uint8_t mode) } } -void Ili9341InitDriver(void) -{ - uint32_t pin_cs = Pin(GPIO_SPI_CS); - uint32_t pin_dc = Pin(GPIO_SPI_DC); - if (!Settings.display_model) { - if (PinUsed(GPIO_ILI9341_CS)) { - pin_cs = Pin(GPIO_ILI9341_CS); - if (PinUsed(GPIO_ILI9341_DC)) { - pin_dc = Pin(GPIO_ILI9341_DC); - } - Settings.display_model = XDSP_04; - } +void Ili9341InitDriver(void) { + if (PinUsed(GPIO_ILI9341_CS) && PinUsed(GPIO_ILI9341_DC) && TasmotaGlobal.spi_enabled) { - // Legacy Settings.display_model = XDSP_04; - } - if (XDSP_04 == Settings.display_model) { if (Settings.display_width != ILI9341_TFTWIDTH) { Settings.display_width = ILI9341_TFTWIDTH; } @@ -120,7 +106,7 @@ void Ili9341InitDriver(void) Settings.display_height = ILI9341_TFTHEIGHT; } - tft = new Adafruit_ILI9341(pin_cs, pin_dc); + tft = new Adafruit_ILI9341(Pin(GPIO_ILI9341_CS), Pin(GPIO_ILI9341_DC)); tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 @@ -131,18 +117,17 @@ void Ili9341InitDriver(void) Ili9341InitMode(); + tft_init_done = true; AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: ILI9341")); } } -void Ili9341Clear(void) -{ +void Ili9341Clear(void) { tft->fillScreen(ILI9341_BLACK); tft->setCursor(0, 0); } -void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) -{ +void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag) { uint16_t active_color = ILI9341_WHITE; tft->setTextSize(Settings.display_size); @@ -156,8 +141,7 @@ void Ili9341DrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint tft->println(str); } -void Ili9341DisplayOnOff() -{ +void Ili9341DisplayOnOff() { // tft->showDisplay(disp_power); // tft->invertDisplay(disp_power); if (PinUsed(GPIO_BACKLIGHT)) { @@ -170,8 +154,7 @@ void Ili9341DisplayOnOff() #ifdef USE_DISPLAY_MODES1TO5 -void Ili9341PrintLog(void) -{ +void Ili9341PrintLog(void) { disp_refresh--; if (!disp_refresh) { disp_refresh = Settings.display_refresh; @@ -217,8 +200,7 @@ void Ili9341PrintLog(void) } } -void Ili9341Refresh(void) // Every second -{ +void Ili9341Refresh(void) { // Every second if (Settings.display_mode) { // Mode 0 is User text // 24-04-2017 13:45:43 = 19 + 1 ('\0') = 20 // 24-04-2017 13:45 = 16 + 1 ('\0') = 17 @@ -263,73 +245,70 @@ void Ili9341Refresh(void) // Every second * Interface \*********************************************************************************************/ -bool Xdsp04(uint8_t function) -{ +bool Xdsp04(uint8_t function) { bool result = false; - if (TasmotaGlobal.spi_enabled) { - if (FUNC_DISPLAY_INIT_DRIVER == function) { - Ili9341InitDriver(); - } - else if (XDSP_04 == Settings.display_model) { + if (FUNC_DISPLAY_INIT_DRIVER == function) { + Ili9341InitDriver(); + } + else if (tft_init_done && (XDSP_04 == Settings.display_model)) { - if (!dsp_color) { dsp_color = ILI9341_WHITE; } + if (!dsp_color) { dsp_color = ILI9341_WHITE; } - switch (function) { - case FUNC_DISPLAY_MODEL: - result = true; - break; - case FUNC_DISPLAY_INIT: - Ili9341Init(dsp_init); - break; - case FUNC_DISPLAY_POWER: - Ili9341DisplayOnOff(); - break; - case FUNC_DISPLAY_CLEAR: - Ili9341Clear(); - break; - case FUNC_DISPLAY_DRAW_HLINE: - tft->writeFastHLine(dsp_x, dsp_y, dsp_len, dsp_color); - break; - case FUNC_DISPLAY_DRAW_VLINE: - tft->writeFastVLine(dsp_x, dsp_y, dsp_len, dsp_color); - break; - case FUNC_DISPLAY_DRAW_LINE: - tft->writeLine(dsp_x, dsp_y, dsp_x2, dsp_y2, dsp_color); - break; - case FUNC_DISPLAY_DRAW_CIRCLE: - tft->drawCircle(dsp_x, dsp_y, dsp_rad, dsp_color); - break; - case FUNC_DISPLAY_FILL_CIRCLE: - tft->fillCircle(dsp_x, dsp_y, dsp_rad, dsp_color); - break; - case FUNC_DISPLAY_DRAW_RECTANGLE: - tft->drawRect(dsp_x, dsp_y, dsp_x2, dsp_y2, dsp_color); - break; - case FUNC_DISPLAY_FILL_RECTANGLE: - tft->fillRect(dsp_x, dsp_y, dsp_x2, dsp_y2, dsp_color); - break; + switch (function) { + case FUNC_DISPLAY_MODEL: + result = true; + break; + case FUNC_DISPLAY_INIT: + Ili9341Init(dsp_init); + break; + case FUNC_DISPLAY_POWER: + Ili9341DisplayOnOff(); + break; + case FUNC_DISPLAY_CLEAR: + Ili9341Clear(); + break; + case FUNC_DISPLAY_DRAW_HLINE: + tft->writeFastHLine(dsp_x, dsp_y, dsp_len, dsp_color); + break; + case FUNC_DISPLAY_DRAW_VLINE: + tft->writeFastVLine(dsp_x, dsp_y, dsp_len, dsp_color); + break; + case FUNC_DISPLAY_DRAW_LINE: + tft->writeLine(dsp_x, dsp_y, dsp_x2, dsp_y2, dsp_color); + break; + case FUNC_DISPLAY_DRAW_CIRCLE: + tft->drawCircle(dsp_x, dsp_y, dsp_rad, dsp_color); + break; + case FUNC_DISPLAY_FILL_CIRCLE: + tft->fillCircle(dsp_x, dsp_y, dsp_rad, dsp_color); + break; + case FUNC_DISPLAY_DRAW_RECTANGLE: + tft->drawRect(dsp_x, dsp_y, dsp_x2, dsp_y2, dsp_color); + break; + case FUNC_DISPLAY_FILL_RECTANGLE: + tft->fillRect(dsp_x, dsp_y, dsp_x2, dsp_y2, dsp_color); + break; // case FUNC_DISPLAY_DRAW_FRAME: // oled->display(); // break; - case FUNC_DISPLAY_TEXT_SIZE: - tft->setTextSize(Settings.display_size); - break; - case FUNC_DISPLAY_FONT_SIZE: + case FUNC_DISPLAY_TEXT_SIZE: + tft->setTextSize(Settings.display_size); + break; + case FUNC_DISPLAY_FONT_SIZE: // tft->setTextSize(Settings.display_font); - break; - case FUNC_DISPLAY_DRAW_STRING: - Ili9341DrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag); - break; - case FUNC_DISPLAY_ROTATION: - tft->setRotation(Settings.display_rotate); - break; + break; + case FUNC_DISPLAY_DRAW_STRING: + Ili9341DrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag); + break; + case FUNC_DISPLAY_ROTATION: + tft->setRotation(Settings.display_rotate); + break; #ifdef USE_DISPLAY_MODES1TO5 - case FUNC_DISPLAY_EVERY_SECOND: - Ili9341Refresh(); - break; + case FUNC_DISPLAY_EVERY_SECOND: + Ili9341Refresh(); + break; #endif // USE_DISPLAY_MODES1TO5 - } } } return result; diff --git a/tasmota/xdsp_05_epaper_29.ino b/tasmota/xdsp_05_epaper_29.ino index 08fcbcf9b..5655f7a19 100644 --- a/tasmota/xdsp_05_epaper_29.ino +++ b/tasmota/xdsp_05_epaper_29.ino @@ -39,18 +39,18 @@ //unsigned char image[(EPD_HEIGHT * EPD_WIDTH) / 8]; extern uint8_t *buffer; uint16_t epd_scroll; +bool epd_init_done = false; Epd *epd; /*********************************************************************************************/ -void EpdInitDriver29() -{ - if (!Settings.display_model) { - Settings.display_model = XDSP_05; - } +void EpdInitDriver29(void) { + if (PinUsed(GPIO_EPAPER29_CS) && + ((TasmotaGlobal.soft_spi_enabled & SPI_MOSI) || (TasmotaGlobal.spi_enabled & SPI_MOSI))) { + + Settings.display_model = XDSP_05; - if (XDSP_05 == Settings.display_model) { if (Settings.display_width != EPD_WIDTH) { Settings.display_width = EPD_WIDTH; } @@ -64,19 +64,14 @@ void EpdInitDriver29() if (!buffer) return; // init renderer - epd = new Epd(EPD_WIDTH,EPD_HEIGHT); + epd = new Epd(EPD_WIDTH, EPD_HEIGHT); // whiten display with full update, takes 3 seconds - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MOSI)) { - epd->Begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK)); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("EPD: HardSPI CS %d, CLK %d, MOSI %d"),Pin(GPIO_SPI_CS), Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MOSI)); + if (TasmotaGlobal.soft_spi_enabled) { + epd->Begin(Pin(GPIO_EPAPER29_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK)); } - else if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_MOSI)) { - epd->Begin(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK)); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("EPD: SoftSPI CS %d, CLK %d, MOSI %d"),Pin(GPIO_SSPI_CS), Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI)); - } else { - free(buffer); - return; + else if (TasmotaGlobal.spi_enabled) { + epd->Begin(Pin(GPIO_EPAPER29_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); } renderer = epd; @@ -95,6 +90,8 @@ void EpdInitDriver29() renderer->fillScreen(0); #endif + epd_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: E-Paper 2.9")); } } @@ -186,21 +183,22 @@ void EpdRefresh29(void) // Every second bool Xdsp05(uint8_t function) { bool result = false; - if (FUNC_DISPLAY_INIT_DRIVER == function) { - EpdInitDriver29(); - } - else if (XDSP_05 == Settings.display_model) { - switch (function) { - case FUNC_DISPLAY_MODEL: - result = true; - break; + + if (FUNC_DISPLAY_INIT_DRIVER == function) { + EpdInitDriver29(); + } + else if (epd_init_done && (XDSP_05 == Settings.display_model)) { + switch (function) { + case FUNC_DISPLAY_MODEL: + result = true; + break; #ifdef USE_DISPLAY_MODES1TO5 - case FUNC_DISPLAY_EVERY_SECOND: - EpdRefresh29(); - break; + case FUNC_DISPLAY_EVERY_SECOND: + EpdRefresh29(); + break; #endif // USE_DISPLAY_MODES1TO5 - } } + } return result; } diff --git a/tasmota/xdsp_06_epaper_42.ino b/tasmota/xdsp_06_epaper_42.ino index fee42db6c..4947d6667 100644 --- a/tasmota/xdsp_06_epaper_42.ino +++ b/tasmota/xdsp_06_epaper_42.ino @@ -35,19 +35,18 @@ #include extern uint8_t *buffer; +bool epd42_init_done = false; Epd42 *epd42; /*********************************************************************************************/ -void EpdInitDriver42() -{ - if (!Settings.display_model) { - Settings.display_model = XDSP_06; - } +void EpdInitDriver42() { + if (PinUsed(GPIO_EPAPER42_CS) && + ((TasmotaGlobal.soft_spi_enabled & SPI_MOSI) || (TasmotaGlobal.spi_enabled & SPI_MOSI))) { - if (XDSP_06 == Settings.display_model) { + Settings.display_model = XDSP_06; if (Settings.display_width != EPD_WIDTH42) { Settings.display_width = EPD_WIDTH42; @@ -62,23 +61,14 @@ void EpdInitDriver42() if (!buffer) return; // init renderer - epd42 = new Epd42(EPD_WIDTH42,EPD_HEIGHT42); + epd42 = new Epd42(EPD_WIDTH42, EPD_HEIGHT42); - #ifdef USE_SPI - if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)) { - epd42->Begin(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK)); - } else { - free(buffer); - return; - } - #else - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { - epd42->Begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK)); - } else { - free(buffer); - return; - } - #endif + if (TasmotaGlobal.soft_spi_enabled) { + epd42->Begin(Pin(GPIO_EPAPER42_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK)); + } + else if (TasmotaGlobal.spi_enabled) { + epd42->Begin(Pin(GPIO_EPAPER42_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } renderer = epd42; @@ -105,6 +95,8 @@ void EpdInitDriver42() renderer->fillScreen(0); #endif + epd42_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: E-Paper 4.2")); } } @@ -134,27 +126,24 @@ bool Xdsp06(uint8_t function) { bool result = false; - if (FUNC_DISPLAY_INIT_DRIVER == function) { - EpdInitDriver42(); - } - else if (XDSP_06 == Settings.display_model) { - - switch (function) { - case FUNC_DISPLAY_MODEL: - result = true; - break; - + if (FUNC_DISPLAY_INIT_DRIVER == function) { + EpdInitDriver42(); + } + else if (epd42_init_done && (XDSP_06 == Settings.display_model)) { + switch (function) { + case FUNC_DISPLAY_MODEL: + result = true; + break; #ifdef USE_DISPLAY_MODES1TO5 - case FUNC_DISPLAY_EVERY_SECOND: - EpdRefresh42(); - break; + case FUNC_DISPLAY_EVERY_SECOND: + EpdRefresh42(); + break; #endif // USE_DISPLAY_MODES1TO5 - } } + } return result; } - #endif // USE_DISPLAY_EPAPER42 #endif // USE_DISPLAY #endif // USE_SPI diff --git a/tasmota/xdsp_08_ILI9488.ino b/tasmota/xdsp_08_ILI9488.ino index af8ac03a1..a64c626bd 100644 --- a/tasmota/xdsp_08_ILI9488.ino +++ b/tasmota/xdsp_08_ILI9488.ino @@ -34,6 +34,7 @@ #include uint8_t ili9488_ctouch_counter = 0; +bool ili9488_init_done = false; // currently fixed #define BACKPLANE_PIN 2 @@ -45,13 +46,10 @@ extern const uint16_t picture[]; /*********************************************************************************************/ -void ILI9488_InitDriver() -{ - if (!Settings.display_model) { - Settings.display_model = XDSP_08; - } +void ILI9488_InitDriver(void) { + if (PinUsed(GPIO_ILI9488_CS) && (TasmotaGlobal.spi_enabled & SPI_MOSI)) { - if (XDSP_08 == Settings.display_model) { + Settings.display_model = XDSP_08; if (Settings.display_width != ILI9488_TFTWIDTH) { Settings.display_width = ILI9488_TFTWIDTH; @@ -61,44 +59,19 @@ void ILI9488_InitDriver() } // disable screen buffer - buffer=NULL; + buffer = NULL; // default colors fg_color = ILI9488_WHITE; bg_color = ILI9488_BLACK; - uint8_t bppin=BACKPLANE_PIN; - if (PinUsed(GPIO_BACKLIGHT)) { - bppin=Pin(GPIO_BACKLIGHT); + uint8_t bppin = BACKPLANE_PIN; + if (PinUsed(GPIO_BACKLIGHT)) { + bppin = Pin(GPIO_BACKLIGHT); } -#ifdef ESP8266 -#undef HW_SPI_MOSI -#define HW_SPI_MOSI 13 -#undef HW_SPI_MISO -#define HW_SPI_MISO 12 -#undef HW_SPI_CLK -#define HW_SPI_CLK 14 -#endif // ESP8266 -#ifdef ESP32 -#undef HW_SPI_MOSI -#define HW_SPI_MOSI 23 -#undef HW_SPI_MISO -#define HW_SPI_MISO 19 -#undef HW_SPI_CLK -#define HW_SPI_CLK 18 -#endif // ESP32 - // init renderer, must use hardware spi - if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { - ili9488 = new ILI9488(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),bppin); - } else { - if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK)) { - ili9488 = new ILI9488(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK),bppin); - } else { - return; - } - } + ili9488 = new ILI9488(Pin(GPIO_ILI9488_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK), bppin); ili9488->begin(); renderer = ili9488; @@ -120,6 +93,9 @@ void ILI9488_InitDriver() #ifdef USE_FT5206 Touch_Init(Wire); #endif + + ili9488_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: ILI9488")); } } @@ -170,25 +146,23 @@ bool Xdsp08(uint8_t function) { bool result = false; - if (FUNC_DISPLAY_INIT_DRIVER == function) { - ILI9488_InitDriver(); - } - else if (XDSP_08 == Settings.display_model) { - - switch (function) { - case FUNC_DISPLAY_MODEL: - result = true; - break; - case FUNC_DISPLAY_EVERY_50_MSECOND: + if (FUNC_DISPLAY_INIT_DRIVER == function) { + ILI9488_InitDriver(); + } + else if (ili9488_init_done && (XDSP_08 == Settings.display_model)) { + switch (function) { + case FUNC_DISPLAY_MODEL: + result = true; + break; + case FUNC_DISPLAY_EVERY_50_MSECOND: #ifdef USE_TOUCH_BUTTONS - if (FT5206_found) { - ILI9488_CheckTouch(); - } + if (FT5206_found) { + ILI9488_CheckTouch(); + } #endif - break; - } + break; } - //} + } return result; } diff --git a/tasmota/xdsp_09_SSD1351.ino b/tasmota/xdsp_09_SSD1351.ino index 1b17bd08a..2e4337e9b 100644 --- a/tasmota/xdsp_09_SSD1351.ino +++ b/tasmota/xdsp_09_SSD1351.ino @@ -33,6 +33,7 @@ #include +bool ssd1351_init_done = false; extern uint8_t *buffer; extern uint8_t color_type; SSD1351 *ssd1351; @@ -40,11 +41,10 @@ SSD1351 *ssd1351; /*********************************************************************************************/ void SSD1351_InitDriver() { - if (!Settings.display_model) { - Settings.display_model = XDSP_09; - } + if (PinUsed(GPIO_SSD1351_CS) && + ((TasmotaGlobal.soft_spi_enabled & SPI_MOSI) || (TasmotaGlobal.spi_enabled & SPI_MOSI))) { - if (XDSP_09 == Settings.display_model) { + Settings.display_model = XDSP_09; if (Settings.display_width != SSD1351_WIDTH) { Settings.display_width = SSD1351_WIDTH; @@ -53,21 +53,18 @@ void SSD1351_InitDriver() { Settings.display_height = SSD1351_HEIGHT; } - buffer=0; + buffer = 0; // default colors fg_color = SSD1351_WHITE; bg_color = SSD1351_BLACK; // init renderer - if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)){ - ssd1351 = new SSD1351(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK)); - } else { - if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { - ssd1351 = new SSD1351(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK)); - } else { - return; - } + if (TasmotaGlobal.soft_spi_enabled){ + ssd1351 = new SSD1351(Pin(GPIO_SSD1351_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK)); + } + else if (TasmotaGlobal.spi_enabled) { + ssd1351 = new SSD1351(Pin(GPIO_SSD1351_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); } delay(100); @@ -85,6 +82,9 @@ void SSD1351_InitDriver() { #endif color_type = COLOR_COLOR; + + ssd1351_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: SSD1351")); } } @@ -162,7 +162,7 @@ bool Xdsp09(uint8_t function) if (FUNC_DISPLAY_INIT_DRIVER == function) { SSD1351_InitDriver(); } - else if (XDSP_09 == Settings.display_model) { + else if (ssd1351_init_done && (XDSP_09 == Settings.display_model)) { switch (function) { case FUNC_DISPLAY_MODEL: result = true; diff --git a/tasmota/xdsp_10_RA8876.ino b/tasmota/xdsp_10_RA8876.ino index 7cc87c4df..9caf5678d 100644 --- a/tasmota/xdsp_10_RA8876.ino +++ b/tasmota/xdsp_10_RA8876.ino @@ -33,19 +33,17 @@ #include +bool ra8876_init_done = false; uint8_t ra8876_ctouch_counter = 0; extern uint8_t *buffer; extern uint8_t color_type; RA8876 *ra8876; /*********************************************************************************************/ -void RA8876_InitDriver() -{ - if (!Settings.display_model) { - Settings.display_model = XDSP_10; - } +void RA8876_InitDriver(void) { + if (PinUsed(GPIO_RA8876_CS) && (SPI_MOSI_MISO == TasmotaGlobal.spi_enabled)) { - if (XDSP_10 == Settings.display_model) { + Settings.display_model = XDSP_10; if (Settings.display_width != RA8876_TFTWIDTH) { Settings.display_width = RA8876_TFTWIDTH; @@ -53,39 +51,15 @@ void RA8876_InitDriver() if (Settings.display_height != RA8876_TFTHEIGHT) { Settings.display_height = RA8876_TFTHEIGHT; } - buffer=0; + + buffer = 0; // default colors fg_color = RA8876_WHITE; bg_color = RA8876_BLACK; -#ifdef ESP8266 -#undef HW_SPI_MOSI -#define HW_SPI_MOSI 13 -#undef HW_SPI_MISO -#define HW_SPI_MISO 12 -#undef HW_SPI_CLK -#define HW_SPI_CLK 14 -#endif // ESP8266 -#ifdef ESP32 -#undef HW_SPI_MOSI -#define HW_SPI_MOSI 23 -#undef HW_SPI_MISO -#define HW_SPI_MISO 19 -#undef HW_SPI_CLK -#define HW_SPI_CLK 18 -#endif // ESP32 - // init renderer, must use hardware spi - if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_MISO)==HW_SPI_MISO) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { - ra8876 = new RA8876(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_MISO),Pin(GPIO_SSPI_SCLK),Pin(GPIO_BACKLIGHT)); - } else { - if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_MISO)==HW_SPI_MISO) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK)) { - ra8876 = new RA8876(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_CLK),Pin(GPIO_BACKLIGHT)); - } else { - return; - } - } + ra8876 = new RA8876(Pin(GPIO_RA8876_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_BACKLIGHT)); ra8876->begin(); renderer = ra8876; @@ -107,6 +81,8 @@ void RA8876_InitDriver() Touch_Init(Wire); #endif + ra8876_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: RA8876")); } } @@ -329,7 +305,7 @@ bool Xdsp10(uint8_t function) if (FUNC_DISPLAY_INIT_DRIVER == function) { RA8876_InitDriver(); } - else if (XDSP_10 == Settings.display_model) { + else if (ra8876_init_done && (XDSP_10 == Settings.display_model)) { switch (function) { case FUNC_DISPLAY_MODEL: result = true; diff --git a/tasmota/xdsp_12_ST7789.ino b/tasmota/xdsp_12_ST7789.ino index 1c9ec1aff..524ecc4d1 100644 --- a/tasmota/xdsp_12_ST7789.ino +++ b/tasmota/xdsp_12_ST7789.ino @@ -53,16 +53,15 @@ Arduino_ST7789 *st7789; #ifdef USE_FT5206 uint8_t st7789_ctouch_counter = 0; #endif // USE_FT5206 +bool st7789_init_done = false; /*********************************************************************************************/ -void ST7789_InitDriver() -{ - if (!Settings.display_model) { - Settings.display_model = XDSP_12; - } +void ST7789_InitDriver(void) { + if (PinUsed(GPIO_ST7789_CS) && PinUsed(GPIO_ST7789_DC) && + ((TasmotaGlobal.soft_spi_enabled & SPI_MOSI) || (TasmotaGlobal.spi_enabled & SPI_MOSI))) { - if (XDSP_12 == Settings.display_model) { + Settings.display_model = XDSP_12; if (!Settings.display_width) { Settings.display_width = 240; @@ -72,57 +71,30 @@ void ST7789_InitDriver() } // disable screen buffer - buffer=NULL; + buffer = NULL; // default colors fg_color = ST7789_WHITE; bg_color = ST7789_BLACK; - int8_t bppin=BACKPLANE_PIN; - if (PinUsed(GPIO_BACKLIGHT)) { - bppin=Pin(GPIO_BACKLIGHT); + int8_t bppin = BACKPLANE_PIN; + if (PinUsed(GPIO_BACKLIGHT)) { + bppin = Pin(GPIO_BACKLIGHT); } int8_t reset = -1; - if (PinUsed(GPIO_OLED_RESET)) { - reset=Pin(GPIO_OLED_RESET); + if (PinUsed(GPIO_OLED_RESET)) { + reset = Pin(GPIO_OLED_RESET); } - int8_t cs = -1; - if (PinUsed(GPIO_SSPI_CS)) { - cs=Pin(GPIO_SSPI_CS); - } else if (PinUsed(GPIO_SPI_CS)) { - cs=Pin(GPIO_SPI_CS); - } - -#ifdef ESP8266 -#undef HW_SPI_MOSI -#define HW_SPI_MOSI 13 -#undef HW_SPI_CLK -#define HW_SPI_CLK 14 -#endif // ESP8266 -#ifdef ESP32 -#undef HW_SPI_MOSI -#define HW_SPI_MOSI 23 -#undef HW_SPI_CLK -#define HW_SPI_CLK 18 -#endif // ESP32 - // init renderer, may use hardware spi - //if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK) && PinUsed(GPIO_SPI_DC)) { - if ((Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK) && PinUsed(GPIO_SPI_DC)) { - st7789 = new Arduino_ST7789(Pin(GPIO_SPI_DC), reset, cs, bppin); - } else { - if ((PinUsed(GPIO_SSPI_CS) || PinUsed(GPIO_OLED_RESET)) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_DC)) { - if ((Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { - st7789 = new Arduino_ST7789(Pin(GPIO_SSPI_DC), reset, cs, bppin); - } else { - st7789 = new Arduino_ST7789(Pin(GPIO_SSPI_DC), reset, Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), cs, bppin); - } - } else { - return; - } + if (TasmotaGlobal.soft_spi_enabled) { + st7789 = new Arduino_ST7789(Pin(GPIO_ST7789_DC), reset, Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), Pin(GPIO_ST7789_CS), bppin); } + else if (TasmotaGlobal.spi_enabled) { + st7789 = new Arduino_ST7789(Pin(GPIO_ST7789_DC), reset, Pin(GPIO_ST7789_CS), bppin); + } + st7789->init(Settings.display_width,Settings.display_height); renderer = st7789; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); @@ -154,6 +126,8 @@ void ST7789_InitDriver() #endif // USE_FT5206 #endif // ESP32 + st7789_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: ST7789")); } } @@ -212,7 +186,7 @@ bool Xdsp12(uint8_t function) if (FUNC_DISPLAY_INIT_DRIVER == function) { ST7789_InitDriver(); } - else if (XDSP_12 == Settings.display_model) { + else if (st7789_init_done && (XDSP_12 == Settings.display_model)) { switch (function) { case FUNC_DISPLAY_MODEL: result = true; diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 4c243d4dc..727aeb011 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -409,14 +409,18 @@ static union{ /********************************************************************************************/ -void MINRFinit(void){ - MINRFinitBLE(1); +void MINRFinit(void) { + if (PinUsed(GPIO_NRF24_CS) && PinUsed(GPIO_NRF24_DC) && TasmotaGlobal.spi_enabled) { + MINRFinitBLE(1); - MINRF.option.allwaysAggregate = 1; - // MINRF.option.ignoreBogusBattery = 1; // from advertisements - MINRF.option.noSummary = 0; - MINRF.option.minimalSummary = 0; - MINRF.option.directBridgeMode = 0; + MINRF.option.allwaysAggregate = 1; + // MINRF.option.ignoreBogusBattery = 1; // from advertisements + MINRF.option.noSummary = 0; + MINRF.option.minimalSummary = 0; + MINRF.option.directBridgeMode = 0; + + AddLog_P(LOG_LEVEL_INFO, PSTR("NRF: Started")); + } } /********************************************************************************************/ @@ -431,7 +435,7 @@ void MINRFinit(void){ bool MINRFinitBLE(uint8_t _mode) { if (MINRF.timer%1000 == 0){ // only re-init every 20 seconds - NRF24radio.begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); + NRF24radio.begin(Pin(GPIO_NRF24_CS),Pin(GPIO_NRF24_DC)); NRF24radio.setAutoAck(false); NRF24radio.setDataRate(RF24_1MBPS); NRF24radio.disableCRC(); @@ -1958,7 +1962,6 @@ bool Xsns61(uint8_t function) switch (function) { case FUNC_INIT: MINRFinit(); - AddLog_P(LOG_LEVEL_INFO,PSTR("NRF: started")); break; case FUNC_EVERY_50_MSECOND: MINRF_EVERY_50_MSECOND(); diff --git a/tasmota/xsns_80_mfrc522.ino b/tasmota/xsns_80_mfrc522.ino index 899c77909..b62c1140f 100644 --- a/tasmota/xsns_80_mfrc522.ino +++ b/tasmota/xsns_80_mfrc522.ino @@ -98,7 +98,7 @@ void RC522ScanForTag(void) { } void RC522Init(void) { - if (PinUsed(GPIO_RC522_CS) && PinUsed(GPIO_RC522_RST)) { + if (PinUsed(GPIO_RC522_CS) && PinUsed(GPIO_RC522_RST) && TasmotaGlobal.spi_enabled) { Mfrc522 = new MFRC522(Pin(GPIO_RC522_CS), Pin(GPIO_RC522_RST)); SPI.begin(); Mfrc522->PCD_Init(); From 08d65c69d50fcceb781f635b39d433e5ba71c03a Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Fri, 1 Jan 2021 01:37:08 +0100 Subject: [PATCH 080/105] show time and date in DiplayMode 3 and 5 --- tasmota/xdsp_14_SSD1331.ino | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino index ac6e3e994..cae0c9aa2 100644 --- a/tasmota/xdsp_14_SSD1331.ino +++ b/tasmota/xdsp_14_SSD1331.ino @@ -28,8 +28,9 @@ #define USE_TINY_FONT #define SSD1331_BLACK 0x0000 // 0, 0, 0 -#define SSD1331_RED 0xF800 // 255, 0, 0 #define SSD1331_WHITE 0xFFFF // 255, 255, 255 +#define SSD1331_RED 0xF800 // 255, 0, 0 +#define SSD1331_BLUE 0x001F // 0, 0, 255 #include #include @@ -90,7 +91,7 @@ void SSD1331_InitDriver() { #ifdef USE_DISPLAY_MODES1TO5 -void SSD1331PrintLog(void) +void SSD1331PrintLog(bool withDateTime) { disp_refresh--; if (!disp_refresh) { @@ -103,6 +104,16 @@ void SSD1331PrintLog(void) renderer->clearDisplay(); renderer->setCursor(0,0); + + if (withDateTime) { + char line[17]; + snprintf_P(line, sizeof(line), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d %02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.hour, RtcTime.minute, RtcTime.day_of_month, RtcTime.month, RtcTime.year); // [12:34 01-02-2018] + renderer->setTextColor(SSD1331_BLUE); + renderer->println(line); + renderer->setTextColor(fg_color); + last_row--; + } + for (byte i = 0; i < last_row; i++) { strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); renderer->println(disp_screen_buffer[i]); @@ -139,10 +150,12 @@ void SSD1331Refresh(void) // Every second SSD1331Time(); break; case 2: // Local - case 3: // Local case 4: // Mqtt - case 5: // Mqtt - SSD1331PrintLog(); + SSD1331PrintLog(false); + break; + case 3: // Local + Time + case 5: // Mqtt + Time + SSD1331PrintLog(true); break; } } From 96ecffe5710f2616e5cda50647508a80f2955694 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 1 Jan 2021 06:43:50 +0100 Subject: [PATCH 081/105] reduce stack pressure, some fixes --- tasmota/xdrv_10_scripter.ino | 347 ++++++++++++++++++++++------------- 1 file changed, 217 insertions(+), 130 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 6f7351c7d..280e02f12 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -499,6 +499,17 @@ uint8_t fast_script=0; uint8_t glob_script=0; uint32_t script_lastmillis; +void Script_AddLog_P(uint32_t loglevel, PGM_P formatP, ...) { + char log_data[128]; + + va_list arg; + va_start(arg, formatP); + vsnprintf_P(log_data, sizeof(log_data), formatP, arg); + va_end(arg); + + AddLogData(loglevel, log_data); +} + void flt2char(float num, char *nbuff) { dtostrfd(num, glob_script_mem.script_dprec, nbuff); } @@ -578,7 +589,9 @@ float *Get_MFAddr(uint8_t index, uint16_t *len, uint16_t *ipos); int16_t Init_Scripter(void) { char *script; + int16_t err = 0; script = glob_script_mem.script_ram; + if (!*script) return -999; // scan lines for >DEF uint16_t lines = 0; @@ -586,15 +599,56 @@ char *script; uint16_t svars = 0; uint16_t vars = 0; char *lp = script; - char vnames[MAXVARS*10]; - char *vnames_p = vnames; + uint16_t imemsize = (MAXVARS*10) + 4; + uint8_t *imemptr = (uint8_t*)calloc(imemsize, 1); + if (!imemptr) { + return -7; + } + + //ClaimSerial(); + //SetSerialBaudrate(115200); + //Serial.printf("size %d\n",imemsize); + //Serial.printf("stack %d\n",GetStack()); // 2848 + // 2896 + //char vnames[MAXVARS*10]; + char *vnames = (char*)imemptr; + char *vnp[MAXVARS]; + float fvalues[MAXVARS]; + struct T_INDEX vtypes[MAXVARS]; + +/* + uint32_t imemp = (uint32_t)imemptr; + imemp += (MAXVARS*10); + imemp = (imemp & 0xfffc) + 4; + Serial.printf(">1 %x\n",imemp); + char *vnp[MAXVARS]; + + //char **vnp = (char**)imemp; + imemp += (sizeof(char*)*MAXVARS); + imemp = (imemp & 0xfffc) + 4; + Serial.printf(">2 %x\n",imemp); + + float fvalues[MAXVARS]; + //float *fvalues = (float*)imemp; + imemp += (sizeof(float*)*MAXVARS); + imemp = (imemp & 0xfffc) + 4; + Serial.printf(">3 %x\n",imemp); + + struct T_INDEX vtypes[MAXVARS]; + //struct T_INDEX *vtypes = (struct T_INDEX*)imemp; +*/ + + char *vnames_p = vnames; char **vnp_p = vnp; + char strings[MAXSVARS*SCRIPT_MAXSSIZE]; + char *snp[MAXSVARS]; + struct M_FILT mfilt[MAXFILT]; char *strings_p = strings; - char *snp[MAXSVARS]; + char **snp_p = snp; uint8_t numperm = 0; uint8_t numflt = 0; @@ -603,10 +657,6 @@ char *script; glob_script_mem.max_ssize = SCRIPT_SVARSIZE; glob_script_mem.scriptptr = 0; - if (!*script) return -999; - - float fvalues[MAXVARS]; - struct T_INDEX vtypes[MAXVARS]; char init = 0; while (1) { // check line @@ -674,6 +724,7 @@ char *script; vtypes[vars].index = numflt; numflt++; if (numflt>MAXFILT) { + if (imemptr) free(imemptr); return -6; } } else { @@ -699,6 +750,7 @@ char *script; if (!vtypes[vars].bits.is_filter) vtypes[vars].index = nvars; nvars++; if (nvars>MAXNVARS) { + if (imemptr) free(imemptr); return -1; } if (vtypes[vars].bits.is_filter) { @@ -731,11 +783,13 @@ char *script; vtypes[vars].index = svars; svars++; if (svars>MAXSVARS) { + if (imemptr) free(imemptr); return -2; } } vars++; if (vars>MAXVARS) { + if (imemptr) free(imemptr); return -3; } } @@ -786,6 +840,7 @@ char *script; uint8_t *script_mem; script_mem = (uint8_t*)calloc(script_mem_size, 1); if (!script_mem) { + if (imemptr) free(imemptr); return -4; } glob_script_mem.script_mem = script_mem; @@ -841,7 +896,6 @@ char *script; //memcpy(script_mem,strings,size); script_mem += size; - // now must recalc memory offsets uint16_t index = 0; #ifdef SCRIPT_LARGE_VNBUFF @@ -864,11 +918,13 @@ char *script; index++; if (index > MAXVNSIZ) { free(glob_script_mem.script_mem); + if (imemptr) free(imemptr); return -5; } } + // variables usage info - AddLog_P(LOG_LEVEL_INFO, PSTR("Script: nv=%d, tv=%d, vns=%d, ram=%d"), nvars, svars, index, glob_script_mem.script_mem_size); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("Script: nv=%d, tv=%d, vns=%d, ram=%d"), nvars, svars, index, glob_script_mem.script_mem_size); // copy string variables char *cp1 = glob_script_mem.glob_snp; @@ -940,7 +996,6 @@ char *script; } } - #ifdef USE_SCRIPT_FATFS if (!glob_script_mem.script_sd_found) { @@ -985,8 +1040,10 @@ char *script; } #endif //USE_SCRIPT_GLOBVARS - return 0; - + if (imemptr) { + free(imemptr); + } + return err; } #ifdef USE_SCRIPT_FATFS @@ -1072,10 +1129,10 @@ void Script_Init_UDP() { if (glob_script_mem.udp_flags.udp_connected) return; if (Script_PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP started")); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP started")); glob_script_mem.udp_flags.udp_connected = 1; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP failed")); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP failed")); glob_script_mem.udp_flags.udp_connected = 0; } } @@ -1089,7 +1146,7 @@ void Script_PollUdp(void) { int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE - 1); packet_buffer[len] = 0; script_udp_remote_ip = Script_PortUdp.remoteIP(); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str()); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str()); char *lp=packet_buffer; if (!strncmp(lp,"=>", 2)) { lp += 2; @@ -1108,10 +1165,10 @@ void Script_PollUdp(void) { uint32_t index; uint32_t res = match_vars(vnam, &fp, &sp, &index); if (res == NUM_RES) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("num var found - %s - %d - %d"), vnam, res, index); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("num var found - %s - %d - %d"), vnam, res, index); *fp=CharToFloat(cp + 1); } else if (res == STR_RES) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("string var found - %s - %d - %d"), vnam, res, index); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("string var found - %s - %d - %d"), vnam, res, index); strlcpy(sp, cp + 1, SCRIPT_MAXSSIZE); } else { // error var not found @@ -1145,10 +1202,10 @@ void script_udp_sendvar(char *vname,float *fp,char *sp) { char flstr[16]; dtostrfd(*fp, 8, flstr); strcat(sbuf, flstr); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"), sbuf); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"), sbuf); } else { strcat(sbuf, sp); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"), sbuf); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"), sbuf); } Script_PortUdp.beginPacket(IPAddress(239, 255, 255, 250), SCRIPT_UDP_PORT); // Udp.print(String("RET UC: ") + String(recv_Packet)); @@ -1269,7 +1326,7 @@ void Set_MFVal(uint8_t index, uint16_t bind, float val) { if (val < 0 || val >= maxind) val = 0; mflp->index = val; } else { - if (bind > 1 && bind <= maxind) { + if (bind >= 1 && bind <= maxind) { mflp->rbuff[bind-1] = val; } } @@ -2053,7 +2110,7 @@ chknext: if (!glob_script_mem.file_flags[cnt].is_open) { if (mode==0) { #ifdef DEBUG_FS - AddLog_P(LOG_LEVEL_INFO, PSTR("open file for read %d"), cnt); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("open file for read %d"), cnt); #endif glob_script_mem.files[cnt] = fsp->open(str, FILE_READ); if (glob_script_mem.files[cnt].isDirectory()) { @@ -2067,12 +2124,12 @@ chknext: if (mode==1) { glob_script_mem.files[cnt] = fsp->open(str,FILE_WRITE); #ifdef DEBUG_FS - AddLog_P(LOG_LEVEL_INFO, PSTR("open file for write %d"), cnt); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("open file for write %d"), cnt); #endif } else { glob_script_mem.files[cnt] = fsp->open(str,FILE_APPEND); #ifdef DEBUG_FS - AddLog_P(LOG_LEVEL_INFO, PSTR("open file for append %d"), cnt); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("open file for append %d"), cnt); #endif } } @@ -2080,7 +2137,7 @@ chknext: fvar = cnt; glob_script_mem.file_flags[cnt].is_open = 1; } else { - AddLog_P(LOG_LEVEL_INFO, PSTR("file open failed")); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("file open failed")); } break; } @@ -2095,7 +2152,7 @@ chknext: uint8_t ind = fvar; if (ind>=SFS_MAX) ind = SFS_MAX - 1; #ifdef DEBUG_FS - AddLog_P(LOG_LEVEL_INFO, PSTR("closing file %d"), ind); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("closing file %d"), ind); #endif glob_script_mem.files[ind].close(); glob_script_mem.file_flags[ind].is_open = 0; @@ -2231,7 +2288,7 @@ chknext: } else { fvar = 0; } - //AddLog_P(LOG_LEVEL_INFO, PSTR("picture save: %d"), len); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("picture save: %d"), len); } else { fvar = 0; } @@ -3624,7 +3681,7 @@ void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dst void toLog(const char *str) { if (!str) return; - AddLog_P(LOG_LEVEL_INFO, str); + Script_AddLog_P(LOG_LEVEL_INFO, str); } @@ -4332,7 +4389,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonParserObject *jo) { } cmd[count] = *lp++; } - //AddLog_P(LOG_LEVEL_INFO, tmp); + //Script_AddLog_P(LOG_LEVEL_INFO, tmp); // replace vars in cmd char *tmp = cmdmem + SCRIPT_CMDMEM / 2; Replace_Cmd_Vars(cmd, 0, tmp, SCRIPT_CMDMEM / 2); @@ -4344,7 +4401,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonParserObject *jo) { } else { if (!sflag) { tasm_cmd_activ = 1; - AddLog_P(glob_script_mem.script_loglevel&0x7f, PSTR("Script: performs \"%s\""), tmp); + Script_AddLog_P(glob_script_mem.script_loglevel&0x7f, PSTR("Script: performs \"%s\""), tmp); } else if (sflag==2) { // allow recursive call } else { @@ -4867,13 +4924,13 @@ uint8_t sc_state; // upload script and start immediately void script_upload_start(void) { - //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload execute")); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload execute")); HTTPUpload& upload = Webserver->upload(); if (upload.status == UPLOAD_FILE_START) { - //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload start")); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload start")); script_ex_ptr = (uint8_t*)glob_script_mem.script_ram; - //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload file %s, %d"),upload.filename.c_str(),upload.totalSize); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload file %s, %d"),upload.filename.c_str(),upload.totalSize); if (strcmp(upload.filename.c_str(), "execute_script")) { Web.upload_error = 1; @@ -4891,7 +4948,7 @@ void script_upload_start(void) { bitWrite(Settings.rule_enabled, 0, 0); } else if(upload.status == UPLOAD_FILE_WRITE) { - //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload write")); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload write")); uint32_t csiz = upload.currentSize; uint32_t tsiz = glob_script_mem.script_size - 1; if (uplsizeupload(); if (upload.status == UPLOAD_FILE_START) { char npath[48]; @@ -5103,7 +5160,7 @@ void script_upload(void) { } else if(upload.status == UPLOAD_FILE_END) { if (upload_file) upload_file.close(); if (Web.upload_error) { - AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload error")); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload error")); } } else { Web.upload_error=1; @@ -5116,13 +5173,13 @@ uint8_t DownloadFile(char *file) { WiFiClient download_Client; if (!fsp->exists(file)) { - AddLog_P(LOG_LEVEL_INFO,PSTR("file not found")); + Script_AddLog_P(LOG_LEVEL_INFO,PSTR("file not found")); return 0; } download_file = fsp->open(file, FILE_READ); if (!download_file) { - AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file")); + Script_AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file")); return 0; } @@ -5189,7 +5246,7 @@ void HandleScriptConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_SCRIPT)); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_SCRIPT)); #ifdef USE_SCRIPT_FATFS if (Webserver->hasArg("d1")) { @@ -5320,7 +5377,7 @@ void ScriptSaveSettings(void) { strlcpy(glob_script_mem.script_ram, str.c_str(), glob_script_mem.script_size); if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { - AddLog_P(LOG_LEVEL_INFO, PSTR("script error: must start with >D")); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("script error: must start with >D")); bitWrite(Settings.rule_enabled, 0, 0); } @@ -5333,14 +5390,14 @@ void ScriptSaveSettings(void) { // uint32_t script_compress(char *dest, uint32_t size) { - //AddLog_P(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); + //Script_AddLog_P(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), dest, size); if (len_compressed > 0) { dest[len_compressed] = 0; - AddLog_P(LOG_LEVEL_INFO,PSTR("script compressed to %d bytes = %d %%"),len_compressed,len_compressed * 100 / strlen(glob_script_mem.script_ram)); + Script_AddLog_P(LOG_LEVEL_INFO,PSTR("script compressed to %d bytes = %d %%"),len_compressed,len_compressed * 100 / strlen(glob_script_mem.script_ram)); return 0; } else { - AddLog_P(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); return 1; } } @@ -5367,7 +5424,7 @@ void SaveScriptEnd(void) { int16_t res = Init_Scripter(); if (res) { - AddLog_P(LOG_LEVEL_INFO, PSTR("script init error: %d"), res); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("script init error: %d"), res); return; } @@ -5693,7 +5750,7 @@ void Script_Check_Hue(String *response) { } *response += String(EncodeLightId(hue_devs + TasmotaGlobal.devices_present + 1))+"\":"; Script_HueStatus(response, hue_devs); - //AddLog_P(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs); } hue_devs++; @@ -5708,7 +5765,7 @@ void Script_Check_Hue(String *response) { } #if 0 if (response) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("Hue: %d"), hue_devs); + Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("Hue: %d"), hue_devs); toLog(">>>>"); toLog(response->c_str()); toLog(response->c_str()+LOGSZ); @@ -5853,7 +5910,7 @@ void Script_Handle_Hue(String *path) { } else { response = FPSTR(sHUE_ERROR_JSON); } - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str()); + Script_AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str()); WSSend(code, CT_JSON, response); if (resp) { Run_Scripter(">E", 2, 0); @@ -5867,7 +5924,7 @@ bool Script_SubCmd(void) { if (!bitRead(Settings.rule_enabled, 0)) return false; if (tasm_cmd_activ) return false; - //AddLog_P(LOG_LEVEL_INFO,PSTR(">> %s, %s, %d, %d "),XdrvMailbox.topic, XdrvMailbox.data, XdrvMailbox.payload, XdrvMailbox.index); + //Script_AddLog_P(LOG_LEVEL_INFO,PSTR(">> %s, %s, %d, %d "),XdrvMailbox.topic, XdrvMailbox.data, XdrvMailbox.payload, XdrvMailbox.index); char command[CMDSZ]; strlcpy(command, XdrvMailbox.topic, CMDSZ); @@ -5895,7 +5952,7 @@ bool Script_SubCmd(void) { } //toLog(cmdbuff); uint32_t res = Run_Scripter(cmdbuff, tlen + 1, 0); - //AddLog_P(LOG_LEVEL_INFO,">>%d",res); + //Script_AddLog_P(LOG_LEVEL_INFO,">>%d",res); if (res) { return false; } @@ -6026,10 +6083,87 @@ void dateTime(uint16_t* date, uint16_t* time) { #endif //USE_SCRIPT_FATFS -//#define DEBUG_MQTT_EVENT + #ifdef SUPPORT_MQTT_EVENT +//#define DEBUG_MQTT_EVENT + +uint32_t JsonParsePath(JsonParserObject *jobj, const char *spath, char delim, float *nres, char *sres, uint32_t slen) { + uint32_t res = 0; + const char *cp = spath; +#ifdef DEBUG_MQTT_EVENT +// Script_AddLog_P(LOG_LEVEL_INFO, PSTR("Script: parsing json key: %s from json: %s"), cp, jpath); +#endif + JsonParserObject obj = *jobj; + JsonParserObject lastobj = obj; + char selem[32]; + uint8_t aindex = 0; + String value = ""; + while (1) { + // read next element + for (uint32_t sp=0; sp%s=%d\n"), event_item.Event.c_str(), ep); - } else { - snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str()); - } + if (!strncmp(lkey.c_str(), "Epoch", 5)) { + uint32_t ep = atoi(value.c_str()) - (uint32_t)EPOCH_OFFSET; + snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%d\n"), event_item.Event.c_str(), ep); + } else { + snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str()); + } #ifdef DEBUG_MQTT_EVENT - AddLog_P(LOG_LEVEL_INFO, PSTR("Script: setting script var %s"), sbuffer); + Script_AddLog_P(LOG_LEVEL_INFO, PSTR("Script: setting script var %s"), sbuffer); #endif - //toLog(sbuffer); - execute_script(sbuffer); + //toLog(sbuffer); + execute_script(sbuffer); + } } } } @@ -6221,7 +6308,7 @@ String ScriptSubscribe(const char *data, int data_len) } } } - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("Script: Subscribe command with parameters: %s, %s, %s."), event_name.c_str(), topic.c_str(), key.c_str()); + //Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("Script: Subscribe command with parameters: %s, %s, %s."), event_name.c_str(), topic.c_str(), key.c_str()); //event_name.toUpperCase(); if (event_name.length() > 0 && topic.length() > 0) { //Search all subscriptions @@ -6242,7 +6329,7 @@ String ScriptSubscribe(const char *data, int data_len) topic.concat("/#"); } } - // AddLog_P(LOG_LEVEL_DEBUG, PSTR("Script: New topic: %s."), topic.c_str()); + // Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("Script: New topic: %s."), topic.c_str()); //MQTT Subscribe subscription_item.Event = event_name; subscription_item.Topic = topic.substring(0, topic.length() - 2); //Remove "/#" so easy to match @@ -6511,7 +6598,7 @@ void ScriptFullWebpage(void) { WSContentBegin(200, CT_HTML); ScriptWebShow('w'); WSContentEnd(); - Serial.printf("fwp update sv %s\n",stmp.c_str() ); + //Serial.printf("fwp update sv %s\n",stmp.c_str() ); return; //goto redraw; // } else { // Serial.printf("fwp update %s\n",stmp.c_str() ); @@ -6519,7 +6606,7 @@ void ScriptFullWebpage(void) { return; } else { - Serial.printf("fwp other %s\n",stmp.c_str() ); + //Serial.printf("fwp other %s\n",stmp.c_str() ); } WSContentBegin(200, CT_HTML); @@ -6547,7 +6634,7 @@ void Script_Check_HTML_Setvars(void) { if (Webserver->hasArg("sv")) { String stmp = Webserver->arg("sv"); - Serial.printf("fwp has arg dv %s\n", stmp.c_str()); + //Serial.printf("fwp has arg dv %s\n", stmp.c_str()); char cmdbuf[64]; memset(cmdbuf, 0, sizeof(cmdbuf)); char *cp = cmdbuf; @@ -7613,7 +7700,7 @@ bool Xdrv10(uint8_t function) if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed] = 0; // indicates scripter use compression bitWrite(Settings.rule_once, 6, 1); - //AddLog_P(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); + //Script_AddLog_P(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); #else // USE_SCRIPT_COMPRESSION // indicates scripter does not use compression bitWrite(Settings.rule_once, 6, 0); @@ -7695,7 +7782,7 @@ bool Xdrv10(uint8_t function) #endif // ESP #endif // USE_SCRIPT_FATFS>=0 - AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount OK!")); + Script_AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount OK!")); //fsp->dateTimeCallback(dateTime); glob_script_mem.script_sd_found = 1; @@ -7717,7 +7804,7 @@ bool Xdrv10(uint8_t function) glob_script_mem.flags = 1; } else { - AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount failed!")); + Script_AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount failed!")); glob_script_mem.script_sd_found = 0; } #endif // USE_SCRIPT_FATFS From 3ee92fb4ba4068d2d6f7362165538a40ecfa2c0c Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 1 Jan 2021 06:44:04 +0100 Subject: [PATCH 082/105] smaller log buffer --- tasmota/xsns_53_sml.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index cccfde736..d91facf37 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -824,7 +824,7 @@ void Dump2log(void) { int16_t index=0,hcnt=0; uint32_t d_lastms; uint8_t dchars[16]; - char log_data[LOGSZ]; // May be a lot smaller... + char log_data[128]; //if (!SML_SAVAILABLE) return; From f8067735e1982ad15823b66bb90b669788b53587 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Fri, 1 Jan 2021 06:45:07 +0100 Subject: [PATCH 083/105] add in and batt current --- tasmota/xdrv_84_core2.ino | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tasmota/xdrv_84_core2.ino b/tasmota/xdrv_84_core2.ino index 9bc18ad0c..f4075967f 100644 --- a/tasmota/xdrv_84_core2.ino +++ b/tasmota/xdrv_84_core2.ino @@ -55,6 +55,8 @@ struct CORE2_globs { struct CORE2_ADC { float vbus_v; float batt_v; + float vbus_c; + float batt_c; float temp; int16_t x; int16_t y; @@ -72,6 +74,8 @@ void CORE2_Module_Init(void) { I2cSetActiveFound(AXP_ADDR, "AXP192"); core2_globs.Axp.SetAdcState(true); + // motor voltage + core2_globs.Axp.SetLDOVoltage(3,2000); core2_globs.Mpu.Init(); I2cSetActiveFound(MPU6886_ADDRESS, "MPU6886"); @@ -91,13 +95,7 @@ void CORE2_Init(void) { TIME_T tmpTime; TasmotaGlobal.ntp_force_sync = true; //force to sync with ntp - // Rtc.utc_time = ReadFromDS3231(); //we read UTC TIME from DS3231 - // from this line, we just copy the function from "void RtcSecond()" at the support.ino ,line 2143 and above - // We need it to set rules etc. BreakTime(Rtc.utc_time, tmpTime); - if (Rtc.utc_time < START_VALID_TIME ) { - //ds3231ReadStatus = true; //if time in DS3231 is valid, do not update again - } Rtc.daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); Rtc.standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); AddLog_P(LOG_LEVEL_INFO, PSTR("Set time from BM8563 to RTC (" D_UTC_TIME ") %s, (" D_DST_TIME ") %s, (" D_STD_TIME ") %s"), @@ -119,7 +117,9 @@ void CORE2_audio_power(bool power) { #ifdef USE_WEBSERVER const char HTTP_CORE2[] PROGMEM = "{s}VBUS Voltage" "{m}%s V" "{e}" + "{s}VBUS Current" "{m}%s mA" "{e}" "{s}BATT Voltage" "{m}%s V" "{e}" + "{s}BATT Current" "{m}%s mA" "{e}" "{s}Chip Temperature" "{m}%s C" "{e}"; #ifdef USE_MPU6886 const char HTTP_CORE2_MPU[] PROGMEM = @@ -131,27 +131,31 @@ const char HTTP_CORE2_MPU[] PROGMEM = void CORE2_loop(uint32_t flg) { - Sync_RTOS_TIME(); + } void CORE2_WebShow(uint32_t json) { char vstring[32]; char bvstring[32]; + char cstring[32]; + char bcstring[32]; char tstring[32]; dtostrfd(core2_adc.vbus_v, 3, vstring); dtostrfd(core2_adc.batt_v, 3, bvstring); + dtostrfd(core2_adc.vbus_c, 1, cstring); + dtostrfd(core2_adc.batt_c, 1, bcstring); dtostrfd(core2_adc.temp, 2, tstring); if (json) { - ResponseAppend_P(PSTR(",\"CORE2\":{\"VBV\":%s,\"BV\":%s,\"CT\":%s"), vstring, bvstring, tstring); + ResponseAppend_P(PSTR(",\"CORE2\":{\"VBV\":%s,\"BV\":%s,\"VBC\":%s,\"BC\":%s,\"CT\":%s"), vstring, cstring, bvstring, bcstring, tstring); #ifdef USE_MPU6886 ResponseAppend_P(PSTR(",\"MPUX\":%d,\"MPUY\":%d,\"MPUZ\":%d"), core2_adc.x, core2_adc.y, core2_adc.z); #endif ResponseJsonEnd(); } else { - WSContentSend_PD(HTTP_CORE2, vstring, bvstring, tstring); + WSContentSend_PD(HTTP_CORE2, vstring, cstring, bvstring, bcstring, tstring); #ifdef USE_MPU6886 WSContentSend_PD(HTTP_CORE2_MPU, core2_adc.x, core2_adc.y, core2_adc.z); @@ -368,13 +372,17 @@ void CORE2_EverySecond(void) { CORE2_DoShutdown(); } } + + Sync_RTOS_TIME(); } } -// currents are not supported by hardware implementation void CORE2_GetADC(void) { core2_adc.vbus_v = core2_globs.Axp.GetVBusVoltage(); core2_adc.batt_v = core2_globs.Axp.GetBatVoltage(); + core2_adc.vbus_c = core2_globs.Axp.GetVinCurrent(); + core2_adc.batt_c = core2_globs.Axp.GetBatCurrent(); + core2_adc.temp = core2_globs.Axp.GetTempInAXP192(); #ifdef USE_MPU6886 float x; From dcbb3f1e0ea2141641c5d4ed5ed8f6d793d26a68 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 13:44:04 +0100 Subject: [PATCH 084/105] Happy New Year --- tasmota/StackThunk_light.cpp | 2 +- tasmota/StackThunk_light.h | 2 +- tasmota/WiFiClientSecureLightBearSSL.cpp | 2 +- tasmota/WiFiClientSecureLightBearSSL.h | 2 +- tasmota/i18n.h | 2 +- tasmota/language/af_AF.h | 2 +- tasmota/language/bg_BG.h | 2 +- tasmota/language/cs_CZ.h | 2 +- tasmota/language/de_DE.h | 2 +- tasmota/language/el_GR.h | 2 +- tasmota/language/en_GB.h | 2 +- tasmota/language/es_ES.h | 2 +- tasmota/language/fr_FR.h | 2 +- tasmota/language/he_HE.h | 2 +- tasmota/language/hu_HU.h | 2 +- tasmota/language/it_IT.h | 2 +- tasmota/language/ko_KO.h | 2 +- tasmota/language/nl_NL.h | 2 +- tasmota/language/pl_PL.h | 2 +- tasmota/language/pt_BR.h | 2 +- tasmota/language/pt_PT.h | 2 +- tasmota/language/ro_RO.h | 2 +- tasmota/language/ru_RU.h | 2 +- tasmota/language/sk_SK.h | 2 +- tasmota/language/sv_SE.h | 2 +- tasmota/language/tr_TR.h | 2 +- tasmota/language/uk_UA.h | 2 +- tasmota/language/vi_VN.h | 2 +- tasmota/language/zh_CN.h | 2 +- tasmota/language/zh_TW.h | 2 +- tasmota/my_user_config.h | 2 +- tasmota/settings.h | 2 +- tasmota/settings.ino | 2 +- tasmota/support.ino | 2 +- tasmota/support_button.ino | 2 +- tasmota/support_command.ino | 2 +- tasmota/support_cores.ino | 2 +- tasmota/support_crash_recorder.ino | 2 +- tasmota/support_device_groups.ino | 2 +- tasmota/support_eeprom.ino | 2 +- tasmota/support_esp32.ino | 2 +- tasmota/support_esptool.ino | 2 +- tasmota/support_features.ino | 2 +- tasmota/support_filesystem.ino | 2 +- tasmota/support_flash_log.ino | 2 +- tasmota/support_float.ino | 2 +- tasmota/support_jpeg.ino | 2 +- tasmota/support_light_list.ino | 10 +++--- tasmota/support_network.ino | 2 +- tasmota/support_rotary.ino | 2 +- tasmota/support_rtc.ino | 2 +- tasmota/support_static_buffer.ino | 2 +- tasmota/support_statistics.ino | 2 +- tasmota/support_switch.ino | 2 +- tasmota/support_tasmota.ino | 2 +- tasmota/support_udp.ino | 2 +- tasmota/support_wifi.ino | 2 +- tasmota/tasmota.h | 2 +- tasmota/tasmota.ino | 2 +- tasmota/tasmota_ca.ino | 2 +- tasmota/tasmota_compat.h | 19 +++++++++++ tasmota/tasmota_configurations.h | 2 +- tasmota/tasmota_configurations_ESP32.h | 2 +- tasmota/tasmota_globals.h | 2 +- tasmota/tasmota_template.h | 2 +- tasmota/tasmota_template_legacy.h | 2 +- tasmota/tasmota_version.h | 2 +- tasmota/user_config_override_sample.h | 2 +- tasmota/xdrv_01_webserver.ino | 2 +- tasmota/xdrv_02_mqtt.ino | 2 +- tasmota/xdrv_03_energy.ino | 2 +- tasmota/xdrv_04_light.ino | 10 +++--- tasmota/xdrv_05_irremote.ino | 2 +- tasmota/xdrv_05_irremote_full.ino | 2 +- tasmota/xdrv_06_snfbridge.ino | 2 +- tasmota/xdrv_07_domoticz.ino | 2 +- tasmota/xdrv_08_serial_bridge.ino | 2 +- tasmota/xdrv_09_timers.ino | 2 +- tasmota/xdrv_10_rules.ino | 2 +- tasmota/xdrv_10_scripter.ino | 2 +- tasmota/xdrv_11_knx.ino | 4 +-- tasmota/xdrv_12_home_assistant.ino | 2 +- tasmota/xdrv_13_display.ino | 2 +- tasmota/xdrv_14_mp3.ino | 2 +- tasmota/xdrv_15_pca9685.ino | 2 +- tasmota/xdrv_16_tuyamcu.ino | 2 +- tasmota/xdrv_17_rcswitch.ino | 2 +- tasmota/xdrv_18_armtronix_dimmers.ino | 2 +- tasmota/xdrv_19_ps16dz_dimmer.ino | 2 +- tasmota/xdrv_20_hue.ino | 2 +- tasmota/xdrv_21_wemo.ino | 2 +- tasmota/xdrv_21_wemo_multi.ino | 2 +- tasmota/xdrv_22_sonoff_ifan.ino | 2 +- tasmota/xdrv_23_zigbee_0_constants.ino | 10 +++--- tasmota/xdrv_23_zigbee_1_headers.ino | 2 +- tasmota/xdrv_23_zigbee_1z_libs.ino | 24 +++++++------- tasmota/xdrv_23_zigbee_2_devices.ino | 20 ++++++------ tasmota/xdrv_23_zigbee_2a_devices_impl.ino | 2 +- tasmota/xdrv_23_zigbee_3_hue.ino | 2 +- tasmota/xdrv_23_zigbee_4_persistence.ino | 2 +- tasmota/xdrv_23_zigbee_4a_nano_fs.ino | 36 ++++++++++----------- tasmota/xdrv_23_zigbee_4b_eeprom.ino | 12 +++---- tasmota/xdrv_23_zigbee_5__constants.ino | 18 +++++------ tasmota/xdrv_23_zigbee_5_converters.ino | 4 +-- tasmota/xdrv_23_zigbee_6_commands.ino | 2 +- tasmota/xdrv_23_zigbee_7_0_statemachine.ino | 2 +- tasmota/xdrv_23_zigbee_7_5_map.ino | 2 +- tasmota/xdrv_23_zigbee_8_parsers.ino | 2 +- tasmota/xdrv_23_zigbee_9_serial.ino | 2 +- tasmota/xdrv_23_zigbee_9a_upload.ino | 2 +- tasmota/xdrv_23_zigbee_A_impl.ino | 6 ++-- tasmota/xdrv_24_buzzer.ino | 2 +- tasmota/xdrv_25_A4988_Stepper.ino | 2 +- tasmota/xdrv_26_ariluxrf.ino | 2 +- tasmota/xdrv_27_shutter.ino | 4 +-- tasmota/xdrv_28_pcf8574.ino | 2 +- tasmota/xdrv_29_deepsleep.ino | 2 +- tasmota/xdrv_30_exs_dimmer.ino | 2 +- tasmota/xdrv_31_tasmota_client.ino | 2 +- tasmota/xdrv_32_hotplug.ino | 2 +- tasmota/xdrv_33_nrf24l01.ino | 2 +- tasmota/xdrv_34_wemos_motor_v1.ino | 2 +- tasmota/xdrv_35_pwm_dimmer.ino | 6 ++-- tasmota/xdrv_36_keeloq.ino | 2 +- tasmota/xdrv_37_sonoff_d1.ino | 2 +- tasmota/xdrv_38_ping.ino | 2 +- tasmota/xdrv_39_thermostat.ino | 2 +- tasmota/xdrv_40_telegram.ino | 2 +- tasmota/xdrv_41_tcp_bridge.ino | 2 +- tasmota/xdrv_42_i2s_audio.ino | 2 +- tasmota/xdrv_43_mlx90640.ino | 2 +- tasmota/xdrv_44_miel_hvac.ino | 2 +- tasmota/xdrv_45_shelly_dimmer.ino | 2 +- tasmota/xdrv_46_ccloader.ino | 24 +++++++------- tasmota/xdrv_47_ftc532.ino | 2 +- tasmota/xdrv_80_odroidgo.ino | 2 +- tasmota/xdrv_81_webcam.ino | 2 +- tasmota/xdrv_82_ethernet.ino | 2 +- tasmota/xdrv_83_esp32watch.ino | 2 +- tasmota/xdrv_84_core2.ino | 2 +- tasmota/xdrv_99_debug.ino | 2 +- tasmota/xdrv_interface.ino | 2 +- tasmota/xdsp_01_lcd.ino | 2 +- tasmota/xdsp_02_ssd1306.ino | 2 +- tasmota/xdsp_03_matrix.ino | 2 +- tasmota/xdsp_04_ili9341.ino | 2 +- tasmota/xdsp_05_epaper_29.ino | 2 +- tasmota/xdsp_06_epaper_42.ino | 2 +- tasmota/xdsp_07_sh1106.ino | 2 +- tasmota/xdsp_08_ILI9488.ino | 2 +- tasmota/xdsp_09_SSD1351.ino | 2 +- tasmota/xdsp_10_RA8876.ino | 2 +- tasmota/xdsp_11_sevenseg.ino | 2 +- tasmota/xdsp_12_ST7789.ino | 2 +- tasmota/xdsp_13_ILI9341-2.ino | 2 +- tasmota/xdsp_interface.ino | 2 +- tasmota/xlgt_01_ws2812.ino | 2 +- tasmota/xlgt_02_my92x1.ino | 2 +- tasmota/xlgt_03_sm16716.ino | 4 +-- tasmota/xlgt_04_sm2135.ino | 2 +- tasmota/xlgt_05_sonoff_l1.ino | 2 +- tasmota/xlgt_06_electriq_moodl.ino | 2 +- tasmota/xlgt_interface.ino | 2 +- tasmota/xnrg_01_hlw8012.ino | 2 +- tasmota/xnrg_02_cse7766.ino | 2 +- tasmota/xnrg_03_pzem004t.ino | 2 +- tasmota/xnrg_04_mcp39f501.ino | 2 +- tasmota/xnrg_05_pzem_ac.ino | 2 +- tasmota/xnrg_06_pzem_dc.ino | 2 +- tasmota/xnrg_07_ade7953.ino | 2 +- tasmota/xnrg_08_sdm120.ino | 2 +- tasmota/xnrg_09_dds2382.ino | 2 +- tasmota/xnrg_10_sdm630.ino | 2 +- tasmota/xnrg_11_ddsu666.ino | 2 +- tasmota/xnrg_12_solaxX1.ino | 2 +- tasmota/xnrg_13_fif_le01mr.ino | 2 +- tasmota/xnrg_14_bl0940.ino | 2 +- tasmota/xnrg_15_teleinfo.ino | 2 +- tasmota/xnrg_16_iem3000.ino | 2 +- tasmota/xnrg_17_ornowe517.ino | 2 +- tasmota/xnrg_interface.ino | 2 +- tasmota/xsns_01_counter.ino | 2 +- tasmota/xsns_02_analog.ino | 2 +- tasmota/xsns_04_snfsc.ino | 2 +- tasmota/xsns_05_ds18x20.ino | 2 +- tasmota/xsns_05_ds18x20_esp32.ino | 2 +- tasmota/xsns_06_dht.ino | 2 +- tasmota/xsns_07_sht1x.ino | 2 +- tasmota/xsns_08_htu21.ino | 2 +- tasmota/xsns_09_bmp.ino | 2 +- tasmota/xsns_10_bh1750.ino | 2 +- tasmota/xsns_11_veml6070.ino | 2 +- tasmota/xsns_12_ads1115.ino | 2 +- tasmota/xsns_13_ina219.ino | 2 +- tasmota/xsns_14_sht3x.ino | 2 +- tasmota/xsns_15_mhz19.ino | 2 +- tasmota/xsns_16_tsl2561.ino | 2 +- tasmota/xsns_17_senseair.ino | 2 +- tasmota/xsns_18_pms5003.ino | 2 +- tasmota/xsns_19_mgs.ino | 2 +- tasmota/xsns_20_novasds.ino | 2 +- tasmota/xsns_21_sgp30.ino | 2 +- tasmota/xsns_22_sr04.ino | 2 +- tasmota/xsns_24_si1145.ino | 2 +- tasmota/xsns_26_lm75ad.ino | 2 +- tasmota/xsns_27_apds9960.ino | 2 +- tasmota/xsns_28_tm1638.ino | 2 +- tasmota/xsns_29_mcp230xx.ino | 2 +- tasmota/xsns_30_mpr121.ino | 2 +- tasmota/xsns_31_ccs811.ino | 2 +- tasmota/xsns_32_mpu6050.ino | 2 +- tasmota/xsns_33_ds3231.ino | 2 +- tasmota/xsns_34_hx711.ino | 2 +- tasmota/xsns_35_tx20.ino | 2 +- tasmota/xsns_36_mgc3130.ino | 4 +-- tasmota/xsns_37_rfsensor.ino | 2 +- tasmota/xsns_38_az7798.ino | 2 +- tasmota/xsns_39_max31855.ino | 2 +- tasmota/xsns_40_pn532.ino | 2 +- tasmota/xsns_41_max44009.ino | 2 +- tasmota/xsns_42_scd30.ino | 2 +- tasmota/xsns_43_hre.ino | 2 +- tasmota/xsns_44_sps30.ino | 2 +- tasmota/xsns_45_vl53l0x.ino | 2 +- tasmota/xsns_46_MLX90614.ino | 2 +- tasmota/xsns_47_max31865.ino | 2 +- tasmota/xsns_48_chirp.ino | 2 +- tasmota/xsns_50_paj7620.ino | 2 +- tasmota/xsns_51_rdm6300.ino | 2 +- tasmota/xsns_52_ibeacon.ino | 2 +- tasmota/xsns_53_sml.ino | 2 +- tasmota/xsns_54_ina226.ino | 2 +- tasmota/xsns_55_hih_series.ino | 2 +- tasmota/xsns_56_hpma.ino | 4 +-- tasmota/xsns_57_tsl2591.ino | 2 +- tasmota/xsns_58_dht12.ino | 2 +- tasmota/xsns_59_ds1624.ino | 2 +- tasmota/xsns_60_GPS.ino | 2 +- tasmota/xsns_61_MI_NRF24.ino | 2 +- tasmota/xsns_62_MI_ESP32.ino | 10 +++--- tasmota/xsns_62_MI_HM10.ino | 10 +++--- tasmota/xsns_63_aht1x.ino | 2 +- tasmota/xsns_64_hrxl.ino | 2 +- tasmota/xsns_65_hdc1080.ino | 2 +- tasmota/xsns_66_iAQ.ino | 2 +- tasmota/xsns_67_as3935.ino | 2 +- tasmota/xsns_68_windmeter.ino | 2 +- tasmota/xsns_69_opentherm.ino | 4 +-- tasmota/xsns_69_opentherm_protocol.ino | 2 +- tasmota/xsns_70_veml6075.ino | 2 +- tasmota/xsns_71_veml7700.ino | 2 +- tasmota/xsns_72_mcp9808.ino | 2 +- tasmota/xsns_73_hp303b.ino | 2 +- tasmota/xsns_74_lmt01.ino | 2 +- tasmota/xsns_75_prometheus.ino | 2 +- tasmota/xsns_76_dyp.ino | 2 +- tasmota/xsns_77_vl53l1x.ino | 2 +- tasmota/xsns_78_ezo.ino | 2 +- tasmota/xsns_78_ezoco2.ino | 2 +- tasmota/xsns_78_ezodo.ino | 4 +-- tasmota/xsns_78_ezoec.ino | 4 +-- tasmota/xsns_78_ezoflo.ino | 2 +- tasmota/xsns_78_ezohum.ino | 2 +- tasmota/xsns_78_ezoo2.ino | 4 +-- tasmota/xsns_78_ezoorp.ino | 4 +-- tasmota/xsns_78_ezoph.ino | 4 +-- tasmota/xsns_78_ezopmp.ino | 2 +- tasmota/xsns_78_ezoprs.ino | 4 +-- tasmota/xsns_78_ezorgb.ino | 2 +- tasmota/xsns_78_ezortd.ino | 4 +-- tasmota/xsns_78_xezo.ino | 2 +- tasmota/xsns_79_as608.ino | 2 +- tasmota/xsns_80_mfrc522.ino | 2 +- tasmota/xsns_interface.ino | 2 +- tasmota/xx2c_interface.ino | 2 +- 275 files changed, 392 insertions(+), 373 deletions(-) diff --git a/tasmota/StackThunk_light.cpp b/tasmota/StackThunk_light.cpp index 1e5fd445a..aea7ae438 100644 --- a/tasmota/StackThunk_light.cpp +++ b/tasmota/StackThunk_light.cpp @@ -7,7 +7,7 @@ between a secondary, user-allocated stack on the heap and the real stack. - Copyright (c) 2017 Earle F. Philhower, III. All rights reserved. + Copyright (C) 2021 Earle F. Philhower, III. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/tasmota/StackThunk_light.h b/tasmota/StackThunk_light.h index 164417000..9fa562655 100644 --- a/tasmota/StackThunk_light.h +++ b/tasmota/StackThunk_light.h @@ -7,7 +7,7 @@ between a secondary, user-allocated stack on the heap and the real stack. - Copyright (c) 2017 Earle F. Philhower, III. All rights reserved. + Copyright (C) 2021 Earle F. Philhower, III. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp index 7d9d51a35..f91d96cfc 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.cpp +++ b/tasmota/WiFiClientSecureLightBearSSL.cpp @@ -3,7 +3,7 @@ - Mostly compatible with Arduino WiFi shield library and standard WiFiClient/ServerSecure (except for certificate handling). - Copyright (c) 2018 Earle F. Philhower, III + Copyright (C) 2021 Earle F. Philhower, III This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/tasmota/WiFiClientSecureLightBearSSL.h b/tasmota/WiFiClientSecureLightBearSSL.h index ed6ced416..f480a9d42 100755 --- a/tasmota/WiFiClientSecureLightBearSSL.h +++ b/tasmota/WiFiClientSecureLightBearSSL.h @@ -3,7 +3,7 @@ - Mostly compatible with Arduino WiFi shield library and standard WiFiClient/ServerSecure (except for certificate handling). - Copyright (c) 2018 Earle F. Philhower, III + Copyright (C) 2021 Earle F. Philhower, III This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/tasmota/i18n.h b/tasmota/i18n.h index 3fd70be4e..0d18f016a 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -1,7 +1,7 @@ /* i18n.h - internationalization for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index ce3da91a0..bfd4177e3 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -1,7 +1,7 @@ /* af_AF.h - localization for Afrikaans - Afrikaans for Tasmota - Copyright (C) 2020 Christiaan Heerze + Copyright (C) 2021 Christiaan Heerze 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 diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index f91454097..f8e3c705c 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -1,7 +1,7 @@ /* bg-BG.h - localization for Bulgaria - Bulgarian for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index c4beb0341..983524bbf 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -1,7 +1,7 @@ /* cs-CZ.h - localization for Czech with diacritics - Czech for Tasmota - Copyright (C) 2020 Vladimír Synek + Copyright (C) 2021 Vladimír Synek 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 diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index e8449f9e7..f1bad46a7 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -1,7 +1,7 @@ /* de-DE.h - localization for German - Germany for Tasmota - Copyright (C) 2020 VinceMasuka + Copyright (C) 2021 VinceMasuka 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 diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 635aa5b27..5820512d6 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -1,7 +1,7 @@ /* el-GR.h - localization for Greek - Greece for Tasmota - Copyright (C) 2020 Theo Arends, translated by Nick Galfas + Copyright (C) 2021 Theo Arends, translated by Nick Galfas 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 diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 20d0902a3..77a325d30 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -1,7 +1,7 @@ /* en-GB.h - localization for English - United Kingdom for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index ab84086ad..e04f2b256 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -1,7 +1,7 @@ /* es-ES.h - localization for Spanish - Spain for Tasmota - Copyright (C) 2020 Adrian Scillato + Copyright (C) 2021 Adrian Scillato 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 diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 0255d49e2..65c14a58d 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -1,6 +1,6 @@ /* fr-FR.h - localization for French - France for Tasmota - Copyright (C) 2020 Olivier Francais + Copyright (C) 2021 Olivier Francais 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 diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index d92bab299..6e9a6ef8e 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -1,7 +1,7 @@ /* he-HE.h - localization for Hebrew - Israel for Tasmota - Copyright (C) 2020 Yuval Mejahez + Copyright (C) 2021 Yuval Mejahez 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 diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index ff6c40498..82fe0b4a4 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -1,7 +1,7 @@ /* hu-HU.h - localization for Hungarian in Hungary for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 74f6b1090..91ae9a830 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -1,7 +1,7 @@ /* it-IT.h - localization for Italian - Italy for Tasmota - Copyright (C) 2020 Gennaro Tortone - some mods by Antonio Fragola - Updated by bovirus - rev. 24.12.2020 + Copyright (C) 2021 Gennaro Tortone - some mods by Antonio Fragola - Updated by bovirus - rev. 24.12.2020 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 diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 4da9f1303..6ab2f1421 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -1,7 +1,7 @@ /* ko-KO.h - localization for Korean - Korean for Tasmota - Copyright (C) 2020 Theo Arends (translated by NyaamZ) + Copyright (C) 2021 Theo Arends (translated by NyaamZ) 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 diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 0be25c2e4..682fbec90 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -1,7 +1,7 @@ /* nl-NL.h - localization for Dutch - Nederland for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index ad522652f..f5497d91d 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -1,7 +1,7 @@ /* pl-PL-d.h - localization for Polish with diacritics - Poland for Tasmota - Copyright (C) 2020 Theo Arends (translated by roblad - Robert L., upgraded by R. Turala) + Copyright (C) 2021 Theo Arends (translated by roblad - Robert L., upgraded by R. Turala) 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 diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index fc50f160f..99d38f192 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -1,7 +1,7 @@ /* pt-BR.h - localization for Portuguese - Brazil for Tasmota - Copyright (C) 2020 Fabiano Bovo + Copyright (C) 2021 Fabiano Bovo 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 diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 67e3b6e6b..5e7c74f36 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -1,7 +1,7 @@ /* pt-PT.h - localization for Portuguese - Portugal for Tasmota - Copyright (C) 2020 Paulo Paiva + Copyright (C) 2021 Paulo Paiva 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 diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 6464e7af2..bb1a09185 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -1,7 +1,7 @@ /* ro-RO.h - localization for Romanian - Romania and Moldova for Tasmota - Copyright (C) 2020 Augustin Marti + Copyright (C) 2021 Augustin Marti 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 diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index da5998e15..df1d5b50e 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -1,7 +1,7 @@ /* ru-RU.h - localization for Russian - Rissia for Tasmota - Copyright (C) 2020 Theo Arends / roman-vn + Copyright (C) 2021 Theo Arends / roman-vn 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 diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index b162e992b..8f5490a19 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -1,7 +1,7 @@ /* sk-SK.h - localization for Slovak with diacritics - Slovak for Tasmota - Copyright (C) 2020 Vladimír Jendroľ + Copyright (C) 2021 Vladimír Jendroľ 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 diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index c15f911e4..6935fa102 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -1,7 +1,7 @@ /* sv-SE.h - localization for Swedish - Svenska for Tasmota - Copyright (C) 2020 Gunnar Norin + Copyright (C) 2021 Gunnar Norin 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 diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index ac8e34ff0..01b73bc75 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -1,7 +1,7 @@ /* tr-TR.h - localization for Turkish - Turkey for Tasmota - Copyright (C) 2020 Ali Sait Teke and Theo Arends + Copyright (C) 2021 Ali Sait Teke and 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 diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index f3d455f72..11fbdac99 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -1,7 +1,7 @@ /* uk-UA.h - localization for Ukrainian - Ukraine for Tasmota - Copyright (C) 2020 Theo Arends / vadym-adik + Copyright (C) 2021 Theo Arends / vadym-adik 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 diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index cf642b6dc..cc666ec82 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -1,7 +1,7 @@ /* vi-VN.h - localization for Vietnam for Tasmota - Copyright (C) 2020 translateb by Tâm.NT + Copyright (C) 2021 translateb by Tâm.NT 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 diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 8b2eb080c..2e6baa64d 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -1,7 +1,7 @@ /* zh-CN.h - localization for Chinese (Simplified) - China for Tasmota - Copyright (C) 2020 Theo Arends (translated by killadm) + Copyright (C) 2021 Theo Arends (translated by killadm) 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 diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 6b79def35..2a2078266 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -1,7 +1,7 @@ /* zh-TW.h - localization for Chinese (Traditional) - Taiwan for Tasmota - Copyright (C) 2020 Theo Arends (translated by dannydu) + Copyright (C) 2021 Theo Arends (translated by dannydu) 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 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index cc75735cf..59cef587c 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -1,7 +1,7 @@ /* my_user_config.h - user specific configuration for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/settings.h b/tasmota/settings.h index 72d0477ce..4842103b4 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -1,7 +1,7 @@ /* settings.h - setting variables for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 859960472..465789eb8 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -1,7 +1,7 @@ /* settings.ino - user settings for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support.ino b/tasmota/support.ino index 215c8ea1d..3d8634e3e 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1,7 +1,7 @@ /* support.ino - support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index 749509b69..53fb218ba 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -1,7 +1,7 @@ /* support_button.ino - button support for Tasmota - Copyright (C) 2020 Federico Leoni and Theo Arends + Copyright (C) 2021 Federico Leoni and 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 diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index bc1121123..59d3f3e41 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1,7 +1,7 @@ /* support_command.ino - command support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_cores.ino b/tasmota/support_cores.ino index 855768bbf..547b776dc 100644 --- a/tasmota/support_cores.ino +++ b/tasmota/support_cores.ino @@ -1,7 +1,7 @@ /* support_cores.ino - Arduino core support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_crash_recorder.ino b/tasmota/support_crash_recorder.ino index aa1d17a15..b9d81b53f 100644 --- a/tasmota/support_crash_recorder.ino +++ b/tasmota/support_crash_recorder.ino @@ -1,7 +1,7 @@ /* support_crash_recorder.ino - record the call stack in RTC in case of crash - Copyright (C) 2020 Stephan Hadinger, Theo Arends, + Copyright (C) 2021 Stephan Hadinger, 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 diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino index becb20c5b..7e589e15e 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -1,7 +1,7 @@ /* support_device_groups.ino - device groups support for Tasmota - Copyright (C) 2020 Paul C Diem + Copyright (C) 2021 Paul C Diem Device group allow multiple devices to be in a group with power, light brightness, fade and speed settings and other module-specific settings diff --git a/tasmota/support_eeprom.ino b/tasmota/support_eeprom.ino index 467459354..10828fe16 100644 --- a/tasmota/support_eeprom.ino +++ b/tasmota/support_eeprom.ino @@ -1,7 +1,7 @@ /* support_eeprom.ino - eeprom support for Sonoff-Tasmota - Copyright (C) 2020 Theo Arends & Gerhard Mutz + Copyright (C) 2021 Theo Arends & Gerhard Mutz 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 diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino index 3018b9de8..275064204 100644 --- a/tasmota/support_esp32.ino +++ b/tasmota/support_esp32.ino @@ -1,7 +1,7 @@ /* support_esp32.ino - ESP32 specific code for Tasmota - Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt + Copyright (C) 2021 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 diff --git a/tasmota/support_esptool.ino b/tasmota/support_esptool.ino index efde513fc..f100a4706 100644 --- a/tasmota/support_esptool.ino +++ b/tasmota/support_esptool.ino @@ -1,7 +1,7 @@ /* support_esptool.ino - esptool support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 7a5d6cbcb..29ef7a15c 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -1,7 +1,7 @@ /* support_features.ino - feature support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_filesystem.ino b/tasmota/support_filesystem.ino index 94b69fea2..445c34ae4 100644 --- a/tasmota/support_filesystem.ino +++ b/tasmota/support_filesystem.ino @@ -1,7 +1,7 @@ /* support_filesystem.ino - Filesystem support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_flash_log.ino b/tasmota/support_flash_log.ino index a1bdd5012..58a8c2dc0 100644 --- a/tasmota/support_flash_log.ino +++ b/tasmota/support_flash_log.ino @@ -1,7 +1,7 @@ /* support_flash_log.ino - log to flash support for Sonoff-Tasmota - Copyright (C) 2020 Theo Arends & Christian Baars + Copyright (C) 2021 Theo Arends & Christian Baars 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 diff --git a/tasmota/support_float.ino b/tasmota/support_float.ino index 1e2edc3f2..2bdf32ef2 100644 --- a/tasmota/support_float.ino +++ b/tasmota/support_float.ino @@ -1,7 +1,7 @@ /* support_float.ino - Small floating point support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/support_jpeg.ino b/tasmota/support_jpeg.ino index e9d0b2813..4669b9ad7 100644 --- a/tasmota/support_jpeg.ino +++ b/tasmota/support_jpeg.ino @@ -1,7 +1,7 @@ /* jpeg_utils.c - Version header file for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_light_list.ino b/tasmota/support_light_list.ino index 316f3f64e..eaaea1322 100644 --- a/tasmota/support_light_list.ino +++ b/tasmota/support_light_list.ino @@ -1,7 +1,7 @@ /* support_light_list.ino - Lightweight Linked List for simple objects - optimized for low code size and low memory - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -18,9 +18,9 @@ */ /*********************************************************************************************\ - * + * * private class for Linked List element - * + * \*********************************************************************************************/ template class LList; @@ -43,9 +43,9 @@ protected: }; /*********************************************************************************************\ - * + * * Lightweight Linked List - optimized for low code size - * + * \*********************************************************************************************/ template class LList { diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino index f50705272..56ac7d799 100644 --- a/tasmota/support_network.ino +++ b/tasmota/support_network.ino @@ -1,7 +1,7 @@ /* support_network.ino - Network support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index f38d8fb9f..7470a0985 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -1,7 +1,7 @@ /* support_rotary.ino - rotary switch support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index 294303026..fc8a14042 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -1,7 +1,7 @@ /* support_rtc.ino - Real Time Clock support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_static_buffer.ino b/tasmota/support_static_buffer.ino index 9504ba3dd..2c3b8887c 100644 --- a/tasmota/support_static_buffer.ino +++ b/tasmota/support_static_buffer.ino @@ -1,7 +1,7 @@ /* support_buffer.ino - Static binary buffer for Zigbee on Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/support_statistics.ino b/tasmota/support_statistics.ino index 59318e575..e899ae604 100644 --- a/tasmota/support_statistics.ino +++ b/tasmota/support_statistics.ino @@ -1,7 +1,7 @@ /* support_statistics.ino - gather statistics for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index 36dc2bb39..3bf500b02 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -1,7 +1,7 @@ /* support_switch.ino - switch support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index b6178f4bc..dedb28f6d 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1,7 +1,7 @@ /* support_tasmota.ino - Core support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino index f83788a59..7c13c86ba 100644 --- a/tasmota/support_udp.ino +++ b/tasmota/support_udp.ino @@ -1,7 +1,7 @@ /* support_udp.ino - Udp support for Tasmota - Copyright (C) 2020 Heiko Krupp and Theo Arends + Copyright (C) 2021 Heiko Krupp and 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 diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino index 6cba8a053..d70e9afd3 100644 --- a/tasmota/support_wifi.ino +++ b/tasmota/support_wifi.ino @@ -1,7 +1,7 @@ /* support_wifi.ino - wifi support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 20f150f69..e01de2d3f 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -1,7 +1,7 @@ /* tasmota.h - Master header file for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 183606909..7dcc7e7ef 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -1,7 +1,7 @@ /* tasmota.ino - Tasmota firmware for iTead Sonoff, Wemos and NodeMCU hardware - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_ca.ino b/tasmota/tasmota_ca.ino index 990a0f970..97b79614b 100644 --- a/tasmota/tasmota_ca.ino +++ b/tasmota/tasmota_ca.ino @@ -1,7 +1,7 @@ /* tasmota_ca.ino - Certificate authorities for Tasmota, LetsEncrypt and AWS - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_compat.h b/tasmota/tasmota_compat.h index 598ca5619..4a75ec3a8 100644 --- a/tasmota/tasmota_compat.h +++ b/tasmota/tasmota_compat.h @@ -1,3 +1,22 @@ +/* + tasmota_compat.h - ESP32 support for Tasmota + + Copyright (C) 2021 Jörg Schüler-Maroldt and 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 . +*/ + #pragma once #ifdef ESP32 diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 6e4169e82..9a4e26e4d 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -1,7 +1,7 @@ /* tasmota_configurations.h - Configurations for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h index 2f21ed0aa..3ce9881f6 100644 --- a/tasmota/tasmota_configurations_ESP32.h +++ b/tasmota/tasmota_configurations_ESP32.h @@ -1,7 +1,7 @@ /* tasmota_configurations_ESP32.h - ESP32 only Configurations for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index 7ef12bb8d..70a8e1745 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -1,7 +1,7 @@ /* tasmota_globals.h - Function prototypes and global configurations for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 786eeed08..714ca0f77 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -1,7 +1,7 @@ /* tasmota_template.h - template settings for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_template_legacy.h b/tasmota/tasmota_template_legacy.h index 153a6801b..4d5f2c507 100644 --- a/tasmota/tasmota_template_legacy.h +++ b/tasmota/tasmota_template_legacy.h @@ -1,7 +1,7 @@ /* tasmota_template_legacy.h - template settings for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 490f68bd8..c61d7dbaa 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -1,7 +1,7 @@ /* tasmota_version.h - Version header file for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/user_config_override_sample.h b/tasmota/user_config_override_sample.h index b04b979fe..d33e5fc75 100644 --- a/tasmota/user_config_override_sample.h +++ b/tasmota/user_config_override_sample.h @@ -1,7 +1,7 @@ /* user_config_override.h - user configuration overrides my_user_config.h for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index ba105332c..56389ea9a 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1,7 +1,7 @@ /* xdrv_01_webserver.ino - webserver for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index a0bc0f494..81de886f4 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -1,7 +1,7 @@ /* xdrv_02_mqtt.ino - mqtt support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index 18c57b371..e7b52b9ab 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -1,7 +1,7 @@ /* xdrv_03_energy.ino - Energy sensor support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index f0b94bcec..5443a8a55 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1,7 +1,7 @@ /* xdrv_04_light.ino - PWM, WS2812 and sonoff led support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 @@ -134,7 +134,7 @@ const char kLightCommands[] PROGMEM = "|" // No prefix D_CMND_WHITE "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|" D_CMND_CTRANGE #ifdef USE_LIGHT_VIRTUAL_CT - "|" D_CMND_VIRTUALCT + "|" D_CMND_VIRTUALCT #endif // USE_LIGHT_VIRTUAL_CT #ifdef USE_LIGHT_PALETTE "|" D_CMND_PALETTE @@ -2385,7 +2385,7 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) { } } #endif // ESP8266 - + // Now see if we need to mix RGB and White // Valid only for LST_RGBW, LST_RGBCW, SetOption105 1, and white is zero (see doc) if ((LST_RGBW <= Light.subtype) && (Settings.flag4.white_blend_mode) && (0 == cur_col_10[3]+cur_col_10[4])) { @@ -2400,7 +2400,7 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) { white_bri10 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023 rgbwwtable_applied_white = true; } - + #ifdef USE_LIGHT_VIRTUAL_CT // compute virtual CT, which is suppsed to be compatible with white_blend_mode if (Light.virtual_ct && (!white_free_cw) && (LST_RGBW <= Light.subtype)) { // any light with a white channel @@ -2444,7 +2444,7 @@ bool calcGammaBulbs(uint16_t cur_col_10[5]) { cur_col_10[3] = white_bri10; // simple case, we set the White level to the required brightness } else if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) { // if sum of both channels is > 255, then channels are probably uncorrelated - if (!white_free_cw) { + if (!white_free_cw) { // then we split the total energy among the cold and warm leds cur_col_10[cw0+1] = changeUIntScale(ct_10, 0, 1023, 0, white_bri10); cur_col_10[cw0] = white_bri10 - cur_col_10[cw0+1]; diff --git a/tasmota/xdrv_05_irremote.ino b/tasmota/xdrv_05_irremote.ino index efa048465..44304c550 100644 --- a/tasmota/xdrv_05_irremote.ino +++ b/tasmota/xdrv_05_irremote.ino @@ -1,7 +1,7 @@ /* xdrv_05_irremote.ino - infra red support for Tasmota - Copyright (C) 2020 Heiko Krupp, Lazar Obradovic and Theo Arends + Copyright (C) 2021 Heiko Krupp, Lazar Obradovic and 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 diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 4bfd00da2..bed0e8199 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -1,7 +1,7 @@ /* xdrv_05_irremote_full.ino - complete integration of IRremoteESP8266 for Tasmota - Copyright (C) 2020 Heiko Krupp, Lazar Obradovic, Theo Arends, Stephan Hadinger + Copyright (C) 2021 Heiko Krupp, Lazar Obradovic, Theo Arends, Stephan Hadinger 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 diff --git a/tasmota/xdrv_06_snfbridge.ino b/tasmota/xdrv_06_snfbridge.ino index 735913ed4..bb77d64c2 100644 --- a/tasmota/xdrv_06_snfbridge.ino +++ b/tasmota/xdrv_06_snfbridge.ino @@ -1,7 +1,7 @@ /* xdrv_06_snfbridge.ino - sonoff RF bridge 433 support for Tasmota - Copyright (C) 2020 Theo Arends and Erik Andrén Zachrisson (fw update) + Copyright (C) 2021 Theo Arends and Erik Andrén Zachrisson (fw update) 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 diff --git a/tasmota/xdrv_07_domoticz.ino b/tasmota/xdrv_07_domoticz.ino index e43ed1ce4..82b769963 100644 --- a/tasmota/xdrv_07_domoticz.ino +++ b/tasmota/xdrv_07_domoticz.ino @@ -1,7 +1,7 @@ /* xdrv_07_domoticz.ino - domoticz support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index 01e1cc5f0..eda328719 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -1,7 +1,7 @@ /* xdrv_08_serial_bridge.ino - serial bridge support for Tasmota - Copyright (C) 2020 Theo Arends and Dániel Zoltán Tolnai + Copyright (C) 2021 Theo Arends and Dániel Zoltán Tolnai 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 diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index 543da7d25..e2a66cfd0 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -1,7 +1,7 @@ /* xdrv_09_timers.ino - timer support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 9a91c9a38..8d8fefc13 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -1,7 +1,7 @@ /* xdrv_10_rules.ino - rule support for Tasmota - Copyright (C) 2020 ESP Easy Group and Theo Arends + Copyright (C) 2021 ESP Easy Group and 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 diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 6f7351c7d..d9a178e2b 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -1,7 +1,7 @@ /* xdrv_10_scripter.ino - script support for Tasmota - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino index 6aaf73715..0a8442e3b 100644 --- a/tasmota/xdrv_11_knx.ino +++ b/tasmota/xdrv_11_knx.ino @@ -1,7 +1,7 @@ /* xdrv_11_knx.ino - KNX IP Protocol support for Tasmota - Copyright (C) 2020 Adrian Scillato (https://github.com/ascillato) + Copyright (C) 2021 Adrian Scillato (https://github.com/ascillato) 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 @@ -590,7 +590,7 @@ void KNX_CB_Action(message_t const &msg, void *arg) else if ((chan->type >= KNX_SLOT1) && (chan->type <= KNX_SLOT5)) // KNX RX SLOTs (write command) { if (!toggle_inhibit) { - char command[35]; //4294967295.00 13chars + 17 + char command[35]; //4294967295.00 13chars + 17 if (msg.data_len == 1) { // Command received snprintf_P(command, sizeof(command), PSTR("event KNXRX_CMND%d=%d"), ((chan->type) - KNX_SLOT1 + 1 ), msg.data[0]); diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index cd92e2e32..e61ec7938 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -1,7 +1,7 @@ /* xdrv_12_home_assistant.ino - home assistant support for Tasmota - Copyright (C) 2020 Erik Montnemery, Federico Leoni and Theo Arends + Copyright (C) 2021 Erik Montnemery, Federico Leoni and 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 diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 2fa7d95d8..00a2ac8a5 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -1,7 +1,7 @@ /* xdrv_13_display.ino - Display support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_14_mp3.ino b/tasmota/xdrv_14_mp3.ino index ed6beee63..b0af75e57 100644 --- a/tasmota/xdrv_14_mp3.ino +++ b/tasmota/xdrv_14_mp3.ino @@ -1,7 +1,7 @@ /* xdrv_14_mp3.ino - MP3 support for Tasmota - Copyright (C) 2020 gemu2015, mike2nl and Theo Arends + Copyright (C) 2021 gemu2015, mike2nl and 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 diff --git a/tasmota/xdrv_15_pca9685.ino b/tasmota/xdrv_15_pca9685.ino index f57a10fd2..950a7df2b 100644 --- a/tasmota/xdrv_15_pca9685.ino +++ b/tasmota/xdrv_15_pca9685.ino @@ -1,7 +1,7 @@ /* xdrv_15_pca9685.ino - Support for I2C PCA9685 12bit 16 pin hardware PWM driver on Tasmota - Copyright (C) 2020 Andre Thomas and Theo Arends + Copyright (C) 2021 Andre Thomas and 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 diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 51a0a9c5b..ba8766b98 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -1,7 +1,7 @@ /* xdrv_16_tuyamcu.ino - Tuya MCU support for Tasmota - Copyright (C) 2020 Federico Leoni, digiblur, Joel Stein and Theo Arends + Copyright (C) 2021 Federico Leoni, digiblur, Joel Stein and 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 diff --git a/tasmota/xdrv_17_rcswitch.ino b/tasmota/xdrv_17_rcswitch.ino index 3930dd8cd..8877544df 100644 --- a/tasmota/xdrv_17_rcswitch.ino +++ b/tasmota/xdrv_17_rcswitch.ino @@ -1,7 +1,7 @@ /* xdrv_17_rcswitch.ino - RF transceiver using RcSwitch library for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_18_armtronix_dimmers.ino b/tasmota/xdrv_18_armtronix_dimmers.ino index a2fa782f5..14fba8c7b 100644 --- a/tasmota/xdrv_18_armtronix_dimmers.ino +++ b/tasmota/xdrv_18_armtronix_dimmers.ino @@ -1,7 +1,7 @@ /* xdrv_18_armtronix_dimmers.ino - Armtronix dimmers support for Tasmota - Copyright (C) 2020 wvdv2002 and Theo Arends + Copyright (C) 2021 wvdv2002 and 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 diff --git a/tasmota/xdrv_19_ps16dz_dimmer.ino b/tasmota/xdrv_19_ps16dz_dimmer.ino index f3cb9ef5f..b44a6da1b 100644 --- a/tasmota/xdrv_19_ps16dz_dimmer.ino +++ b/tasmota/xdrv_19_ps16dz_dimmer.ino @@ -1,7 +1,7 @@ /* xdrv_19_ps16dz.dimmer.ino - PS_16_DZ dimmer support for Tasmota - Copyright (C) 2020 Joel Stein and Theo Arends + Copyright (C) 2021 Joel Stein and 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 diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index e7289af7f..b0a18d16a 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -1,7 +1,7 @@ /* xdrv_20_hue.ino - Philips Hue support for Tasmota - Copyright (C) 2020 Heiko Krupp and Theo Arends + Copyright (C) 2021 Heiko Krupp and 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 diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index b63c89e89..96e937d21 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -1,7 +1,7 @@ /* xdrv_21_wemo.ino - wemo support for Tasmota - Copyright (C) 2020 Heiko Krupp and Theo Arends + Copyright (C) 2021 Heiko Krupp and 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 diff --git a/tasmota/xdrv_21_wemo_multi.ino b/tasmota/xdrv_21_wemo_multi.ino index 09c05b718..ec3fb7d42 100644 --- a/tasmota/xdrv_21_wemo_multi.ino +++ b/tasmota/xdrv_21_wemo_multi.ino @@ -1,7 +1,7 @@ /* xdrv_21_wemo_multi.ino - multiple wemo support for Tasmota - Copyright (C) 2020 Magic73, Heiko Krupp and Theo Arends + Copyright (C) 2021 Magic73, Heiko Krupp and 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 diff --git a/tasmota/xdrv_22_sonoff_ifan.ino b/tasmota/xdrv_22_sonoff_ifan.ino index 5ea74c792..4ee897020 100644 --- a/tasmota/xdrv_22_sonoff_ifan.ino +++ b/tasmota/xdrv_22_sonoff_ifan.ino @@ -1,7 +1,7 @@ /* xdrv_22_sonoff_ifan.ino - sonoff iFan02 and iFan03 support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 50c9e4eee..f29c787c6 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_constants.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -1165,11 +1165,11 @@ String getEmberStatus(uint8_t status) { 0x39, 0x3A, 0x3D, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x58, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6C, - 0x70, 0x71, 0x72, 0x74, 0x75, 0x76, - 0x80, 0x81, 0x82, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x70, 0x71, 0x72, 0x74, 0x75, 0x76, + 0x80, 0x81, 0x82, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x94, 0x96, 0x98, 0x99, 0x9A, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0x93, 0x95, 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA8, - 0xB3, 0xB7, 0xB8, 0xBB, 0xBD, 0xA9, 0xAA, + 0x93, 0x95, 0xA1, 0xA3, 0xA4, 0xA5, 0xA6, 0xA8, + 0xB3, 0xB7, 0xB8, 0xBB, 0xBD, 0xA9, 0xAA, 0xB0, 0xB1, 0xB4, 0xB6, 0xB5, 0xBA }; char msg[32]; diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino index 33ca5381e..3b9c73536 100644 --- a/tasmota/xdrv_23_zigbee_1_headers.ino +++ b/tasmota/xdrv_23_zigbee_1_headers.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_1_headers.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_1z_libs.ino b/tasmota/xdrv_23_zigbee_1z_libs.ino index 65ea266d2..4e018a21e 100644 --- a/tasmota/xdrv_23_zigbee_1z_libs.ino +++ b/tasmota/xdrv_23_zigbee_1z_libs.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_1z_libs.ino - zigbee support for Tasmota, JSON replacement libs - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -45,9 +45,9 @@ int strcmp_PP(const char *p1, const char *p2) { } /*********************************************************************************************\ - * + * * Variables for Rules from last Zigbee message received - * + * \*********************************************************************************************/ typedef struct Z_LastMessageVars { @@ -65,9 +65,9 @@ uint16_t Z_GetLastCluster(void) { return gZbLastMessage.cluster; } uint8_t Z_GetLastEndpoint(void) { return gZbLastMessage.endpoint; } /*********************************************************************************************\ - * + * * Class for single attribute - * + * \*********************************************************************************************/ enum class Za_type : uint8_t { @@ -126,7 +126,7 @@ public: attr_type(0xFF), attr_multiplier(1) {}; - + Z_attribute(const Z_attribute & rhs) { deepCopy(rhs); } @@ -213,9 +213,9 @@ protected: }; /*********************************************************************************************\ - * + * * Class for attribute ordered list - * + * \*********************************************************************************************/ @@ -309,9 +309,9 @@ Z_attribute & Z_attribute_list::addAttributePMEM(const char * name) { } /*********************************************************************************************\ - * + * * Implementation for Z_attribute - * + * \*********************************************************************************************/ // free any allocated memoruy for keys @@ -719,9 +719,9 @@ void Z_attribute::deepCopy(const Z_attribute & rhs) { } /*********************************************************************************************\ - * + * * Implementation for Z_attribute_list - * + * \*********************************************************************************************/ // add a cluster/attr_id attribute at the end of the list Z_attribute & Z_attribute_list::addAttribute(uint16_t cluster, uint16_t attr_id, uint8_t suffix) { diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index c319bb26f..e03e27d3d 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -235,7 +235,7 @@ public: inline void setCT(uint16_t _ct) { ct = _ct; } inline void setX(uint16_t _x) { x = _x; } inline void setY(uint16_t _y) { y = _y; } - + static const Z_Data_Type type = Z_Data_Type::Z_Light; // 12 bytes uint8_t colormode; // 0x00: Hue/Sat, 0x01: XY, 0x02: CT | 0xFF not set, default 0x01 @@ -248,7 +248,7 @@ public: /*********************************************************************************************\ * Device specific: PIR - * + * // List of occupancy time-outs: // 0xF = default (90 s) // 0x0 = no time-out @@ -274,7 +274,7 @@ public: inline uint8_t getOccupancy(void) const { return occupancy; } inline uint16_t getIlluminance(void) const { return illuminance; } - + inline void setOccupancy(uint8_t _occupancy) { occupancy = _occupancy; } inline void setIlluminance(uint16_t _illuminance) { illuminance = _illuminance; } @@ -429,7 +429,7 @@ public: } void convertZoneStatus(Z_attribute_list & attr_list, uint16_t val) const; - + // 4 bytes uint16_t zone_status; // last known state for sensor 1 & 2 uint16_t zone_type; // mapped to the Zigbee standard @@ -503,7 +503,7 @@ void Z_Data_Alarm::convertZoneStatus(Z_attribute_list & attr_list, uint16_t val) /*********************************************************************************************\ * Mode - * + * // List of modes // 0x1 = Tuya Zigbee mode // 0xF (default) = ZCL standard mode @@ -524,7 +524,7 @@ public: }; /*********************************************************************************************\ - * + * \*********************************************************************************************/ const uint8_t Z_Data_Type_len[] PROGMEM = { 0, // 0x00 Z_Data_Type::Z_Unknown @@ -556,9 +556,9 @@ size_t Z_Data::DataTypeToLength(Z_Data_Type t) { /*********************************************************************************************\ - * + * * Device specific Linked List - * + * \*********************************************************************************************/ class Z_Data_Set : public LList { public: @@ -886,7 +886,7 @@ public: Z_Device & isKnownLongAddrDevice(uint64_t longaddr) const; Z_Device & isKnownIndexDevice(uint32_t index) const; Z_Device & isKnownFriendlyNameDevice(const char * name) const; - + Z_Device & findShortAddr(uint16_t shortaddr); const Z_Device & findShortAddr(uint16_t shortaddr) const; Z_Device & findLongAddr(uint64_t longaddr); diff --git a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino index b54f2aff1..0a97a9938 100644 --- a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino +++ b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_2a_devices_impl.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index 2939e75b5..100faef9c 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_4_persistence.ino b/tasmota/xdrv_23_zigbee_4_persistence.ino index 91c516194..35d25922b 100644 --- a/tasmota/xdrv_23_zigbee_4_persistence.ino +++ b/tasmota/xdrv_23_zigbee_4_persistence.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_4a_nano_fs.ino b/tasmota/xdrv_23_zigbee_4a_nano_fs.ino index 2c9ea9ec7..007615c1b 100644 --- a/tasmota/xdrv_23_zigbee_4a_nano_fs.ino +++ b/tasmota/xdrv_23_zigbee_4a_nano_fs.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_4a_eeprom.ino - zigbee support for Tasmota - nano filesystem for EEPROM, with anti-weavering - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -93,9 +93,9 @@ // - only file size actually changes /*********************************************************************************************\ - * + * * Constants - * + * \*********************************************************************************************/ const size_t ZFS_BLOCK_SIZE = 256; const size_t ZFS_ENTRY_SIZE = 8; // each entry is 32 bytes @@ -124,7 +124,7 @@ public: blk_start(0), reserved(0) {} - + inline static bool validIdx(uint8_t blk_start) { return ((blk_start != 0x00) && (blk_start != 0x01) && (blk_start != 0xFF)); }; static uint16_t getAddress(uint8_t entry_idx); void read(uint8_t entry_idx); @@ -190,9 +190,9 @@ public: }; /*********************************************************************************************\ - * + * * Formatting implementations - * + * \*********************************************************************************************/ void ZFS_Dir_Block::format(void) { @@ -229,9 +229,9 @@ void ZFS_Map::format(void) { } /*********************************************************************************************\ - * + * * Writing a file - * + * \*********************************************************************************************/ class ZFS_Write_File { @@ -256,9 +256,9 @@ protected: /*********************************************************************************************\ - * + * * Check that the EEPROM is formatted - * + * \*********************************************************************************************/ // Main class for the Zigbee filesystem @@ -277,9 +277,9 @@ public: }; /*********************************************************************************************\ - * + * * Check that the EEPROM is formatted - * + * \*********************************************************************************************/ bool ZFS::findFileEntry(uint32_t name, ZFS_File_Entry & entry, uint8_t * _entry_idx) { @@ -317,9 +317,9 @@ void ZFS::erase(void) { } /*********************************************************************************************\ - * + * * Reading a file - * + * \*********************************************************************************************/ int32_t ZFS::readBytes(uint32_t name, void* buffer, size_t buffer_len, uint16_t read_start, uint16_t read_len) { if (!zigbee.eeprom_ready) { return -1; } @@ -349,9 +349,9 @@ int32_t ZFS::readBytes(uint32_t name, void* buffer, size_t buffer_len, uint16_t } /*********************************************************************************************\ - * + * * Check that the EEPROM is formatted - * + * \*********************************************************************************************/ void ZFS::initOrFormat(void) { @@ -386,7 +386,7 @@ void ZFS::initOrFormat(void) { format(); } delete dir; - + zigbee.eeprom_ready = true; } @@ -408,7 +408,7 @@ void ZFS::format(void) { zigbee.eeprom.writeBytes(0x0100, 256, (byte*) map); delete map; - // Dir + // Dir ZFS_Dir_Block * dir = new ZFS_Dir_Block(); dir->format(); zigbee.eeprom.writeBytes(0x0000, 256, (byte*) dir); diff --git a/tasmota/xdrv_23_zigbee_4b_eeprom.ino b/tasmota/xdrv_23_zigbee_4b_eeprom.ino index 360efb59d..88fa1e391 100644 --- a/tasmota/xdrv_23_zigbee_4b_eeprom.ino +++ b/tasmota/xdrv_23_zigbee_4b_eeprom.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_4a_eeprom.ino - zigbee support for Tasmota - saving configuration in I2C Eeprom of ZBBridge - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -107,9 +107,9 @@ int32_t hydrateSingleDevice(const class SBuffer & buf, size_t start, size_t len) } /*********************************************************************************************\ - * + * * Hydrate data from the EEPROM - * + * \*********************************************************************************************/ // Parse the entire blob // return true if ok @@ -200,9 +200,9 @@ class SBuffer hibernateDeviceData(const struct Z_Device & device, bool mqtt = fa } /*********************************************************************************************\ - * + * * Hibernate data to the EEPROM - * + * \*********************************************************************************************/ void hibernateAllData(void) { #ifdef USE_ZIGBEE_EZSP @@ -255,7 +255,7 @@ bool hibernateDevicesInEEPROM(void) { if (!zigbee.eeprom_ready) { return false; } ZFS_Write_File write_data(ZIGB_NAME2); - + // first prefix is number of devices uint8_t devices_size = zigbee_devices.devicesSize(); if (devices_size > 64) { devices_size = 64; } // arbitrarily limit to 64 devices in EEPROM instead of 32 in Flash diff --git a/tasmota/xdrv_23_zigbee_5__constants.ino b/tasmota/xdrv_23_zigbee_5__constants.ino index dd7e9234c..fdd161c50 100644 --- a/tasmota/xdrv_23_zigbee_5__constants.ino +++ b/tasmota/xdrv_23_zigbee_5__constants.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_5__constants.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -40,30 +40,30 @@ def clean(s): def strings_to_pmem(arg): #strings = arg.split("\n") strings = re.findall(pat, arg) - + # do some basic cleaning strings_cleaned = [ clean(x) for x in strings if clean(x) != ""] - + # remove duplicates strings_cleaned = list(dict.fromkeys(strings_cleaned)) - + out_s = "const char Z_strings[] PROGMEM = \n" out_i = "enum Z_offsets {\n" - + index = 0; # add a first empty string out_s += " \"\\x00\"\n" out_i += " Zo_ = " + str(index) + ",\n" index += 1 - + for s in strings_cleaned: out_s += " \"" + s + "\" \"\\x00\"\n" out_i += " Zo_" + s + " = " + str(index) + ",\n" index += len(s) + 1 # add one for null char - + out_s += " \"\\x00\";" out_i += "};" - + return ("", out_s, out_i) @@ -73,7 +73,7 @@ def strings_to_pmem(arg): DO NOT EDIT */ -const char Z_strings[] PROGMEM = +const char Z_strings[] PROGMEM = "\x00" "ZCLVersion" "\x00" "AppVersion" "\x00" diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 06c59ece8..8af9ee7fa 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_converters.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -1624,7 +1624,7 @@ void ZCLFrame::parseClusterSpecificCommand(Z_attribute_list& attr_list) { void ZCLFrame::syntheticAnalogValue(Z_attribute_list &attr_list, class Z_attribute &attr) { const char * modelId_c = zigbee_devices.getModelId(_srcaddr); // null if unknown String modelId((char*) modelId_c); - + if (modelId.startsWith(F("lumi.sensor_cube"))) { attr.setKeyId(0x000C, 0xFF55); // change to AqaraRotate } diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 63ea80869..89e3a6e65 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_converters.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino index d314e86b4..7c00cfb42 100644 --- a/tasmota/xdrv_23_zigbee_7_0_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_0_statemachine.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_7_5_map.ino b/tasmota/xdrv_23_zigbee_7_5_map.ino index 17c79d5e5..790720320 100644 --- a/tasmota/xdrv_23_zigbee_7_5_map.ino +++ b/tasmota/xdrv_23_zigbee_7_5_map.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_7_5_map.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index 32709c7dc..4fc3d4f1b 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino index b3600c151..e2c5550a4 100644 --- a/tasmota/xdrv_23_zigbee_9_serial.ino +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_9_serial.ino - zigbee: serial communication with MCU - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_9a_upload.ino b/tasmota/xdrv_23_zigbee_9a_upload.ino index d3fff537d..b946848a3 100644 --- a/tasmota/xdrv_23_zigbee_9a_upload.ino +++ b/tasmota/xdrv_23_zigbee_9a_upload.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee_9a_upload.ino - zigbee: serial xmodem upload to MCU - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 61d8e2963..799274dd0 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -1,7 +1,7 @@ /* xdrv_23_zigbee.ino - zigbee support for Tasmota - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -2072,7 +2072,7 @@ void ZigbeeShow(bool json) WSContentSend_P(msg[ZB_WEB_LINE_END]); // Terminate current multi column table and open new table if (zigbee.permit_end_time) { // PermitJoin in progress - + WSContentSend_P(msg[ZB_WEB_PERMITJOIN_ACTIVE], D_ZIGBEE_PERMITJOIN_ACTIVE); } #endif @@ -2085,7 +2085,7 @@ void ZigbeeMapRefresh(void) { ZigbeeMapAllDevices(); } Webserver->sendHeader("Location","/zbm"); // Add a header to respond with a new location for the browser to go to the home page again - Webserver->send(302); + Webserver->send(302); } // Display a graphical representation of the Zigbee map using vis.js network diff --git a/tasmota/xdrv_24_buzzer.ino b/tasmota/xdrv_24_buzzer.ino index 8dcb949c9..e6665e21f 100644 --- a/tasmota/xdrv_24_buzzer.ino +++ b/tasmota/xdrv_24_buzzer.ino @@ -1,7 +1,7 @@ /* xdrv_24_Buzzer.ino - buzzer support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_25_A4988_Stepper.ino b/tasmota/xdrv_25_A4988_Stepper.ino index f70ed76f0..50e9997b1 100644 --- a/tasmota/xdrv_25_A4988_Stepper.ino +++ b/tasmota/xdrv_25_A4988_Stepper.ino @@ -2,7 +2,7 @@ /* xdrv_25_a4988_stepper.ino - A4988 StepMotorDriverCircuit- support for Tasmota - Copyright (C) 2020 Tim Leuscher and Theo Arends + Copyright (C) 2021 Tim Leuscher and 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 diff --git a/tasmota/xdrv_26_ariluxrf.ino b/tasmota/xdrv_26_ariluxrf.ino index dc0010ac1..fca693c8d 100644 --- a/tasmota/xdrv_26_ariluxrf.ino +++ b/tasmota/xdrv_26_ariluxrf.ino @@ -1,7 +1,7 @@ /* xdrv_26_ariluxrf.ino - Arilux Rf support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index e46dbbca7..ed6e72c57 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -1,7 +1,7 @@ /* xdrv_27_Shutter[i].ino - Shutter/Blind support for Tasmota - Copyright (C) 2020 Stefan Bode + Copyright (C) 2021 Stefan Bode 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 @@ -984,7 +984,7 @@ void CmndShutterStop(void) AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter[i].direction); Shutter[i].target_position = Shutter[i].real_position; - } + } if (XdrvMailbox.command) ResponseCmndDone(); } else { diff --git a/tasmota/xdrv_28_pcf8574.ino b/tasmota/xdrv_28_pcf8574.ino index f7939a815..58bb5239c 100644 --- a/tasmota/xdrv_28_pcf8574.ino +++ b/tasmota/xdrv_28_pcf8574.ino @@ -1,7 +1,7 @@ /* xdrv_28_pcf8574.ino - PCF8574 I2C support for Tasmota - Copyright (C) 2020 Stefan Bode + Copyright (C) 2021 Stefan Bode 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 diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index 43ad54c6b..3e28a9d31 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -1,7 +1,7 @@ /* xdrv_29_deepsleep.ino - DeepSleep support for Tasmota - Copyright (C) 2020 Stefan Bode + Copyright (C) 2021 Stefan Bode 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 diff --git a/tasmota/xdrv_30_exs_dimmer.ino b/tasmota/xdrv_30_exs_dimmer.ino index 84b051c68..b704d616d 100644 --- a/tasmota/xdrv_30_exs_dimmer.ino +++ b/tasmota/xdrv_30_exs_dimmer.ino @@ -1,7 +1,7 @@ /* xdrv_30_exs_dimmer.ino - ex-store dimmer support for Tasmota - Copyright (C) 2020 Andreas Schultz + Copyright (C) 2021 Andreas Schultz 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 diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino index cac38cf01..bf4426b61 100644 --- a/tasmota/xdrv_31_tasmota_client.ino +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -1,7 +1,7 @@ /* xdrv_31_tasmota_client.ino - Support for external microcontroller on serial - Copyright (C) 2020 Andre Thomas and Theo Arends + Copyright (C) 2021 Andre Thomas and 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 diff --git a/tasmota/xdrv_32_hotplug.ino b/tasmota/xdrv_32_hotplug.ino index bfdafbd4b..e7dc4ac69 100644 --- a/tasmota/xdrv_32_hotplug.ino +++ b/tasmota/xdrv_32_hotplug.ino @@ -1,7 +1,7 @@ /* xdrv_32_hotplug.ino - HotPlug support for sensors - Copyright (C) 2020 Leonid Myravjev + Copyright (C) 2021 Leonid Myravjev 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 diff --git a/tasmota/xdrv_33_nrf24l01.ino b/tasmota/xdrv_33_nrf24l01.ino index b1e8d43c4..e992c398b 100644 --- a/tasmota/xdrv_33_nrf24l01.ino +++ b/tasmota/xdrv_33_nrf24l01.ino @@ -1,7 +1,7 @@ /* xdrv_33_nrf24l01.ino - nrf24l01 support for Tasmota - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and 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 diff --git a/tasmota/xdrv_34_wemos_motor_v1.ino b/tasmota/xdrv_34_wemos_motor_v1.ino index 9e6c0a967..cfd9de2d2 100644 --- a/tasmota/xdrv_34_wemos_motor_v1.ino +++ b/tasmota/xdrv_34_wemos_motor_v1.ino @@ -1,7 +1,7 @@ /* xdrv_34_wemos_motor_v1.ino - Support for I2C WEMOS motor shield (6612FNG) - Copyright (C) 2020 Denis Sborets and Theo Arends + Copyright (C) 2021 Denis Sborets and 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 diff --git a/tasmota/xdrv_35_pwm_dimmer.ino b/tasmota/xdrv_35_pwm_dimmer.ino index c54d071f1..3bca88477 100644 --- a/tasmota/xdrv_35_pwm_dimmer.ino +++ b/tasmota/xdrv_35_pwm_dimmer.ino @@ -1,7 +1,7 @@ /* xdrv_35_pwm_dimmer.ino - PWM Dimmer Switch support for Tasmota - Copyright (C) 2020 Paul C Diem + Copyright (C) 2021 Paul C Diem 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 @@ -99,7 +99,7 @@ void PWMModulePreInit(void) // determine how long a button is held before a reset command is executed. If SetOption32 is // still 5, change it to 40 (the default). if (Settings.param[P_HOLD_TIME] == 5) Settings.param[P_HOLD_TIME] = 40; - + // Make sure the brightness level settings are sensible. if (!Settings.bri_power_on) Settings.bri_power_on = 128; if (!Settings.bri_preset_low) Settings.bri_preset_low = 10; @@ -286,7 +286,7 @@ void PWMDimmerHandleButton(uint32_t button_index, bool pressed) uint32_t now = millis(); // If the button was pressed and released but was not processed by support_button because the - // button interval had not elapsed, + // button interval had not elapsed, if (button_unprocessed[button_index]) { mqtt_trigger = 5; #ifdef USE_PWM_DIMMER_REMOTE diff --git a/tasmota/xdrv_36_keeloq.ino b/tasmota/xdrv_36_keeloq.ino index a1a392897..4a0f33a83 100644 --- a/tasmota/xdrv_36_keeloq.ino +++ b/tasmota/xdrv_36_keeloq.ino @@ -1,7 +1,7 @@ /* xdrv_36_keeloq.ino - Jarolift Keeloq shutter support for Tasmota - Copyright (C) 2020 he-so + Copyright (C) 2021 he-so 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 diff --git a/tasmota/xdrv_37_sonoff_d1.ino b/tasmota/xdrv_37_sonoff_d1.ino index 30b061775..5abefd452 100644 --- a/tasmota/xdrv_37_sonoff_d1.ino +++ b/tasmota/xdrv_37_sonoff_d1.ino @@ -1,7 +1,7 @@ /* xdrv_37_sonoff_d1.ino - sonoff D1 dimmer support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino index d4d5ea5d9..3f87a54bb 100644 --- a/tasmota/xdrv_38_ping.ino +++ b/tasmota/xdrv_38_ping.ino @@ -1,7 +1,7 @@ /* xdrv_38_ping.ino - support for ICMP Ping - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_39_thermostat.ino b/tasmota/xdrv_39_thermostat.ino index d8cd0f11c..455e45f13 100644 --- a/tasmota/xdrv_39_thermostat.ino +++ b/tasmota/xdrv_39_thermostat.ino @@ -1,7 +1,7 @@ /* xdrv_39_thermostat.ino - Thermostat controller for Tasmota - Copyright (C) 2020 Javier Arigita + Copyright (C) 2021 Javier Arigita 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 diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino index 628ae0782..a96842065 100644 --- a/tasmota/xdrv_40_telegram.ino +++ b/tasmota/xdrv_40_telegram.ino @@ -1,7 +1,7 @@ /* xdrv_40_telegram.ino - telegram for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xdrv_41_tcp_bridge.ino b/tasmota/xdrv_41_tcp_bridge.ino index 3bd1e045c..7533e7d6d 100644 --- a/tasmota/xdrv_41_tcp_bridge.ino +++ b/tasmota/xdrv_41_tcp_bridge.ino @@ -1,7 +1,7 @@ /* xdrv_41_tcp_bridge.ino - TCP to serial bridge - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/tasmota/xdrv_42_i2s_audio.ino b/tasmota/xdrv_42_i2s_audio.ino index 0bb02e652..1e468593b 100644 --- a/tasmota/xdrv_42_i2s_audio.ino +++ b/tasmota/xdrv_42_i2s_audio.ino @@ -1,7 +1,7 @@ /* xdrv_42_i2s_audio.ino - audio dac support for Tasmota - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xdrv_43_mlx90640.ino b/tasmota/xdrv_43_mlx90640.ino index a95b0f1e0..18255c079 100644 --- a/tasmota/xdrv_43_mlx90640.ino +++ b/tasmota/xdrv_43_mlx90640.ino @@ -1,7 +1,7 @@ /* xdrv_43_mlx90640.ino - MLX90640 support for Tasmota - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and 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 diff --git a/tasmota/xdrv_44_miel_hvac.ino b/tasmota/xdrv_44_miel_hvac.ino index aad4205bd..680d9d72f 100644 --- a/tasmota/xdrv_44_miel_hvac.ino +++ b/tasmota/xdrv_44_miel_hvac.ino @@ -1,7 +1,7 @@ /* xdrv_44_miel_hvac.ino - Mitsubishi Electric HVAC support for Tasmota - Copyright (C) 2020 David Gwynne + Copyright (C) 2021 David Gwynne 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 diff --git a/tasmota/xdrv_45_shelly_dimmer.ino b/tasmota/xdrv_45_shelly_dimmer.ino index b4785291e..0b44cde96 100644 --- a/tasmota/xdrv_45_shelly_dimmer.ino +++ b/tasmota/xdrv_45_shelly_dimmer.ino @@ -1,7 +1,7 @@ /* xdrv_45_shelly_dimmer.ino - shelly dimmer support for Tasmota - Copyright (C) 2020 James Turton + Copyright (C) 2021 James Turton 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 diff --git a/tasmota/xdrv_46_ccloader.ino b/tasmota/xdrv_46_ccloader.ino index 32901adc6..3675ca676 100644 --- a/tasmota/xdrv_46_ccloader.ino +++ b/tasmota/xdrv_46_ccloader.ino @@ -1,7 +1,7 @@ /* xdrv_46_ccloader.ino - CCLoader for Tasmota - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and Theo Arends based on CCLoader - Copyright (c) 2012-2014 RedBearLab @@ -25,14 +25,14 @@ 0.9.0.0 20191124 started - further development by Christian Baars forked - CCLoader - Copyright (c) 2012-2014 RedBearLab - + */ #ifdef USE_CCLOADER /*********************************************************************************************\ * CCLOader * -* Usage: +* Usage: \*********************************************************************************************/ #define XDRV_46 46 @@ -123,7 +123,7 @@ struct { bool init = false; } CCL; -const char CCLtype[] PROGMEM = "CCL"; +const char CCLtype[] PROGMEM = "CCL"; // Debug control pins & the indicate LED int CCL_RESET = 14; //GPIO14=D5 on NodeMCU/WeMos D1 Mini @@ -175,7 +175,7 @@ unsigned char CCLread_debug_byte(void) if(HIGH == digitalRead(CCL_DD)) { data |= 0x01; - } + } digitalWrite(CCL_DC, LOW); // DC low } return data; @@ -604,23 +604,23 @@ bool CLLFlashFirmware(uint8_t* data, uint32_t size) // Enable DMA (Disable DMA_PAUSE bit in debug configuration) debug_config = 0x22; CCLdebug_command(CCL_CMD_WR_CONFIG, &debug_config, 1); - - unsigned char rxBuf[512]; - uint32_t block = 0; + + unsigned char rxBuf[512]; + uint32_t block = 0; unsigned int addr = 0x0000; AddLog_P(LOG_LEVEL_INFO,PSTR("CCL: will flash ....")); AddLogBuffer(LOG_LEVEL_DEBUG,data,16); // quick check to compare with a hex editor while((block*512)4 && MGC_data.out.id != MGC3130_FW_VERSION){ AddLog_P(LOG_LEVEL_DEBUG,PSTR("MGC3130: missed a packet, mismatch: %u"), _mismatch - 1); AddLogBuffer(LOG_LEVEL_DEBUG,MGC_data.buffer,i); - } + } } _lastCounter = MGC_data.out.counter; success = true; diff --git a/tasmota/xsns_37_rfsensor.ino b/tasmota/xsns_37_rfsensor.ino index 7dd376b97..aee5f6641 100644 --- a/tasmota/xsns_37_rfsensor.ino +++ b/tasmota/xsns_37_rfsensor.ino @@ -1,7 +1,7 @@ /* xsns_37_rfsensor.ino - RF sensor receiver for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_38_az7798.ino b/tasmota/xsns_38_az7798.ino index 1b5ba7f5f..b063dc166 100644 --- a/tasmota/xsns_38_az7798.ino +++ b/tasmota/xsns_38_az7798.ino @@ -1,7 +1,7 @@ /* xsns_38_az7798.ino - AZ_Instrument 7798 CO2/temperature/humidity meter support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_39_max31855.ino b/tasmota/xsns_39_max31855.ino index a6e592c21..2a6304ce1 100644 --- a/tasmota/xsns_39_max31855.ino +++ b/tasmota/xsns_39_max31855.ino @@ -1,7 +1,7 @@ /* xsns_39_max31855.ino - MAX31855 thermocouple sensor support for Tasmota - Copyright (C) 2020 Markus Past + Copyright (C) 2021 Markus Past 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 diff --git a/tasmota/xsns_40_pn532.ino b/tasmota/xsns_40_pn532.ino index fb6d31354..4e9bbdcc4 100644 --- a/tasmota/xsns_40_pn532.ino +++ b/tasmota/xsns_40_pn532.ino @@ -1,7 +1,7 @@ /* xsns_40_pn532.ino - Support for PN532 (HSU) NFC Tag Reader on Tasmota - Copyright (C) 2020 Andre Thomas and Theo Arends + Copyright (C) 2021 Andre Thomas and 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 diff --git a/tasmota/xsns_41_max44009.ino b/tasmota/xsns_41_max44009.ino index b07d37567..7eccb043e 100644 --- a/tasmota/xsns_41_max44009.ino +++ b/tasmota/xsns_41_max44009.ino @@ -1,7 +1,7 @@ /* xsns_41_max44009.ino - MAX44009 ambient light sensor support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_42_scd30.ino b/tasmota/xsns_42_scd30.ino index c208c3307..458e046aa 100644 --- a/tasmota/xsns_42_scd30.ino +++ b/tasmota/xsns_42_scd30.ino @@ -1,7 +1,7 @@ /* xsns_42_scd30.ino - SC30 CO2 sensor support for Tasmota - Copyright (C) 2020 Frogmore42 + Copyright (C) 2021 Frogmore42 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 diff --git a/tasmota/xsns_43_hre.ino b/tasmota/xsns_43_hre.ino index f7240ec17..68299b066 100644 --- a/tasmota/xsns_43_hre.ino +++ b/tasmota/xsns_43_hre.ino @@ -1,7 +1,7 @@ /* xsns_43_hre.ino - Badger HR-E Water Meter Encoder interface - Copyright (C) 2020 Jon Little + Copyright (C) 2021 Jon Little 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 diff --git a/tasmota/xsns_44_sps30.ino b/tasmota/xsns_44_sps30.ino index c9316ba4c..9dd73dbcf 100644 --- a/tasmota/xsns_44_sps30.ino +++ b/tasmota/xsns_44_sps30.ino @@ -1,7 +1,7 @@ /* xsns_44_sps30.ino - Sensirion SPS30 support for Tasmota - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xsns_45_vl53l0x.ino b/tasmota/xsns_45_vl53l0x.ino index 623dda9a0..54c49534c 100644 --- a/tasmota/xsns_45_vl53l0x.ino +++ b/tasmota/xsns_45_vl53l0x.ino @@ -1,7 +1,7 @@ /* xsns_45_vl53l0x.ino - VL53L0X time of flight sensor support for Tasmota - Copyright (C) 2020 Theo Arends and Gerhard Mutz + Copyright (C) 2021 Theo Arends and Gerhard Mutz 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 diff --git a/tasmota/xsns_46_MLX90614.ino b/tasmota/xsns_46_MLX90614.ino index 54e27f359..8032cdf2f 100644 --- a/tasmota/xsns_46_MLX90614.ino +++ b/tasmota/xsns_46_MLX90614.ino @@ -1,7 +1,7 @@ /* xsns_46_MLX90614.ino - Support for MLX ir temperature sensor - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xsns_47_max31865.ino b/tasmota/xsns_47_max31865.ino index 4c45af4fe..83bef5e9a 100644 --- a/tasmota/xsns_47_max31865.ino +++ b/tasmota/xsns_47_max31865.ino @@ -1,7 +1,7 @@ /* xsns_39_MAX31865.ino - MAX31865 thermocouple sensor support for Tasmota - Copyright (C) 2020 Alberto Lopez Siemens + Copyright (C) 2021 Alberto Lopez Siemens 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 diff --git a/tasmota/xsns_48_chirp.ino b/tasmota/xsns_48_chirp.ino index ded5b30e6..1e92d6c79 100644 --- a/tasmota/xsns_48_chirp.ino +++ b/tasmota/xsns_48_chirp.ino @@ -1,7 +1,7 @@ /* xsns_48_chirp.ino - soil moisture sensor support for Tasmota - Copyright (C) 2020 Theo Arends & Christian Baars + Copyright (C) 2021 Theo Arends & Christian Baars 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 diff --git a/tasmota/xsns_50_paj7620.ino b/tasmota/xsns_50_paj7620.ino index ad5ce5a2c..174febc7d 100644 --- a/tasmota/xsns_50_paj7620.ino +++ b/tasmota/xsns_50_paj7620.ino @@ -1,7 +1,7 @@ /* xsns_50_paj7620.ino - gesture sensor support for Tasmota - Copyright (C) 2020 Theo Arends & Christian Baars + Copyright (C) 2021 Theo Arends & Christian Baars 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 diff --git a/tasmota/xsns_51_rdm6300.ino b/tasmota/xsns_51_rdm6300.ino index ebc9ab175..a277e7d65 100644 --- a/tasmota/xsns_51_rdm6300.ino +++ b/tasmota/xsns_51_rdm6300.ino @@ -1,7 +1,7 @@ /* xsns_51_rdm6300.ino - Support for RDM630(0) 125kHz NFC Tag Reader on Tasmota - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino index db5c5951e..731189827 100755 --- a/tasmota/xsns_52_ibeacon.ino +++ b/tasmota/xsns_52_ibeacon.ino @@ -1,7 +1,7 @@ /* xsns_52_ibeacon.ino - Support for HM17 BLE Module + ibeacon reader on Tasmota - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index cccfde736..06fa2300e 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -4,7 +4,7 @@ Created by Gerhard Mutz on 07.10.11. adapted for Tasmota - Copyright (C) 2020 Gerhard Mutz and Theo Arends + Copyright (C) 2021 Gerhard Mutz and 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 diff --git a/tasmota/xsns_54_ina226.ino b/tasmota/xsns_54_ina226.ino index 49a6b5890..f89d799e9 100644 --- a/tasmota/xsns_54_ina226.ino +++ b/tasmota/xsns_54_ina226.ino @@ -1,7 +1,7 @@ /* xsns_54_ina226.ino - INA226 Current Sensor support for Tasmota - Copyright (C) 2020 Stephen Rodgers and Theo Arends + Copyright (C) 2021 Stephen Rodgers and 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 diff --git a/tasmota/xsns_55_hih_series.ino b/tasmota/xsns_55_hih_series.ino index 89278e432..d42ec8a4b 100644 --- a/tasmota/xsns_55_hih_series.ino +++ b/tasmota/xsns_55_hih_series.ino @@ -1,7 +1,7 @@ /* xsns_55_hih_series.ino - Honeywell HIH series temperature and humidity sensor support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_56_hpma.ino b/tasmota/xsns_56_hpma.ino index 576cf19d2..c400fba1e 100644 --- a/tasmota/xsns_56_hpma.ino +++ b/tasmota/xsns_56_hpma.ino @@ -1,8 +1,8 @@ /* xsns_56_hpma.ino - Honeywell HPMA115S0 particle concentration sensor support for Tasmota - Copyright (C) 2020 Theo Arends - Copyright (C) 2020 David Hunt + Copyright (C) 2021 Theo Arends + Copyright (C) 2021 David Hunt 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 diff --git a/tasmota/xsns_57_tsl2591.ino b/tasmota/xsns_57_tsl2591.ino index 395b69b23..1ec7a6838 100644 --- a/tasmota/xsns_57_tsl2591.ino +++ b/tasmota/xsns_57_tsl2591.ino @@ -1,7 +1,7 @@ /* xsns_57_tsl2591.ino - TSL2591 light sensor support for Tasmota - Copyright (C) 2020 Markus Bösling and Theo Arends + Copyright (C) 2021 Markus Bösling and 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 diff --git a/tasmota/xsns_58_dht12.ino b/tasmota/xsns_58_dht12.ino index a772e3cea..4bab87bb3 100644 --- a/tasmota/xsns_58_dht12.ino +++ b/tasmota/xsns_58_dht12.ino @@ -1,7 +1,7 @@ /* xsns_58_dht12.ino - DHT12 I2C temperature and humidity sensor support for Tasmota - Copyright (C) 2020 Stefan Oskamp and Theo Arends + Copyright (C) 2021 Stefan Oskamp and 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 diff --git a/tasmota/xsns_59_ds1624.ino b/tasmota/xsns_59_ds1624.ino index 12189164e..ccc079f4c 100644 --- a/tasmota/xsns_59_ds1624.ino +++ b/tasmota/xsns_59_ds1624.ino @@ -1,7 +1,7 @@ /* xsns_59_ds1624.ino - Support for I2C DS1624 Temperature Sensor - Copyright (C) 2020 Leonid Myravjev + Copyright (C) 2021 Leonid Myravjev 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 diff --git a/tasmota/xsns_60_GPS.ino b/tasmota/xsns_60_GPS.ino index 63fc147f2..10e02efc2 100644 --- a/tasmota/xsns_60_GPS.ino +++ b/tasmota/xsns_60_GPS.ino @@ -1,7 +1,7 @@ /* xsns_60_GPS.ino - GPS UBLOX support for Tasmota - Copyright (C) 2020 Theo Arends, Christian Baars and Adrian Scillato + Copyright (C) 2021 Theo Arends, Christian Baars and Adrian Scillato 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 diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index 727aeb011..8dff44920 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -1,7 +1,7 @@ /* xsns_61_MI_NRF24.ino - MI-BLE-sensors via nrf24l01 support for Tasmota - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and 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 diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino index 44094140e..9e9c70dc5 100644 --- a/tasmota/xsns_62_MI_ESP32.ino +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -1,7 +1,7 @@ /* xsns_62_MI_ESP32.ino - MI-BLE-sensors via ESP32 support for Tasmota - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and 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 @@ -1634,7 +1634,7 @@ bool MI32isInBlockList(uint8_t* MAC){ void MI32removeMIBLEsensor(uint8_t* MAC){ MIBLEsensors.erase( std::remove_if( MIBLEsensors.begin() , MIBLEsensors.end(), [MAC]( mi_sensor_t _sensor )->bool - { return (memcmp(_sensor.MAC,MAC,6) == 0); } + { return (memcmp(_sensor.MAC,MAC,6) == 0); } ), end( MIBLEsensors ) ); } /***********************************************************************\ @@ -1930,7 +1930,7 @@ void CmndMi32Block(void){ break; case 1: ResponseCmndIdxChar(PSTR("show block list")); - break; + break; } } else { @@ -1939,7 +1939,7 @@ void CmndMi32Block(void){ switch (XdrvMailbox.index) { case 0: MIBLEBlockList.erase( std::remove_if( begin( MIBLEBlockList ), end( MIBLEBlockList ), [_MACasBytes]( MAC_t& _entry )->bool - { return (memcmp(_entry.buf,_MACasBytes.buf,6) == 0); } + { return (memcmp(_entry.buf,_MACasBytes.buf,6) == 0); } ), end( MIBLEBlockList ) ); ResponseCmndIdxChar(PSTR("MAC not blocked anymore")); break; @@ -1956,7 +1956,7 @@ void CmndMi32Block(void){ MI32removeMIBLEsensor(_MACasBytes.buf); } // AddLog_P(LOG_LEVEL_INFO,PSTR("MI32: size of ilist: %u"), MIBLEBlockList.size()); - break; + break; } } MI32.mode.shallShowBlockList = 1; diff --git a/tasmota/xsns_62_MI_HM10.ino b/tasmota/xsns_62_MI_HM10.ino index da28d7306..af3ce56ca 100644 --- a/tasmota/xsns_62_MI_HM10.ino +++ b/tasmota/xsns_62_MI_HM10.ino @@ -1,7 +1,7 @@ /* xsns_62_MI_HM10.ino - MI-BLE-sensors via HM-10 support for Tasmota - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and 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 @@ -1085,7 +1085,7 @@ bool HM10isInBlockList(uint8_t* MAC){ void HM10removeMIBLEsensor(uint8_t* MAC){ MIBLEsensors.erase( std::remove_if( MIBLEsensors.begin() , MIBLEsensors.end(), [MAC]( mi_sensor_t _sensor )->bool - { return (memcmp(_sensor.MAC,MAC,6) == 0); } + { return (memcmp(_sensor.MAC,MAC,6) == 0); } ), end( MIBLEsensors ) ); } /*********************************************************************************************\ @@ -1693,7 +1693,7 @@ void CmndHM10Block(void){ break; case 1: ResponseCmndIdxChar(PSTR("show block list")); - break; + break; } } else { @@ -1702,7 +1702,7 @@ void CmndHM10Block(void){ switch (XdrvMailbox.index) { case 0: MIBLEBlockList.erase( std::remove_if( begin( MIBLEBlockList ), end( MIBLEBlockList ), [_MACasBytes]( MAC_t& _entry )->bool - { return (memcmp(_entry.buf,_MACasBytes.buf,6) == 0); } + { return (memcmp(_entry.buf,_MACasBytes.buf,6) == 0); } ), end( MIBLEBlockList ) ); ResponseCmndIdxChar(PSTR("MAC not blocked anymore")); break; @@ -1719,7 +1719,7 @@ void CmndHM10Block(void){ HM10removeMIBLEsensor(_MACasBytes.buf); } // AddLog_P(LOG_LEVEL_INFO,PSTR("HM10: size of ilist: %u"), MIBLEBlockList.size()); - break; + break; } } HM10.mode.shallShowBlockList = 1; diff --git a/tasmota/xsns_63_aht1x.ino b/tasmota/xsns_63_aht1x.ino index cba95662a..88da71890 100644 --- a/tasmota/xsns_63_aht1x.ino +++ b/tasmota/xsns_63_aht1x.ino @@ -1,7 +1,7 @@ /* xsns_63_AHT1x.ino - AHT10 I2C temperature and humidity sensor support for Tasmota - Copyright (C) 2020 Martin Wagner + Copyright (C) 2021 Martin Wagner 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 diff --git a/tasmota/xsns_64_hrxl.ino b/tasmota/xsns_64_hrxl.ino index 389197e1a..be78b49ec 100644 --- a/tasmota/xsns_64_hrxl.ino +++ b/tasmota/xsns_64_hrxl.ino @@ -1,7 +1,7 @@ /* xsns_64_hrxl.ino - MaxBotix HRXL serial interface - Copyright (C) 2020 Jon Little + Copyright (C) 2021 Jon Little 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 diff --git a/tasmota/xsns_65_hdc1080.ino b/tasmota/xsns_65_hdc1080.ino index ac6a71be8..d20241ab8 100644 --- a/tasmota/xsns_65_hdc1080.ino +++ b/tasmota/xsns_65_hdc1080.ino @@ -1,7 +1,7 @@ /* xsns_65_hdc1080.ino - Texas Instruments HDC1080 temperature and humidity sensor support for Tasmota - Copyright (C) 2020 Luis Teixeira + Copyright (C) 2021 Luis Teixeira 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 diff --git a/tasmota/xsns_66_iAQ.ino b/tasmota/xsns_66_iAQ.ino index 962480748..fc3dff2da 100644 --- a/tasmota/xsns_66_iAQ.ino +++ b/tasmota/xsns_66_iAQ.ino @@ -1,7 +1,7 @@ /* xsns_66_iAQ.ino - Support for iAQ-Core - Indoor Air Quality Sensor Module - Copyright (C) 2020 Christian Baars and Theo Arends + Copyright (C) 2021 Christian Baars and 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 diff --git a/tasmota/xsns_67_as3935.ino b/tasmota/xsns_67_as3935.ino index a625163b6..030581768 100644 --- a/tasmota/xsns_67_as3935.ino +++ b/tasmota/xsns_67_as3935.ino @@ -1,7 +1,7 @@ /* xsns_67_as3935.ino - AS3935 Franklin Lightning Sensor support for Tasmota - Copyright (C) 2020 Martin Wagner + Copyright (C) 2021 Martin Wagner 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 diff --git a/tasmota/xsns_68_windmeter.ino b/tasmota/xsns_68_windmeter.ino index a5b2aa49e..6b552ee38 100644 --- a/tasmota/xsns_68_windmeter.ino +++ b/tasmota/xsns_68_windmeter.ino @@ -1,7 +1,7 @@ /* xsns_68_windmeter.ino - Analog wind sensor support for Tasmota - Copyright (C) 2020 Matteo Albinola + Copyright (C) 2021 Matteo Albinola (inspired by great works of Thomas Eckerstorfer, Norbert Richter, Maarten Damen and Theo Arends) This program is free software: you can redistribute it and/or modify diff --git a/tasmota/xsns_69_opentherm.ino b/tasmota/xsns_69_opentherm.ino index 41f3377b7..adcef07b0 100644 --- a/tasmota/xsns_69_opentherm.ino +++ b/tasmota/xsns_69_opentherm.ino @@ -1,7 +1,7 @@ /* xsns_69_opentherm.ino - OpenTherm protocol support for Tasmota - Copyright (C) 2020 Yuriy Sannikov + Copyright (C) 2021 Yuriy Sannikov 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 @@ -35,7 +35,7 @@ // Seconds before OT will make an attempt to connect to the boiler after connection error #define SNS_OT_DISCONNECT_COOLDOWN_SECONDS 4 -// Number of consecutive timeouts which are accepted before entering disconnect state +// Number of consecutive timeouts which are accepted before entering disconnect state #define SNS_OT_MAX_TIMEOUTS_BEFORE_DISCONNECT 3 // Count of the OpenThermSettingsFlags diff --git a/tasmota/xsns_69_opentherm_protocol.ino b/tasmota/xsns_69_opentherm_protocol.ino index 6311b818b..6158be9c7 100644 --- a/tasmota/xsns_69_opentherm_protocol.ino +++ b/tasmota/xsns_69_opentherm_protocol.ino @@ -1,7 +1,7 @@ /* xsns_69_opentherm_protocol.ino - OpenTherm protocol support for Tasmota - Copyright (C) 2020 Yuriy Sannikov + Copyright (C) 2021 Yuriy Sannikov 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 diff --git a/tasmota/xsns_70_veml6075.ino b/tasmota/xsns_70_veml6075.ino index 4735d1140..449ec89ec 100644 --- a/tasmota/xsns_70_veml6075.ino +++ b/tasmota/xsns_70_veml6075.ino @@ -1,7 +1,7 @@ /* xsns_70_veml6075.ino - VEML6075 UVA/UVB/UVINDEX Sensor support for Tasmota - Copyright (C) 2020 Martin Wagner + Copyright (C) 2021 Martin Wagner 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 diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino index 655d52992..a4bf12905 100644 --- a/tasmota/xsns_71_veml7700.ino +++ b/tasmota/xsns_71_veml7700.ino @@ -1,7 +1,7 @@ /* xsns_71_VEML7700.ino - VEML7700 Ambient light intensity Sensor support for Tasmota - Copyright (C) 2020 Martin Wagner + Copyright (C) 2021 Martin Wagner 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 diff --git a/tasmota/xsns_72_mcp9808.ino b/tasmota/xsns_72_mcp9808.ino index 587123d2c..98fc48066 100644 --- a/tasmota/xsns_72_mcp9808.ino +++ b/tasmota/xsns_72_mcp9808.ino @@ -1,7 +1,7 @@ /* xsns_72_mcp9808 - MCP9808 I2C temperature sensor support for Tasmota - Copyright (C) 2020 Martin Wagner and Theo Arends + Copyright (C) 2021 Martin Wagner and 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 diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 30a14945c..50589e4d5 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -1,7 +1,7 @@ /* xsns_72_hp303b.ino - HP303B digital barometric air pressure sensor support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino index 85d97a492..8c6cfdb92 100644 --- a/tasmota/xsns_74_lmt01.ino +++ b/tasmota/xsns_74_lmt01.ino @@ -1,7 +1,7 @@ /* xns_74_lmt01.ino - Support for single wire LMT01 Temperature Sensor - Copyright (C) 2020 Theo Arends, Justifiably + Copyright (C) 2021 Theo Arends, Justifiably 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 diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino index b6afd3f70..0dac5ed9f 100644 --- a/tasmota/xsns_75_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -1,7 +1,7 @@ /* xsns_75_prometheus.ino - Web based information for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_76_dyp.ino b/tasmota/xsns_76_dyp.ino index adfaef5bc..0c4506502 100644 --- a/tasmota/xsns_76_dyp.ino +++ b/tasmota/xsns_76_dyp.ino @@ -1,7 +1,7 @@ /* xsns_76_dyp.ino - DYP ME007 serial interface - Copyright (C) 2020 Janusz Kostorz + Copyright (C) 2021 Janusz Kostorz 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 diff --git a/tasmota/xsns_77_vl53l1x.ino b/tasmota/xsns_77_vl53l1x.ino index 23be88a69..f245fda86 100644 --- a/tasmota/xsns_77_vl53l1x.ino +++ b/tasmota/xsns_77_vl53l1x.ino @@ -1,7 +1,7 @@ /* xsns_77_vl53l1x.ino - VL53L1X sensor support for Tasmota - Copyright (C) 2020 Theo Arends, Rui Marinho and Johann Obermeier + Copyright (C) 2021 Theo Arends, Rui Marinho and Johann Obermeier 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 diff --git a/tasmota/xsns_78_ezo.ino b/tasmota/xsns_78_ezo.ino index b8ba523ea..a33ad9cdc 100644 --- a/tasmota/xsns_78_ezo.ino +++ b/tasmota/xsns_78_ezo.ino @@ -1,7 +1,7 @@ /* xsns_78_ezo.ino - EZO modules base class - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_78_ezoco2.ino b/tasmota/xsns_78_ezoco2.ino index a7fe76cc8..8d038308a 100644 --- a/tasmota/xsns_78_ezoco2.ino +++ b/tasmota/xsns_78_ezoco2.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoco2.ino - EZO CO2 I2C CO2 sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_78_ezodo.ino b/tasmota/xsns_78_ezodo.ino index a0dd6a36f..8a22bceb3 100644 --- a/tasmota/xsns_78_ezodo.ino +++ b/tasmota/xsns_78_ezodo.ino @@ -1,7 +1,7 @@ /* xsns_78_ezodo.ino - EZO DO I2C DO sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -41,7 +41,7 @@ struct EZODO : public EZOStruct { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_DO "\":%d}" ), name, str); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_DO, name, str); #endif // USE_WEBSERVER diff --git a/tasmota/xsns_78_ezoec.ino b/tasmota/xsns_78_ezoec.ino index 1566e2907..e134e4da1 100644 --- a/tasmota/xsns_78_ezoec.ino +++ b/tasmota/xsns_78_ezoec.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoec.ino - EZO EC I2C EC sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -41,7 +41,7 @@ struct EZOEC : public EZOStruct { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_EC "\":%s}" ), name, str); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_EC, name, str); #endif // USE_WEBSERVER diff --git a/tasmota/xsns_78_ezoflo.ino b/tasmota/xsns_78_ezoflo.ino index 31cb7c082..9b30238b9 100644 --- a/tasmota/xsns_78_ezoflo.ino +++ b/tasmota/xsns_78_ezoflo.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoflo.ino - EZO FLO I2C FLO sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_78_ezohum.ino b/tasmota/xsns_78_ezohum.ino index a403eeb56..04a2ce74f 100644 --- a/tasmota/xsns_78_ezohum.ino +++ b/tasmota/xsns_78_ezohum.ino @@ -1,7 +1,7 @@ /* xsns_78_ezohum.ino - EZO HUM I2C HUM sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_78_ezoo2.ino b/tasmota/xsns_78_ezoo2.ino index bc98fe00c..cafdeb813 100644 --- a/tasmota/xsns_78_ezoo2.ino +++ b/tasmota/xsns_78_ezoo2.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoo2.ino - EZO O2 I2C O2 sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -41,7 +41,7 @@ struct EZOO2 : public EZOStruct { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_O2 "\":%d}" ), name, str); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_O2, name, str); #endif // USE_WEBSERVER diff --git a/tasmota/xsns_78_ezoorp.ino b/tasmota/xsns_78_ezoorp.ino index d9faa999c..09db9983c 100644 --- a/tasmota/xsns_78_ezoorp.ino +++ b/tasmota/xsns_78_ezoorp.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoorp.ino - EZO ORP I2C ORP sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -41,7 +41,7 @@ struct EZOORP : public EZOStruct { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_ORP "\":%s}" ), name, str); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_ORP, name, str); #endif // USE_WEBSERVER diff --git a/tasmota/xsns_78_ezoph.ino b/tasmota/xsns_78_ezoph.ino index 77939d97a..c4e6a7425 100644 --- a/tasmota/xsns_78_ezoph.ino +++ b/tasmota/xsns_78_ezoph.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoph.ino - EZO pH I2C pH sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -41,7 +41,7 @@ struct EZOPH : public EZOStruct { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_PH "\":%s}" ), name, str); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_PH, name, str); #endif // USE_WEBSERVER diff --git a/tasmota/xsns_78_ezopmp.ino b/tasmota/xsns_78_ezopmp.ino index cea7a9cf0..225c3285f 100644 --- a/tasmota/xsns_78_ezopmp.ino +++ b/tasmota/xsns_78_ezopmp.ino @@ -1,7 +1,7 @@ /* xsns_78_ezopmp.ino - EZO PMP I2C PMP sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_78_ezoprs.ino b/tasmota/xsns_78_ezoprs.ino index 9ad34ab0d..f80eba82e 100644 --- a/tasmota/xsns_78_ezoprs.ino +++ b/tasmota/xsns_78_ezoprs.ino @@ -1,7 +1,7 @@ /* xsns_78_ezoprs.ino - EZO PRS I2C PRS sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -47,7 +47,7 @@ struct EZOPRS : public EZOStruct { } ResponseJsonEnd(); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_PRESSURE, name, str, PressureUnit().c_str()); if (Settings.altitude != 0) { diff --git a/tasmota/xsns_78_ezorgb.ino b/tasmota/xsns_78_ezorgb.ino index 5bbb49d79..2bbab0d24 100644 --- a/tasmota/xsns_78_ezorgb.ino +++ b/tasmota/xsns_78_ezorgb.ino @@ -1,7 +1,7 @@ /* xsns_78_ezorgb.ino - EZO RGB I2C RGB sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_78_ezortd.ino b/tasmota/xsns_78_ezortd.ino index 1d564d095..cf731a346 100644 --- a/tasmota/xsns_78_ezortd.ino +++ b/tasmota/xsns_78_ezortd.ino @@ -1,7 +1,7 @@ /* xsns_78_ezortd.ino - EZO RTD I2C RTD sensor support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 @@ -41,7 +41,7 @@ struct EZORTD : public EZOStruct { if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), name, str); } -#ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER else { WSContentSend_PD(HTTP_SNS_TEMP, name, str, TempUnit()); #endif // USE_WEBSERVER diff --git a/tasmota/xsns_78_xezo.ino b/tasmota/xsns_78_xezo.ino index 2774c7a0c..60b3cd8e4 100644 --- a/tasmota/xsns_78_xezo.ino +++ b/tasmota/xsns_78_xezo.ino @@ -1,7 +1,7 @@ /* xsns_78_xezo.ino - EZO family I2C driver support for Tasmota - Copyright (C) 2020 Christopher Tremblay + Copyright (C) 2021 Christopher Tremblay 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 diff --git a/tasmota/xsns_79_as608.ino b/tasmota/xsns_79_as608.ino index f4e7d3939..7bff7736c 100644 --- a/tasmota/xsns_79_as608.ino +++ b/tasmota/xsns_79_as608.ino @@ -1,7 +1,7 @@ /* xsns_79_as608.ino - AS608 and R503 fingerprint sensor support for Tasmota - Copyright (C) 2020 boaschti and Theo Arends + Copyright (C) 2021 boaschti and 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 diff --git a/tasmota/xsns_80_mfrc522.ino b/tasmota/xsns_80_mfrc522.ino index b62c1140f..9a9b19e21 100644 --- a/tasmota/xsns_80_mfrc522.ino +++ b/tasmota/xsns_80_mfrc522.ino @@ -1,7 +1,7 @@ /* xsns_80_mfrc522.ino - Support for MFRC522 (SPI) NFC Tag Reader on Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tasmota/xsns_interface.ino b/tasmota/xsns_interface.ino index fd05ccc57..21918f22c 100644 --- a/tasmota/xsns_interface.ino +++ b/tasmota/xsns_interface.ino @@ -1,7 +1,7 @@ /* xsns_interface.ino - Sensor interface support for Tasmota - Copyright (C) 2020 Theo Arends inspired by ESPEasy + Copyright (C) 2021 Theo Arends inspired by ESPEasy 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 diff --git a/tasmota/xx2c_interface.ino b/tasmota/xx2c_interface.ino index 5732fbaf9..fcbc17677 100644 --- a/tasmota/xx2c_interface.ino +++ b/tasmota/xx2c_interface.ino @@ -1,7 +1,7 @@ /* xx2c_interface.ino - I2c interface support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 From fc93b0547625777bc3e115cb260d1df38b0821c3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 13:57:04 +0100 Subject: [PATCH 085/105] Happy New Year --- .../TasmotaSerial-3.1.0/src/TasmotaSerial.cpp | 2 +- .../TasmotaSerial-3.1.0/src/TasmotaSerial.h | 2 +- lib/default/UdpListener/src/UdpListener.h | 2 +- .../src/UnishoxStrings.cpp | 2 +- .../src/UnishoxStrings.h | 22 +++++++++---------- .../jsmn-shadinger-1.0/src/JsonGenerator.cpp | 2 +- .../jsmn-shadinger-1.0/src/JsonGenerator.h | 2 +- .../jsmn-shadinger-1.0/src/JsonParser.cpp | 2 +- .../jsmn-shadinger-1.0/src/JsonParser.h | 4 ++-- .../TasmotaModbus-1.2.0/src/TasmotaModbus.cpp | 2 +- .../TasmotaModbus-1.2.0/src/TasmotaModbus.h | 2 +- .../ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp | 2 +- .../ESP32-to-ESP8266-compat/src/ESP8266WiFi.h | 2 +- tools/decode-status.py | 2 +- tools/serial-plotter.py | 3 +-- tools/templates/templates.py | 2 +- 16 files changed, 27 insertions(+), 28 deletions(-) diff --git a/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp index d7ac0866e..1d0445351 100644 --- a/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.cpp @@ -1,7 +1,7 @@ /* TasmotaSerial.cpp - Implementation of software serial with hardware serial fallback for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 Theo Arends 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 diff --git a/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.h index bc5161d65..2a97741e3 100644 --- a/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.1.0/src/TasmotaSerial.h @@ -1,7 +1,7 @@ /* TasmotaSerial.h - Implementation of software serial with hardware serial fallback for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 Theo Arends 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 diff --git a/lib/default/UdpListener/src/UdpListener.h b/lib/default/UdpListener/src/UdpListener.h index b4f5af93b..57bce0dae 100644 --- a/lib/default/UdpListener/src/UdpListener.h +++ b/lib/default/UdpListener/src/UdpListener.h @@ -1,7 +1,7 @@ /* UdpListener.h - webserver for Tasmota - Copyright (C) 2020 Theo Arends & Stephan Hadinger + Copyright (C) 2021 Theo Arends & Stephan Hadinger 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 diff --git a/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.cpp b/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.cpp index 223399e2f..22b8cbcc3 100644 --- a/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.cpp +++ b/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.cpp @@ -1,7 +1,7 @@ /* UnishoxStrings.c - support library for compressed strings in Flash - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 diff --git a/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.h b/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.h index 12de778d4..3ded62ffe 100644 --- a/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.h +++ b/lib/default/Unishox-1.0-shadinger/src/UnishoxStrings.h @@ -1,7 +1,7 @@ /* UnishoxStrings.c - support library for compressed strings in Flash - Copyright (C) 2020 Theo Arends and Stephan Hadinger + Copyright (C) 2021 Theo Arends and Stephan Hadinger 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 @@ -28,18 +28,18 @@ /*******************************************************************************************/ /* * UnishoxStrings compressed literal strings - * + * * To be typically used for web UI to have multiple strings like JS, CSS, HTML * compressed in a single list of small strings. This is where Unishox shines. - * + * * Strings before compression are separated with NULL chars, which makes them ready to use * once you know the offset in the global array. - * + * * The list of string is marked by an empty stings, i.e. two consecutive NULL chars - * + * * To distinguish from uncompressed templates, and to indicate the global size * the compressed array is prefixed with NULL and the uncompressed size * 16 bytes. - * + * * Compressed format: * - Byte 00 : \00 - if non-null, then it is not compressed * - Byte 01 : - uncompressed size is * 16 bytes (always rounded up) @@ -54,22 +54,22 @@ * This class is initialzed with either a PMEM uncompressed list of strings * or a PMEM unishox-compressed list of strings; in this case RAM is allocated * to hold the uncompressed data, until the class gets out of scope. - * + * * To encode, use https://tasmota.hadinger.fr/util * and use the "Compress strings template with unishox" * past the C code for the strings, and copy/paste the result * (don't foget to rename the variable). - * + * * Input: * Each string must be terminated with an explicit NULL char "\0". The list is hence * terminated with a double-NULL. - * + * * Each string is then indexed as its byte offset in the whole template. * The offsets are computed at the same time as the compressed version. * You need to use the online compressor even if you don't use the comrpessed version. - * + * * Indexes are marked as C++ comments starting with "//=" - * + * * Example input: * con * // start of strings diff --git a/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.cpp b/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.cpp index 0bdd77768..b823c58d9 100644 --- a/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.cpp +++ b/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.cpp @@ -1,7 +1,7 @@ /* JsonGenerator.cpp - lightweight JSON parser - Copyright (C) 2020 Stephan Hadinger + Copyright (C) 2021 Stephan Hadinger 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 diff --git a/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.h b/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.h index 589c60167..2f27b846b 100644 --- a/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.h +++ b/lib/default/jsmn-shadinger-1.0/src/JsonGenerator.h @@ -1,7 +1,7 @@ /* JsonGenerator.h - lightweight JSON generator - Copyright (C) 2020 Stephan Hadinger + Copyright (C) 2021 Stephan Hadinger 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 diff --git a/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp b/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp index 050505d07..73703d6ed 100644 --- a/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp +++ b/lib/default/jsmn-shadinger-1.0/src/JsonParser.cpp @@ -1,7 +1,7 @@ /* JsonParser.cpp - lightweight JSON parser - Copyright (C) 2020 Stephan Hadinger + Copyright (C) 2021 Stephan Hadinger 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 diff --git a/lib/default/jsmn-shadinger-1.0/src/JsonParser.h b/lib/default/jsmn-shadinger-1.0/src/JsonParser.h index 85d401407..a31f28c91 100644 --- a/lib/default/jsmn-shadinger-1.0/src/JsonParser.h +++ b/lib/default/jsmn-shadinger-1.0/src/JsonParser.h @@ -1,7 +1,7 @@ /* JsonParser.h - lightweight JSON parser - Copyright (C) 2020 Stephan Hadinger + Copyright (C) 2021 Stephan Hadinger 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 @@ -228,7 +228,7 @@ public: // destructor ~JsonParser(); - + // set the current buffer for attribute access (i.e. set the global) void setCurrent(void) { k_current_json_buffer = _json; } diff --git a/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.cpp b/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.cpp index 057001779..b1a8c48f8 100644 --- a/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.cpp +++ b/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.cpp @@ -1,7 +1,7 @@ /* TasmotaModbus.cpp - Basic modbus wrapper for TasmotaSerial for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 Theo Arends 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 diff --git a/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.h b/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.h index 4a5fbc7a8..22d4e12f3 100644 --- a/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.h +++ b/lib/lib_basic/TasmotaModbus-1.2.0/src/TasmotaModbus.h @@ -1,7 +1,7 @@ /* TasmotaModbus.h - Basic modbus wrapper for TasmotaSerial for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 Theo Arends 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 diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp index a72d95cb6..0e26883ba 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp @@ -1,7 +1,7 @@ /* WiFi compat with ESP32 - Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt + Copyright (C) 2021 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 diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h index df9f54273..9649f49f5 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h @@ -1,7 +1,7 @@ /* WiFi compat with ESP32 - Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt + Copyright (C) 2021 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 diff --git a/tools/decode-status.py b/tools/decode-status.py index 678cf5a73..aa2bfc4e1 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -3,7 +3,7 @@ """ decode-status.py - decode status for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 diff --git a/tools/serial-plotter.py b/tools/serial-plotter.py index 83ec6dba6..2e08e2c62 100644 --- a/tools/serial-plotter.py +++ b/tools/serial-plotter.py @@ -3,7 +3,7 @@ """ serial-plotter.py - for Tasmota - Copyright (C) 2020 Christian Baars + Copyright (C) 2021 Christian Baars 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 @@ -189,4 +189,3 @@ text_box.on_submit(submit) if ser.is_open==True: plt.show() - \ No newline at end of file diff --git a/tools/templates/templates.py b/tools/templates/templates.py index 5387ceaaa..5a6cea513 100644 --- a/tools/templates/templates.py +++ b/tools/templates/templates.py @@ -3,7 +3,7 @@ """ templates.py - template beautify TEMPLATES.md for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2021 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 From 54c1a2d029ae8147acbb5498680264fa3658e85d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 15:05:58 +0100 Subject: [PATCH 086/105] Add support for SPI display driver for ST7789 TFT Add support for SPI display driver for ST7789 TFT by Gerhard Mutz (#9037) --- BUILDS.md | 7 ++++--- CHANGELOG.md | 1 + RELEASENOTES.md | 1 + tasmota/my_user_config.h | 3 ++- tasmota/support.ino | 7 +++---- tasmota/support_features.ino | 23 ++++++++++++++++------- tasmota/support_tasmota.ino | 31 ++++++++++++++++--------------- tasmota/tasmota_configurations.h | 7 ++++--- tasmota/xdsp_12_ST7789.ino | 11 ++++++++--- tools/decode-status.py | 4 ++-- 10 files changed, 57 insertions(+), 38 deletions(-) diff --git a/BUILDS.md b/BUILDS.md index 5eb73cc99..34d386c62 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -201,9 +201,10 @@ | USE_DISPLAY_ILI9341 | - | - | - | - | - | - | x | | USE_DISPLAY_EPAPER_29 | - | - | - | - | - | - | x | | USE_DISPLAY_EPAPER_42 | - | - | - | - | - | - | x | -| USE_DISPLAY_ILI9488 | - | - | - | - | - | - | - | -| USE_DISPLAY_SSD1351 | - | - | - | - | - | - | - | -| USE_DISPLAY_RA8876 | - | - | - | - | - | - | - | +| USE_DISPLAY_ILI9488 | - | - | - | - | - | - | x | +| USE_DISPLAY_SSD1351 | - | - | - | - | - | - | x | +| USE_DISPLAY_RA8876 | - | - | - | - | - | - | x | +| USE_DISPLAY_ST7789 | - | - | - | - | - | - | x | ## Additional Features and Sensors on ESP32 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f1a34e5b..f2844aa8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to this project will be documented in this file. - Support for Afrikaans language translations by Christiaan Heerze - Support for IR inverted leds using ``#define IR_SEND_INVERTED true`` (#10301) - Support for disabling 38kHz IR modulation using ``#define IR_SEND_USE_MODULATION false`` (#10301) +- Support for SPI display driver for ST7789 TFT by Gerhard Mutz (#9037) ### Changed - Logging from heap to stack freeing 700 bytes RAM diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 83cfe63c7..539323f9d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -70,6 +70,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota - Support for Afrikaans language translations by Christiaan Heerze - Support for IR inverted leds using ``#define IR_SEND_INVERTED true`` [#10301](https://github.com/arendst/Tasmota/issues/10301) - Support for disabling 38kHz IR modulation using ``#define IR_SEND_USE_MODULATION false`` [#10301](https://github.com/arendst/Tasmota/issues/10301) +- Support for SPI display driver for ST7789 TFT by Gerhard Mutz [#9037](https://github.com/arendst/Tasmota/issues/9037) - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin [#8630](https://github.com/arendst/Tasmota/issues/8630) ### Breaking Changed diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 59cef587c..63db85b25 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -626,8 +626,9 @@ // #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code) // #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display // #define USE_DISPLAY_ILI9488 // [DisplayModel 8] [I2cDriver38] (Touch) -// #define USE_DISPLAY_SSD1351 // [DisplayModel 9] +// #define USE_DISPLAY_SSD1351 // [DisplayModel 9] Enable SSD1351 module // #define USE_DISPLAY_RA8876 // [DisplayModel 10] [I2cDriver39] (Touch) +// #define USE_DISPLAY_ST7789 // [DisplayModel 12] Enable ST7789 module // #define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code) // #define USE_RC522_DATA_FUNCTION // Add support for reading data block content (+0k4 code) // #define USE_RC522_TYPE_INFORMATION // Add support for showing card type (+0k4 code) diff --git a/tasmota/support.ino b/tasmota/support.ino index 3d8634e3e..e9b6fe204 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1503,12 +1503,11 @@ bool ValidGPIO(uint32_t pin, uint32_t gpio) { return (GPIO_USER == ValidPin(pin, BGPIO(gpio))); // Only allow GPIO_USER pins } -bool ValidSpiGPIO(uint32_t gpio) { +bool ValidSpiPinUsed(uint32_t gpio) { // ESP8266: If SPI pin selected chk if it's not one of the three Hardware SPI pins (12..14) - bool result = true; // Not used and therefore valid - uint32_t pin; + bool result = false; if (PinUsed(gpio)) { - pin = Pin(gpio); + uint32_t pin = Pin(gpio); result = ((pin < 12) || (pin > 14)); } return result; diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 29ef7a15c..d86544aac 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -162,7 +162,7 @@ void ResponseAppendFeatures(void) feature2 |= 0x00000800; // xdsp_05_epaper.ino #endif #if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SH1106) - feature2 |= 0x00001000; // xdsp_06_sh1106.ino + feature2 |= 0x00001000; // xdsp_07_sh1106.ino #endif #ifdef USE_MP3_PLAYER feature2 |= 0x00002000; // xdrv_14_mp3.ino @@ -671,12 +671,21 @@ void ResponseAppendFeatures(void) #ifdef USE_FTC532 feature7 |= 0x00004000; // xdrv_47_ftc532.ino #endif -// feature7 |= 0x00008000; - -// feature7 |= 0x00010000; -// feature7 |= 0x00020000; -// feature7 |= 0x00040000; -// feature7 |= 0x00080000; +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_EPAPER_42) + feature7 |= 0x00008000; // xdsp_06_epaper_42.ino +#endif +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_ILI9488) + feature7 |= 0x00010000; // xdsp_08_ILI9488.ino +#endif +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1351) + feature7 |= 0x00020000; // xdsp_09_SSD1351.ino +#endif +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_RA8876) + feature7 |= 0x00040000; // xdsp_10_RA8876.ino +#endif +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_ST7789) + feature7 |= 0x00080000; // xdsp_12_ST7789.ino +#endif // feature7 |= 0x00100000; // feature7 |= 0x00200000; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index dedb28f6d..c76896f73 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1604,23 +1604,23 @@ void GpioInit(void) #ifdef USE_SPI #ifdef ESP8266 if (!TasmotaGlobal.soft_spi_enabled) { - bool valid_cs = (ValidSpiGPIO(GPIO_SPI_CS) && - ValidSpiGPIO(GPIO_RC522_CS) && - ValidSpiGPIO(GPIO_NRF24_CS) && - ValidSpiGPIO(GPIO_ILI9341_CS) && - ValidSpiGPIO(GPIO_EPAPER29_CS) && - ValidSpiGPIO(GPIO_EPAPER42_CS) && - ValidSpiGPIO(GPIO_ILI9488_CS) && - ValidSpiGPIO(GPIO_SSD1351_CS) && - ValidSpiGPIO(GPIO_RA8876_CS) && - ValidSpiGPIO(GPIO_ST7789_CS) + bool valid_cs = (ValidSpiPinUsed(GPIO_SPI_CS) || + ValidSpiPinUsed(GPIO_RC522_CS) || + ValidSpiPinUsed(GPIO_NRF24_CS) || + ValidSpiPinUsed(GPIO_ILI9341_CS) || + ValidSpiPinUsed(GPIO_EPAPER29_CS) || + ValidSpiPinUsed(GPIO_EPAPER42_CS) || + ValidSpiPinUsed(GPIO_ILI9488_CS) || + ValidSpiPinUsed(GPIO_SSD1351_CS) || + ValidSpiPinUsed(GPIO_RA8876_CS) || + ValidSpiPinUsed(GPIO_ST7789_DC) || // ST7789 CS may be omitted so chk DC too + ValidSpiPinUsed(GPIO_ST7789_CS) ); - bool valid_dc = (ValidSpiGPIO(GPIO_SPI_DC) && - ValidSpiGPIO(GPIO_NRF24_DC) && - ValidSpiGPIO(GPIO_ILI9341_DC) && - ValidSpiGPIO(GPIO_ST7789_DC) + bool valid_dc = (ValidSpiPinUsed(GPIO_SPI_DC) || + ValidSpiPinUsed(GPIO_NRF24_DC) || + ValidSpiPinUsed(GPIO_ILI9341_DC) || + ValidSpiPinUsed(GPIO_ST7789_DC) ); - // If SPI_CS and/or SPI_DC is used they must be valid TasmotaGlobal.spi_enabled = (valid_cs && valid_dc) ? SPI_MOSI_MISO : SPI_NONE; if (TasmotaGlobal.spi_enabled) { @@ -1643,6 +1643,7 @@ void GpioInit(void) PinUsed(GPIO_ILI9488_CS) || PinUsed(GPIO_SSD1351_CS) || PinUsed(GPIO_RA8876_CS) || + PinUsed(GPIO_ST7789_DC) || // ST7789 CS may be omitted so chk DC too PinUsed(GPIO_ST7789_CS) ) { uint32_t spi_mosi = (PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MOSI)) ? SPI_MOSI : SPI_NONE; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 9a4e26e4d..86078c8ab 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -306,9 +306,10 @@ #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code) #define USE_DISPLAY_EPAPER_29 // [DisplayModel 5] Enable e-paper 2.9 inch display (+19k code) #define USE_DISPLAY_EPAPER_42 // [DisplayModel 6] Enable e-paper 4.2 inch display -// #define USE_DISPLAY_ILI9488 // [DisplayModel 8] -// #define USE_DISPLAY_SSD1351 // [DisplayModel 9] -// #define USE_DISPLAY_RA8876 // [DisplayModel 10] + #define USE_DISPLAY_ILI9488 // [DisplayModel 8] + #define USE_DISPLAY_SSD1351 // [DisplayModel 9] + #define USE_DISPLAY_RA8876 // [DisplayModel 10] + #define USE_DISPLAY_ST7789 // [DisplayModel 12] Enable ST7789 module #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code diff --git a/tasmota/xdsp_12_ST7789.ino b/tasmota/xdsp_12_ST7789.ino index 141080da1..624fd535c 100644 --- a/tasmota/xdsp_12_ST7789.ino +++ b/tasmota/xdsp_12_ST7789.ino @@ -58,7 +58,7 @@ bool st7789_init_done = false; /*********************************************************************************************/ void ST7789_InitDriver(void) { - if (PinUsed(GPIO_ST7789_CS) && PinUsed(GPIO_ST7789_DC) && + if (PinUsed(GPIO_ST7789_DC) && // This device does not need CS which breaks SPI bus usage ((TasmotaGlobal.soft_spi_enabled & SPI_MOSI) || (TasmotaGlobal.spi_enabled & SPI_MOSI))) { Settings.display_model = XDSP_12; @@ -87,12 +87,17 @@ void ST7789_InitDriver(void) { reset = Pin(GPIO_OLED_RESET); } + int8_t cs = -1; + if (PinUsed(GPIO_ST7789_CS)) { + reset = Pin(GPIO_ST7789_CS); + } + // init renderer, may use hardware spi if (TasmotaGlobal.soft_spi_enabled) { - st7789 = new Arduino_ST7789(Pin(GPIO_ST7789_DC), reset, Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), Pin(GPIO_ST7789_CS), bppin); + st7789 = new Arduino_ST7789(Pin(GPIO_ST7789_DC), reset, Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), cs, bppin); } else if (TasmotaGlobal.spi_enabled) { - st7789 = new Arduino_ST7789(Pin(GPIO_ST7789_DC), reset, Pin(GPIO_ST7789_CS), bppin); + st7789 = new Arduino_ST7789(Pin(GPIO_ST7789_DC), reset, cs, bppin); } st7789->init(Settings.display_width,Settings.display_height); diff --git a/tools/decode-status.py b/tools/decode-status.py index aa2bfc4e1..c4c4309c0 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -239,8 +239,8 @@ a_features = [[ "USE_EZOORP","USE_EZORTD","USE_EZOHUM","USE_EZOEC", "USE_EZOCO2","USE_EZOO2","USE_EZOPRS","USE_EZOFLO", "USE_EZODO","USE_EZORGB","USE_EZOPMP","USE_AS608", - "USE_SHELLY_DIMMER","USE_RC522","USE_FTC532","", - "","","","", + "USE_SHELLY_DIMMER","USE_RC522","USE_FTC532","USE_DISPLAY_EPAPER_42", + "USE_DISPLAY_ILI9488","USE_DISPLAY_SSD1351","USE_DISPLAY_RA8876","USE_DISPLAY_ST7789", "","","","", "","","","", "","","","" From 46d7e9392e0cec81de9f6bec46433b390a3ef54a Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 15:54:47 +0100 Subject: [PATCH 087/105] Fix ST7789 --- tasmota/xdsp_12_ST7789.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdsp_12_ST7789.ino b/tasmota/xdsp_12_ST7789.ino index 624fd535c..cdb9ad167 100644 --- a/tasmota/xdsp_12_ST7789.ino +++ b/tasmota/xdsp_12_ST7789.ino @@ -89,7 +89,7 @@ void ST7789_InitDriver(void) { int8_t cs = -1; if (PinUsed(GPIO_ST7789_CS)) { - reset = Pin(GPIO_ST7789_CS); + cs = Pin(GPIO_ST7789_CS); } // init renderer, may use hardware spi From ee1648d3e09b42febb0206203d6e0fb8d0c699e3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 16:05:06 +0100 Subject: [PATCH 088/105] Prep SSD1331 driver --- tasmota/language/af_AF.h | 2 ++ tasmota/language/bg_BG.h | 2 ++ tasmota/language/cs_CZ.h | 2 ++ tasmota/language/de_DE.h | 2 ++ tasmota/language/el_GR.h | 2 ++ tasmota/language/en_GB.h | 2 ++ tasmota/language/es_ES.h | 2 ++ tasmota/language/fr_FR.h | 2 ++ tasmota/language/he_HE.h | 2 ++ tasmota/language/hu_HU.h | 2 ++ tasmota/language/it_IT.h | 2 ++ tasmota/language/ko_KO.h | 2 ++ tasmota/language/nl_NL.h | 2 ++ tasmota/language/pl_PL.h | 2 ++ tasmota/language/pt_BR.h | 2 ++ tasmota/language/pt_PT.h | 2 ++ tasmota/language/ro_RO.h | 2 ++ tasmota/language/ru_RU.h | 2 ++ tasmota/language/sk_SK.h | 2 ++ tasmota/language/sv_SE.h | 2 ++ tasmota/language/tr_TR.h | 2 ++ tasmota/language/uk_UA.h | 2 ++ tasmota/language/vi_VN.h | 2 ++ tasmota/language/zh_CN.h | 2 ++ tasmota/language/zh_TW.h | 2 ++ tasmota/my_user_config.h | 1 + tasmota/support_features.ino | 5 ++-- tasmota/support_tasmota.ino | 9 ++++-- tasmota/tasmota_configurations.h | 1 + tasmota/tasmota_template.h | 8 ++++- tasmota/xdsp_09_SSD1351.ino | 15 ++++------ tasmota/xdsp_14_SSD1331.ino | 50 +++++++++++++++++--------------- tools/decode-status.py | 2 +- 33 files changed, 102 insertions(+), 39 deletions(-) diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index bfd4177e3..4eab30241 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index f8e3c705c..e9003a386 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -775,6 +775,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 983524bbf..159d00878 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index f1bad46a7..cdbc1f994 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 5820512d6..8e2e3f093 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 77a325d30..2d6a47f43 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index e04f2b256..31640385e 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 65c14a58d..7bb645751 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -772,6 +772,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index 6e9a6ef8e..ab7ff6d77 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 82fe0b4a4..e2d335ce6 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 91ae9a830..9aa08db46 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 - CS" #define D_SENSOR_ST7789_CS "ST7789 - CS" #define D_SENSOR_ST7789_DC "ST7789 - DC" +#define D_SENSOR_SSD1331_CS "SSD1331 - CS" +#define D_SENSOR_SSD1331_DC "SSD1331 - DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 6ab2f1421..0d9f91af4 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 682fbec90..8087a8770 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index f5497d91d..5919b35b5 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 99d38f192..8069a265f 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 5e7c74f36..af9ee37a0 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index bb1a09185..bf23a7c8d 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index df1d5b50e..965f5f5d7 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index 8f5490a19..20a691be6 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 6935fa102..18822f2b8 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 01b73bc75..f307a9e73 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 11fbdac99..2626572ae 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index cc666ec82..d8d9d5124 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 2e6baa64d..1895fc690 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "安" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 2a2078266..2f2ec544e 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -776,6 +776,8 @@ #define D_SENSOR_RA8876_CS "RA8876 CS" #define D_SENSOR_ST7789_CS "ST7789 CS" #define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" // Units #define D_UNIT_AMPERE "安培" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 63db85b25..fb9c30774 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -629,6 +629,7 @@ // #define USE_DISPLAY_SSD1351 // [DisplayModel 9] Enable SSD1351 module // #define USE_DISPLAY_RA8876 // [DisplayModel 10] [I2cDriver39] (Touch) // #define USE_DISPLAY_ST7789 // [DisplayModel 12] Enable ST7789 module +// #define USE_DISPLAY_SSD1331 // [DisplayModel 14] Enable SSD1331 module // #define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code) // #define USE_RC522_DATA_FUNCTION // Add support for reading data block content (+0k4 code) // #define USE_RC522_TYPE_INFORMATION // Add support for showing card type (+0k4 code) diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index d86544aac..1def3db1c 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -686,8 +686,9 @@ void ResponseAppendFeatures(void) #if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_ST7789) feature7 |= 0x00080000; // xdsp_12_ST7789.ino #endif - -// feature7 |= 0x00100000; +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1331) + feature7 |= 0x00100000; // xdsp_14_SSD1331.ino +#endif // feature7 |= 0x00200000; // feature7 |= 0x00400000; // feature7 |= 0x00800000; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index c76896f73..84bc2dd53 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1614,12 +1614,14 @@ void GpioInit(void) ValidSpiPinUsed(GPIO_SSD1351_CS) || ValidSpiPinUsed(GPIO_RA8876_CS) || ValidSpiPinUsed(GPIO_ST7789_DC) || // ST7789 CS may be omitted so chk DC too - ValidSpiPinUsed(GPIO_ST7789_CS) + ValidSpiPinUsed(GPIO_ST7789_CS) || + ValidSpiPinUsed(GPIO_SSD1331_CS) ); bool valid_dc = (ValidSpiPinUsed(GPIO_SPI_DC) || ValidSpiPinUsed(GPIO_NRF24_DC) || ValidSpiPinUsed(GPIO_ILI9341_DC) || - ValidSpiPinUsed(GPIO_ST7789_DC) + ValidSpiPinUsed(GPIO_ST7789_DC) || + ValidSpiPinUsed(GPIO_SSD1331_DC) ); // If SPI_CS and/or SPI_DC is used they must be valid TasmotaGlobal.spi_enabled = (valid_cs && valid_dc) ? SPI_MOSI_MISO : SPI_NONE; @@ -1644,7 +1646,8 @@ void GpioInit(void) PinUsed(GPIO_SSD1351_CS) || PinUsed(GPIO_RA8876_CS) || PinUsed(GPIO_ST7789_DC) || // ST7789 CS may be omitted so chk DC too - PinUsed(GPIO_ST7789_CS) + PinUsed(GPIO_ST7789_CS) || + PinUsed(GPIO_SSD1331_CS) ) { uint32_t spi_mosi = (PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MOSI)) ? SPI_MOSI : SPI_NONE; uint32_t spi_miso = (PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MISO)) ? SPI_MISO : SPI_NONE; diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 86078c8ab..142045bab 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -310,6 +310,7 @@ #define USE_DISPLAY_SSD1351 // [DisplayModel 9] #define USE_DISPLAY_RA8876 // [DisplayModel 10] #define USE_DISPLAY_ST7789 // [DisplayModel 12] Enable ST7789 module +// #define USE_DISPLAY_SSD1331 // [DisplayModel 14] Enable SSD1331 module #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index 714ca0f77..874f5ab2f 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -141,6 +141,7 @@ enum UserSelectablePins { GPIO_SSD1351_CS, GPIO_RA8876_CS, GPIO_ST7789_CS, GPIO_ST7789_DC, + GPIO_SSD1331_CS, GPIO_SSD1331_DC, GPIO_SENSOR_END }; enum ProgramSelectablePins { @@ -302,6 +303,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_SSD1351_CS "|" D_SENSOR_RA8876_CS "|" D_SENSOR_ST7789_CS "|" D_SENSOR_ST7789_DC "|" + D_SENSOR_SSD1331_CS "|" D_SENSOR_SSD1331_DC "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -403,7 +405,11 @@ const uint16_t kGpioNiceList[] PROGMEM = { #ifdef USE_DISPLAY_ST7789 AGPIO(GPIO_ST7789_CS), AGPIO(GPIO_ST7789_DC), -#endif //f USE_DISPLAY_ST7789 +#endif // USE_DISPLAY_ST7789 +#ifdef USE_DISPLAY_SSD1331 + AGPIO(GPIO_SSD1331_CS), + AGPIO(GPIO_SSD1331_DC), +#endif // USE_DISPLAY_SSD1331 AGPIO(GPIO_BACKLIGHT), // Display backlight control AGPIO(GPIO_OLED_RESET), // OLED Display Reset #endif diff --git a/tasmota/xdsp_09_SSD1351.ino b/tasmota/xdsp_09_SSD1351.ino index b0318b0ed..f3ad53b29 100644 --- a/tasmota/xdsp_09_SSD1351.ino +++ b/tasmota/xdsp_09_SSD1351.ino @@ -90,8 +90,7 @@ void SSD1351_InitDriver() { #ifdef USE_DISPLAY_MODES1TO5 -void SSD1351PrintLog(void) -{ +void SSD1351PrintLog(void) { disp_refresh--; if (!disp_refresh) { disp_refresh = Settings.display_refresh; @@ -119,8 +118,7 @@ void SSD1351PrintLog(void) } } -void SSD1351Time(void) -{ +void SSD1351Time(void) { char line[12]; renderer->clearDisplay(); @@ -133,8 +131,7 @@ void SSD1351Time(void) renderer->Updateframe(); } -void SSD1351Refresh(void) // Every second -{ +void SSD1351Refresh(void) { // Every second if (Settings.display_mode) { // Mode 0 is User text switch (Settings.display_mode) { case 1: // Time @@ -151,12 +148,12 @@ void SSD1351Refresh(void) // Every second } #endif // USE_DISPLAY_MODES1TO5 -/*********************************************************************************************/ + /*********************************************************************************************\ * Interface \*********************************************************************************************/ -bool Xdsp09(uint8_t function) -{ + +bool Xdsp09(uint8_t function) { bool result = false; if (FUNC_DISPLAY_INIT_DRIVER == function) { diff --git a/tasmota/xdsp_14_SSD1331.ino b/tasmota/xdsp_14_SSD1331.ino index cae0c9aa2..be5417426 100644 --- a/tasmota/xdsp_14_SSD1331.ino +++ b/tasmota/xdsp_14_SSD1331.ino @@ -1,7 +1,7 @@ /* xdsp_14_SSD1331.ino - Display SSD1331 support for Tasmota - Copyright (C) 2020 Jeroen Vermeulen, Gerhard Mutz and Theo Arends + Copyright (C) 2021 Jeroen Vermeulen, Gerhard Mutz and 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 @@ -35,6 +35,7 @@ #include #include +bool ssd1331_init_done = false; extern uint8_t *buffer; extern uint8_t color_type; Adafruit_SSD1331 *ssd1331; @@ -42,11 +43,10 @@ Adafruit_SSD1331 *ssd1331; /*********************************************************************************************/ void SSD1331_InitDriver() { - if (!Settings.display_model) { - Settings.display_model = XDSP_14; - } + if (PinUsed(GPIO_SSD1331_CS) && PinUsed(GPIO_SSD1331_DC) && + ((TasmotaGlobal.soft_spi_enabled & SPI_MOSI) || (TasmotaGlobal.spi_enabled & SPI_MOSI))) { - if (XDSP_14 == Settings.display_model) { + Settings.display_model = XDSP_14; if (Settings.display_width != Adafruit_SSD1331::TFTWIDTH) { Settings.display_width = Adafruit_SSD1331::TFTWIDTH; @@ -55,26 +55,30 @@ void SSD1331_InitDriver() { Settings.display_height = Adafruit_SSD1331::TFTHEIGHT; } - buffer=0; + buffer = 0; // default colors fg_color = SSD1331_WHITE; bg_color = SSD1331_BLACK; + int8_t reset = -1; + if (PinUsed(GPIO_OLED_RESET)) { + reset = Pin(GPIO_OLED_RESET); + } + // init renderer - if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_DC) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_OLED_RESET)) { - ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_DC),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),Pin(GPIO_OLED_RESET)); - } else if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { - ssd1331 = new Adafruit_SSD1331(&SPI,Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC),Pin(GPIO_OLED_RESET)); - } else { - return; + if (TasmotaGlobal.soft_spi_enabled) { + ssd1331 = new Adafruit_SSD1331(Pin(GPIO_SSD1331_CS), Pin(GPIO_SSD1331_DC), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_SCLK), reset); + } + else if (TasmotaGlobal.spi_enabled) { + ssd1331 = new Adafruit_SSD1331(&SPI, Pin(GPIO_SSD1331_CS), Pin(GPIO_SSD1331_DC), reset); } delay(100); ssd1331->begin(); renderer = ssd1331; // Rotation is currently broken, https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/issues/26 - renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); + renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font); renderer->dim(Settings.display_dimmer); #ifdef SHOW_SPLASH @@ -86,13 +90,15 @@ void SSD1331_InitDriver() { #endif color_type = COLOR_COLOR; + + ssd1331_init_done = true; + AddLog_P(LOG_LEVEL_INFO, PSTR("DSP: SSD1331")); } } #ifdef USE_DISPLAY_MODES1TO5 -void SSD1331PrintLog(bool withDateTime) -{ +void SSD1331PrintLog(bool withDateTime) { disp_refresh--; if (!disp_refresh) { disp_refresh = Settings.display_refresh; @@ -129,8 +135,7 @@ void SSD1331PrintLog(bool withDateTime) } } -void SSD1331Time(void) -{ +void SSD1331Time(void) { char line[12]; renderer->clearDisplay(); @@ -142,8 +147,7 @@ void SSD1331Time(void) renderer->Updateframe(); } -void SSD1331Refresh(void) // Every second -{ +void SSD1331Refresh(void) { // Every second if (Settings.display_mode) { // Mode 0 is User text switch (Settings.display_mode) { case 1: // Time @@ -162,18 +166,18 @@ void SSD1331Refresh(void) // Every second } #endif // USE_DISPLAY_MODES1TO5 -/*********************************************************************************************/ + /*********************************************************************************************\ * Interface \*********************************************************************************************/ -bool Xdsp14(uint8_t function) -{ + +bool Xdsp14(uint8_t function) { bool result = false; if (FUNC_DISPLAY_INIT_DRIVER == function) { SSD1331_InitDriver(); } - else if (XDSP_14 == Settings.display_model) { + else if (ssd1331_init_done && (XDSP_14 == Settings.display_model)) { switch (function) { case FUNC_DISPLAY_MODEL: result = true; diff --git a/tools/decode-status.py b/tools/decode-status.py index c4c4309c0..ba5ead287 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -241,7 +241,7 @@ a_features = [[ "USE_EZODO","USE_EZORGB","USE_EZOPMP","USE_AS608", "USE_SHELLY_DIMMER","USE_RC522","USE_FTC532","USE_DISPLAY_EPAPER_42", "USE_DISPLAY_ILI9488","USE_DISPLAY_SSD1351","USE_DISPLAY_RA8876","USE_DISPLAY_ST7789", - "","","","", + "USE_DISPLAY_SSD1331","","","", "","","","", "","","","" ]] From 628f17de8c91bade92edefe3b1b4d544e644710d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 17:04:36 +0100 Subject: [PATCH 089/105] Add TasAutoMutex --- tasmota/support.ino | 76 ++++++++++++++++++--------------------- tasmota/support_esp32.ino | 3 +- tasmota/tasmota.ino | 2 +- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index a504b077d..7dd03d978 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -111,7 +111,7 @@ String GetResetReason(void) } } - +#ifdef ESP32 /*********************************************************************************************\ * ESP32 AutoMutex \*********************************************************************************************/ @@ -128,9 +128,7 @@ String GetResetReason(void) // - the same thread can take multiple times (recursive). // - advanced options m.give() and m.take() allow you fine control within a function. class TasAutoMutex { -#ifdef ESP32 SemaphoreHandle_t mutex; -#endif bool taken; public: TasAutoMutex(void * mutex, bool take=true); @@ -141,63 +139,53 @@ class TasAutoMutex { }; ////////////////////////////////////////// -TasAutoMutex::TasAutoMutex(void * mutex, bool take){ -#ifdef ESP32 - if(mutex){ - if (take){ +TasAutoMutex::TasAutoMutex(void * mutex, bool take) { + if (mutex) { + if (take) { xSemaphoreTakeRecursive(mutex, portMAX_DELAY); this->taken = true; } - this->mutex = (SemaphoreHandle_t ) mutex; + this->mutex = (SemaphoreHandle_t)mutex; } else { - this->mutex = (SemaphoreHandle_t )nullptr; + this->mutex = (SemaphoreHandle_t)nullptr; } -#endif } -TasAutoMutex::~TasAutoMutex(){ -#ifdef ESP32 - if (this->mutex){ - if (this->taken){ +TasAutoMutex::~TasAutoMutex() { + if (this->mutex) { + if (this->taken) { xSemaphoreGiveRecursive(this->mutex); this->taken = false; } } -#endif } -void TasAutoMutex::init(void ** ptr){ -#ifdef ESP32 +void TasAutoMutex::init(void ** ptr) { SemaphoreHandle_t mutex = xSemaphoreCreateRecursiveMutex(); (*ptr) = (void *) mutex; -#else - // needed, else we will initialis more than once in logging - (*ptr) = (void *) 1; -#endif + // needed, else for ESP8266 as we will initialis more than once in logging +// (*ptr) = (void *) 1; } -void TasAutoMutex::give(){ -#ifdef ESP32 - if (this->mutex){ - if (this->taken){ +void TasAutoMutex::give() { + if (this->mutex) { + if (this->taken) { xSemaphoreGiveRecursive(this->mutex); this->taken= false; } } -#endif } -void TasAutoMutex::take(){ -#ifdef ESP32 - if (this->mutex){ - if (!this->taken){ + +void TasAutoMutex::take() { + if (this->mutex) { + if (!this->taken) { xSemaphoreTakeRecursive(this->mutex, portMAX_DELAY); this->taken = true; } } -#endif } - +#endif // ESP32 /*********************************************************************************************\ * Miscellaneous @@ -2054,9 +2042,12 @@ void SyslogAsync(bool refresh) { } bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) { - // this takes the mutex, and will be release when the class is destroyed - + +#ifdef ESP32 + // this takes the mutex, and will be release when the class is destroyed - // i.e. when the functon leaves You CAN call mutex.give() to leave early. - TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); +#endif // ESP32 // Skip initial buffer fill if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - LOGSZ) { return false; } @@ -2073,9 +2064,11 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l if (TasmotaGlobal.uptime < 3) { return false; } // Allow time to setup correct log level if (!req_loglevel || (index == TasmotaGlobal.log_buffer_pointer)) { return false; } - // this takes the mutex, and will be release when the class is destroyed - +#ifdef ESP32 + // this takes the mutex, and will be release when the class is destroyed - // i.e. when the functon leaves You CAN call mutex.give() to leave early. - TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); +#endif // ESP32 if (!index) { // Dump all index = TasmotaGlobal.log_buffer_pointer +1; @@ -2116,17 +2109,18 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l void AddLogData(uint32_t loglevel, const char* log_data) { - if (!TasmotaGlobal.log_buffer_mutex){ +#ifdef ESP32 + if (!TasmotaGlobal.log_buffer_mutex) { TasAutoMutex::init(&TasmotaGlobal.log_buffer_mutex); } + // this takes the mutex, and will be release when the class is destroyed - + // i.e. when the functon leaves You CAN call mutex.give() to leave early. + TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); +#endif // ESP32 char mxtime[14]; // "13:45:21.999 " snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d.%03d "), RtcTime.hour, RtcTime.minute, RtcTime.second, RtcMillis()); - // this takes the mutex, and will be release when the class is destroyed - - // i.e. when the functon leaves You CAN call mutex.give() to leave early. - TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); - if ((loglevel <= TasmotaGlobal.seriallog_level) && (TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) { Serial.printf("%s%s\r\n", mxtime, log_data); diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino index 275064204..0554129e8 100644 --- a/tasmota/support_esp32.ino +++ b/tasmota/support_esp32.ino @@ -413,4 +413,5 @@ uint8_t* FlashDirectAccess(void) { */ return data; } -#endif // ESP32 + +#endif // ESP32 \ No newline at end of file diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index dd1bd9bf4..d8b95433e 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -89,6 +89,7 @@ struct { uint32_t log_buffer_pointer; // Index in log buffer uint32_t uptime; // Counting every second until 4294967295 = 130 year GpioOptionABits gpio_optiona; // GPIO Option_A flags + void *log_buffer_mutex; // Control access to log buffer power_t power; // Current copy of Settings.power power_t rel_inverted; // Relay inverted flag (1 = (0 = On, 1 = Off)) @@ -171,7 +172,6 @@ struct { char mqtt_topic[TOPSZ]; // Composed MQTT topic char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer char log_buffer[LOG_BUFFER_SIZE]; // Web log buffer - void *log_buffer_mutex; // control, access to log buffer } TasmotaGlobal; #ifdef SUPPORT_IF_STATEMENT From 85dea8bbcc4753aa3e7a82b7ea9f5f6ee79d8090 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 1 Jan 2021 17:32:21 +0100 Subject: [PATCH 090/105] Move FT5206 lib from I2c to Display --- lib/{lib_i2c => lib_display}/FT5206_Library/.gitignore | 0 lib/{lib_i2c => lib_display}/FT5206_Library/LICENSE | 0 lib/{lib_i2c => lib_display}/FT5206_Library/README.md | 0 lib/{lib_i2c => lib_display}/FT5206_Library/keywords.txt | 0 lib/{lib_i2c => lib_display}/FT5206_Library/library.properties | 0 lib/{lib_i2c => lib_display}/FT5206_Library/src/FT5206.cpp | 0 lib/{lib_i2c => lib_display}/FT5206_Library/src/FT5206.h | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename lib/{lib_i2c => lib_display}/FT5206_Library/.gitignore (100%) rename lib/{lib_i2c => lib_display}/FT5206_Library/LICENSE (100%) rename lib/{lib_i2c => lib_display}/FT5206_Library/README.md (100%) rename lib/{lib_i2c => lib_display}/FT5206_Library/keywords.txt (100%) rename lib/{lib_i2c => lib_display}/FT5206_Library/library.properties (100%) rename lib/{lib_i2c => lib_display}/FT5206_Library/src/FT5206.cpp (100%) rename lib/{lib_i2c => lib_display}/FT5206_Library/src/FT5206.h (100%) diff --git a/lib/lib_i2c/FT5206_Library/.gitignore b/lib/lib_display/FT5206_Library/.gitignore similarity index 100% rename from lib/lib_i2c/FT5206_Library/.gitignore rename to lib/lib_display/FT5206_Library/.gitignore diff --git a/lib/lib_i2c/FT5206_Library/LICENSE b/lib/lib_display/FT5206_Library/LICENSE similarity index 100% rename from lib/lib_i2c/FT5206_Library/LICENSE rename to lib/lib_display/FT5206_Library/LICENSE diff --git a/lib/lib_i2c/FT5206_Library/README.md b/lib/lib_display/FT5206_Library/README.md similarity index 100% rename from lib/lib_i2c/FT5206_Library/README.md rename to lib/lib_display/FT5206_Library/README.md diff --git a/lib/lib_i2c/FT5206_Library/keywords.txt b/lib/lib_display/FT5206_Library/keywords.txt similarity index 100% rename from lib/lib_i2c/FT5206_Library/keywords.txt rename to lib/lib_display/FT5206_Library/keywords.txt diff --git a/lib/lib_i2c/FT5206_Library/library.properties b/lib/lib_display/FT5206_Library/library.properties similarity index 100% rename from lib/lib_i2c/FT5206_Library/library.properties rename to lib/lib_display/FT5206_Library/library.properties diff --git a/lib/lib_i2c/FT5206_Library/src/FT5206.cpp b/lib/lib_display/FT5206_Library/src/FT5206.cpp similarity index 100% rename from lib/lib_i2c/FT5206_Library/src/FT5206.cpp rename to lib/lib_display/FT5206_Library/src/FT5206.cpp diff --git a/lib/lib_i2c/FT5206_Library/src/FT5206.h b/lib/lib_display/FT5206_Library/src/FT5206.h similarity index 100% rename from lib/lib_i2c/FT5206_Library/src/FT5206.h rename to lib/lib_display/FT5206_Library/src/FT5206.h From 0747239d4c6bf702b8c258b845cd79e5c12d9f58 Mon Sep 17 00:00:00 2001 From: Christian Langanke Date: Fri, 1 Jan 2021 18:17:55 +0100 Subject: [PATCH 091/105] - for 7 segment displays - added support for FUNC_DISPLAY_DIM - added new FUNC_DISPLAY_BLINKRATE with new command DisplayBlinkrate Value is not being persistently stored, so no seting req. - added SevensegLog for DisplayMode 1..5 support, displaying the nth sensor value to nth atached 7-segment display. For that unsed display adresses before the first one being used may not be zero, but must be configured to unused addresses (e.g. 0xFF), otherwise driver init will fail. --- tasmota/xdrv_13_display.ino | 23 ++++++++++--- tasmota/xdsp_11_sevenseg.ino | 63 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 00a2ac8a5..6bdab9d03 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -63,6 +63,7 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log #define D_CMND_DISP_TEXT "Text" #define D_CMND_DISP_WIDTH "Width" #define D_CMND_DISP_HEIGHT "Height" +#define D_CMND_DISP_BLINKRATE "Blinkrate" enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND, FUNC_DISPLAY_MODEL, FUNC_DISPLAY_MODE, FUNC_DISPLAY_POWER, @@ -70,19 +71,20 @@ enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_E FUNC_DISPLAY_DRAW_HLINE, FUNC_DISPLAY_DRAW_VLINE, FUNC_DISPLAY_DRAW_LINE, FUNC_DISPLAY_DRAW_CIRCLE, FUNC_DISPLAY_FILL_CIRCLE, FUNC_DISPLAY_DRAW_RECTANGLE, FUNC_DISPLAY_FILL_RECTANGLE, - FUNC_DISPLAY_TEXT_SIZE, FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING }; + FUNC_DISPLAY_TEXT_SIZE, FUNC_DISPLAY_FONT_SIZE, FUNC_DISPLAY_ROTATION, FUNC_DISPLAY_DRAW_STRING, + FUNC_DISPLAY_DIM, FUNC_DISPLAY_BLINKRATE }; enum DisplayInitModes { DISPLAY_INIT_MODE, DISPLAY_INIT_PARTIAL, DISPLAY_INIT_FULL }; const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix "|" D_CMND_DISP_MODEL "|" D_CMND_DISP_WIDTH "|" D_CMND_DISP_HEIGHT "|" D_CMND_DISP_MODE "|" D_CMND_DISP_REFRESH "|" D_CMND_DISP_DIMMER "|" D_CMND_DISP_COLS "|" D_CMND_DISP_ROWS "|" D_CMND_DISP_SIZE "|" D_CMND_DISP_FONT "|" - D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS ; + D_CMND_DISP_ROTATE "|" D_CMND_DISP_TEXT "|" D_CMND_DISP_ADDRESS "|" D_CMND_DISP_BLINKRATE ; void (* const DisplayCommand[])(void) PROGMEM = { &CmndDisplay, &CmndDisplayModel, &CmndDisplayWidth, &CmndDisplayHeight, &CmndDisplayMode, &CmndDisplayRefresh, &CmndDisplayDimmer, &CmndDisplayColumns, &CmndDisplayRows, &CmndDisplaySize, &CmndDisplayFont, - &CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress }; + &CmndDisplayRotate, &CmndDisplayText, &CmndDisplayAddress, &CmndDisplayBlinkrate }; char *dsp_str; @@ -1410,11 +1412,24 @@ void CmndDisplayDimmer(void) else if (!Settings.display_dimmer && disp_power) { ExecuteCommandPower(disp_device, POWER_OFF, SRC_DISPLAY); } - if (renderer) renderer->dim(Settings.display_dimmer); + if (renderer) + renderer->dim(Settings.display_dimmer); + else + XdspCall(FUNC_DISPLAY_DIM); } ResponseCmndNumber(Settings.display_dimmer); } +void CmndDisplayBlinkrate(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { + + if (!renderer) + XdspCall(FUNC_DISPLAY_BLINKRATE); + } + ResponseCmndNumber(XdrvMailbox.payload); +} + void CmndDisplaySize(void) { if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 4)) { diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index ea3db7e4a..b3bde3149 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -62,6 +62,61 @@ void SevensegWrite(void) } } +void SevensegLog(void) +{ + // get sensor data + ResponseClear(); + ResponseAppendTime(); + XsnsCall(FUNC_JSON_APPEND); + ResponseJsonEnd(); + + // display nth sensor value on nth display + // code adapted from xdrv_13_display.ino, DisplayAnalyzeJson() + uint8_t unit = 0; + int16_t valueDecimal = 0; + double valueFloat = 0; + uint8 fDigits = 0; + String jsonStr = TasmotaGlobal.mqtt_data; // Move from stack to heap to fix watchdogs (20180626) + JsonParser parser((char*)jsonStr.c_str()); + JsonParserObject object_root = parser.getRootObject(); + if (object_root) { + for (auto key_level1 : object_root) { + JsonParserToken token_level1 = key_level1.getValue(); + if (token_level1.isObject()) { + JsonParserObject object_level1 = token_level1.getObject(); + for (auto key_level2 : object_level1) { + const char* value_level2 = key_level2.getValue().getStr(nullptr); + if (value_level2 != nullptr) { + if ((unit < sevensegs) && (sevenseg[unit] != nullptr)) { + if (strchr( value_level2, '.') == NULL) { + sevenseg[unit]->print(atoi(value_level2), DEC); + } else { + sevenseg[unit]->printFloat(atof(value_level2), 1, DEC); + } + sevenseg[unit]->writeDisplay(); + unit++; + } + } + } + } + } + } +} + +void SevensegDim(void) +{ + for (uint32_t i = 0; i < sevensegs; i++) { + sevenseg[i]->setBrightness(Settings.display_dimmer); + } +} + +void SevensegBlinkrate( void) +{ + for (uint32_t i = 0; i < sevensegs; i++) { + sevenseg[i]->blinkRate(XdrvMailbox.payload); + } +} + void SevensegClear(void) { for (uint32_t i = 0; i < sevensegs; i++) { @@ -352,6 +407,7 @@ void SevensegRefresh(void) // Every second case 4: // Mqtt case 3: // Local case 5: { // Mqtt + SevensegLog(); break; } } @@ -396,6 +452,13 @@ bool Xdsp11(uint8_t function) case FUNC_DISPLAY_DRAW_STRING: SevensegDrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag); break; + case FUNC_DISPLAY_DIM: + SevensegDim(); + break; + case FUNC_DISPLAY_BLINKRATE: + SevensegBlinkrate(); + break; + } } return result; From 30a5355526c1a35fb41f2f9ad3fb25913b6cfd0f Mon Sep 17 00:00:00 2001 From: jaapgvk <40623760+jaapgvk@users.noreply.github.com> Date: Fri, 1 Jan 2021 20:47:03 +0100 Subject: [PATCH 092/105] Delete xsns_15_mhz19.ino --- tasmota/xsns_15_mhz19.ino | 396 -------------------------------------- 1 file changed, 396 deletions(-) delete mode 100644 tasmota/xsns_15_mhz19.ino diff --git a/tasmota/xsns_15_mhz19.ino b/tasmota/xsns_15_mhz19.ino deleted file mode 100644 index 0444bce64..000000000 --- a/tasmota/xsns_15_mhz19.ino +++ /dev/null @@ -1,396 +0,0 @@ -/* - xsns_15_mhz19.ino - MH-Z19(B) CO2 sensor support for Tasmota - - Copyright (C) 2021 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 . -*/ - -#ifdef USE_MHZ19 -/*********************************************************************************************\ - * MH-Z19 - CO2 sensor - * - * Adapted from EspEasy plugin P049 by Dmitry (rel22 ___ inbox.ru) - * - * Hardware Serial will be selected if GPIO1 = [MHZ Rx] and GPIO3 = [MHZ Tx] - ********************************************************************************************** - * Filter usage - * - * Select filter usage on low stability readings -\*********************************************************************************************/ - -#define XSNS_15 15 - -enum MhzFilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FILTER_FAST, MHZ19_FILTER_MEDIUM, MHZ19_FILTER_SLOW}; - -#define MHZ19_FILTER_OPTION MHZ19_FILTER_FAST - -/*********************************************************************************************\ - * Source: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf - * - * Automatic Baseline Correction (ABC logic function) is enabled by default but may be disabled with command - * Sensor15 0 - * and enabled again with command - * Sensor15 1 - * - * ABC logic function refers to that sensor itself do zero point judgment and automatic calibration procedure - * intelligently after a continuous operation period. The automatic calibration cycle is every 24 hours after powered on. - * - * The zero point of automatic calibration is 400ppm. - * - * This function is usually suitable for indoor air quality monitor such as offices, schools and homes, - * not suitable for greenhouse, farm and refrigeratory where this function should be off. - * - * Please do zero calibration timely, such as manual or commend calibration. -\*********************************************************************************************/ - -#include - -#ifndef CO2_LOW -#define CO2_LOW 800 // Below this CO2 value show green light -#endif -#ifndef CO2_HIGH -#define CO2_HIGH 1200 // Above this CO2 value show red light -#endif - -#define MHZ19_READ_TIMEOUT 400 // Must be way less than 1000 but enough to read 9 bytes at 9600 bps -#define MHZ19_RETRY_COUNT 8 - -TasmotaSerial *MhzSerial; - -const char kMhzModels[] PROGMEM = "|B"; - -const char ABC_ENABLED[] = "ABC is Enabled"; -const char ABC_DISABLED[] = "ABC is Disabled"; - -enum MhzCommands { MHZ_CMND_READPPM, MHZ_CMND_ABCENABLE, MHZ_CMND_ABCDISABLE, MHZ_CMND_ZEROPOINT, MHZ_CMND_RESET, MHZ_CMND_RANGE_1000, MHZ_CMND_RANGE_2000, MHZ_CMND_RANGE_3000, MHZ_CMND_RANGE_5000 }; -const uint8_t kMhzCommands[][4] PROGMEM = { -// 2 3 6 7 - {0x86,0x00,0x00,0x00}, // mhz_cmnd_read_ppm - {0x79,0xA0,0x00,0x00}, // mhz_cmnd_abc_enable - {0x79,0x00,0x00,0x00}, // mhz_cmnd_abc_disable - {0x87,0x00,0x00,0x00}, // mhz_cmnd_zeropoint - {0x8D,0x00,0x00,0x00}, // mhz_cmnd_reset - {0x99,0x00,0x03,0xE8}, // mhz_cmnd_set_range_1000 - {0x99,0x00,0x07,0xD0}, // mhz_cmnd_set_range_2000 - {0x99,0x00,0x0B,0xB8}, // mhz_cmnd_set_range_3000 - {0x99,0x00,0x13,0x88}}; // mhz_cmnd_set_range_5000 - -uint8_t mhz_type = 1; -uint16_t mhz_last_ppm = 0; -uint8_t mhz_filter = MHZ19_FILTER_OPTION; -bool mhz_abc_must_apply = false; - -float mhz_temperature = 0; -uint8_t mhz_retry = MHZ19_RETRY_COUNT; -uint8_t mhz_received = 0; -uint8_t mhz_state = 0; - -/*********************************************************************************************/ - -uint8_t MhzCalculateChecksum(uint8_t *array) -{ - uint8_t checksum = 0; - for (uint32_t i = 1; i < 8; i++) { - checksum += array[i]; - } - checksum = 255 - checksum; - return (checksum +1); -} - -size_t MhzSendCmd(uint8_t command_id) -{ - uint8_t mhz_send[9] = { 0 }; - - mhz_send[0] = 0xFF; // Start byte, fixed - mhz_send[1] = 0x01; // Sensor number, 0x01 by default - memcpy_P(&mhz_send[2], kMhzCommands[command_id], sizeof(uint16_t)); -/* - mhz_send[4] = 0x00; - mhz_send[5] = 0x00; -*/ - memcpy_P(&mhz_send[6], kMhzCommands[command_id] + sizeof(uint16_t), sizeof(uint16_t)); - mhz_send[8] = MhzCalculateChecksum(mhz_send); - -// AddLog_P(LOG_LEVEL_DEBUG, PSTR("Final MhzCommand: %x %x %x %x %x %x %x %x %x"),mhz_send[0],mhz_send[1],mhz_send[2],mhz_send[3],mhz_send[4],mhz_send[5],mhz_send[6],mhz_send[7],mhz_send[8]); - - return MhzSerial->write(mhz_send, sizeof(mhz_send)); -} - -/*********************************************************************************************/ - -bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s) -{ - if (1 == s) { - return false; // S==1 => "A" version sensor bootup, do not use values. - } - if (mhz_last_ppm < 400 || mhz_last_ppm > 5000) { - // Prevent unrealistic values during start-up with filtering enabled. - // Just assume the entered value is correct. - mhz_last_ppm = ppm; - return true; - } - int32_t difference = ppm - mhz_last_ppm; - if (s > 0 && s < 64 && mhz_filter != MHZ19_FILTER_OFF) { - // Not the "B" version of the sensor, S value is used. - // S==0 => "B" version, else "A" version - // The S value is an indication of the stability of the reading. - // S == 64 represents a stable reading and any lower value indicates (unusual) fast change. - // Now we increase the delay filter for low values of S and increase response time when the - // value is more stable. - // This will make the reading useful in more turbulent environments, - // where the sensor would report more rapid change of measured values. - difference *= s; - difference /= 64; - } - if (MHZ19_FILTER_OFF == mhz_filter) { - if (s != 0 && s != 64) { - return false; - } - } else { - difference >>= (mhz_filter -1); - } - mhz_last_ppm = static_cast(mhz_last_ppm + difference); - return true; -} - -void MhzEverySecond(void) -{ - mhz_state++; - if (8 == mhz_state) { // Every 8 sec start a MH-Z19 measuring cycle (which takes 1005 +5% ms) - mhz_state = 0; - - if (mhz_retry) { - mhz_retry--; - if (!mhz_retry) { - mhz_last_ppm = 0; - mhz_temperature = 0; - } - } - - MhzSerial->flush(); // Sync reception - MhzSendCmd(MHZ_CMND_READPPM); - mhz_received = 0; - } - - if ((mhz_state > 2) && !mhz_received) { // Start reading response after 3 seconds every second until received - uint8_t mhz_response[9]; - - unsigned long start = millis(); - uint8_t counter = 0; - while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) { - if (MhzSerial->available() > 0) { - mhz_response[counter++] = MhzSerial->read(); - } else { - delay(5); - } - } - - AddLogBuffer(LOG_LEVEL_DEBUG_MORE, mhz_response, counter); - - if (counter < 9) { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout")); - return; - } - - uint8_t crc = MhzCalculateChecksum(mhz_response); - if (mhz_response[8] != crc) { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error")); - return; - } - if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response")); - return; - } - - mhz_received = 1; - - uint16_t u = (mhz_response[6] << 8) | mhz_response[7]; - if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000 - if (Settings.SensorBits1.mhz19b_abc_disable) { - // After bootup of the sensor the ABC will be enabled. - // Thus only actively disable after bootup. - mhz_abc_must_apply = true; - } - } else { - uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3]; - mhz_temperature = ConvertTemp((float)mhz_response[4] - 40); - uint8_t s = mhz_response[5]; - mhz_type = (s) ? 1 : 2; - if (MhzCheckAndApplyFilter(ppm, s)) { - mhz_retry = MHZ19_RETRY_COUNT; -#ifdef USE_LIGHT - LightSetSignal(CO2_LOW, CO2_HIGH, mhz_last_ppm); -#endif // USE_LIGHT - - if (0 == s || 64 == s) { // Reading is stable. - if (mhz_abc_must_apply) { - mhz_abc_must_apply = false; - if (!Settings.SensorBits1.mhz19b_abc_disable) { - MhzSendCmd(MHZ_CMND_ABCENABLE); - } else { - MhzSendCmd(MHZ_CMND_ABCDISABLE); - } - } - } - - } - } - - } -} - -/*********************************************************************************************\ - * Command Sensor15 - * - * 0 - ABC Off - * 1 - ABC On (Default) - * 2 - Manual start = ABC Off - * 3 - (Not implemented) Optional filter settings - * 9 - Reset - * 1000 - Range - * 2000 - Range - * 3000 - Range - * 5000 - Range -\*********************************************************************************************/ - -#define D_JSON_RANGE_1000 "1000 ppm range" -#define D_JSON_RANGE_2000 "2000 ppm range" -#define D_JSON_RANGE_3000 "3000 ppm range" -#define D_JSON_RANGE_5000 "5000 ppm range" - -bool MhzCommandSensor(void) -{ - bool serviced = true; - - switch (XdrvMailbox.payload) { - case 0: - Settings.SensorBits1.mhz19b_abc_disable = true; - MhzSendCmd(MHZ_CMND_ABCDISABLE); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED); - break; - case 1: - Settings.SensorBits1.mhz19b_abc_disable = false; - MhzSendCmd(MHZ_CMND_ABCENABLE); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED); - break; - case 2: - MhzSendCmd(MHZ_CMND_ZEROPOINT); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION); - break; - case 9: - MhzSendCmd(MHZ_CMND_RESET); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RESET); - break; - case 1000: - MhzSendCmd(MHZ_CMND_RANGE_1000); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_1000); - break; - case 2000: - MhzSendCmd(MHZ_CMND_RANGE_2000); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_2000); - break; - case 3000: - MhzSendCmd(MHZ_CMND_RANGE_3000); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_3000); - break; - case 5000: - MhzSendCmd(MHZ_CMND_RANGE_5000); - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_5000); - break; - default: - if (!Settings.SensorBits1.mhz19b_abc_disable) { - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED); - } else { - Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED); - } - } - - return serviced; -} - -/*********************************************************************************************/ - -void MhzInit(void) -{ - mhz_type = 0; - if (PinUsed(GPIO_MHZ_RXD) && PinUsed(GPIO_MHZ_TXD)) { - MhzSerial = new TasmotaSerial(Pin(GPIO_MHZ_RXD), Pin(GPIO_MHZ_TXD), 1); - if (MhzSerial->begin(9600)) { - if (MhzSerial->hardwareSerial()) { ClaimSerial(); } - mhz_type = 1; - } - - } -} - -void MhzShow(bool json) -{ - char types[7] = "MHZ19B"; // MHZ19B for legacy reasons. Prefered is MHZ19 - char temperature[33]; - dtostrfd(mhz_temperature, Settings.flag2.temperature_resolution, temperature); - char model[3]; - GetTextIndexed(model, sizeof(model), mhz_type -1, kMhzModels); - - if (json) { - ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_MODEL "\":\"%s\",\"" D_JSON_CO2 "\":%d,\"" D_JSON_TEMPERATURE "\":%s}"), types, model, mhz_last_ppm, temperature); -#ifdef USE_DOMOTICZ - if (0 == TasmotaGlobal.tele_period) { - DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm); - DomoticzSensor(DZ_TEMP, temperature); - } -#endif // USE_DOMOTICZ -#ifdef USE_WEBSERVER - } else { - WSContentSend_PD(HTTP_SNS_CO2, types, mhz_last_ppm); - WSContentSend_PD(HTTP_SNS_TEMP, types, temperature, TempUnit()); -#endif // USE_WEBSERVER - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xsns15(uint8_t function) -{ - bool result = false; - - if (mhz_type) { - switch (function) { - case FUNC_INIT: - MhzInit(); - break; - case FUNC_EVERY_SECOND: - MhzEverySecond(); - break; - case FUNC_COMMAND_SENSOR: - if (XSNS_15 == XdrvMailbox.index) { - result = MhzCommandSensor(); - } - break; - case FUNC_JSON_APPEND: - MhzShow(1); - break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - MhzShow(0); - break; -#endif // USE_WEBSERVER - } - } - return result; -} - -#endif // USE_MHZ19 From 2b12e995d38befcf05eada03f69b15ffdf301a6b Mon Sep 17 00:00:00 2001 From: jaapgvk <40623760+jaapgvk@users.noreply.github.com> Date: Fri, 1 Jan 2021 20:47:29 +0100 Subject: [PATCH 093/105] Add files via upload --- tasmota/xsns_15_mhz19.ino | 402 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 tasmota/xsns_15_mhz19.ino diff --git a/tasmota/xsns_15_mhz19.ino b/tasmota/xsns_15_mhz19.ino new file mode 100644 index 000000000..a2afb267f --- /dev/null +++ b/tasmota/xsns_15_mhz19.ino @@ -0,0 +1,402 @@ +/* + xsns_15_mhz19.ino - MH-Z19(B) CO2 sensor support for Tasmota + + Copyright (C) 2021 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 . +*/ + +#ifdef USE_MHZ19 +/*********************************************************************************************\ + * MH-Z19 - CO2 sensor + * + * Adapted from EspEasy plugin P049 by Dmitry (rel22 ___ inbox.ru) + * + * Hardware Serial will be selected if GPIO1 = [MHZ Rx] and GPIO3 = [MHZ Tx] + ********************************************************************************************** + * Filter usage + * + * Select filter usage on low stability readings +\*********************************************************************************************/ + +#define XSNS_15 15 + +enum MhzFilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FILTER_FAST, MHZ19_FILTER_MEDIUM, MHZ19_FILTER_SLOW}; + +#define MHZ19_FILTER_OPTION MHZ19_FILTER_FAST + +/*********************************************************************************************\ + * Source: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf + * + * Automatic Baseline Correction (ABC logic function) is enabled by default but may be disabled with command + * Sensor15 0 + * and enabled again with command + * Sensor15 1 + * + * ABC logic function refers to that sensor itself do zero point judgment and automatic calibration procedure + * intelligently after a continuous operation period. The automatic calibration cycle is every 24 hours after powered on. + * + * The zero point of automatic calibration is 400ppm. + * + * This function is usually suitable for indoor air quality monitor such as offices, schools and homes, + * not suitable for greenhouse, farm and refrigeratory where this function should be off. + * + * Please do zero calibration timely, such as manual or commend calibration. +\*********************************************************************************************/ + +#include + +#ifndef CO2_LOW +#define CO2_LOW 800 // Below this CO2 value show green light +#endif +#ifndef CO2_HIGH +#define CO2_HIGH 1200 // Above this CO2 value show red light +#endif + +#define MHZ19_READ_TIMEOUT 400 // Must be way less than 1000 but enough to read 9 bytes at 9600 bps +#define MHZ19_RETRY_COUNT 8 + +TasmotaSerial *MhzSerial; + +const char kMhzModels[] PROGMEM = "|B"; + +const char ABC_ENABLED[] = "ABC is Enabled"; +const char ABC_DISABLED[] = "ABC is Disabled"; + +enum MhzCommands { MHZ_CMND_READPPM, MHZ_CMND_ABCENABLE, MHZ_CMND_ABCDISABLE, MHZ_CMND_ZEROPOINT, MHZ_CMND_RESET, MHZ_CMND_RANGE_1000, MHZ_CMND_RANGE_2000, MHZ_CMND_RANGE_3000, MHZ_CMND_RANGE_5000, MHZ_CMND_RANGE_10000 }; +const uint8_t kMhzCommands[][4] PROGMEM = { +// 2 3 6 7 + {0x86,0x00,0x00,0x00}, // mhz_cmnd_read_ppm + {0x79,0xA0,0x00,0x00}, // mhz_cmnd_abc_enable + {0x79,0x00,0x00,0x00}, // mhz_cmnd_abc_disable + {0x87,0x00,0x00,0x00}, // mhz_cmnd_zeropoint + {0x8D,0x00,0x00,0x00}, // mhz_cmnd_reset + {0x99,0x00,0x03,0xE8}, // mhz_cmnd_set_range_1000 + {0x99,0x00,0x07,0xD0}, // mhz_cmnd_set_range_2000 + {0x99,0x00,0x0B,0xB8}, // mhz_cmnd_set_range_3000 + {0x99,0x00,0x13,0x88}, // mhz_cmnd_set_range_5000 + {0x99,0x00,0x27,0x10}}; // mhz_cmnd_set_range_10000 + +uint8_t mhz_type = 1; +uint16_t mhz_last_ppm = 0; +uint8_t mhz_filter = MHZ19_FILTER_OPTION; +bool mhz_abc_must_apply = false; + +float mhz_temperature = 0; +uint8_t mhz_retry = MHZ19_RETRY_COUNT; +uint8_t mhz_received = 0; +uint8_t mhz_state = 0; + +/*********************************************************************************************/ + +uint8_t MhzCalculateChecksum(uint8_t *array) +{ + uint8_t checksum = 0; + for (uint32_t i = 1; i < 8; i++) { + checksum += array[i]; + } + checksum = 255 - checksum; + return (checksum +1); +} + +size_t MhzSendCmd(uint8_t command_id) +{ + uint8_t mhz_send[9] = { 0 }; + + mhz_send[0] = 0xFF; // Start byte, fixed + mhz_send[1] = 0x01; // Sensor number, 0x01 by default + memcpy_P(&mhz_send[2], kMhzCommands[command_id], sizeof(uint16_t)); +/* + mhz_send[4] = 0x00; + mhz_send[5] = 0x00; +*/ + memcpy_P(&mhz_send[6], kMhzCommands[command_id] + sizeof(uint16_t), sizeof(uint16_t)); + mhz_send[8] = MhzCalculateChecksum(mhz_send); + +// AddLog_P(LOG_LEVEL_DEBUG, PSTR("Final MhzCommand: %x %x %x %x %x %x %x %x %x"),mhz_send[0],mhz_send[1],mhz_send[2],mhz_send[3],mhz_send[4],mhz_send[5],mhz_send[6],mhz_send[7],mhz_send[8]); + + return MhzSerial->write(mhz_send, sizeof(mhz_send)); +} + +/*********************************************************************************************/ + +bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s) +{ + if (1 == s) { + return false; // S==1 => "A" version sensor bootup, do not use values. + } + if (mhz_last_ppm < 400 || mhz_last_ppm > 10000) { + // Prevent unrealistic values during start-up with filtering enabled. + // Just assume the entered value is correct. + mhz_last_ppm = ppm; + return true; + } + int32_t difference = ppm - mhz_last_ppm; + if (s > 0 && s < 64 && mhz_filter != MHZ19_FILTER_OFF) { + // Not the "B" version of the sensor, S value is used. + // S==0 => "B" version, else "A" version + // The S value is an indication of the stability of the reading. + // S == 64 represents a stable reading and any lower value indicates (unusual) fast change. + // Now we increase the delay filter for low values of S and increase response time when the + // value is more stable. + // This will make the reading useful in more turbulent environments, + // where the sensor would report more rapid change of measured values. + difference *= s; + difference /= 64; + } + if (MHZ19_FILTER_OFF == mhz_filter) { + if (s != 0 && s != 64) { + return false; + } + } else { + difference >>= (mhz_filter -1); + } + mhz_last_ppm = static_cast(mhz_last_ppm + difference); + return true; +} + +void MhzEverySecond(void) +{ + mhz_state++; + if (8 == mhz_state) { // Every 8 sec start a MH-Z19 measuring cycle (which takes 1005 +5% ms) + mhz_state = 0; + + if (mhz_retry) { + mhz_retry--; + if (!mhz_retry) { + mhz_last_ppm = 0; + mhz_temperature = 0; + } + } + + MhzSerial->flush(); // Sync reception + MhzSendCmd(MHZ_CMND_READPPM); + mhz_received = 0; + } + + if ((mhz_state > 2) && !mhz_received) { // Start reading response after 3 seconds every second until received + uint8_t mhz_response[9]; + + unsigned long start = millis(); + uint8_t counter = 0; + while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) { + if (MhzSerial->available() > 0) { + mhz_response[counter++] = MhzSerial->read(); + } else { + delay(5); + } + } + + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, mhz_response, counter); + + if (counter < 9) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout")); + return; + } + + uint8_t crc = MhzCalculateChecksum(mhz_response); + if (mhz_response[8] != crc) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error")); + return; + } + if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response")); + return; + } + + mhz_received = 1; + + uint16_t u = (mhz_response[6] << 8) | mhz_response[7]; + if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000 + if (Settings.SensorBits1.mhz19b_abc_disable) { + // After bootup of the sensor the ABC will be enabled. + // Thus only actively disable after bootup. + mhz_abc_must_apply = true; + } + } else { + uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3]; + mhz_temperature = ConvertTemp((float)mhz_response[4] - 40); + uint8_t s = mhz_response[5]; + mhz_type = (s) ? 1 : 2; + if (MhzCheckAndApplyFilter(ppm, s)) { + mhz_retry = MHZ19_RETRY_COUNT; +#ifdef USE_LIGHT + LightSetSignal(CO2_LOW, CO2_HIGH, mhz_last_ppm); +#endif // USE_LIGHT + + if (0 == s || 64 == s) { // Reading is stable. + if (mhz_abc_must_apply) { + mhz_abc_must_apply = false; + if (!Settings.SensorBits1.mhz19b_abc_disable) { + MhzSendCmd(MHZ_CMND_ABCENABLE); + } else { + MhzSendCmd(MHZ_CMND_ABCDISABLE); + } + } + } + + } + } + + } +} + +/*********************************************************************************************\ + * Command Sensor15 + * + * 0 - ABC Off + * 1 - ABC On (Default) + * 2 - Manual start = ABC Off + * 3 - (Not implemented) Optional filter settings + * 9 - Reset + * 1000 - Range + * 2000 - Range + * 3000 - Range + * 5000 - Range +\*********************************************************************************************/ + +#define D_JSON_RANGE_1000 "1000 ppm range" +#define D_JSON_RANGE_2000 "2000 ppm range" +#define D_JSON_RANGE_3000 "3000 ppm range" +#define D_JSON_RANGE_5000 "5000 ppm range" +#define D_JSON_RANGE_10000 "10000 ppm range" + +bool MhzCommandSensor(void) +{ + bool serviced = true; + + switch (XdrvMailbox.payload) { + case 0: + Settings.SensorBits1.mhz19b_abc_disable = true; + MhzSendCmd(MHZ_CMND_ABCDISABLE); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED); + break; + case 1: + Settings.SensorBits1.mhz19b_abc_disable = false; + MhzSendCmd(MHZ_CMND_ABCENABLE); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED); + break; + case 2: + MhzSendCmd(MHZ_CMND_ZEROPOINT); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_ZERO_POINT_CALIBRATION); + break; + case 9: + MhzSendCmd(MHZ_CMND_RESET); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RESET); + break; + case 1000: + MhzSendCmd(MHZ_CMND_RANGE_1000); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_1000); + break; + case 2000: + MhzSendCmd(MHZ_CMND_RANGE_2000); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_2000); + break; + case 3000: + MhzSendCmd(MHZ_CMND_RANGE_3000); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_3000); + break; + case 5000: + MhzSendCmd(MHZ_CMND_RANGE_5000); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_5000); + break; + case 10000: + MhzSendCmd(MHZ_CMND_RANGE_10000); + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, D_JSON_RANGE_10000); + break; + default: + if (!Settings.SensorBits1.mhz19b_abc_disable) { + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_ENABLED); + } else { + Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_15, ABC_DISABLED); + } + } + + return serviced; +} + +/*********************************************************************************************/ + +void MhzInit(void) +{ + mhz_type = 0; + if (PinUsed(GPIO_MHZ_RXD) && PinUsed(GPIO_MHZ_TXD)) { + MhzSerial = new TasmotaSerial(Pin(GPIO_MHZ_RXD), Pin(GPIO_MHZ_TXD), 1); + if (MhzSerial->begin(9600)) { + if (MhzSerial->hardwareSerial()) { ClaimSerial(); } + mhz_type = 1; + } + + } +} + +void MhzShow(bool json) +{ + char types[7] = "MHZ19B"; // MHZ19B for legacy reasons. Prefered is MHZ19 + char temperature[33]; + dtostrfd(mhz_temperature, Settings.flag2.temperature_resolution, temperature); + char model[3]; + GetTextIndexed(model, sizeof(model), mhz_type -1, kMhzModels); + + if (json) { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_MODEL "\":\"%s\",\"" D_JSON_CO2 "\":%d,\"" D_JSON_TEMPERATURE "\":%s}"), types, model, mhz_last_ppm, temperature); +#ifdef USE_DOMOTICZ + if (0 == TasmotaGlobal.tele_period) { + DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm); + DomoticzSensor(DZ_TEMP, temperature); + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_CO2, types, mhz_last_ppm); + WSContentSend_PD(HTTP_SNS_TEMP, types, temperature, TempUnit()); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns15(uint8_t function) +{ + bool result = false; + + if (mhz_type) { + switch (function) { + case FUNC_INIT: + MhzInit(); + break; + case FUNC_EVERY_SECOND: + MhzEverySecond(); + break; + case FUNC_COMMAND_SENSOR: + if (XSNS_15 == XdrvMailbox.index) { + result = MhzCommandSensor(); + } + break; + case FUNC_JSON_APPEND: + MhzShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + MhzShow(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_MHZ19 From 9fdeac89249c6b2c9d0474f22785cb6c1789e5e8 Mon Sep 17 00:00:00 2001 From: Simon Hailes Date: Sat, 2 Jan 2021 09:02:11 +0000 Subject: [PATCH 094/105] update TasAutoMutex & use. Automatically initialise it. Add a name per instance. Add a default timeout of 40ticks - at which point it enters anyway and logs to serial the potential deadlock. --- tasmota/support.ino | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 7dd03d978..4845e8115 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -120,18 +120,23 @@ String GetResetReason(void) // automutex. // create a mute in your driver with: // void *mutex = nullptr; -// TasAutoMutex::init(&mutex); // // then protect any function with -// TasAutoMutex m(mutex); +// TasAutoMutex m(&mutex, "somename"); +// - mutex is automatically initialised if not already intialised. // - it will be automagically released when the function is over. // - the same thread can take multiple times (recursive). // - advanced options m.give() and m.take() allow you fine control within a function. +// - if take=false at creat, it will not be initially taken. +// - name is used in serial log of mutex deadlock. +// - maxWait in ticks is how long it will wait before failing in a deadlock scenario (and then emitting on serial) class TasAutoMutex { SemaphoreHandle_t mutex; bool taken; + int maxWait; + const char *name; public: - TasAutoMutex(void * mutex, bool take=true); + TasAutoMutex(void ** mutex, const char *name = "", int maxWait = 40, bool take=true); ~TasAutoMutex(); void give(); void take(); @@ -139,13 +144,20 @@ class TasAutoMutex { }; ////////////////////////////////////////// -TasAutoMutex::TasAutoMutex(void * mutex, bool take) { +TasAutoMutex::TasAutoMutex(void **mutex, const char *name, int maxWait, bool take) { if (mutex) { - if (take) { - xSemaphoreTakeRecursive(mutex, portMAX_DELAY); - this->taken = true; + if (!(*mutex)){ + TasAutoMutex::init(mutex); + } + this->mutex = (SemaphoreHandle_t)*mutex; + this->maxWait = maxWait; + this->name = name; + if (take) { + this->taken = xSemaphoreTakeRecursive(this->mutex, this->maxWait); + if (!this->taken){ + Serial.printf("\r\nMutexfail %s\r\n", this->name); + } } - this->mutex = (SemaphoreHandle_t)mutex; } else { this->mutex = (SemaphoreHandle_t)nullptr; } @@ -179,14 +191,17 @@ void TasAutoMutex::give() { void TasAutoMutex::take() { if (this->mutex) { if (!this->taken) { - xSemaphoreTakeRecursive(this->mutex, portMAX_DELAY); - this->taken = true; + this->taken = xSemaphoreTakeRecursive(this->mutex, this->maxWait); + if (!this->taken){ + Serial.printf("\r\nMutexfail %s\r\n", this->name); + } } } } #endif // ESP32 + /*********************************************************************************************\ * Miscellaneous \*********************************************************************************************/ @@ -2046,7 +2061,7 @@ bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) { #ifdef ESP32 // this takes the mutex, and will be release when the class is destroyed - // i.e. when the functon leaves You CAN call mutex.give() to leave early. - TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + TasAutoMutex mutex(&TasmotaGlobal.log_buffer_mutex); #endif // ESP32 // Skip initial buffer fill @@ -2067,7 +2082,7 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l #ifdef ESP32 // this takes the mutex, and will be release when the class is destroyed - // i.e. when the functon leaves You CAN call mutex.give() to leave early. - TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + TasAutoMutex mutex(&TasmotaGlobal.log_buffer_mutex); #endif // ESP32 if (!index) { // Dump all @@ -2110,12 +2125,9 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l void AddLogData(uint32_t loglevel, const char* log_data) { #ifdef ESP32 - if (!TasmotaGlobal.log_buffer_mutex) { - TasAutoMutex::init(&TasmotaGlobal.log_buffer_mutex); - } // this takes the mutex, and will be release when the class is destroyed - // i.e. when the functon leaves You CAN call mutex.give() to leave early. - TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); + TasAutoMutex mutex(&TasmotaGlobal.log_buffer_mutex); #endif // ESP32 char mxtime[14]; // "13:45:21.999 " From 78ce7b142d2d169927c6970dc32054ee116f8cf0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 2 Jan 2021 12:23:30 +0100 Subject: [PATCH 095/105] Tune log string stack usage --- tasmota/xdrv_09_timers.ino | 2 +- tasmota/xdrv_99_debug.ino | 8 +++---- tasmota/xsns_36_mgc3130.ino | 48 +++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index e2a66cfd0..c40045a31 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -880,7 +880,7 @@ void HandleTimerConfiguration(void) void TimerSaveSettings(void) { char tmp[MAX_TIMERS *12]; // Need space for MAX_TIMERS x 10 digit numbers separated by a comma - char message[LOGSZ]; + char message[32 + (MAX_TIMERS *11)]; // MQT: Timers 0,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 Timer timer; Settings.flag3.timers_enable = Webserver->hasArg("e0"); // CMND_TIMERS diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index c4aeda6e6..46bfa441e 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -258,7 +258,7 @@ void DebugRtcDump(char* parms) maxrow = srow + mrow; } - char log_data[LOGSZ]; + char log_data[100]; // 020: C7 2B 2E AB 70 E8 09 AE C8 88 3D EA 7C FF 48 2F | +. p = | H/| for (row = srow; row < maxrow; row++) { idx = row * CFG_COLS; snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx); @@ -310,7 +310,7 @@ void DebugDump(uint32_t start, uint32_t size) { maxrow = srow + mrow; } - char log_data[LOGSZ]; + char log_data[150]; // 020: C7 2B 2E AB 70 E8 09 AE C8 88 3D EA 7C FF 48 2F 0E A7 D7 BF 02 0E D7 7D C9 6F B9 3A 1D 01 3F 28 | +. p = | H/ } o : ?(| for (row = srow; row < maxrow; row++) { idx = row * CFG_COLS; snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx); @@ -361,7 +361,7 @@ void DebugCfgDump(char* parms) maxrow = srow + mrow; } - char log_data[LOGSZ]; + char log_data[100]; // 020: 6D 75 73 31 3A 38 30 2F 61 70 69 2F 61 72 64 75 |mus1:80/api/ardu| for (row = srow; row < maxrow; row++) { idx = row * CFG_COLS; snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), idx); @@ -397,7 +397,7 @@ void DebugCfgPeek(char* parms) uint16_t data16 = (buffer[address +1] << 8) + buffer[address]; uint32_t data32 = (buffer[address +3] << 24) + (buffer[address +2] << 16) + data16; - char log_data[LOGSZ]; + char log_data[100]; // 000: 09 12 00 10 | | 0x09 (9), 0x1209 (4617), 0x10001209 (268440073) snprintf_P(log_data, sizeof(log_data), PSTR("%03X:"), address); for (uint32_t i = 0; i < 4; i++) { snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, buffer[address +i]); diff --git a/tasmota/xsns_36_mgc3130.ino b/tasmota/xsns_36_mgc3130.ino index 6ab7ed4d4..c68714419 100644 --- a/tasmota/xsns_36_mgc3130.ino +++ b/tasmota/xsns_36_mgc3130.ino @@ -238,7 +238,6 @@ void MGC3130_sendMessage(uint8_t data[], uint8_t length){ void MGC3130_handleGesture(){ - //char log[LOGSZ]; char edge[5]; if (MGC_data.out.gestureInfo.edgeFlick){ snprintf_P(edge, sizeof(edge), PSTR("ED_")); @@ -248,141 +247,138 @@ void MGC3130_handleGesture(){ } switch(MGC_data.out.gestureInfo.gestureCode){ case MGC3130_GESTURE_GARBAGE: - //snprintf_P(log, sizeof(log), PSTR("NONE")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("NONE")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("NONE")); break; case MGC3130_FLICK_WEST_EAST: - //snprintf_P(log, sizeof(log), PSTR("%sFL_WE"), edge); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("%sFL_WE"), edge); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("%sFL_WE"), edge); break; case MGC3130_FLICK_EAST_WEST: - //snprintf_P(log, sizeof(log), PSTR("%sFL_EW"), edge); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("%sFL_EW"), edge); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("%sFL_EW"), edge); break; case MGC3130_FLICK_SOUTH_NORTH: - //snprintf_P(log, sizeof(log), PSTR("%sFL_SN"), edge); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("%sFL_SN"), edge); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("%sFL_SN"), edge); break; case MGC3130_FLICK_NORTH_SOUTH: - //snprintf_P(log, sizeof(log), PSTR("%sFL_NS"), edge); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("%sFL_NS"), edge); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("%sFL_NS"), edge); break; case MGC3130_CIRCLE_CLOCKWISE: - //snprintf_P(log, sizeof(log), PSTR("CW")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("CW")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("CW")); break; case MGC3130_CIRCLE_CCLOCKWISE: - //snprintf_P(log, sizeof(log), PSTR("CCW")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("CCW")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("CCW")); break; } - //AddLog_P(LOG_LEVEL_DEBUG, log); } bool MGC3130_handleTouch(){ - //char log[LOGSZ]; bool success = false; // if we find a touch of higher order, we are done if (MGC_data.out.touchInfo.doubleTapCentre && !success){ - //snprintf_P(log, sizeof(log), PSTR("DTAP_CENTRE")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("DTAP_CENTRE")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("DT_C")); MGC3130_touchTimeout = 5; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.doubleTapEast && !success){ - //snprintf_P(log, sizeof(log), PSTR("DTAP_EAST")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("DTAP_EAST")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("DT_E")); MGC3130_touchTimeout = 5; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.doubleTapNorth && !success){ - //snprintf_P(log, sizeof(log), PSTR("DTAP_NORTH")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("DTAP_NORTH")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("DT_N")); MGC3130_touchTimeout = 5; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.doubleTapWest && !success){ - //snprintf_P(log, sizeof(log), PSTR("DTAP_WEST")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("DTAP_WEST")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("DT_W")); MGC3130_touchTimeout = 5; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.doubleTapSouth && !success){ - //snprintf_P(log, sizeof(log), PSTR("DTAP_SOUTH")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("DTAP_SOUTH")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("DT_S")); MGC3130_touchTimeout = 5; success = true; MGC3130_touchCounter = 1; } if (MGC_data.out.touchInfo.tapCentre && !success){ - //snprintf_P(log, sizeof(log), PSTR("TAP_CENTRE")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TAP_CENTRE")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TP_C")); MGC3130_touchTimeout = 2; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.tapEast && !success){ - //snprintf_P(log, sizeof(log), PSTR("TAP_EAST")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TAP_EAST")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TP_E")); MGC3130_touchTimeout = 2; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.tapNorth && !success){ - //snprintf_P(log, sizeof(log), PSTR("TAP_NORTH")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TAP_NORTH")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TP_N")); MGC3130_touchTimeout = 2; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.tapWest && !success){ - //snprintf_P(log, sizeof(log), PSTR("TAP_WEST")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TAP_WEST")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TP_W")); MGC3130_touchTimeout = 2; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.tapSouth && !success){ - //snprintf_P(log, sizeof(log), PSTR("TAP_SOUTH")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TAP_SOUTH")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TP_S")); MGC3130_touchTimeout = 2; success = true; MGC3130_touchCounter = 1; } else if (MGC_data.out.touchInfo.touchCentre && !success){ - //snprintf_P(log, sizeof(log), PSTR("TOUCH_CENTRE")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TOUCH_CENTRE")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TH_C")); success = true; MGC3130_touchCounter++; // This will reset to 0 after touching for approx. 1h and 50 minutes ;) } else if (MGC_data.out.touchInfo.touchEast && !success){ - //snprintf_P(log, sizeof(log), PSTR("TOUCH_EAST")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TOUCH_EAST")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TH_E")); success = true; MGC3130_touchCounter++; } else if (MGC_data.out.touchInfo.touchNorth && !success){ - //snprintf_P(log, sizeof(log), PSTR("TOUCH_NORTH")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TOUCH_NORTH")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TH_N")); success = true; MGC3130_touchCounter++; } else if (MGC_data.out.touchInfo.touchWest && !success){ - //snprintf_P(log, sizeof(log), PSTR("TOUCH_WEST")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TOUCH_WEST")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TH_W")); success = true; MGC3130_touchCounter++; } else if (MGC_data.out.touchInfo.touchSouth && !success){ - //snprintf_P(log, sizeof(log), PSTR("TOUCH_SOUTH")); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("TOUCH_SOUTH")); snprintf_P(MGC3130_currentGesture, sizeof(MGC3130_currentGesture), PSTR("TH_S")); success = true; MGC3130_touchCounter++; } - //AddLog_P(LOG_LEVEL_DEBUG, log); return success; } From cb45eb52019a9aa4c80740f3eabd6eacaa0fd50b Mon Sep 17 00:00:00 2001 From: Jeroen Vermeulen - MageHost Date: Sat, 2 Jan 2021 13:26:18 +0100 Subject: [PATCH 096/105] fixes DisplayMode 1-5 support for ILI9342_2 driver --- tasmota/xdsp_13_ILI9341-2.ino | 84 ++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/tasmota/xdsp_13_ILI9341-2.ino b/tasmota/xdsp_13_ILI9341-2.ino index 48cd486f9..6095b5c53 100644 --- a/tasmota/xdsp_13_ILI9341-2.ino +++ b/tasmota/xdsp_13_ILI9341-2.ino @@ -95,8 +95,9 @@ void ILI9341_2_InitDriver() // Welcome text renderer->setTextFont(2); renderer->setTextColor(ILI9341_2_WHITE,ILI9341_2_BLACK); - renderer->DrawStringAt(30, 100, "ILI9341 TFT!", ILI9341_2_WHITE,0); + renderer->DrawStringAt(20, 140, "ILI9341 TFT!", ILI9341_2_RED,0); delay(1000); + renderer->clearDisplay(); #endif color_type = COLOR_COLOR; @@ -174,6 +175,77 @@ ili9342_ctouch_counter++; #endif // ESP32 +#ifdef USE_DISPLAY_MODES1TO5 + +void ILI9341_2_PrintLog(bool withDateTime) { + disp_refresh--; + if (!disp_refresh) { + disp_refresh = Settings.display_refresh; + if (!disp_screen_buffer_cols) { DisplayAllocScreenBuffer(); } + + char* txt = DisplayLogBuffer('\370'); + if (txt != NULL) { + uint8_t last_row = Settings.display_rows -1; + + renderer->clearDisplay(); /** TODO: Would be smoother without clear, like ILI9341_2_Time() does. **/ + renderer->setCursor(0,0); + + if (withDateTime) { + char line[21]; + snprintf_P(line, sizeof(line), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d %02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.hour, RtcTime.minute, RtcTime.second, RtcTime.day_of_month, RtcTime.month, RtcTime.year); // [12:34:56 31-12-2021] + renderer->setTextColor(ILI9341_2_BLUE); + renderer->println(line); + renderer->setTextColor(fg_color); + last_row--; + } + + for (byte i = 0; i < last_row; i++) { + strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); + renderer->println(disp_screen_buffer[i]); + } + strlcpy(disp_screen_buffer[last_row], txt, disp_screen_buffer_cols); + DisplayFillScreen(last_row); + + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "[%s]"), disp_screen_buffer[last_row]); + + renderer->println(disp_screen_buffer[last_row]); + renderer->Updateframe(); + } + } +} + +void ILI9341_2_Time(void) { + char line[12]; + /** TODO: DisplaySize is working, but renderer->println() does not respect DisplayFont **/ + snprintf_P(line, sizeof(line), PSTR(" %02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); // [ 12:34:56 ] + renderer->setCursor(60, 140); + renderer->println(line); + snprintf_P(line, sizeof(line), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); // [01-02-2018] + renderer->setCursor(60, 160); + renderer->println(line); + renderer->Updateframe(); +} + +void ILI9341_2_Refresh(void) { // Every second + if (Settings.display_mode) { // Mode 0 is User text + switch (Settings.display_mode) { + case 1: // Time + ILI9341_2_Time(); + break; + case 2: // Local + case 4: // Mqtt + ILI9341_2_PrintLog(false); + break; + case 3: // Local + Time + case 5: // Mqtt + Time + ILI9341_2_PrintLog(true); + break; + } + } +} + +#endif // USE_DISPLAY_MODES1TO5 + /*********************************************************************************************/ /*********************************************************************************************\ * Interface @@ -190,6 +262,11 @@ bool Xdsp13(uint8_t function) case FUNC_DISPLAY_MODEL: result = true; break; + case FUNC_DISPLAY_TEXT_SIZE: + case FUNC_DISPLAY_FONT_SIZE: + case DISPLAY_INIT_MODE: + renderer->clearDisplay(); + break; #ifdef USE_FT5206 #ifdef USE_TOUCH_BUTTONS case FUNC_DISPLAY_EVERY_50_MSECOND: @@ -199,6 +276,11 @@ bool Xdsp13(uint8_t function) break; #endif // USE_TOUCH_BUTTONS #endif // USE_FT5206 +#ifdef USE_DISPLAY_MODES1TO5 + case FUNC_DISPLAY_EVERY_SECOND: + ILI9341_2_Refresh(); + break; +#endif // USE_DISPLAY_MODES1TO5 } } return result; From 708d231c9cd80aff0ba977ac5f8396494835d809 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 2 Jan 2021 14:59:02 +0100 Subject: [PATCH 097/105] Reduce generic log buffer to 128 chars --- tasmota/support.ino | 33 ++++++++++++++++++++++++++------- tasmota/xdrv_02_mqtt.ino | 8 +++++--- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/tasmota/support.ino b/tasmota/support.ino index 4845e8115..78c7f93dc 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -147,7 +147,7 @@ class TasAutoMutex { TasAutoMutex::TasAutoMutex(void **mutex, const char *name, int maxWait, bool take) { if (mutex) { if (!(*mutex)){ - TasAutoMutex::init(mutex); + TasAutoMutex::init(mutex); } this->mutex = (SemaphoreHandle_t)*mutex; this->maxWait = maxWait; @@ -2172,12 +2172,22 @@ void AddLogData(uint32_t loglevel, const char* log_data) { void AddLog_P(uint32_t loglevel, PGM_P formatP, ...) { - char log_data[LOGSZ]; + char log_data[132]; va_list arg; va_start(arg, formatP); - vsnprintf_P(log_data, sizeof(log_data), formatP, arg); + uint32_t len = vsnprintf_P(log_data, 129, formatP, arg); va_end(arg); + if (len > 128) { strcat(log_data, "..."); } // Actual data is more + +#ifdef DEBUG_TASMOTA_CORE + // Profile max_len + static uint32_t max_len = 0; + if (len > max_len) { + max_len = len; + Serial.printf("PRF: AddLog_P %d\n", max_len); + } +#endif AddLogData(loglevel, log_data); } @@ -2188,9 +2198,18 @@ void AddLog_Debug(PGM_P formatP, ...) va_list arg; va_start(arg, formatP); - vsnprintf_P(log_data, sizeof(log_data), formatP, arg); + uint32_t len = vsnprintf_P(log_data, sizeof(log_data), formatP, arg); va_end(arg); +#ifdef DEBUG_TASMOTA_CORE + // Profile max_len + static uint32_t max_len = 0; + if (len > max_len) { + max_len = len; + Serial.printf("PRF: AddLog_Debug %d\n", max_len); + } +#endif + AddLogData(LOG_LEVEL_DEBUG, log_data); } @@ -2211,13 +2230,13 @@ void AddLogMissed(const char *sensor, uint32_t misses) } void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32_t size) { - char log_data[LOGSZ]; + char log_data[4 + (count * size * 3)]; snprintf_P(log_data, sizeof(log_data), PSTR("DMP:")); for (uint32_t i = 0; i < count; i++) { - if (1 == size) { // uint8_t + if (1 == size) { // uint8_t snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, *(buffer)); - } else { // uint16_t + } else { // uint16_t snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X%02X"), log_data, *(buffer +1), *(buffer)); } buffer += size; diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 81de886f4..471d55ff4 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -218,11 +218,13 @@ bool MqttPublishLib(const char* topic, bool retained) { return result; } +#ifdef DEBUG_TASMOTA_CORE void MqttDumpData(char* topic, char* data, uint32_t data_len) { char dump_data[data_len +1]; memcpy(dump_data, data, sizeof(dump_data)); // Make another copy for removing optional control characters - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_MQTT D_DATA_SIZE " %d, \"%s %s\""), data_len, topic, RemoveControlCharacter(dump_data)); + DEBUG_CORE_LOG(PSTR(D_LOG_MQTT "Size %d, \"%s %s\""), data_len, topic, RemoveControlCharacter(dump_data)); } +#endif void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len) { #ifdef USE_DEBUG_DRIVER @@ -248,9 +250,9 @@ void MqttDataHandler(char* mqtt_topic, uint8_t* mqtt_data, unsigned int data_len char data[data_len +1]; memcpy(data, mqtt_data, sizeof(data)); -// AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_MQTT D_DATA_SIZE " %d, \"%s %s\""), data_len, topic, data); -// if (LOG_LEVEL_DEBUG_MORE <= TasmotaGlobal.seriallog_level) { Serial.println(data); } +#ifdef DEBUG_TASMOTA_CORE MqttDumpData(topic, data, data_len); // Use a function to save stack space used by dump_data +#endif // MQTT pre-processing XdrvMailbox.index = strlen(topic); From 827a1e7764f0ab92eab6dd8b4de85e6d5220b957 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 2 Jan 2021 15:47:03 +0100 Subject: [PATCH 098/105] Refactor shutter logging --- tasmota/xdrv_27_shutter.ino | 81 +++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index ed6e72c57..cd54878d7 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -107,7 +107,7 @@ void ShutterLogPos(uint32_t i) { char stemp2[10]; dtostrfd((float)Shutter[i].time / STEPS_PER_SECOND, 2, stemp2); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d Real %d, Start %d, Stop %d, Dir %d, Delay %d, Rtc %s [s], Freq %d, PWM %d"), + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Real %d, Start %d, Stop %d, Dir %d, Delay %d, Rtc %s [s], Freq %d, PWM %d"), i+1, Shutter[i].real_position, Shutter[i].start_position, Shutter[i].target_position, Shutter[i].direction, Shutter[i].motordelay, stemp2, Shutter[i].pwm_velocity, Shutter[i].pwm_value); } @@ -144,7 +144,7 @@ void ShutterRtc50mS(void) case SHT_COUNTER: if (Shutter[i].accelerator) { - //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: accelerator i=%d -> %d"),i, Shutter[i].accelerator); + //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Accelerator i=%d -> %d"),i, Shutter[i].accelerator); ShutterUpdateVelocity(i); analogWriteFreq(Shutter[i].pwm_velocity); analogWrite(Pin(GPIO_PWM1, i), 50); @@ -173,15 +173,15 @@ int32_t ShutterPercentToRealPosition(int16_t percent, uint32_t index) for (uint32_t k = 0; k < 5; k++) { if ((percent * 10) >= Settings.shuttercoeff[k][index]) { realpos = SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[k+1], 100); - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realposition TEMP1: %d, %d %%, coeff %d"), realpos, percent, Settings.shuttercoeff[k][index]); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Realposition TEMP1: %d, %d %%, coeff %d"), realpos, percent, Settings.shuttercoeff[k][index]); } else { - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Shutter[%d].open_max: %d"),index, Shutter[index].open_max); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Shutter[%d].open_max: %d"),index, Shutter[index].open_max); if (0 == k) { realpos = SHT_DIV_ROUND((int64_t)percent * Shutter[index].open_max * calibrate_pos[k+1], Settings.shuttercoeff[k][index]*10 ); - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realposition TEMP3: %d, %d %%, coeff %d"), realpos, percent, Settings.shuttercoeff[k][index]); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Realposition TEMP3: %d, %d %%, coeff %d"), realpos, percent, Settings.shuttercoeff[k][index]); } else { //uint32_t addon = ( percent*10 - Settings.shuttercoeff[k-1][index] ) * Shutter[index].open_max * (calibrate_pos[k+1] - calibrate_pos[k]) / (Settings.shuttercoeff[k][index] -Settings.shuttercoeff[k-1][index]) / 100; - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realposition TEMP2: %d, %d %%, coeff %d"), addon, (calibrate_pos[k+1] - calibrate_pos[k]), (Settings.shuttercoeff[k][index] -Settings.shuttercoeff[k-1][index])); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Realposition TEMP2: %d, %d %%, coeff %d"), addon, (calibrate_pos[k+1] - calibrate_pos[k]), (Settings.shuttercoeff[k][index] -Settings.shuttercoeff[k-1][index])); realpos += SHT_DIV_ROUND(((int64_t)percent*10 - Settings.shuttercoeff[k-1][index] ) * Shutter[index].open_max * (calibrate_pos[k+1] - calibrate_pos[k]), (Settings.shuttercoeff[k][index] - Settings.shuttercoeff[k-1][index])*100); } break; @@ -200,15 +200,15 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index) for (uint32_t j = 0; j < 5; j++) { if (realpos >= Shutter[index].open_max * calibrate_pos[j+1] / 100) { realpercent = SHT_DIV_ROUND(Settings.shuttercoeff[j][index], 10); - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realpercent TEMP1: %d %%, %d, coeff %d"), realpercent, realpos, Shutter[index].open_max * calibrate_pos[j+1] / 100); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Realpercent TEMP1: %d %%, %d, coeff %d"), realpercent, realpos, Shutter[index].open_max * calibrate_pos[j+1] / 100); } else { - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Shutter[%d].open_max: %d"),index, Shutter[index].open_max); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Shutter[%d].open_max: %d"),index, Shutter[index].open_max); if (0 == j) { realpercent = SHT_DIV_ROUND(((int64_t)realpos - SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[j], 100)) * Settings.shuttercoeff[j][index], calibrate_pos[j+1]/10*Shutter[index].open_max); } else { //uint16_t addon = ( realpos - (Shutter[index].open_max * calibrate_pos[j] / 100) ) * 10 * (Settings.shuttercoeff[j][index] - Settings.shuttercoeff[j-1][index]) / (calibrate_pos[j+1] - calibrate_pos[j])/Shutter[index].open_max; //uint16_t addon = ( realpercent*10 - Settings.shuttercoeff[j-1][index] ) * Shutter[index].open_max * (calibrate_pos[j+1] - calibrate_pos[j]) / (Settings.shuttercoeff[j][index] -Settings.shuttercoeff[j-1][index]) / 100; - //AddLog_P(LOG_LEVEL_ERROR, PSTR("Realpercent TEMP2: %d %%, delta %d, %d, coeff %d"), addon,( realpos - (Shutter[index].open_max * calibrate_pos[j] / 100) ) , (calibrate_pos[j+1] - calibrate_pos[j])* Shutter[index].open_max/100, (Settings.shuttercoeff[j][index] -Settings.shuttercoeff[j-1][index])); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Realpercent TEMP2: %d %%, delta %d, %d, coeff %d"), addon,( realpos - (Shutter[index].open_max * calibrate_pos[j] / 100) ) , (calibrate_pos[j+1] - calibrate_pos[j])* Shutter[index].open_max/100, (Settings.shuttercoeff[j][index] -Settings.shuttercoeff[j-1][index])); realpercent += SHT_DIV_ROUND(((int64_t)realpos - SHT_DIV_ROUND(Shutter[index].open_max * calibrate_pos[j], 100)) * (Settings.shuttercoeff[j][index] - Settings.shuttercoeff[j-1][index]), (calibrate_pos[j+1] - calibrate_pos[j])/10*Shutter[index].open_max) ; } break; @@ -251,10 +251,10 @@ void ShutterInit(void) if (Settings.shutter_mode == SHT_UNDEF) { bool relay_in_interlock = false; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: mode undef.. calculate...")); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Mode undef.. calculate...")); for (uint32_t j = 0; j < MAX_INTERLOCKS * Settings.flag.interlock; j++) { // CMND_INTERLOCK - Enable/disable interlock - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Interlock state i=%d %d, flag %d, , shuttermask %d, maskedIL %d"),i, Settings.interlock[i], Settings.flag.interlock,ShutterGlobal.RelayShutterMask, Settings.interlock[i]&ShutterGlobal.RelayShutterMask); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Interlock state i=%d %d, flag %d, Shuttermask %d, MaskedIL %d"),i, Settings.interlock[i], Settings.flag.interlock,ShutterGlobal.RelayShutterMask, Settings.interlock[i]&ShutterGlobal.RelayShutterMask); if (Settings.interlock[j] && (Settings.interlock[j] & ShutterGlobal.RelayShutterMask)) { //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Relay in Interlock group")); relay_in_interlock = true; @@ -293,7 +293,7 @@ void ShutterInit(void) Settings.shuttercoeff[1][i] = Shutter[i].open_max/10 * (100 - Settings.shutter_set50percent[i] ) / 5000 ; Settings.shuttercoeff[0][i] = Shutter[i].open_max/100 - (Settings.shuttercoeff[1][i] * 10); Settings.shuttercoeff[2][i] = (int32_t)(Settings.shuttercoeff[0][i]*10 + 5 * Settings.shuttercoeff[1][i]) / 5; - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT%d: Shutter[i].open_max %d, 50perc:%d, 0:%d, 1:%d 2:%d"), i, Shutter[i].open_max, Settings.shutter_set50percent[i], Settings.shuttercoeff[0][i],Settings.shuttercoeff[1][i],Settings.shuttercoeff[2][i]); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Shutter[i].open_max %d, 50perc:%d, 0:%d, 1:%d 2:%d"), i, Shutter[i].open_max, Settings.shutter_set50percent[i], Settings.shuttercoeff[0][i],Settings.shuttercoeff[1][i],Settings.shuttercoeff[2][i]); } ShutterGlobal.RelayShutterMask |= 3 << (Settings.shutter_startrelay[i] -1); @@ -313,8 +313,8 @@ void ShutterInit(void) } Shutter[i].close_velocity_max = ShutterGlobal.open_velocity_max*Shutter[i].open_time / Shutter[i].close_time; - //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d Openvel %d, Closevel: %d"),i, ShutterGlobal.open_velocity_max, Shutter[i].close_velocity_max); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT%d: Init. Pos: %d,inverted %d, locked %d, end stop time enabled %d, webButtons inverted %d"), + //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Openvel %d, Closevel: %d"),i, ShutterGlobal.open_velocity_max, Shutter[i].close_velocity_max); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Init. Pos %d, Inverted %d, Locked %d, End stop time enabled %d, webButtons inverted %d"), i+1, Shutter[i].real_position, (Settings.shutter_options[i]&1) ? 1 : 0, (Settings.shutter_options[i]&2) ? 1 : 0, (Settings.shutter_options[i]&4) ? 1 : 0, (Settings.shutter_options[i]&8) ? 1 : 0); @@ -338,7 +338,7 @@ void ShutterReportPosition(bool always, uint32_t index) n = index+1; } for (i; i < n; i++) { - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Real Pos: %d"), i+1,Shutter[i].real_position); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Real Pos %d"), i+1,Shutter[i].real_position); uint32_t position = ShutterRealToPercentPosition(Shutter[i].real_position, i); if (Shutter[i].direction != 0) { TasmotaGlobal.rules_flag.shutter_moving = 1; @@ -352,7 +352,7 @@ void ShutterReportPosition(bool always, uint32_t index) if (always || (TasmotaGlobal.rules_flag.shutter_moving)) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); // RulesProcess() now re-entry protected } - //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: TasmotaGlobal.rules_flag.shutter_moving: %d, moved %d"), TasmotaGlobal.rules_flag.shutter_moving, TasmotaGlobal.rules_flag.shutter_moved); + //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), TasmotaGlobal.rules_flag.shutter_moving, TasmotaGlobal.rules_flag.shutter_moved); } void ShutterLimitRealAndTargetPositions(uint32_t i) { @@ -400,7 +400,7 @@ void ShutterDecellerateForStop(uint8_t i) int16_t missing_steps; Shutter[i].accelerator = -(ShutterGlobal.open_velocity_max / (Shutter[i].motordelay>4 ? (Shutter[i].motordelay*11)/10 : 4) ); while (Shutter[i].pwm_velocity > -2*Shutter[i].accelerator ) { - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: velocity: %ld, delta: %d"), Shutter[i].pwm_velocity, Shutter[i].accelerator ); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Velocity %ld, Delta %d"), Shutter[i].pwm_velocity, Shutter[i].accelerator ); //Shutter[i].pwm_velocity = tmax(Shutter[i].pwm_velocity-Shutter[i].accelerator , 0); // Control will be done in RTC Ticker. delay(50); @@ -408,7 +408,7 @@ void ShutterDecellerateForStop(uint8_t i) if (ShutterGlobal.position_mode == SHT_COUNTER){ missing_steps = ((Shutter[i].target_position-Shutter[i].start_position)*Shutter[i].direction*ShutterGlobal.open_velocity_max/RESOLUTION/STEPS_PER_SECOND) - RtcSettings.pulse_counter[i]; //prepare for stop PWM - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter[i].pwm_velocity); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d, Counter %d, Freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter[i].pwm_velocity); Shutter[i].accelerator = 0; Shutter[i].pwm_velocity = Shutter[i].pwm_velocity > 250 ? 250 : Shutter[i].pwm_velocity; analogWriteFreq(Shutter[i].pwm_velocity); @@ -420,7 +420,7 @@ void ShutterDecellerateForStop(uint8_t i) } analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog Shutter[i].real_position = ShutterCalculatePosition(i); - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter[i].real_position,RtcSettings.pulse_counter[i], Shutter[i].start_position); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, Pulsecount %d, Start %d"), Shutter[i].real_position,RtcSettings.pulse_counter[i], Shutter[i].start_position); } Shutter[i].direction = 0; @@ -481,9 +481,9 @@ void ShutterUpdatePosition(void) XdrvRulesProcess(); ShutterGlobal.start_reported = 1; } - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: time: %d, toBeAcc %d, current_stop_way %d,vel_cur %d, vel_max %d, act_vel_change %d, min_runtime_ms %d, act.pos %d, next_stop %d, target: %d, max_vel_change %d, dir: %d"),Shutter[i].time,toBeAcc,current_stop_way, - Shutter[i].pwm_velocity,velocity_max, Shutter[i].accelerator,min_runtime_ms,Shutter[i].real_position, next_possible_stop_position,Shutter[i].target_position,velocity_change_per_step_max,Shutter[i].direction); - + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Time %d, toBA %d, cStop %d, cVelo %d, mVelo %d, aVelo %d, mRun %d, aPos %d, nStop %d, Trgt %d, mVelo %d, Dir %d"), + Shutter[i].time, toBeAcc, current_stop_way, Shutter[i].pwm_velocity, velocity_max, Shutter[i].accelerator, min_runtime_ms, Shutter[i].real_position, + next_possible_stop_position, Shutter[i].target_position, velocity_change_per_step_max, Shutter[i].direction); if ( Shutter[i].real_position * Shutter[i].direction >= Shutter[i].target_position * Shutter[i].direction || Shutter[i].pwm_velocity> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_IGNORE != TasmotaGlobal.last_source && SRC_SHUTTER != TasmotaGlobal.last_source && SRC_PULSETIMER != TasmotaGlobal.last_source ; uint8 manual_relays_changed = ((ShutterGlobal.RelayCurrentMask >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_SHUTTER != TasmotaGlobal.last_source && SRC_PULSETIMER != TasmotaGlobal.last_source ; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, ShutterGlobal.RelayCurrentMask %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Source %s, Powerstate %ld, RelayMask %d, ManualChange %d"), + i+1, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed); if (manual_relays_changed) { //ShutterGlobal.skip_relay_change = true; ShutterLimitRealAndTargetPositions(i); @@ -613,7 +614,8 @@ void ShutterRelayChanged(void) if (Shutter[i].direction != 0 && powerstate_local) { Shutter[i].target_position = Shutter[i].real_position; powerstate_local = 0; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, ShutterGlobal.RelayCurrentMask %d, manual change %d"), i+1, Shutter[i].target_position, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Switch OFF motor. Target %ld, Source %s, Powerstate %ld, RelayMask %d, ManualChange %d"), + i+1, Shutter[i].target_position, GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource), powerstate_local,ShutterGlobal.RelayCurrentMask,manual_relays_changed); } break; default: @@ -635,7 +637,7 @@ void ShutterRelayChanged(void) ShutterStartInit(i, -1, 0); break; default: - //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor."),i); + //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Switch OFF motor."),i); Shutter[i].target_position = Shutter[i].real_position; } break; @@ -648,7 +650,7 @@ void ShutterRelayChanged(void) ShutterStartInit(i, -1, 0); break; default: - //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor."),i); + //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Switch OFF motor."),i); Shutter[i].target_position = Shutter[i].real_position; } break; @@ -656,7 +658,7 @@ void ShutterRelayChanged(void) switch (powerstate_local) { case 1: ShutterStartInit(i, Shutter[i].lastdirection*-1 , Shutter[i].lastdirection == 1 ? 0 : Shutter[i].open_max); - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d Garage. NewTarget %d"), i, Shutter[i].target_position); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d Garage. NewTarget %d"), i, Shutter[i].target_position); break; default: Shutter[i].target_position = Shutter[i].real_position; @@ -664,7 +666,7 @@ void ShutterRelayChanged(void) } // switch (ShutterGlobal.position_mode) - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Target: %ld, powerstatelocal %d"), i+1, Shutter[i].target_position, powerstate_local); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Target %ld, Powerstatelocal %d"), i+1, Shutter[i].target_position, powerstate_local); } // if (manual_relays_changed) } // for (uint32_t i = 0; i < TasmotaGlobal.shutters_present; i++) } @@ -755,15 +757,16 @@ void ShutterButtonHandler(void) // check for simultaneous shutter button press uint32 min_shutterbutton_press_counter = -1; // -1 == max(uint32) for (uint32_t i = 0; i < MAX_KEYS; i++) { - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Settings.shutter_button[i] %ld, shutter_index %d, Button.press_counter[i] %d, min_shutterbutton_press_counter %d, i %d"), Settings.shutter_button[i], shutter_index, Button.press_counter[i] , min_shutterbutton_press_counter, i); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: ShutterButton[i] %ld, ShutterIndex %d, ButtonPressCounter[i] %d, minShutterButtonPressCounter %d, i %d"), + Settings.shutter_button[i], shutter_index, Button.press_counter[i] , min_shutterbutton_press_counter, i); if ((button_index != i) && (Settings.shutter_button[i] & (1<<31)) && ((Settings.shutter_button[i] & 0x03) == shutter_index) && (i != button_index) && (Button.press_counter[i] < min_shutterbutton_press_counter)) { min_shutterbutton_press_counter = Button.press_counter[i]; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: min_shutterbutton_press_counter %d"), min_shutterbutton_press_counter); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: minShutterButtonPressCounter %d"), min_shutterbutton_press_counter); } } if (min_shutterbutton_press_counter == Button.press_counter[button_index]) { // simultaneous shutter button press detected - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: simultanous presss deteced")); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Simultanous press detected")); press_index = Button.press_counter[button_index]; for (uint32_t i = 0; i < MAX_KEYS; i++) if ((Settings.shutter_button[i] & (1<<31)) && ((Settings.shutter_button[i] & 0x03) != shutter_index)) @@ -810,7 +813,7 @@ void ShutterButtonHandler(void) if (Settings.shutter_startrelay[shutter_index] && Settings.shutter_startrelay[shutter_index] <9) { uint8_t pos_press_index = (buttonState == SHT_PRESSED_HOLD) ? 3 : (press_index-1); if (pos_press_index>3) pos_press_index=3; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: shutter %d, button %d = %d (single=1, double=2, tripple=3, hold=4)"), shutter_index+1, button_index+1, pos_press_index+1); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d, Button %d = %d (single=1, double=2, tripple=3, hold=4)"), shutter_index+1, button_index+1, pos_press_index+1); XdrvMailbox.index = shutter_index +1; TasmotaGlobal.last_source = SRC_BUTTON; XdrvMailbox.data_len = 0; @@ -828,7 +831,7 @@ void ShutterButtonHandler(void) CmndShutterStop(); } else { XdrvMailbox.payload = position = (position-1)<<1; - //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: shutter %d -> %d"), shutter_index+1, position); + //AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shtr%d -> %d"), shutter_index+1, position); if (102 == position) { XdrvMailbox.payload = XdrvMailbox.index; CmndShutterToggle(); @@ -1398,7 +1401,7 @@ void CmndShutterPwmRange(void) } Settings.shutter_pwmrange[i][XdrvMailbox.index -1] = field; } - AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT%d: Init1. pwmmin %d, pwmmax %d"), XdrvMailbox.index , Settings.shutter_pwmrange[0][XdrvMailbox.index -1], Settings.shutter_pwmrange[1][XdrvMailbox.index -1]); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shtr%d Init1. pwmmin %d, pwmmax %d"), XdrvMailbox.index , Settings.shutter_pwmrange[0][XdrvMailbox.index -1], Settings.shutter_pwmrange[1][XdrvMailbox.index -1]); ShutterInit(); ResponseCmndIdxChar(XdrvMailbox.data); } else { @@ -1431,7 +1434,7 @@ void CmndShutterCalibration(void) Settings.shutter_set50percent[XdrvMailbox.index -1] = 50; for (i = 0; i < 5; i++) { Settings.shuttercoeff[i][XdrvMailbox.index -1] = SHT_DIV_ROUND((uint32_t)messwerte[i] * 1000, messwerte[4]); - AddLog_P(LOG_LEVEL_DEBUG, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("SHT: Shuttercoeff %d, i %d, Value %d, MeasuredValue %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]); } ShutterInit(); ResponseCmndIdxChar(XdrvMailbox.data); @@ -1512,7 +1515,7 @@ bool Xdrv27(uint8_t function) char stemp1[10]; // extract the number of the relay that was switched and save for later in Update Position. ShutterGlobal.RelayCurrentMask = XdrvMailbox.index ^ ShutterGlobal.RelayOldMask; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay: %d by %s"), ShutterGlobal.RelayCurrentMask,GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource)); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay %d by %s"), ShutterGlobal.RelayCurrentMask,GetTextIndexed(stemp1, sizeof(stemp1), TasmotaGlobal.last_source, kCommandSource)); ShutterRelayChanged(); ShutterGlobal.RelayOldMask = XdrvMailbox.index; break; @@ -1525,10 +1528,10 @@ bool Xdrv27(uint8_t function) } ShutterGlobal.RelayCurrentMask >>= 1; } - //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: skip relay change: %d"),i+1); + //AddLog_P(LOG_LEVEL_ERROR, PSTR("SHT: Skip relay change %d"), i+1); result = true; ShutterGlobal.skip_relay_change = 0; - AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Skipping switch off relay %d"),i); + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Skipping switch off relay %d"), i); ExecuteCommandPowerShutter(i+1, 0, SRC_SHUTTER); } break; From 0ab125853aebfeb21fbe7552bb098a567f3bfd26 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 2 Jan 2021 16:06:05 +0100 Subject: [PATCH 099/105] Refactor DGR logging --- tasmota/support_device_groups.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino index 7e589e15e..e5b00cba2 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -423,7 +423,7 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de write_log: *log_ptr++ = 0; - AddLog_P(LOG_LEVEL_DEBUG_MORE, log_buffer); + AddLogData(LOG_LEVEL_DEBUG_MORE, log_buffer); // If this is a received status request message, then if the requestor didn't just ack our // previous full status update, send a full status update. From 2a7f4179b1d4653387f190a6c2baf144d552886c Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 2 Jan 2021 16:14:32 +0100 Subject: [PATCH 100/105] Odroid has 4Mb PSRAM --- platformio_tasmota_env32.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index bad0b800a..1d64e6650 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -41,7 +41,7 @@ extends = env:tasmota32 board = odroid_esp32 board_build.f_cpu = 240000000L board_build.partitions = esp32_partition_app1984k_ffat12M.csv -build_flags = ${common32.build_flags} -DFIRMWARE_ODROID_GO +build_flags = ${common32.build_flags} -DBOARD_HAS_PSRAM=true -DFIRMWARE_ODROID_GO lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display [env:tasmota32-minimal] From 83b00e64f84dfce7a42fa0c397f5b3112033b1c4 Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sat, 2 Jan 2021 16:16:07 +0100 Subject: [PATCH 101/105] add missing odroid go --- platformio_override_sample.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 3f76397af..eaaf59729 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -36,6 +36,7 @@ default_envs = ; tasmota32-ir ; tasmota32-ircustom ; tasmota32solo1 +; tasmota32-odroidgo [common] From 2b7d605696cdb9b90f06e6146e4f9d26072d88ad Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 2 Jan 2021 16:20:15 +0100 Subject: [PATCH 102/105] Changed maximum chars in AddLog_P logging Changed maximum chars in AddLog_P logging reduced from 700 to 128 (LOGSZ) to enhance stability --- CHANGELOG.md | 3 +++ tasmota/support.ino | 14 +++++++------- tasmota/support_command.ino | 6 +++--- tasmota/tasmota.h | 3 ++- tasmota/xdrv_01_webserver.ino | 2 +- tasmota/xdrv_02_mqtt.ino | 2 +- tasmota/xdrv_10_scripter.ino | 4 ++-- tasmota/xdrv_12_home_assistant.ino | 2 +- tasmota/xdrv_16_tuyamcu.ino | 2 +- 9 files changed, 21 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2844aa8d..649f15289 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ All notable changes to this project will be documented in this file. - Replaced SSD1351 GPIO selection from ``SPI CS`` by ``SSD1351 CS`` - Replaced RA8876 GPIO selection from ``SPI CS`` by ``RA8876 CS`` +### Changed +- Maximum chars in AddLog_P logging reduced from 700 to 128 (LOGSZ) to enhance stability + ## [9.2.0.1] 20201229 ### Added - Milliseconds to console output (#10152) diff --git a/tasmota/support.ino b/tasmota/support.ino index 78c7f93dc..8138e39d9 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -1321,7 +1321,7 @@ void DumpConvertTable(void) { ResponseAppend_P(PSTR(",")); } jsflg = true; - if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kGpioConvert) -1)) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (MAX_LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kGpioConvert) -1)) { ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; @@ -1336,7 +1336,7 @@ void DumpConvertTable(void) { ResponseAppend_P(PSTR(",")); } jsflg = true; - if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kAdcNiceList) -1)) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%d\""), i, data) > (MAX_LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kAdcNiceList) -1)) { ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; @@ -2065,7 +2065,7 @@ bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) { #endif // ESP32 // Skip initial buffer fill - if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - LOGSZ) { return false; } + if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - MAX_LOGSZ) { return false; } char* line; size_t len; @@ -2172,13 +2172,13 @@ void AddLogData(uint32_t loglevel, const char* log_data) { void AddLog_P(uint32_t loglevel, PGM_P formatP, ...) { - char log_data[132]; + char log_data[LOGSZ +4]; va_list arg; va_start(arg, formatP); - uint32_t len = vsnprintf_P(log_data, 129, formatP, arg); + uint32_t len = vsnprintf_P(log_data, LOGSZ +1, formatP, arg); va_end(arg); - if (len > 128) { strcat(log_data, "..."); } // Actual data is more + if (len > LOGSZ) { strcat(log_data, "..."); } // Actual data is more #ifdef DEBUG_TASMOTA_CORE // Profile max_len @@ -2194,7 +2194,7 @@ void AddLog_P(uint32_t loglevel, PGM_P formatP, ...) void AddLog_Debug(PGM_P formatP, ...) { - char log_data[LOGSZ]; + char log_data[MAX_LOGSZ]; va_list arg; va_start(arg, formatP); diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 59d3f3e41..047208824 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -1124,7 +1124,7 @@ void CmndModules(void) } jsflg = true; uint32_t j = i ? midx +1 : 0; - if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), j, AnyModuleName(midx).c_str()) > (LOGSZ - TOPSZ)) || (i == sizeof(kModuleNiceList))) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), j, AnyModuleName(midx).c_str()) > (MAX_LOGSZ - TOPSZ)) || (i == sizeof(kModuleNiceList))) { ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; @@ -1192,7 +1192,7 @@ void CmndGpio(void) sensor_names = kSensorNamesFixed; } char stemp1[TOPSZ]; - if ((ResponseAppend_P(PSTR("\"" D_CMND_GPIO "%d\":{\"%d\":\"%s%s\"}"), i, sensor_type, GetTextIndexed(stemp1, sizeof(stemp1), sensor_name_idx, sensor_names), sindex) > (LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(Settings.my_gp.io) -1)) { + if ((ResponseAppend_P(PSTR("\"" D_CMND_GPIO "%d\":{\"%d\":\"%s%s\"}"), i, sensor_type, GetTextIndexed(stemp1, sizeof(stemp1), sensor_name_idx, sensor_names), sindex) > (MAX_LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(Settings.my_gp.io) -1)) { ResponseJsonEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg2 = true; @@ -1227,7 +1227,7 @@ void ShowGpios(const uint16_t *NiceList, uint32_t size, uint32_t offset, uint32_ } jsflg = true; char stemp1[TOPSZ]; - if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), ridx, GetTextIndexed(stemp1, sizeof(stemp1), midx, kSensorNames)) > (LOGSZ - TOPSZ)) || (i == size -1)) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), ridx, GetTextIndexed(stemp1, sizeof(stemp1), midx, kSensorNames)) > (MAX_LOGSZ - TOPSZ)) || (i == size -1)) { ResponseJsonEndEnd(); MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index e01de2d3f..dddc43fc1 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -135,7 +135,8 @@ const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in seria const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32) const uint16_t CMDSZ = 24; // Max number of characters in command const uint16_t TOPSZ = 151; // Max number of characters in topic string -const uint16_t LOGSZ = 700; // Max number of characters in log +const uint16_t LOGSZ = 128; // Max number of characters in AddLog_P log +const uint16_t MAX_LOGSZ = 700; // Max number of characters in log const uint16_t MIN_MESSZ = 1040; // Min number of characters in MQTT message (1200 - TOPSZ - 9 header bytes) const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 56389ea9a..1fe064b08 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -1927,7 +1927,7 @@ void OtherSaveSettings(void) char tmp[300]; // Needs to hold complete ESP32 template of minimal 230 chars char webindex[5]; char friendlyname[TOPSZ]; - char message[LOGSZ]; + char message[MAX_LOGSZ]; WebGetArg("dn", tmp, sizeof(tmp)); SettingsUpdateText(SET_DEVICENAME, (!strlen(tmp)) ? "" : (!strcmp(tmp,"1")) ? SettingsText(SET_FRIENDLYNAME1) : tmp); diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 471d55ff4..d34b98b57 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -321,7 +321,7 @@ void MqttPublish(const char* topic, bool retained) { } } - char log_data[LOGSZ]; + char log_data[MAX_LOGSZ]; snprintf_P(log_data, sizeof(log_data), PSTR("%s%s = %s"), slog_type, (Settings.flag.mqtt_enabled) ? topic : strrchr(topic,'/')+1, TasmotaGlobal.mqtt_data); // SetOption3 - Enable MQTT if (strlen(log_data) >= (sizeof(log_data) - strlen(sretained) -1)) { log_data[sizeof(log_data) - strlen(sretained) -5] = '\0'; diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 93076f701..bf4b8887a 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -3696,7 +3696,7 @@ void toLogN(const char *cp, uint8_t len) { void toLogEOL(const char *s1,const char *str) { if (!str) return; uint8_t index = 0; - char log_data[LOGSZ]; + char log_data[MAX_LOGSZ]; char *cp = log_data; strcpy(cp, s1); cp += strlen(s1); @@ -5768,7 +5768,7 @@ void Script_Check_Hue(String *response) { Script_AddLog_P(LOG_LEVEL_DEBUG, PSTR("Hue: %d"), hue_devs); toLog(">>>>"); toLog(response->c_str()); - toLog(response->c_str()+LOGSZ); + toLog(response->c_str()+MAX_LOGSZ); } #endif } diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index e61ec7938..8ef33c91f 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -370,7 +370,7 @@ void TryResponseAppend_P(const char *format, ...) { AddLog_P(LOG_LEVEL_ERROR, PSTR("%s (%u/%u):"), kHAssError1, dlen, slen); va_start(args, format); - char log_data[LOGSZ]; + char log_data[MAX_LOGSZ]; vsnprintf_P(log_data, sizeof(log_data), format, args); AddLogData(LOG_LEVEL_ERROR, log_data); } diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index ba8766b98..278564047 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -404,7 +404,7 @@ void TuyaSendCmd(uint8_t cmd, uint8_t payload[] = nullptr, uint16_t payload_len TuyaSerial->write(cmd); // Tuya command TuyaSerial->write(payload_len >> 8); // following data length (Hi) TuyaSerial->write(payload_len & 0xFF); // following data length (Lo) - char log_data[LOGSZ]; + char log_data[MAX_LOGSZ]; snprintf_P(log_data, sizeof(log_data), PSTR("TYA: Send \"55aa00%02x%02x%02x"), cmd, payload_len >> 8, payload_len & 0xFF); for (uint32_t i = 0; i < payload_len; ++i) { TuyaSerial->write(payload[i]); From c9cce37c0a7be94196636130c3b5821980d96a3d Mon Sep 17 00:00:00 2001 From: Jimmy Wennlund Date: Sat, 2 Jan 2021 18:48:33 +0100 Subject: [PATCH 103/105] Add option to remove the device addr from json payload (#10355) * Add option to move ZbReceived from json into the subtopic of the MQTT message. This will make parsing simpler in homeassistant * Follow the setting naming conv. * Zigbee: Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic --- tasmota/settings.h | 4 ++-- tasmota/xdrv_23_zigbee_2a_devices_impl.ino | 27 +++++++++++++++------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/tasmota/settings.h b/tasmota/settings.h index 4842103b4..81a62c835 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -143,8 +143,8 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t mi32_enable : 1; // bit 1 (v9.1.0.1) - SetOption115 - (ESP32 BLE) Enable ESP32 MI32 BLE (1) uint32_t zb_disable_autoquery : 1; // bit 2 (v9.1.0.1) - SetOption116 - (Zigbee) Disable auto-query of zigbee lights and devices (1) uint32_t fade_fixed_duration : 1; // bit 3 (v9.1.0.2) - SetOption117 - (Light) run fading at fixed duration instead of fixed slew rate - uint32_t spare04 : 1; // bit 4 - uint32_t spare05 : 1; // bit 5 + uint32_t zb_received_as_subtopic : 1; // bit 4 (v9.2.0.3) - SetOption118 - (Zigbee) Move ZbReceived form JSON message and into the subtopic replacing "SENSOR" default + uint32_t zb_omit_json_addr : 1; // bit 5 (v9.2.0.3) - SetOption119 - (Zigbee) Remove the device addr from json payload, can be used with zb_topic_fname where the addr is already known from the topic uint32_t spare06 : 1; // bit 6 uint32_t spare07 : 1; // bit 7 uint32_t spare08 : 1; // bit 8 diff --git a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino index 0a97a9938..80a69441c 100644 --- a/tasmota/xdrv_23_zigbee_2a_devices_impl.ino +++ b/tasmota/xdrv_23_zigbee_2a_devices_impl.ino @@ -511,15 +511,19 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l TasmotaGlobal.mqtt_data[0] = 0; // clear string // Do we prefix with `ZbReceived`? - if (!Settings.flag4.remove_zbreceived) { + if (!Settings.flag4.remove_zbreceived && !Settings.flag5.zb_received_as_subtopic) { Response_P(PSTR("{\"%s\":"), json_prefix); } // What key do we use, shortaddr or name? - if (use_fname) { - Response_P(PSTR("%s{\"%s\":{"), TasmotaGlobal.mqtt_data, friendlyName); - } else { - Response_P(PSTR("%s{\"0x%04X\":{"), TasmotaGlobal.mqtt_data, shortaddr); + if (!Settings.flag5.zb_omit_json_addr) { + if (use_fname) { + Response_P(PSTR("%s{\"%s\":"), TasmotaGlobal.mqtt_data, friendlyName); + } else { + Response_P(PSTR("%s{\"0x%04X\":"), TasmotaGlobal.mqtt_data, shortaddr); + } } + ResponseAppend_P(PSTR("{")); + // Add "Device":"0x...." ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\","), shortaddr); // Add "Name":"xxx" if name is present @@ -527,9 +531,13 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l ResponseAppend_P(PSTR("\"" D_JSON_ZIGBEE_NAME "\":\"%s\","), EscapeJSONString(friendlyName).c_str()); } // Add all other attributes - ResponseAppend_P(PSTR("%s}}"), attr_list.toString(false).c_str()); + ResponseAppend_P(PSTR("%s}"), attr_list.toString(false).c_str()); - if (!Settings.flag4.remove_zbreceived) { + if (!Settings.flag5.zb_omit_json_addr) { + ResponseAppend_P(PSTR("}")); + } + + if (!Settings.flag4.remove_zbreceived && !Settings.flag5.zb_received_as_subtopic) { ResponseAppend_P(PSTR("}")); } @@ -545,7 +553,10 @@ void Z_Device::jsonPublishAttrList(const char * json_prefix, const Z_attribute_l snprintf_P(subtopic, sizeof(subtopic), PSTR("%s/%04X"), TasmotaGlobal.mqtt_topic, shortaddr); } char stopic[TOPSZ]; - GetTopic_P(stopic, TELE, subtopic, D_RSLT_SENSOR); + if (Settings.flag5.zb_received_as_subtopic) + GetTopic_P(stopic, TELE, subtopic, json_prefix); + else + GetTopic_P(stopic, TELE, subtopic, D_RSLT_SENSOR); MqttPublish(stopic, Settings.flag.mqtt_sensor_retain); } else { MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); From d0b426b5050f50ee73a5c60e2daf1c0547c5c1c7 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 2 Jan 2021 19:26:24 +0100 Subject: [PATCH 104/105] Disable `USE_LIGHT`` light support for ZBBridge (saves 17.6kb) --- CHANGELOG.md | 1 + tasmota/tasmota_configurations.h | 2 +- tasmota/xdrv_01_webserver.ino | 2 +- tasmota/xdrv_04_light.ino | 313 +--------------------------- tasmota/xdrv_04_light_utils.ino | 335 ++++++++++++++++++++++++++++++ tasmota/xdrv_10_scripter.ino | 4 +- tasmota/xdrv_20_hue.ino | 20 +- tasmota/xdrv_23_zigbee_3_hue.ino | 2 +- tasmota/xdrv_23_zigbee_A_impl.ino | 4 +- 9 files changed, 362 insertions(+), 321 deletions(-) create mode 100644 tasmota/xdrv_04_light_utils.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 649f15289..5bb01ac2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Basic support for ESP32 Odroid Go 16MB binary tasmota32-odroidgo.bin (#8630) - Command ``CTRange`` to specify the visible CT range the bulb is capable of (#10311) - Command ``VirtualCT`` to simulate or fine tune CT bulbs with 3,4,5 channels (#10311) +- Disable `USE_LIGHT`` light support for ZBBridge (saves 17.6kb) ### Breaking Changed - Replaced MFRC522 13.56MHz rfid card reader GPIO selection from ``SPI CS`` by ``RC522 CS`` diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 142045bab..87022257c 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -509,7 +509,7 @@ #undef USE_SONOFF_D1 // Disable support for Sonoff D1 Dimmer (+0k7 code) // -- Optional light modules ---------------------- -//#undef USE_LIGHT // Enable Dimmer/Light support +#undef USE_LIGHT // Disable Dimmer/Light support #undef USE_LIGHT_VIRTUAL_CT // Disable support for Virtual White Color Temperature (SO106) #undef USE_WS2812 // Disable WS2812 Led string using library NeoPixelBus (+5k code, +1k mem, 232 iram) - Disable by // #undef USE_MY92X1 // Disable support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 1fe064b08..3d57bdc95 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -947,7 +947,7 @@ void HandleRoot(void) char scolor[8]; snprintf_P(scolor, sizeof(scolor), PSTR("#%02X%02X%02X"), dcolor, dcolor, dcolor); // Saturation start color from Black to White uint8_t red, green, blue; - LightHsToRgb(hue, 255, &red, &green, &blue); + HsToRgb(hue, 255, &red, &green, &blue); snprintf_P(stemp, sizeof(stemp), PSTR("#%02X%02X%02X"), red, green, blue); // Saturation end color WSContentSend_P(HTTP_MSG_SLIDER_GRADIENT, // Saturation diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 5443a8a55..90d94ffb7 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -196,83 +196,6 @@ const vct_pivot_t CT_PIVOTS_RGB PROGMEM = { 255, 255, 255, 0, 0 }; const vct_pivot_t CT_PIVOTS_CWW PROGMEM = { 0, 0, 0, 255, 0 }; const vct_pivot_t CT_PIVOTS_WWW PROGMEM = { 0, 0, 0, 0, 255 }; -// New version of Gamma correction compute -// Instead of a table, we do a multi-linear approximation, which is close enough -// At low levels, the slope is a bit higher than actual gamma, to make changes smoother -// Internal resolution is 10 bits. - -typedef struct gamma_table_t { - uint16_t to_src; - uint16_t to_gamma; -} gamma_table_t; - -const gamma_table_t gamma_table[] = { // don't put in PROGMEM for performance reasons - { 1, 1 }, - { 4, 1 }, - { 209, 13 }, - { 312, 41 }, - { 457, 106 }, - { 626, 261 }, - { 762, 450 }, - { 895, 703 }, - { 1023, 1023 }, - { 0xFFFF, 0xFFFF } // fail-safe if out of range -}; - -// simplified Gamma table for Fade, cheating a little at low brightness -const gamma_table_t gamma_table_fast[] = { - { 384, 192 }, - { 768, 576 }, - { 1023, 1023 }, - { 0xFFFF, 0xFFFF } // fail-safe if out of range -}; - -// For reference, below are the computed gamma tables, via ledGamma() -// for 8 bits output: -// 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, -// 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, -// 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, -// 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, -// 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, -// 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, -// 25, 26, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 37, 38, -// 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, -// 54, 55, 56, 57, 58, 59, 60, 61, 61, 62, 63, 64, 65, 67, 68, 69, -// 71, 72, 73, 75, 76, 78, 79, 80, 82, 83, 85, 86, 87, 89, 90, 91, -// 93, 94, 95, 97, 98,100,101,102,104,105,107,108,109,111,112,114, -// 116,118,120,122,124,125,127,129,131,133,135,137,139,141,143,144, -// 146,148,150,152,154,156,158,160,162,164,166,168,170,171,173,175, -// 178,180,183,185,188,190,193,195,198,200,203,205,208,210,213,215, -// 218,220,223,225,228,230,233,235,238,240,243,245,248,250,253,255 -// -// and for 10 bits output: -// 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, -// 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, -// 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, -// 12, 12, 13, 13, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -// 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, -// 45, 47, 49, 50, 52, 54, 56, 58, 59, 61, 63, 65, 67, 68, 70, 72, -// 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 92, 93, 95, 97, 99, 101, -// 102, 104, 106, 110, 113, 117, 121, 124, 128, 132, 135, 139, 143, 146, 150, 154, -// 158, 162, 166, 169, 173, 177, 180, 184, 188, 191, 195, 199, 202, 206, 210, 213, -// 217, 221, 224, 228, 232, 235, 239, 243, 246, 250, 254, 257, 261, 267, 272, 278, -// 283, 289, 294, 300, 305, 311, 317, 322, 328, 333, 339, 344, 350, 356, 361, 367, -// 372, 378, 383, 389, 394, 400, 406, 411, 417, 422, 428, 433, 439, 444, 450, 458, -// 465, 473, 480, 488, 496, 503, 511, 518, 526, 534, 541, 549, 557, 564, 572, 579, -// 587, 595, 602, 610, 617, 627, 635, 642, 650, 657, 665, 673, 680, 688, 695, 703, -// 713, 723, 733, 743, 753, 763, 773, 783, 793, 803, 813, 823, 833, 843, 853, 863, -// 873, 883, 893, 903, 913, 923, 933, 943, 953, 963, 973, 983, 993,1003,1013,1023 -// -// Output for Dimmer 0..100 values -// 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, -// 10, 10, 11, 12, 12, 13, 15, 17, 21, 23, 26, 28, 31, 34, 37, -// 40, 43, 49, 52, 58, 61, 67, 70, 76, 79, 84, 90, 93, 99,102, -// 110,117,128,135,146,158,166,177,184,195,202,213,221,232,239, -// 250,261,272,289,300,317,328,344,356,372,389,400,417,428,444, -// 458,480,496,518,534,557,579,595,617,635,657,673,695,713,743, -// 773,793,823,843,873,893,923,943,973,993,1023 - struct LIGHT { uint32_t strip_timer_counter = 0; // Bars and Gradient power_t power = 0; // Power for each channel if SetOption68, or boolean if single light @@ -728,13 +651,6 @@ class LightStateClass { _r, _g, _b, _wc, _ww); #endif } - - // new version of RGB to HSB with only integer calculation - static void RgbToHsb(uint8_t r, uint8_t g, uint8_t b, uint16_t *r_hue, uint8_t *r_sat, uint8_t *r_bri); - static void HsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t *r_b); - static void RgbToXy(uint8_t i_r, uint8_t i_g, uint8_t i_b, float *r_x, float *r_y); - static void XyToRgb(float x, float y, uint8_t *rr, uint8_t *rg, uint8_t *rb); - }; @@ -742,167 +658,6 @@ class LightStateClass { * LightStateClass implementation \*********************************************************************************************/ -// new version with only integer computing -// brightness is not needed, it is controlled via Dimmer -void LightStateClass::RgbToHsb(uint8_t ir, uint8_t ig, uint8_t ib, uint16_t *r_hue, uint8_t *r_sat, uint8_t *r_bri) { - uint32_t r = ir; - uint32_t g = ig; - uint32_t b = ib; - uint32_t max = (r > g && r > b) ? r : (g > b) ? g : b; // 0..255 - uint32_t min = (r < g && r < b) ? r : (g < b) ? g : b; // 0..255 - uint32_t d = max - min; // 0..255 - - uint16_t hue = 0; // hue value in degrees ranges from 0 to 359 - uint8_t sat = 0; // 0..255 - uint8_t bri = max; // 0..255 - - if (d != 0) { - sat = changeUIntScale(d, 0, max, 0, 255); - if (r == max) { - hue = (g > b) ? changeUIntScale(g-b,0,d,0,60) : 360 - changeUIntScale(b-g,0,d,0,60); - } else if (g == max) { - hue = (b > r) ? 120 + changeUIntScale(b-r,0,d,0,60) : 120 - changeUIntScale(r-b,0,d,0,60); - } else { - hue = (r > g) ? 240 + changeUIntScale(r-g,0,d,0,60) : 240 - changeUIntScale(g-r,0,d,0,60); - } - hue = hue % 360; // 0..359 - } - - if (r_hue) *r_hue = hue; - if (r_sat) *r_sat = sat; - if (r_bri) *r_bri = bri; - //AddLog_P(LOG_LEVEL_DEBUG_MORE, "RgbToHsb rgb (%d %d %d) hsb (%d %d %d)", r, g, b, hue, sat, bri); -} - -void LightStateClass::HsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t *r_b) { - uint32_t r = 255; // default to white - uint32_t g = 255; - uint32_t b = 255; - // we take brightness at 100%, brightness should be set separately - hue = hue % 360; // normalize to 0..359 - - if (sat > 0) { - uint32_t i = hue / 60; // quadrant 0..5 - uint32_t f = hue % 60; // 0..59 - uint32_t q = 255 - changeUIntScale(f, 0, 60, 0, sat); // 0..59 - uint32_t p = 255 - sat; - uint32_t t = 255 - changeUIntScale(60 - f, 0, 60, 0, sat); - - switch (i) { - case 0: - //r = 255; - g = t; - b = p; - break; - case 1: - r = q; - //g = 255; - b = p; - break; - case 2: - r = p; - //g = 255; - b = t; - break; - case 3: - r = p; - g = q; - //b = 255; - break; - case 4: - r = t; - g = p; - //b = 255; - break; - default: - //r = 255; - g = p; - b = q; - break; - } - } - if (r_r) *r_r = r; - if (r_g) *r_g = g; - if (r_b) *r_b = b; -} - -#define POW FastPrecisePowf - -// -// Matrix 3x3 multiplied to a 3 vector, result in a 3 vector -// -void mat3x3(const float *mat33, const float *vec3, float *res3) { - for (uint32_t i = 0; i < 3; i++) { - const float * v = vec3; - *res3 = 0.0f; - for (uint32_t j = 0; j < 3; j++) { - *res3 += *mat33++ * *v++; - } - res3++; - } -} - -void LightStateClass::RgbToXy(uint8_t i_r, uint8_t i_g, uint8_t i_b, float *r_x, float *r_y) { - float x = 0.31271f; // default medium white - float y = 0.32902f; - - if (i_r + i_b + i_g > 0) { - float rgb[3] = { (float)i_r, (float)i_g, (float)i_b }; - // https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d - // Gamma correction - for (uint32_t i = 0; i < 3; i++) { - rgb[i] = rgb[i] / 255.0f; - rgb[i] = (rgb[i] > 0.04045f) ? POW((rgb[i] + 0.055f) / (1.0f + 0.055f), 2.4f) : (rgb[i] / 12.92f); - } - - // conversion to X, Y, Z - // Y is also the Luminance - float XYZ[3]; - static const float XYZ_factors[] = { 0.649926f, 0.103455f, 0.197109f, - 0.234327f, 0.743075f, 0.022598f, - 0.000000f, 0.053077f, 1.035763f }; - mat3x3(XYZ_factors, rgb, XYZ); - - float XYZ_sum = XYZ[0] + XYZ[1] + XYZ[2]; - x = XYZ[0] / XYZ_sum; - y = XYZ[1] / XYZ_sum; - // we keep the raw gamut, one nice thing could be to convert to a narrower gamut - } - if (r_x) *r_x = x; - if (r_y) *r_y = y; -} - -void LightStateClass::XyToRgb(float x, float y, uint8_t *rr, uint8_t *rg, uint8_t *rb) -{ - float XYZ[3], rgb[3]; - x = (x > 0.99f ? 0.99f : (x < 0.01f ? 0.01f : x)); - y = (y > 0.99f ? 0.99f : (y < 0.01f ? 0.01f : y)); - float z = 1.0f - x - y; - XYZ[0] = x / y; - XYZ[1] = 1.0f; - XYZ[2] = z / y; - - static const float rgb_factors[] = { 3.2406f, -1.5372f, -0.4986f, - -0.9689f, 1.8758f, 0.0415f, - 0.0557f, -0.2040f, 1.0570f }; - mat3x3(rgb_factors, XYZ, rgb); - float max = (rgb[0] > rgb[1] && rgb[0] > rgb[2]) ? rgb[0] : (rgb[1] > rgb[2]) ? rgb[1] : rgb[2]; - - for (uint32_t i = 0; i < 3; i++) { - rgb[i] = rgb[i] / max; // normalize to max == 1.0 - rgb[i] = (rgb[i] <= 0.0031308f) ? 12.92f * rgb[i] : 1.055f * POW(rgb[i], (1.0f / 2.4f)) - 0.055f; // gamma - } - - int32_t irgb[3]; - for (uint32_t i = 0; i < 3; i++) { - irgb[i] = rgb[i] * 255.0f + 0.5f; - } - - if (rr) { *rr = (irgb[0] > 255 ? 255: (irgb[0] < 0 ? 0 : irgb[0])); } - if (rg) { *rg = (irgb[1] > 255 ? 255: (irgb[1] < 0 ? 0 : irgb[1])); } - if (rb) { *rb = (irgb[2] > 255 ? 255: (irgb[2] < 0 ? 0 : irgb[2])); } -} - class LightControllerClass { private: LightStateClass *_state; @@ -1167,18 +922,6 @@ public: LightStateClass light_state = LightStateClass(); LightControllerClass light_controller = LightControllerClass(light_state); -/*********************************************************************************************\ - * Change scales from 8 bits to 10 bits and vice versa -\*********************************************************************************************/ -// 8 to 10 to 8 is guaranteed to give the same result -uint16_t change8to10(uint8_t v) { - return changeUIntScale(v, 0, 255, 0, 1023); -} -// change from 10 bits to 8 bits, but any non-zero input will be non-zero -uint8_t change10to8(uint16_t v) { - return (0 == v) ? 0 : changeUIntScale(v, 4, 1023, 1, 255); -} - /*********************************************************************************************\ * CT (White Color Temperature) \*********************************************************************************************/ @@ -1241,54 +984,6 @@ void setAlexaCTRange(void) { // depending on SetOption82, full or limited CT } } -/*********************************************************************************************\ - * Gamma correction -\*********************************************************************************************/ -// Calculate the gamma corrected value for LEDS -uint16_t ledGamma_internal(uint16_t v, const struct gamma_table_t *gt_ptr) { - uint16_t from_src = 0; - uint16_t from_gamma = 0; - - for (const gamma_table_t *gt = gt_ptr; ; gt++) { - uint16_t to_src = gt->to_src; - uint16_t to_gamma = gt->to_gamma; - if (v <= to_src) { - return changeUIntScale(v, from_src, to_src, from_gamma, to_gamma); - } - from_src = to_src; - from_gamma = to_gamma; - } -} -// Calculate the reverse gamma value for LEDS -uint16_t ledGammaReverse_internal(uint16_t vg, const struct gamma_table_t *gt_ptr) { - uint16_t from_src = 0; - uint16_t from_gamma = 0; - - for (const gamma_table_t *gt = gt_ptr; ; gt++) { - uint16_t to_src = gt->to_src; - uint16_t to_gamma = gt->to_gamma; - if (vg <= to_gamma) { - return changeUIntScale(vg, from_gamma, to_gamma, from_src, to_src); - } - from_src = to_src; - from_gamma = to_gamma; - } -} - -// 10 bits in, 10 bits out -uint16_t ledGamma10_10(uint16_t v) { - return ledGamma_internal(v, gamma_table); -} -// 10 bits resolution, 8 bits in -uint16_t ledGamma10(uint8_t v) { - return ledGamma10_10(change8to10(v)); -} - -// Legacy function -uint8_t ledGamma(uint8_t v) { - return change10to8(ledGamma10(v)); -} - /********************************************************************************************/ void LightPwmOffset(uint32_t offset) @@ -1513,10 +1208,6 @@ void LightGetXY(float *X, float *Y) { light_state.getXY(X, Y); } -void LightHsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t *r_b) { - light_state.HsToRgb(hue, sat, r_r, r_g, r_b); -} - // If SetOption68 is set, get the brightness for a specific device uint8_t LightGetBri(uint8_t device) { uint8_t bri = 254; // default value if relay @@ -2120,14 +1811,14 @@ bool isChannelCT(uint32_t channel) { // Calculate the Gamma correction, if any, for fading, using the fast Gamma curve (10 bits in+out) uint16_t fadeGamma(uint32_t channel, uint16_t v) { if (isChannelGammaCorrected(channel)) { - return ledGamma_internal(v, gamma_table_fast); + return ledGammaFast(v); } else { return v; } } uint16_t fadeGammaReverse(uint32_t channel, uint16_t vg) { if (isChannelGammaCorrected(channel)) { - return ledGammaReverse_internal(vg, gamma_table_fast); + return leddGammaReverseFast(vg); } else { return vg; } diff --git a/tasmota/xdrv_04_light_utils.ino b/tasmota/xdrv_04_light_utils.ino new file mode 100644 index 000000000..8ab379d62 --- /dev/null +++ b/tasmota/xdrv_04_light_utils.ino @@ -0,0 +1,335 @@ +/* + xdrv_04_light_utils.ino - Converter functions for lights + + 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 . +*/ + +// This file is compiled even if `USE_LIGHT` is not defined and provides +// general purpose converter fucntions + + +// New version of Gamma correction compute +// Instead of a table, we do a multi-linear approximation, which is close enough +// At low levels, the slope is a bit higher than actual gamma, to make changes smoother +// Internal resolution is 10 bits. + +typedef struct gamma_table_t { + uint16_t to_src; + uint16_t to_gamma; +} gamma_table_t; + +const gamma_table_t gamma_table[] = { // don't put in PROGMEM for performance reasons + { 1, 1 }, + { 4, 1 }, + { 209, 13 }, + { 312, 41 }, + { 457, 106 }, + { 626, 261 }, + { 762, 450 }, + { 895, 703 }, + { 1023, 1023 }, + { 0xFFFF, 0xFFFF } // fail-safe if out of range +}; + +// simplified Gamma table for Fade, cheating a little at low brightness +const gamma_table_t gamma_table_fast[] = { + { 384, 192 }, + { 768, 576 }, + { 1023, 1023 }, + { 0xFFFF, 0xFFFF } // fail-safe if out of range +}; + +// For reference, below are the computed gamma tables, via ledGamma() +// for 8 bits output: +// 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, +// 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, +// 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, +// 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, +// 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, +// 18, 19, 19, 20, 20, 21, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, +// 25, 26, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 37, 38, +// 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 51, 52, 53, +// 54, 55, 56, 57, 58, 59, 60, 61, 61, 62, 63, 64, 65, 67, 68, 69, +// 71, 72, 73, 75, 76, 78, 79, 80, 82, 83, 85, 86, 87, 89, 90, 91, +// 93, 94, 95, 97, 98,100,101,102,104,105,107,108,109,111,112,114, +// 116,118,120,122,124,125,127,129,131,133,135,137,139,141,143,144, +// 146,148,150,152,154,156,158,160,162,164,166,168,170,171,173,175, +// 178,180,183,185,188,190,193,195,198,200,203,205,208,210,213,215, +// 218,220,223,225,228,230,233,235,238,240,243,245,248,250,253,255 +// +// and for 10 bits output: +// 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, +// 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, +// 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, +// 12, 12, 13, 13, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, +// 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, +// 45, 47, 49, 50, 52, 54, 56, 58, 59, 61, 63, 65, 67, 68, 70, 72, +// 74, 76, 77, 79, 81, 83, 84, 86, 88, 90, 92, 93, 95, 97, 99, 101, +// 102, 104, 106, 110, 113, 117, 121, 124, 128, 132, 135, 139, 143, 146, 150, 154, +// 158, 162, 166, 169, 173, 177, 180, 184, 188, 191, 195, 199, 202, 206, 210, 213, +// 217, 221, 224, 228, 232, 235, 239, 243, 246, 250, 254, 257, 261, 267, 272, 278, +// 283, 289, 294, 300, 305, 311, 317, 322, 328, 333, 339, 344, 350, 356, 361, 367, +// 372, 378, 383, 389, 394, 400, 406, 411, 417, 422, 428, 433, 439, 444, 450, 458, +// 465, 473, 480, 488, 496, 503, 511, 518, 526, 534, 541, 549, 557, 564, 572, 579, +// 587, 595, 602, 610, 617, 627, 635, 642, 650, 657, 665, 673, 680, 688, 695, 703, +// 713, 723, 733, 743, 753, 763, 773, 783, 793, 803, 813, 823, 833, 843, 853, 863, +// 873, 883, 893, 903, 913, 923, 933, 943, 953, 963, 973, 983, 993,1003,1013,1023 +// +// Output for Dimmer 0..100 values +// 0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, +// 10, 10, 11, 12, 12, 13, 15, 17, 21, 23, 26, 28, 31, 34, 37, +// 40, 43, 49, 52, 58, 61, 67, 70, 76, 79, 84, 90, 93, 99,102, +// 110,117,128,135,146,158,166,177,184,195,202,213,221,232,239, +// 250,261,272,289,300,317,328,344,356,372,389,400,417,428,444, +// 458,480,496,518,534,557,579,595,617,635,657,673,695,713,743, +// 773,793,823,843,873,893,923,943,973,993,1023 + + +/*********************************************************************************************\ + * Color converters +\*********************************************************************************************/ + +// new version with only integer computing +// brightness is not needed, it is controlled via Dimmer +void RgbToHsb(uint8_t ir, uint8_t ig, uint8_t ib, uint16_t *r_hue, uint8_t *r_sat, uint8_t *r_bri) { + uint32_t r = ir; + uint32_t g = ig; + uint32_t b = ib; + uint32_t max = (r > g && r > b) ? r : (g > b) ? g : b; // 0..255 + uint32_t min = (r < g && r < b) ? r : (g < b) ? g : b; // 0..255 + uint32_t d = max - min; // 0..255 + + uint16_t hue = 0; // hue value in degrees ranges from 0 to 359 + uint8_t sat = 0; // 0..255 + uint8_t bri = max; // 0..255 + + if (d != 0) { + sat = changeUIntScale(d, 0, max, 0, 255); + if (r == max) { + hue = (g > b) ? changeUIntScale(g-b,0,d,0,60) : 360 - changeUIntScale(b-g,0,d,0,60); + } else if (g == max) { + hue = (b > r) ? 120 + changeUIntScale(b-r,0,d,0,60) : 120 - changeUIntScale(r-b,0,d,0,60); + } else { + hue = (r > g) ? 240 + changeUIntScale(r-g,0,d,0,60) : 240 - changeUIntScale(g-r,0,d,0,60); + } + hue = hue % 360; // 0..359 + } + + if (r_hue) *r_hue = hue; + if (r_sat) *r_sat = sat; + if (r_bri) *r_bri = bri; + //AddLog_P(LOG_LEVEL_DEBUG_MORE, "RgbToHsb rgb (%d %d %d) hsb (%d %d %d)", r, g, b, hue, sat, bri); +} + +void HsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t *r_b) { + uint32_t r = 255; // default to white + uint32_t g = 255; + uint32_t b = 255; + // we take brightness at 100%, brightness should be set separately + hue = hue % 360; // normalize to 0..359 + + if (sat > 0) { + uint32_t i = hue / 60; // quadrant 0..5 + uint32_t f = hue % 60; // 0..59 + uint32_t q = 255 - changeUIntScale(f, 0, 60, 0, sat); // 0..59 + uint32_t p = 255 - sat; + uint32_t t = 255 - changeUIntScale(60 - f, 0, 60, 0, sat); + + switch (i) { + case 0: + //r = 255; + g = t; + b = p; + break; + case 1: + r = q; + //g = 255; + b = p; + break; + case 2: + r = p; + //g = 255; + b = t; + break; + case 3: + r = p; + g = q; + //b = 255; + break; + case 4: + r = t; + g = p; + //b = 255; + break; + default: + //r = 255; + g = p; + b = q; + break; + } + } + if (r_r) *r_r = r; + if (r_g) *r_g = g; + if (r_b) *r_b = b; +} + +#define POW FastPrecisePowf + +// +// Matrix 3x3 multiplied to a 3 vector, result in a 3 vector +// +void mat3x3(const float *mat33, const float *vec3, float *res3) { + for (uint32_t i = 0; i < 3; i++) { + const float * v = vec3; + *res3 = 0.0f; + for (uint32_t j = 0; j < 3; j++) { + *res3 += *mat33++ * *v++; + } + res3++; + } +} + +void RgbToXy(uint8_t i_r, uint8_t i_g, uint8_t i_b, float *r_x, float *r_y) { + float x = 0.31271f; // default medium white + float y = 0.32902f; + + if (i_r + i_b + i_g > 0) { + float rgb[3] = { (float)i_r, (float)i_g, (float)i_b }; + // https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d + // Gamma correction + for (uint32_t i = 0; i < 3; i++) { + rgb[i] = rgb[i] / 255.0f; + rgb[i] = (rgb[i] > 0.04045f) ? POW((rgb[i] + 0.055f) / (1.0f + 0.055f), 2.4f) : (rgb[i] / 12.92f); + } + + // conversion to X, Y, Z + // Y is also the Luminance + float XYZ[3]; + static const float XYZ_factors[] = { 0.649926f, 0.103455f, 0.197109f, + 0.234327f, 0.743075f, 0.022598f, + 0.000000f, 0.053077f, 1.035763f }; + mat3x3(XYZ_factors, rgb, XYZ); + + float XYZ_sum = XYZ[0] + XYZ[1] + XYZ[2]; + x = XYZ[0] / XYZ_sum; + y = XYZ[1] / XYZ_sum; + // we keep the raw gamut, one nice thing could be to convert to a narrower gamut + } + if (r_x) *r_x = x; + if (r_y) *r_y = y; +} + +void XyToRgb(float x, float y, uint8_t *rr, uint8_t *rg, uint8_t *rb) +{ + float XYZ[3], rgb[3]; + x = (x > 0.99f ? 0.99f : (x < 0.01f ? 0.01f : x)); + y = (y > 0.99f ? 0.99f : (y < 0.01f ? 0.01f : y)); + float z = 1.0f - x - y; + XYZ[0] = x / y; + XYZ[1] = 1.0f; + XYZ[2] = z / y; + + static const float rgb_factors[] = { 3.2406f, -1.5372f, -0.4986f, + -0.9689f, 1.8758f, 0.0415f, + 0.0557f, -0.2040f, 1.0570f }; + mat3x3(rgb_factors, XYZ, rgb); + float max = (rgb[0] > rgb[1] && rgb[0] > rgb[2]) ? rgb[0] : (rgb[1] > rgb[2]) ? rgb[1] : rgb[2]; + + for (uint32_t i = 0; i < 3; i++) { + rgb[i] = rgb[i] / max; // normalize to max == 1.0 + rgb[i] = (rgb[i] <= 0.0031308f) ? 12.92f * rgb[i] : 1.055f * POW(rgb[i], (1.0f / 2.4f)) - 0.055f; // gamma + } + + int32_t irgb[3]; + for (uint32_t i = 0; i < 3; i++) { + irgb[i] = rgb[i] * 255.0f + 0.5f; + } + + if (rr) { *rr = (irgb[0] > 255 ? 255: (irgb[0] < 0 ? 0 : irgb[0])); } + if (rg) { *rg = (irgb[1] > 255 ? 255: (irgb[1] < 0 ? 0 : irgb[1])); } + if (rb) { *rb = (irgb[2] > 255 ? 255: (irgb[2] < 0 ? 0 : irgb[2])); } +} + +/*********************************************************************************************\ + * Change scales from 8 bits to 10 bits and vice versa +\*********************************************************************************************/ +// 8 to 10 to 8 is guaranteed to give the same result +uint16_t change8to10(uint8_t v) { + return changeUIntScale(v, 0, 255, 0, 1023); +} +// change from 10 bits to 8 bits, but any non-zero input will be non-zero +uint8_t change10to8(uint16_t v) { + return (0 == v) ? 0 : changeUIntScale(v, 4, 1023, 1, 255); +} + +/*********************************************************************************************\ + * Gamma correction +\*********************************************************************************************/ +// Calculate the gamma corrected value for LEDS +uint16_t ledGamma_internal(uint16_t v, const struct gamma_table_t *gt_ptr) { + uint16_t from_src = 0; + uint16_t from_gamma = 0; + + for (const gamma_table_t *gt = gt_ptr; ; gt++) { + uint16_t to_src = gt->to_src; + uint16_t to_gamma = gt->to_gamma; + if (v <= to_src) { + return changeUIntScale(v, from_src, to_src, from_gamma, to_gamma); + } + from_src = to_src; + from_gamma = to_gamma; + } +} +// Calculate the reverse gamma value for LEDS +uint16_t ledGammaReverse_internal(uint16_t vg, const struct gamma_table_t *gt_ptr) { + uint16_t from_src = 0; + uint16_t from_gamma = 0; + + for (const gamma_table_t *gt = gt_ptr; ; gt++) { + uint16_t to_src = gt->to_src; + uint16_t to_gamma = gt->to_gamma; + if (vg <= to_gamma) { + return changeUIntScale(vg, from_gamma, to_gamma, from_src, to_src); + } + from_src = to_src; + from_gamma = to_gamma; + } +} + +// 10 bits in, 10 bits out +uint16_t ledGamma10_10(uint16_t v) { + return ledGamma_internal(v, gamma_table); +} + +// 10 bits resolution, 8 bits in +uint16_t ledGamma10(uint8_t v) { + return ledGamma10_10(change8to10(v)); +} + +// Legacy function +uint8_t ledGamma(uint8_t v) { + return change10to8(ledGamma10(v)); +} + +// Fast versions for Fading +uint16_t ledGammaFast(uint16_t v) { + return ledGamma_internal(v, gamma_table_fast); +} + +uint16_t leddGammaReverseFast(uint16_t vg) { + return ledGammaReverse_internal(vg, gamma_table_fast); +} \ No newline at end of file diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index bf4b8887a..44c4e2b21 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -5848,8 +5848,8 @@ void Script_Handle_Hue(String *path) { String x_str = tok_x.getStr(); String y_str = tok_y.getStr(); uint8_t rr,gg,bb; - LightStateClass::XyToRgb(x, y, &rr, &gg, &bb); - LightStateClass::RgbToHsb(rr, gg, bb, &hue, &sat, nullptr); + XyToRgb(x, y, &rr, &gg, &bb); + RgbToHsb(rr, gg, bb, &hue, &sat, nullptr); if (resp) { response += ","; } response += FPSTR(sHUE_LIGHT_RESPONSE_JSON); response.replace("{id", String(device)); diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index b0a18d16a..93252af12 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -17,7 +17,7 @@ along with this program. If not, see . */ -#if defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT) +#if defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && (defined(USE_ZIGBEE) || defined(USE_LIGHT)) /*********************************************************************************************\ * Philips Hue bridge emulation * @@ -303,6 +303,7 @@ uint16_t prev_ct = 254; char prev_x_str[24] = "\0"; // store previously set xy by Alexa app char prev_y_str[24] = "\0"; +#ifdef USE_LIGHT uint8_t getLocalLightSubtype(uint8_t device) { if (TasmotaGlobal.light_type) { if (device >= Light.device) { @@ -422,6 +423,7 @@ void HueLightStatus2(uint8_t device, String *response) *response += buf; free(buf); } +#endif // USE_LIGHT // generate a unique lightId mixing local IP address and device number // it is limited to 32 devices. @@ -496,7 +498,9 @@ void HueGlobalConfig(String *path) { path->remove(0,1); // cut leading / to get response = F("{\"lights\":{"); bool appending = false; // do we need to add a comma to append +#ifdef USE_LIGHT CheckHue(&response, appending); +#endif // USE_LIGHT #ifdef USE_ZIGBEE ZigbeeCheckHue(&response, appending); #endif // USE_ZIGBEE @@ -515,6 +519,7 @@ void HueAuthentication(String *path) AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Authentication Result (%s)"), response); } +#ifdef USE_LIGHT // refactored to remove code duplicates void CheckHue(String * response, bool &appending) { uint8_t maxhue = (TasmotaGlobal.devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : TasmotaGlobal.devices_present; @@ -621,8 +626,8 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { strlcpy(prev_x_str, tok_x.getStr(), sizeof(prev_x_str)); strlcpy(prev_y_str, tok_y.getStr(), sizeof(prev_y_str)); uint8_t rr,gg,bb; - LightStateClass::XyToRgb(x, y, &rr, &gg, &bb); - LightStateClass::RgbToHsb(rr, gg, bb, &hue, &sat, nullptr); + XyToRgb(x, y, &rr, &gg, &bb); + RgbToHsb(rr, gg, bb, &hue, &sat, nullptr); prev_hue = changeUIntScale(hue, 0, 360, 0, 65535); // calculate back prev_hue prev_sat = (sat > 254 ? 254 : sat); //AddLog_P(LOG_LEVEL_DEBUG_MORE, "XY RGB (%d %d %d) HS (%d %d)", rr,gg,bb,hue,sat); @@ -728,6 +733,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { } free(buf); } +#endif // USE_LIGHT void HueLights(String *path) { @@ -744,7 +750,9 @@ void HueLights(String *path) if (path->endsWith(F("/lights"))) { // Got /lights response = "{"; bool appending = false; +#ifdef USE_LIGHT CheckHue(&response, appending); +#endif // USE_LIGHT #ifdef USE_ZIGBEE ZigbeeCheckHue(&response, appending); #endif // USE_ZIGBEE @@ -771,9 +779,11 @@ void HueLights(String *path) return Script_Handle_Hue(path); } #endif +#ifdef USE_LIGHT if ((device >= 1) || (device <= maxhue)) { HueLightsCommand(device, device_id, response); } +#endif // USE_LIGHT } else if(path->indexOf(F("/lights/")) >= 0) { // Got /lights/ID @@ -797,12 +807,14 @@ void HueLights(String *path) } #endif +#ifdef USE_LIGHT if ((device < 1) || (device > maxhue)) { device = 1; } response += F("{\"state\":"); HueLightStatus1(device, &response); HueLightStatus2(device, &response); +#endif // USE_LIGHT } else { response = "{}"; @@ -835,7 +847,9 @@ void HueGroups(String *path) ZigbeeHueGroups(&response); #endif // USE_ZIGBEE response.replace("{l1", lights); +#ifdef USE_LIGHT HueLightStatus1(1, &response); +#endif // USE_LIGHT response += F("}"); } diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index 100faef9c..cc77d2314 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -18,7 +18,7 @@ */ #ifdef USE_ZIGBEE -#if defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT) +#if defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) // Add global functions for Hue Emulation diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 799274dd0..9bdf84175 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -2048,11 +2048,11 @@ void ZigbeeShow(bool json) if (light.validHue() && light.validSat() && (channels >= 3)) { uint8_t r,g,b; uint8_t sat = changeUIntScale(light.getSat(), 0, 254, 0, 255); // scale to 0..255 - LightStateClass::HsToRgb(light.getHue(), sat, &r, &g, &b); + HsToRgb(light.getHue(), sat, &r, &g, &b); WSContentSend_P(msg[ZB_WEB_COLOR_RGB], r,g,b,r,g,b); } else if (light.validX() && light.validY() && (channels >= 3)) { uint8_t r,g,b; - LightStateClass::XyToRgb(light.getX() / 65535.0f, light.getY() / 65535.0f, &r, &g, &b); + XyToRgb(light.getX() / 65535.0f, light.getY() / 65535.0f, &r, &g, &b); WSContentSend_P(msg[ZB_WEB_COLOR_RGB], r,g,b,r,g,b); } } From 76ff052ec6be3d7e930786862e7dd3668fdd3774 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 2 Jan 2021 23:11:09 +0100 Subject: [PATCH 105/105] Quick Fix Display watchdogs --- .../Adafruit_SPITFT_Renderer.cpp | 2217 ----------------- .../Adafruit_SPITFT_Renderer.h | 520 ---- .../Adafruit_SSD1331.cpp | 190 -- .../Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h | 76 - .../Adafruit_SSD1331-1.2.0/README.md | 24 - .../Adafruit_SSD1331-1.2.0/library.properties | 10 - .../Adafruit_SSD1331-1.2.0/license.txt | 26 - 7 files changed, 3063 deletions(-) delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/README.md delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties delete mode 100644 lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp deleted file mode 100644 index d49141a28..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.cpp +++ /dev/null @@ -1,2217 +0,0 @@ -/*! - * @file Adafruit_SPITFT.cpp - * - * @mainpage Adafruit SPI TFT Displays (and some others) - * - * @section intro_sec Introduction - * - * Part of Adafruit's GFX graphics library. Originally this class was - * written to handle a range of color TFT displays connected via SPI, - * but over time this library and some display-specific subclasses have - * mutated to include some color OLEDs as well as parallel-interfaced - * displays. The name's been kept for the sake of older code. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - - * @section dependencies Dependencies - * - * This library depends on - * Adafruit_GFX being present on your system. Please make sure you have - * installed the latest version before using this library. - * - * @section author Author - * - * Written by Limor "ladyada" Fried for Adafruit Industries, - * with contributions from the open source community. - * - * @section license License - * - * BSD license, all text here must be included in any redistribution. - */ - -#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all - -#include "Adafruit_SPITFT_Renderer.h" - -#if defined(__AVR__) -#if defined(__AVR_XMEGA__) //only tested with __AVR_ATmega4809__ -#define AVR_WRITESPI(x) for(SPI0_DATA = (x); (!(SPI0_INTFLAGS & _BV(SPI_IF_bp))); ) -#else -#define AVR_WRITESPI(x) for(SPDR = (x); (!(SPSR & _BV(SPIF))); ) -#endif -#endif - -#if defined(PORT_IOBUS) -// On SAMD21, redefine digitalPinToPort() to use the slightly-faster -// PORT_IOBUS rather than PORT (not needed on SAMD51). -#undef digitalPinToPort -#define digitalPinToPort(P) (&(PORT_IOBUS->Group[g_APinDescription[P].ulPort])) -#endif // end PORT_IOBUS - -#if defined(USE_SPI_DMA) - #include - #include "wiring_private.h" // pinPeripheral() function - #include // memalign() function - #define tcNum 2 // Timer/Counter for parallel write strobe PWM - #define wrPeripheral PIO_CCL // Use CCL to invert write strobe - - // DMA transfer-in-progress indicator and callback - static volatile bool dma_busy = false; - static void dma_callback(Adafruit_ZeroDMA *dma) { - dma_busy = false; - } - - #if defined(__SAMD51__) - // Timer/counter info by index # - static const struct { - Tc *tc; // -> Timer/Counter base address - int gclk; // GCLK ID - int evu; // EVSYS user ID - } tcList[] = { - { TC0, TC0_GCLK_ID, EVSYS_ID_USER_TC0_EVU }, - { TC1, TC1_GCLK_ID, EVSYS_ID_USER_TC1_EVU }, - { TC2, TC2_GCLK_ID, EVSYS_ID_USER_TC2_EVU }, - { TC3, TC3_GCLK_ID, EVSYS_ID_USER_TC3_EVU }, - #if defined(TC4) - { TC4, TC4_GCLK_ID, EVSYS_ID_USER_TC4_EVU }, - #endif - #if defined(TC5) - { TC5, TC5_GCLK_ID, EVSYS_ID_USER_TC5_EVU }, - #endif - #if defined(TC6) - { TC6, TC6_GCLK_ID, EVSYS_ID_USER_TC6_EVU }, - #endif - #if defined(TC7) - { TC7, TC7_GCLK_ID, EVSYS_ID_USER_TC7_EVU } - #endif - }; - #define NUM_TIMERS (sizeof tcList / sizeof tcList[0]) ///< # timer/counters - #endif // end __SAMD51__ - -#endif // end USE_SPI_DMA - -// Possible values for Adafruit_SPITFT.connection: -#define TFT_HARD_SPI 0 ///< Display interface = hardware SPI -#define TFT_SOFT_SPI 1 ///< Display interface = software SPI -#define TFT_PARALLEL 2 ///< Display interface = 8- or 16-bit parallel - - -// CONSTRUCTORS ------------------------------------------------------------ - -/*! - @brief Adafruit_SPITFT constructor for software (bitbang) SPI. - @param w Display width in pixels at default rotation setting (0). - @param h Display height in pixels at default rotation setting (0). - @param cs Arduino pin # for chip-select (-1 if unused, tie CS low). - @param dc Arduino pin # for data/command select (required). - @param mosi Arduino pin # for bitbang SPI MOSI signal (required). - @param sck Arduino pin # for bitbang SPI SCK signal (required). - @param rst Arduino pin # for display reset (optional, display reset - can be tied to MCU reset, default of -1 means unused). - @param miso Arduino pin # for bitbang SPI MISO signal (optional, - -1 default, many displays don't support SPI read). - @return Adafruit_SPITFT object. - @note Output pins are not initialized; application typically will - need to call subclass' begin() function, which in turn calls - this library's initSPI() function to initialize pins. -*/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t mosi, int8_t sck, int8_t rst, int8_t miso) : - Renderer(w, h), connection(TFT_SOFT_SPI), _rst(rst), _cs(cs), _dc(dc) { - swspi._sck = sck; - swspi._mosi = mosi; - swspi._miso = miso; -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(CORE_TEENSY) - #if !defined(KINETISK) - dcPinMask = digitalPinToBitMask(dc); - swspi.sckPinMask = digitalPinToBitMask(sck); - swspi.mosiPinMask = digitalPinToBitMask(mosi); - #endif - dcPortSet = portSetRegister(dc); - dcPortClr = portClearRegister(dc); - swspi.sckPortSet = portSetRegister(sck); - swspi.sckPortClr = portClearRegister(sck); - swspi.mosiPortSet = portSetRegister(mosi); - swspi.mosiPortClr = portClearRegister(mosi); - if(cs >= 0) { - #if !defined(KINETISK) - csPinMask = digitalPinToBitMask(cs); - #endif - csPortSet = portSetRegister(cs); - csPortClr = portClearRegister(cs); - } else { - #if !defined(KINETISK) - csPinMask = 0; - #endif - csPortSet = dcPortSet; - csPortClr = dcPortClr; - } - if(miso >= 0) { - swspi.misoPort = portInputRegister(miso); - #if !defined(KINETISK) - swspi.misoPinMask = digitalPinToBitMask(miso); - #endif - } else { - swspi.misoPort = portInputRegister(dc); - } - #else // !CORE_TEENSY - dcPinMask =digitalPinToBitMask(dc); - swspi.sckPinMask =digitalPinToBitMask(sck); - swspi.mosiPinMask=digitalPinToBitMask(mosi); - dcPortSet =&(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg); - dcPortClr =&(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg); - swspi.sckPortSet =&(PORT->Group[g_APinDescription[sck].ulPort].OUTSET.reg); - swspi.sckPortClr =&(PORT->Group[g_APinDescription[sck].ulPort].OUTCLR.reg); - swspi.mosiPortSet=&(PORT->Group[g_APinDescription[mosi].ulPort].OUTSET.reg); - swspi.mosiPortClr=&(PORT->Group[g_APinDescription[mosi].ulPort].OUTCLR.reg); - if(cs >= 0) { - csPinMask = digitalPinToBitMask(cs); - csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg); - csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csPortSet = dcPortSet; - csPortClr = dcPortClr; - csPinMask = 0; - } - if(miso >= 0) { - swspi.misoPinMask=digitalPinToBitMask(miso); - swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(miso)); - } else { - swspi.misoPinMask=0; - swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(dc)); - } - #endif // end !CORE_TEENSY - #else // !HAS_PORT_SET_CLR - dcPort =(PORTreg_t)portOutputRegister(digitalPinToPort(dc)); - dcPinMaskSet =digitalPinToBitMask(dc); - swspi.sckPort =(PORTreg_t)portOutputRegister(digitalPinToPort(sck)); - swspi.sckPinMaskSet =digitalPinToBitMask(sck); - swspi.mosiPort =(PORTreg_t)portOutputRegister(digitalPinToPort(mosi)); - swspi.mosiPinMaskSet=digitalPinToBitMask(mosi); - if(cs >= 0) { - csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs)); - csPinMaskSet = digitalPinToBitMask(cs); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csPort = dcPort; - csPinMaskSet = 0; - } - if(miso >= 0) { - swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(miso)); - swspi.misoPinMask=digitalPinToBitMask(miso); - } else { - swspi.misoPort =(PORTreg_t)portInputRegister(digitalPinToPort(dc)); - swspi.misoPinMask=0; - } - csPinMaskClr = ~csPinMaskSet; - dcPinMaskClr = ~dcPinMaskSet; - swspi.sckPinMaskClr = ~swspi.sckPinMaskSet; - swspi.mosiPinMaskClr = ~swspi.mosiPinMaskSet; - #endif // !end HAS_PORT_SET_CLR -#endif // end USE_FAST_PINIO -} - -/*! - @brief Adafruit_SPITFT constructor for hardware SPI using the board's - default SPI peripheral. - @param w Display width in pixels at default rotation setting (0). - @param h Display height in pixels at default rotation setting (0). - @param cs Arduino pin # for chip-select (-1 if unused, tie CS low). - @param dc Arduino pin # for data/command select (required). - @param rst Arduino pin # for display reset (optional, display reset - can be tied to MCU reset, default of -1 means unused). - @return Adafruit_SPITFT object. - @note Output pins are not initialized; application typically will - need to call subclass' begin() function, which in turn calls - this library's initSPI() function to initialize pins. -*/ -#if defined(ESP8266) // See notes below -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, - int8_t dc, int8_t rst) : Renderer(w, h), - connection(TFT_HARD_SPI), _rst(rst), _cs(cs), _dc(dc) { - hwspi._spi = &SPI; -} -#else // !ESP8266 -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, int8_t cs, - int8_t dc, int8_t rst) : Adafruit_SPITFT(w, h, &SPI, cs, dc, rst) { - // This just invokes the hardware SPI constructor below, - // passing the default SPI device (&SPI). -} -#endif // end !ESP8266 - -#if !defined(ESP8266) -// ESP8266 compiler freaks out at this constructor -- it can't disambiguate -// beteween the SPIClass pointer (argument #3) and a regular integer. -// Solution here it to just not offer this variant on the ESP8266. You can -// use the default hardware SPI peripheral, or you can use software SPI, -// but if there's any library out there that creates a 'virtual' SPIClass -// peripheral and drives it with software bitbanging, that's not supported. -/*! - @brief Adafruit_SPITFT constructor for hardware SPI using a specific - SPI peripheral. - @param w Display width in pixels at default rotation (0). - @param h Display height in pixels at default rotation (0). - @param spiClass Pointer to SPIClass type (e.g. &SPI or &SPI1). - @param cs Arduino pin # for chip-select (-1 if unused, tie CS low). - @param dc Arduino pin # for data/command select (required). - @param rst Arduino pin # for display reset (optional, display reset - can be tied to MCU reset, default of -1 means unused). - @return Adafruit_SPITFT object. - @note Output pins are not initialized in constructor; application - typically will need to call subclass' begin() function, which - in turn calls this library's initSPI() function to initialize - pins. EXCEPT...if you have built your own SERCOM SPI peripheral - (calling the SPIClass constructor) rather than one of the - built-in SPI devices (e.g. &SPI, &SPI1 and so forth), you will - need to call the begin() function for your object as well as - pinPeripheral() for the MOSI, MISO and SCK pins to configure - GPIO manually. Do this BEFORE calling the display-specific - begin or init function. Unfortunate but unavoidable. -*/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, - int8_t cs, int8_t dc, int8_t rst) : Renderer(w, h), - connection(TFT_HARD_SPI), _rst(rst), _cs(cs), _dc(dc) { - hwspi._spi = spiClass; -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(CORE_TEENSY) - #if !defined(KINETISK) - dcPinMask = digitalPinToBitMask(dc); - #endif - dcPortSet = portSetRegister(dc); - dcPortClr = portClearRegister(dc); - if(cs >= 0) { - #if !defined(KINETISK) - csPinMask = digitalPinToBitMask(cs); - #endif - csPortSet = portSetRegister(cs); - csPortClr = portClearRegister(cs); - } else { // see comments below - #if !defined(KINETISK) - csPinMask = 0; - #endif - csPortSet = dcPortSet; - csPortClr = dcPortClr; - } - #else // !CORE_TEENSY - dcPinMask = digitalPinToBitMask(dc); - dcPortSet = &(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg); - dcPortClr = &(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg); - if(cs >= 0) { - csPinMask = digitalPinToBitMask(cs); - csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg); - csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csPortSet = dcPortSet; - csPortClr = dcPortClr; - csPinMask = 0; - } - #endif // end !CORE_TEENSY - #else // !HAS_PORT_SET_CLR - dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(dc)); - dcPinMaskSet = digitalPinToBitMask(dc); - if(cs >= 0) { - csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs)); - csPinMaskSet = digitalPinToBitMask(cs); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csPort = dcPort; - csPinMaskSet = 0; - } - csPinMaskClr = ~csPinMaskSet; - dcPinMaskClr = ~dcPinMaskSet; - #endif // end !HAS_PORT_SET_CLR -#endif // end USE_FAST_PINIO -} -#endif // end !ESP8266 - -/*! - @brief Adafruit_SPITFT constructor for parallel display connection. - @param w Display width in pixels at default rotation (0). - @param h Display height in pixels at default rotation (0). - @param busWidth If tft16 (enumeration in header file), is a 16-bit - parallel connection, else 8-bit. - 16-bit isn't fully implemented or tested yet so - applications should pass "tft8bitbus" for now...needed to - stick a required enum argument in there to - disambiguate this constructor from the soft-SPI case. - Argument is ignored on 8-bit architectures (no 'wide' - support there since PORTs are 8 bits anyway). - @param d0 Arduino pin # for data bit 0 (1+ are extrapolated). - The 8 (or 16) data bits MUST be contiguous and byte- - aligned (or word-aligned for wide interface) within - the same PORT register (might not correspond to - Arduino pin sequence). - @param wr Arduino pin # for write strobe (required). - @param dc Arduino pin # for data/command select (required). - @param cs Arduino pin # for chip-select (optional, -1 if unused, - tie CS low). - @param rst Arduino pin # for display reset (optional, display reset - can be tied to MCU reset, default of -1 means unused). - @param rd Arduino pin # for read strobe (optional, -1 if unused). - @return Adafruit_SPITFT object. - @note Output pins are not initialized; application typically will need - to call subclass' begin() function, which in turn calls this - library's initSPI() function to initialize pins. - Yes, the name is a misnomer...this library originally handled - only SPI displays, parallel being a recent addition (but not - wanting to break existing code). -*/ -Adafruit_SPITFT::Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth, - int8_t d0, int8_t wr, int8_t dc, int8_t cs, int8_t rst, int8_t rd) : - Renderer(w, h), connection(TFT_PARALLEL), _rst(rst), _cs(cs), _dc(dc) { - tft8._d0 = d0; - tft8._wr = wr; - tft8._rd = rd; - tft8.wide = (busWidth == tft16bitbus); -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(CORE_TEENSY) - tft8.wrPortSet = portSetRegister(wr); - tft8.wrPortClr = portClearRegister(wr); - #if !defined(KINETISK) - dcPinMask = digitalPinToBitMask(dc); - #endif - dcPortSet = portSetRegister(dc); - dcPortClr = portClearRegister(dc); - if(cs >= 0) { - #if !defined(KINETISK) - csPinMask = digitalPinToBitMask(cs); - #endif - csPortSet = portSetRegister(cs); - csPortClr = portClearRegister(cs); - } else { // see comments below - #if !defined(KINETISK) - csPinMask = 0; - #endif - csPortSet = dcPortSet; - csPortClr = dcPortClr; - } - if(rd >= 0) { // if read-strobe pin specified... - #if defined(KINETISK) - tft8.rdPinMask = 1; - #else // !KINETISK - tft8.rdPinMask = digitalPinToBitMask(rd); - #endif - tft8.rdPortSet = portSetRegister(rd); - tft8.rdPortClr = portClearRegister(rd); - } else { - tft8.rdPinMask = 0; - tft8.rdPortSet = dcPortSet; - tft8.rdPortClr = dcPortClr; - } - // These are all uint8_t* pointers -- elsewhere they're recast - // as necessary if a 'wide' 16-bit interface is in use. - tft8.writePort = portOutputRegister(d0); - tft8.readPort = portInputRegister(d0); - tft8.dirSet = portModeRegister(d0); - tft8.dirClr = portModeRegister(d0); - #else // !CORE_TEENSY - tft8.wrPinMask = digitalPinToBitMask(wr); - tft8.wrPortSet = &(PORT->Group[g_APinDescription[wr].ulPort].OUTSET.reg); - tft8.wrPortClr = &(PORT->Group[g_APinDescription[wr].ulPort].OUTCLR.reg); - dcPinMask = digitalPinToBitMask(dc); - dcPortSet = &(PORT->Group[g_APinDescription[dc].ulPort].OUTSET.reg); - dcPortClr = &(PORT->Group[g_APinDescription[dc].ulPort].OUTCLR.reg); - if(cs >= 0) { - csPinMask = digitalPinToBitMask(cs); - csPortSet = &(PORT->Group[g_APinDescription[cs].ulPort].OUTSET.reg); - csPortClr = &(PORT->Group[g_APinDescription[cs].ulPort].OUTCLR.reg); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csPortSet = dcPortSet; - csPortClr = dcPortClr; - csPinMask = 0; - } - if(rd >= 0) { // if read-strobe pin specified... - tft8.rdPinMask =digitalPinToBitMask(rd); - tft8.rdPortSet =&(PORT->Group[g_APinDescription[rd].ulPort].OUTSET.reg); - tft8.rdPortClr =&(PORT->Group[g_APinDescription[rd].ulPort].OUTCLR.reg); - } else { - tft8.rdPinMask = 0; - tft8.rdPortSet = dcPortSet; - tft8.rdPortClr = dcPortClr; - } - // Get pointers to PORT write/read/dir bytes within 32-bit PORT - uint8_t dBit = g_APinDescription[d0].ulPin; // d0 bit # in PORT - PortGroup *p = (&(PORT->Group[g_APinDescription[d0].ulPort])); - uint8_t offset = dBit / 8; // d[7:0] byte # within PORT - if(tft8.wide) offset &= ~1; // d[15:8] byte # within PORT - // These are all uint8_t* pointers -- elsewhere they're recast - // as necessary if a 'wide' 16-bit interface is in use. - tft8.writePort = (volatile uint8_t *)&(p->OUT.reg) + offset; - tft8.readPort = (volatile uint8_t *)&(p->IN.reg) + offset; - tft8.dirSet = (volatile uint8_t *)&(p->DIRSET.reg) + offset; - tft8.dirClr = (volatile uint8_t *)&(p->DIRCLR.reg) + offset; - #endif // end !CORE_TEENSY - #else // !HAS_PORT_SET_CLR - tft8.wrPort = (PORTreg_t)portOutputRegister(digitalPinToPort(wr)); - tft8.wrPinMaskSet = digitalPinToBitMask(wr); - dcPort = (PORTreg_t)portOutputRegister(digitalPinToPort(dc)); - dcPinMaskSet = digitalPinToBitMask(dc); - if(cs >= 0) { - csPort = (PORTreg_t)portOutputRegister(digitalPinToPort(cs)); - csPinMaskSet = digitalPinToBitMask(cs); - } else { - // No chip-select line defined; might be permanently tied to GND. - // Assign a valid GPIO register (though not used for CS), and an - // empty pin bitmask...the nonsense bit-twiddling might be faster - // than checking _cs and possibly branching. - csPort = dcPort; - csPinMaskSet = 0; - } - if(rd >= 0) { // if read-strobe pin specified... - tft8.rdPort =(PORTreg_t)portOutputRegister(digitalPinToPort(rd)); - tft8.rdPinMaskSet =digitalPinToBitMask(rd); - } else { - tft8.rdPort = dcPort; - tft8.rdPinMaskSet = 0; - } - csPinMaskClr = ~csPinMaskSet; - dcPinMaskClr = ~dcPinMaskSet; - tft8.wrPinMaskClr = ~tft8.wrPinMaskSet; - tft8.rdPinMaskClr = ~tft8.rdPinMaskSet; - tft8.writePort = (PORTreg_t)portOutputRegister(digitalPinToPort(d0)); - tft8.readPort = (PORTreg_t)portInputRegister(digitalPinToPort(d0)); - tft8.portDir = (PORTreg_t)portModeRegister(digitalPinToPort(d0)); - #endif // end !HAS_PORT_SET_CLR -#endif // end USE_FAST_PINIO -} - -// end constructors ------- - - -// CLASS MEMBER FUNCTIONS -------------------------------------------------- - -// begin() and setAddrWindow() MUST be declared by any subclass. - -/*! - @brief Configure microcontroller pins for TFT interfacing. Typically - called by a subclass' begin() function. - @param freq SPI frequency when using hardware SPI. If default (0) - is passed, will fall back on a device-specific value. - Value is ignored when using software SPI or parallel - connection. - @param spiMode SPI mode when using hardware SPI. MUST be one of the - values SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3 - defined in SPI.h. Do NOT attempt to pass '0' for - SPI_MODE0 and so forth...the values are NOT the same! - Use ONLY the defines! (Pity it's not an enum.) - @note Another anachronistically-named function; this is called even - when the display connection is parallel (not SPI). Also, this - could probably be made private...quite a few class functions - were generously put in the public section. -*/ -void Adafruit_SPITFT::initSPI(uint32_t freq, uint8_t spiMode) { - - if(!freq) freq = DEFAULT_SPI_FREQ; // If no freq specified, use default - - // Init basic control pins common to all connection types - if(_cs >= 0) { - pinMode(_cs, OUTPUT); - digitalWrite(_cs, HIGH); // Deselect - } - pinMode(_dc, OUTPUT); - digitalWrite(_dc, HIGH); // Data mode - - if(connection == TFT_HARD_SPI) { - -#if defined(SPI_HAS_TRANSACTION) - hwspi.settings = SPISettings(freq, MSBFIRST, spiMode); -#else - hwspi._freq = freq; // Save freq value for later -#endif - hwspi._mode = spiMode; // Save spiMode value for later - // Call hwspi._spi->begin() ONLY if this is among the 'established' - // SPI interfaces in variant.h. For DIY roll-your-own SERCOM SPIs, - // begin() and pinPeripheral() calls MUST be made in one's calling - // code, BEFORE the screen-specific begin/init function is called. - // Reason for this is that SPI::begin() makes its own calls to - // pinPeripheral() based on g_APinDescription[n].ulPinType, which - // on non-established SPI interface pins will always be PIO_DIGITAL - // or similar, while we need PIO_SERCOM or PIO_SERCOM_ALT...it's - // highly unique between devices and variants for each pin or - // SERCOM so we can't make those calls ourselves here. And the SPI - // device needs to be set up before calling this because it's - // immediately followed with initialization commands. Blargh. - if( -#if !defined(SPI_INTERFACES_COUNT) - 1 -#endif -#if SPI_INTERFACES_COUNT > 0 - (hwspi._spi == &SPI) -#endif -#if SPI_INTERFACES_COUNT > 1 - || (hwspi._spi == &SPI1) -#endif -#if SPI_INTERFACES_COUNT > 2 - || (hwspi._spi == &SPI2) -#endif -#if SPI_INTERFACES_COUNT > 3 - || (hwspi._spi == &SPI3) -#endif -#if SPI_INTERFACES_COUNT > 4 - || (hwspi._spi == &SPI4) -#endif -#if SPI_INTERFACES_COUNT > 5 - || (hwspi._spi == &SPI5) -#endif - ) { - hwspi._spi->begin(); - } - } else if(connection == TFT_SOFT_SPI) { - - pinMode(swspi._mosi, OUTPUT); - digitalWrite(swspi._mosi, LOW); - pinMode(swspi._sck, OUTPUT); - digitalWrite(swspi._sck, LOW); - if(swspi._miso >= 0) { - pinMode(swspi._miso, INPUT); - } - - } else { // TFT_PARALLEL - - // Initialize data pins. We were only passed d0, so scan - // the pin description list looking for the other pins. - // They'll be on the same PORT, and within the next 7 (or 15) bits - // (because we need to write to a contiguous PORT byte or word). -#if defined(__AVR__) - // PORT registers are 8 bits wide, so just need a register match... - for(uint8_t i=0; i= dBit ) && - (g_APinDescription[i].ulPin <= (uint32_t)lastBit)) { - pinMode(i, OUTPUT); - digitalWrite(i, LOW); - } - } - #endif // end !CORE_TEENSY -#endif - pinMode(tft8._wr, OUTPUT); - digitalWrite(tft8._wr, HIGH); - if(tft8._rd >= 0) { - pinMode(tft8._rd, OUTPUT); - digitalWrite(tft8._rd, HIGH); - } - } - - if(_rst >= 0) { - // Toggle _rst low to reset - pinMode(_rst, OUTPUT); - digitalWrite(_rst, HIGH); - delay(100); - digitalWrite(_rst, LOW); - delay(100); - digitalWrite(_rst, HIGH); - delay(200); - } - -#if defined(USE_SPI_DMA) - if(((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) && - (dma.allocate() == DMA_STATUS_OK)) { // Allocate channel - // The DMA library needs to alloc at least one valid descriptor, - // so we do that here. It's not used in the usual sense though, - // just before a transfer we copy descriptor[0] to this address. - if(dptr = dma.addDescriptor(NULL, NULL, 42, DMA_BEAT_SIZE_BYTE, - false, false)) { - // Alloc 2 scanlines worth of pixels on display's major axis, - // whichever that is, rounding each up to 2-pixel boundary. - int major = (WIDTH > HEIGHT) ? WIDTH : HEIGHT; - major += (major & 1); // -> next 2-pixel bound, if needed. - maxFillLen = major * 2; // 2 scanlines - // Note to future self: if you decide to make the pixel buffer - // much larger, remember that DMA transfer descriptors can't - // exceed 65,535 bytes (not 65,536), meaning 32,767 pixels max. - // Not that we have that kind of RAM to throw around right now. - if((pixelBuf[0] = - (uint16_t *)malloc(maxFillLen * sizeof(uint16_t)))) { - // Alloc OK. Get pointer to start of second scanline. - pixelBuf[1] = &pixelBuf[0][major]; - // Determine number of DMA descriptors needed to cover - // entire screen when entire 2-line pixelBuf is used - // (round up for fractional last descriptor). - int numDescriptors = (WIDTH * HEIGHT + (maxFillLen - 1)) / - maxFillLen; - // DMA descriptors MUST be 128-bit (16 byte) aligned. - // memalign() is considered obsolete but it's replacements - // (aligned_alloc() or posix_memalign()) are not currently - // available in the version of ARM GCC in use, but this - // is, so here we are. - if((descriptor = (DmacDescriptor *)memalign(16, - numDescriptors * sizeof(DmacDescriptor)))) { - int dmac_id; - volatile uint32_t *data_reg; - - if(connection == TFT_HARD_SPI) { - // THIS IS AN AFFRONT TO NATURE, but I don't know - // any "clean" way to get the sercom number from the - // the SPIClass pointer (e.g. &SPI or &SPI1), which - // is all we have to work with. SPIClass does contain - // a SERCOM pointer but it is a PRIVATE member! - // Doing an UNSPEAKABLY HORRIBLE THING here, directly - // accessing the first 32-bit value in the SPIClass - // structure, knowing that's (currently) where the - // SERCOM pointer lives, but this ENTIRELY DEPENDS on - // that structure not changing nor the compiler - // rearranging things. Oh the humanity! - - if(*(SERCOM **)hwspi._spi == &sercom0) { - dmac_id = SERCOM0_DMAC_ID_TX; - data_reg = &SERCOM0->SPI.DATA.reg; -#if defined SERCOM1 - } else if(*(SERCOM **)hwspi._spi == &sercom1) { - dmac_id = SERCOM1_DMAC_ID_TX; - data_reg = &SERCOM1->SPI.DATA.reg; -#endif -#if defined SERCOM2 - } else if(*(SERCOM **)hwspi._spi == &sercom2) { - dmac_id = SERCOM2_DMAC_ID_TX; - data_reg = &SERCOM2->SPI.DATA.reg; -#endif -#if defined SERCOM3 - } else if(*(SERCOM **)hwspi._spi == &sercom3) { - dmac_id = SERCOM3_DMAC_ID_TX; - data_reg = &SERCOM3->SPI.DATA.reg; -#endif -#if defined SERCOM4 - } else if(*(SERCOM **)hwspi._spi == &sercom4) { - dmac_id = SERCOM4_DMAC_ID_TX; - data_reg = &SERCOM4->SPI.DATA.reg; -#endif -#if defined SERCOM5 - } else if(*(SERCOM **)hwspi._spi == &sercom5) { - dmac_id = SERCOM5_DMAC_ID_TX; - data_reg = &SERCOM5->SPI.DATA.reg; -#endif -#if defined SERCOM6 - } else if(*(SERCOM **)hwspi._spi == &sercom6) { - dmac_id = SERCOM6_DMAC_ID_TX; - data_reg = &SERCOM6->SPI.DATA.reg; -#endif -#if defined SERCOM7 - } else if(*(SERCOM **)hwspi._spi == &sercom7) { - dmac_id = SERCOM7_DMAC_ID_TX; - data_reg = &SERCOM7->SPI.DATA.reg; -#endif - } - dma.setPriority(DMA_PRIORITY_3); - dma.setTrigger(dmac_id); - dma.setAction(DMA_TRIGGER_ACTON_BEAT); - - // Initialize descriptor list. - for(int d=0; dChannel[dmaChannel].CHEVCTRL.bit.EVOE = 1; - DMAC->Channel[dmaChannel].CHEVCTRL.bit.EVOMODE = 0; - - // CONFIGURE TIMER/COUNTER (for write strobe) - - Tc *timer = tcList[tcNum].tc; // -> Timer struct - int id = tcList[tcNum].gclk; // Timer GCLK ID - GCLK_PCHCTRL_Type pchctrl; - - // Set up timer clock source from GCLK - GCLK->PCHCTRL[id].bit.CHEN = 0; // Stop timer - while(GCLK->PCHCTRL[id].bit.CHEN); // Wait for it - pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK0_Val; - pchctrl.bit.CHEN = 1; // Enable - GCLK->PCHCTRL[id].reg = pchctrl.reg; - while(!GCLK->PCHCTRL[id].bit.CHEN); // Wait for it - - // Disable timer/counter before configuring it - timer->COUNT8.CTRLA.bit.ENABLE = 0; - while(timer->COUNT8.SYNCBUSY.bit.STATUS); - - timer->COUNT8.WAVE.bit.WAVEGEN = 2; // NPWM - timer->COUNT8.CTRLA.bit.MODE = 1; // 8-bit - timer->COUNT8.CTRLA.bit.PRESCALER = 0; // 1:1 - while(timer->COUNT8.SYNCBUSY.bit.STATUS); - - timer->COUNT8.CTRLBCLR.bit.DIR = 1; // Count UP - while(timer->COUNT8.SYNCBUSY.bit.CTRLB); - timer->COUNT8.CTRLBSET.bit.ONESHOT = 1; // One-shot - while(timer->COUNT8.SYNCBUSY.bit.CTRLB); - timer->COUNT8.PER.reg = 6; // PWM top - while(timer->COUNT8.SYNCBUSY.bit.PER); - timer->COUNT8.CC[0].reg = 2; // Compare - while(timer->COUNT8.SYNCBUSY.bit.CC0); - // Enable async input events, - // event action = restart. - timer->COUNT8.EVCTRL.bit.TCEI = 1; - timer->COUNT8.EVCTRL.bit.EVACT = 1; - - // Enable timer - timer->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE; - while(timer->COUNT8.SYNCBUSY.bit.STATUS); - -#if(wrPeripheral == PIO_CCL) - // CONFIGURE CCL (inverts timer/counter output) - - MCLK->APBCMASK.bit.CCL_ = 1; // Enable CCL clock - CCL->CTRL.bit.ENABLE = 0; // Disable to config - CCL->CTRL.bit.SWRST = 1; // Reset CCL registers - CCL->LUTCTRL[tcNum].bit.ENABLE = 0; // Disable LUT - CCL->LUTCTRL[tcNum].bit.FILTSEL = 0; // No filter - CCL->LUTCTRL[tcNum].bit.INSEL0 = 6; // TC input - CCL->LUTCTRL[tcNum].bit.INSEL1 = 0; // MASK - CCL->LUTCTRL[tcNum].bit.INSEL2 = 0; // MASK - CCL->LUTCTRL[tcNum].bit.TRUTH = 1; // Invert in 0 - CCL->LUTCTRL[tcNum].bit.ENABLE = 1; // Enable LUT - CCL->CTRL.bit.ENABLE = 1; // Enable CCL -#endif - - // CONFIGURE EVENT SYSTEM - - // Set up event system clock source from GCLK... - // Disable EVSYS, wait for disable - GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN = 0; - while(GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN); - pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK0_Val; - pchctrl.bit.CHEN = 1; // Re-enable - GCLK->PCHCTRL[EVSYS_GCLK_ID_0].reg = pchctrl.reg; - // Wait for it, then enable EVSYS clock - while(!GCLK->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN); - MCLK->APBBMASK.bit.EVSYS_ = 1; - - // Connect Timer EVU to ch 0 - EVSYS->USER[tcList[tcNum].evu].reg = 1; - // Datasheet recommends single write operation; - // reg instead of bit. Also datasheet: PATH bits - // must be zero when using async! - EVSYS_CHANNEL_Type ev; - ev.reg = 0; - ev.bit.PATH = 2; // Asynchronous - ev.bit.EVGEN = 0x22 + dmaChannel; // DMA channel 0+ - EVSYS->Channel[0].CHANNEL.reg = ev.reg; - - // Initialize descriptor list. - for(int d=0; d= 0) SPI_CS_LOW(); -} - -/*! - @brief Call after issuing command(s) or data to display. Performs - chip-deselect (if required) and ends an SPI transaction (if - using hardware SPI and transactions are supported). Required - for all display types; not an SPI-specific function. -*/ -void Adafruit_SPITFT::endWrite(void) { - if(_cs >= 0) SPI_CS_HIGH(); - SPI_END_TRANSACTION(); -} - - -// ------------------------------------------------------------------------- -// Lower-level graphics operations. These functions require a chip-select -// and/or SPI transaction around them (via startWrite(), endWrite() above). -// Higher-level graphics primitives might start a single transaction and -// then make multiple calls to these functions (e.g. circle or text -// rendering might make repeated lines or rects) before ending the -// transaction. It's more efficient than starting a transaction every time. - -/*! - @brief Draw a single pixel to the display at requested coordinates. - Not self-contained; should follow a startWrite() call. - @param x Horizontal position (0 = left). - @param y Vertical position (0 = top). - @param color 16-bit pixel color in '565' RGB format. -*/ -void Adafruit_SPITFT::writePixel(int16_t x, int16_t y, uint16_t color) { - if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { - setAddrWindow(x, y, 1, 1); - SPI_WRITE16(color); - } -} - -/*! - @brief Issue a series of pixels from memory to the display. Not self- - contained; should follow startWrite() and setAddrWindow() calls. - @param colors Pointer to array of 16-bit pixel values in '565' RGB - format. - @param len Number of elements in 'colors' array. - @param block If true (default case if unspecified), function blocks - until DMA transfer is complete. This is simply IGNORED - if DMA is not enabled. If false, the function returns - immediately after the last DMA transfer is started, - and one should use the dmaWait() function before - doing ANY other display-related activities (or even - any SPI-related activities, if using an SPI display - that shares the bus with other devices). - @param bigEndian If using DMA, and if set true, bitmap in memory is in - big-endian order (most significant byte first). By - default this is false, as most microcontrollers seem - to be little-endian and 16-bit pixel values must be - byte-swapped before issuing to the display (which tend - to be big-endian when using SPI or 8-bit parallel). - If an application can optimize around this -- for - example, a bitmap in a uint16_t array having the byte - values already reordered big-endian, this can save - some processing time here, ESPECIALLY if using this - function's non-blocking DMA mode. Not all cases are - covered...this is really here only for SAMD DMA and - much forethought on the application side. -*/ -void Adafruit_SPITFT::writePixels(uint16_t *colors, uint32_t len, - bool block, bool bigEndian) { - - if(!len) return; // Avoid 0-byte transfers - -#if defined(ESP32) // ESP32 has a special SPI pixel-writing function... - if(connection == TFT_HARD_SPI) { - hwspi._spi->writePixels(colors, len * 2); - return; - } -#elif defined(USE_SPI_DMA) - if((connection == TFT_HARD_SPI) || (connection == TFT_PARALLEL)) { - int maxSpan = maxFillLen / 2; // One scanline max - uint8_t pixelBufIdx = 0; // Active pixel buffer number - #if defined(__SAMD51__) - if(connection == TFT_PARALLEL) { - // Switch WR pin to PWM or CCL - pinPeripheral(tft8._wr, wrPeripheral); - } - #endif // end __SAMD51__ - if(!bigEndian) { // Normal little-endian situation... - while(len) { - int count = (len < maxSpan) ? len : maxSpan; - - // Because TFT and SAMD endianisms are different, must swap - // bytes from the 'colors' array passed into a DMA working - // buffer. This can take place while the prior DMA transfer - // is in progress, hence the need for two pixelBufs. - for(int i=0; isetDataMode(hwspi._mode); - } else { - pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO - } - #endif // end __SAMD51__ || _SAMD21_ - } - return; - } -#endif // end USE_SPI_DMA - - // All other cases (bitbang SPI or non-DMA hard SPI or parallel), - // use a loop with the normal 16-bit data write function: - while(len--) { - SPI_WRITE16(*colors++); - } -} - -/*! - @brief Wait for the last DMA transfer in a prior non-blocking - writePixels() call to complete. This does nothing if DMA - is not enabled, and is not needed if blocking writePixels() - was used (as is the default case). -*/ -void Adafruit_SPITFT::dmaWait(void) { -#if defined(USE_SPI_DMA) - while(dma_busy); - #if defined(__SAMD51__) || defined(_SAMD21_) - if(connection == TFT_HARD_SPI) { - // See SAMD51/21 note in writeColor() - hwspi._spi->setDataMode(hwspi._mode); - } else { - pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO - } - #endif // end __SAMD51__ || _SAMD21_ -#endif -} - -/*! - @brief Issue a series of pixels, all the same color. Not self- - contained; should follow startWrite() and setAddrWindow() calls. - @param color 16-bit pixel color in '565' RGB format. - @param len Number of pixels to draw. -*/ -void Adafruit_SPITFT::writeColor(uint16_t color, uint32_t len) { - - if(!len) return; // Avoid 0-byte transfers - - uint8_t hi = color >> 8, lo = color; - -#if defined(ESP32) // ESP32 has a special SPI pixel-writing function... - if(connection == TFT_HARD_SPI) { - #define SPI_MAX_PIXELS_AT_ONCE 32 - #define TMPBUF_LONGWORDS (SPI_MAX_PIXELS_AT_ONCE + 1) / 2 - #define TMPBUF_PIXELS (TMPBUF_LONGWORDS * 2) - static uint32_t temp[TMPBUF_LONGWORDS]; - uint32_t c32 = color * 0x00010001; - uint16_t bufLen = (len < TMPBUF_PIXELS) ? len : TMPBUF_PIXELS, - xferLen, fillLen; - // Fill temp buffer 32 bits at a time - fillLen = (bufLen + 1) / 2; // Round up to next 32-bit boundary - for(uint32_t t=0; t= 16)) { // Don't bother with DMA on short pixel runs - int i, d, numDescriptors; - if(hi == lo) { // If high & low bytes are same... - onePixelBuf = color; - // Can do this with a relatively short descriptor list, - // each transferring a max of 32,767 (not 32,768) pixels. - // This won't run off the end of the allocated descriptor list, - // since we're using much larger chunks per descriptor here. - numDescriptors = (len + 32766) / 32767; - for(d=0; d lastFillLen) { - int fillStart = lastFillLen / 2, - fillEnd = (((len < maxFillLen) ? - len : maxFillLen) + 1) / 2; - for(i=fillStart; isetDataMode(hwspi._mode); - } else { - pinPeripheral(tft8._wr, PIO_OUTPUT); // Switch WR back to GPIO - } - #endif // end __SAMD51__ - return; - } - #endif // end USE_SPI_DMA -#endif // end !ESP32 - - // All other cases (non-DMA hard SPI, bitbang SPI, parallel)... - - if(connection == TFT_HARD_SPI) { -#if defined(ESP8266) - do { - uint32_t pixelsThisPass = len; - if(pixelsThisPass > 50000) pixelsThisPass = 50000; - len -= pixelsThisPass; - yield(); // Periodic yield() on long fills - while(pixelsThisPass--) { - hwspi._spi->write(hi); - hwspi._spi->write(lo); - } - } while(len); -#else // !ESP8266 - while(len--) { - #if defined(__AVR__) - AVR_WRITESPI(hi); - AVR_WRITESPI(lo); - #elif defined(ESP32) - hwspi._spi->write(hi); - hwspi._spi->write(lo); - #else - hwspi._spi->transfer(hi); - hwspi._spi->transfer(lo); - #endif - } -#endif // end !ESP8266 - } else if(connection == TFT_SOFT_SPI) { -#if defined(ESP8266) - do { - uint32_t pixelsThisPass = len; - if(pixelsThisPass > 20000) pixelsThisPass = 20000; - len -= pixelsThisPass; - yield(); // Periodic yield() on long fills - while(pixelsThisPass--) { - for(uint16_t bit=0, x=color; bit<16; bit++) { - if(x & 0x8000) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - SPI_SCK_LOW(); - x <<= 1; - } - } - } while(len); -#else // !ESP8266 - while(len--) { - #if defined(__AVR__) - for(uint8_t bit=0, x=hi; bit<8; bit++) { - if(x & 0x80) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - SPI_SCK_LOW(); - x <<= 1; - } - for(uint8_t bit=0, x=lo; bit<8; bit++) { - if(x & 0x80) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - SPI_SCK_LOW(); - x <<= 1; - } - #else // !__AVR__ - for(uint16_t bit=0, x=color; bit<16; bit++) { - if(x & 0x8000) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - x <<= 1; - SPI_SCK_LOW(); - } - #endif // end !__AVR__ - } -#endif // end !ESP8266 - } else { // PARALLEL - if(hi == lo) { -#if defined(__AVR__) - len *= 2; - *tft8.writePort = hi; - while(len--) { - TFT_WR_STROBE(); - } -#elif defined(USE_FAST_PINIO) - if(!tft8.wide) { - len *= 2; - *tft8.writePort = hi; - } else { - *(volatile uint16_t *)tft8.writePort = color; - } - while(len--) { - TFT_WR_STROBE(); - } -#endif - } else { - while(len--) { -#if defined(__AVR__) - *tft8.writePort = hi; - TFT_WR_STROBE(); - *tft8.writePort = lo; -#elif defined(USE_FAST_PINIO) - if(!tft8.wide) { - *tft8.writePort = hi; - TFT_WR_STROBE(); - *tft8.writePort = lo; - } else { - *(volatile uint16_t *)tft8.writePort = color; - } -#endif - TFT_WR_STROBE(); - } - } - } -} - -/*! - @brief Draw a filled rectangle to the display. Not self-contained; - should follow startWrite(). Typically used by higher-level - graphics primitives; user code shouldn't need to call this and - is likely to use the self-contained fillRect() instead. - writeFillRect() performs its own edge clipping and rejection; - see writeFillRectPreclipped() for a more 'raw' implementation. - @param x Horizontal position of first corner. - @param y Vertical position of first corner. - @param w Rectangle width in pixels (positive = right of first - corner, negative = left of first corner). - @param h Rectangle height in pixels (positive = below first - corner, negative = above first corner). - @param color 16-bit fill color in '565' RGB format. - @note Written in this deep-nested way because C by definition will - optimize for the 'if' case, not the 'else' -- avoids branches - and rejects clipped rectangles at the least-work possibility. -*/ -void Adafruit_SPITFT::writeFillRect(int16_t x, int16_t y, - int16_t w, int16_t h, uint16_t color) { - if(w && h) { // Nonzero width and height? - if(w < 0) { // If negative width... - x += w + 1; // Move X to left edge - w = -w; // Use positive width - } - if(x < _width) { // Not off right - if(h < 0) { // If negative height... - y += h + 1; // Move Y to top edge - h = -h; // Use positive height - } - if(y < _height) { // Not off bottom - int16_t x2 = x + w - 1; - if(x2 >= 0) { // Not off left - int16_t y2 = y + h - 1; - if(y2 >= 0) { // Not off top - // Rectangle partly or fully overlaps screen - if(x < 0) { x = 0; w = x2 + 1; } // Clip left - if(y < 0) { y = 0; h = y2 + 1; } // Clip top - if(x2 >= _width) { w = _width - x; } // Clip right - if(y2 >= _height) { h = _height - y; } // Clip bottom - writeFillRectPreclipped(x, y, w, h, color); - } - } - } - } - } -} - -/*! - @brief Draw a horizontal line on the display. Performs edge clipping - and rejection. Not self-contained; should follow startWrite(). - Typically used by higher-level graphics primitives; user code - shouldn't need to call this and is likely to use the self- - contained drawFastHLine() instead. - @param x Horizontal position of first point. - @param y Vertical position of first point. - @param w Line width in pixels (positive = right of first point, - negative = point of first corner). - @param color 16-bit line color in '565' RGB format. -*/ -void inline Adafruit_SPITFT::writeFastHLine(int16_t x, int16_t y, int16_t w, - uint16_t color) { - if((y >= 0) && (y < _height) && w) { // Y on screen, nonzero width - if(w < 0) { // If negative width... - x += w + 1; // Move X to left edge - w = -w; // Use positive width - } - if(x < _width) { // Not off right - int16_t x2 = x + w - 1; - if(x2 >= 0) { // Not off left - // Line partly or fully overlaps screen - if(x < 0) { x = 0; w = x2 + 1; } // Clip left - if(x2 >= _width) { w = _width - x; } // Clip right - writeFillRectPreclipped(x, y, w, 1, color); - } - } - } -} - -/*! - @brief Draw a vertical line on the display. Performs edge clipping and - rejection. Not self-contained; should follow startWrite(). - Typically used by higher-level graphics primitives; user code - shouldn't need to call this and is likely to use the self- - contained drawFastVLine() instead. - @param x Horizontal position of first point. - @param y Vertical position of first point. - @param h Line height in pixels (positive = below first point, - negative = above first point). - @param color 16-bit line color in '565' RGB format. -*/ -void inline Adafruit_SPITFT::writeFastVLine(int16_t x, int16_t y, int16_t h, - uint16_t color) { - if((x >= 0) && (x < _width) && h) { // X on screen, nonzero height - if(h < 0) { // If negative height... - y += h + 1; // Move Y to top edge - h = -h; // Use positive height - } - if(y < _height) { // Not off bottom - int16_t y2 = y + h - 1; - if(y2 >= 0) { // Not off top - // Line partly or fully overlaps screen - if(y < 0) { y = 0; h = y2 + 1; } // Clip top - if(y2 >= _height) { h = _height - y; } // Clip bottom - writeFillRectPreclipped(x, y, 1, h, color); - } - } - } -} - -/*! - @brief A lower-level version of writeFillRect(). This version requires - all inputs are in-bounds, that width and height are positive, - and no part extends offscreen. NO EDGE CLIPPING OR REJECTION IS - PERFORMED. If higher-level graphics primitives are written to - handle their own clipping earlier in the drawing process, this - can avoid unnecessary function calls and repeated clipping - operations in the lower-level functions. - @param x Horizontal position of first corner. MUST BE WITHIN - SCREEN BOUNDS. - @param y Vertical position of first corner. MUST BE WITHIN SCREEN - BOUNDS. - @param w Rectangle width in pixels. MUST BE POSITIVE AND NOT - EXTEND OFF SCREEN. - @param h Rectangle height in pixels. MUST BE POSITIVE AND NOT - EXTEND OFF SCREEN. - @param color 16-bit fill color in '565' RGB format. - @note This is a new function, no graphics primitives besides rects - and horizontal/vertical lines are written to best use this yet. -*/ -inline void Adafruit_SPITFT::writeFillRectPreclipped(int16_t x, int16_t y, - int16_t w, int16_t h, uint16_t color) { - setAddrWindow(x, y, w, h); - writeColor(color, (uint32_t)w * h); -} - - -// ------------------------------------------------------------------------- -// Ever-so-slightly higher-level graphics operations. Similar to the 'write' -// functions above, but these contain their own chip-select and SPI -// transactions as needed (via startWrite(), endWrite()). They're typically -// used solo -- as graphics primitives in themselves, not invoked by higher- -// level primitives (which should use the functions above for better -// performance). - -/*! - @brief Draw a single pixel to the display at requested coordinates. - Self-contained and provides its own transaction as needed - (see writePixel(x,y,color) for a lower-level variant). - Edge clipping is performed here. - @param x Horizontal position (0 = left). - @param y Vertical position (0 = top). - @param color 16-bit pixel color in '565' RGB format. -*/ -void Adafruit_SPITFT::drawPixel(int16_t x, int16_t y, uint16_t color) { - // Clip first... - if((x >= 0) && (x < _width) && (y >= 0) && (y < _height)) { - // THEN set up transaction (if needed) and draw... - startWrite(); - setAddrWindow(x, y, 1, 1); - SPI_WRITE16(color); - endWrite(); - } -} - -/*! - @brief Draw a filled rectangle to the display. Self-contained and - provides its own transaction as needed (see writeFillRect() or - writeFillRectPreclipped() for lower-level variants). Edge - clipping and rejection is performed here. - @param x Horizontal position of first corner. - @param y Vertical position of first corner. - @param w Rectangle width in pixels (positive = right of first - corner, negative = left of first corner). - @param h Rectangle height in pixels (positive = below first - corner, negative = above first corner). - @param color 16-bit fill color in '565' RGB format. - @note This repeats the writeFillRect() function almost in its entirety, - with the addition of a transaction start/end. It's done this way - (rather than starting the transaction and calling writeFillRect() - to handle clipping and so forth) so that the transaction isn't - performed at all if the rectangle is rejected. It's really not - that much code. -*/ -void Adafruit_SPITFT::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { - if(w && h) { // Nonzero width and height? - if(w < 0) { // If negative width... - x += w + 1; // Move X to left edge - w = -w; // Use positive width - } - if(x < _width) { // Not off right - if(h < 0) { // If negative height... - y += h + 1; // Move Y to top edge - h = -h; // Use positive height - } - if(y < _height) { // Not off bottom - int16_t x2 = x + w - 1; - if(x2 >= 0) { // Not off left - int16_t y2 = y + h - 1; - if(y2 >= 0) { // Not off top - // Rectangle partly or fully overlaps screen - if(x < 0) { x = 0; w = x2 + 1; } // Clip left - if(y < 0) { y = 0; h = y2 + 1; } // Clip top - if(x2 >= _width) { w = _width - x; } // Clip right - if(y2 >= _height) { h = _height - y; } // Clip bottom - startWrite(); - writeFillRectPreclipped(x, y, w, h, color); - endWrite(); - } - } - } - } - } -} - -/*! - @brief Draw a horizontal line on the display. Self-contained and - provides its own transaction as needed (see writeFastHLine() for - a lower-level variant). Edge clipping and rejection is performed - here. - @param x Horizontal position of first point. - @param y Vertical position of first point. - @param w Line width in pixels (positive = right of first point, - negative = point of first corner). - @param color 16-bit line color in '565' RGB format. - @note This repeats the writeFastHLine() function almost in its - entirety, with the addition of a transaction start/end. It's - done this way (rather than starting the transaction and calling - writeFastHLine() to handle clipping and so forth) so that the - transaction isn't performed at all if the line is rejected. -*/ -void Adafruit_SPITFT::drawFastHLine(int16_t x, int16_t y, int16_t w, - uint16_t color) { - if((y >= 0) && (y < _height) && w) { // Y on screen, nonzero width - if(w < 0) { // If negative width... - x += w + 1; // Move X to left edge - w = -w; // Use positive width - } - if(x < _width) { // Not off right - int16_t x2 = x + w - 1; - if(x2 >= 0) { // Not off left - // Line partly or fully overlaps screen - if(x < 0) { x = 0; w = x2 + 1; } // Clip left - if(x2 >= _width) { w = _width - x; } // Clip right - startWrite(); - writeFillRectPreclipped(x, y, w, 1, color); - endWrite(); - } - } - } -} - -/*! - @brief Draw a vertical line on the display. Self-contained and provides - its own transaction as needed (see writeFastHLine() for a lower- - level variant). Edge clipping and rejection is performed here. - @param x Horizontal position of first point. - @param y Vertical position of first point. - @param h Line height in pixels (positive = below first point, - negative = above first point). - @param color 16-bit line color in '565' RGB format. - @note This repeats the writeFastVLine() function almost in its - entirety, with the addition of a transaction start/end. It's - done this way (rather than starting the transaction and calling - writeFastVLine() to handle clipping and so forth) so that the - transaction isn't performed at all if the line is rejected. -*/ -void Adafruit_SPITFT::drawFastVLine(int16_t x, int16_t y, int16_t h, - uint16_t color) { - if((x >= 0) && (x < _width) && h) { // X on screen, nonzero height - if(h < 0) { // If negative height... - y += h + 1; // Move Y to top edge - h = -h; // Use positive height - } - if(y < _height) { // Not off bottom - int16_t y2 = y + h - 1; - if(y2 >= 0) { // Not off top - // Line partly or fully overlaps screen - if(y < 0) { y = 0; h = y2 + 1; } // Clip top - if(y2 >= _height) { h = _height - y; } // Clip bottom - startWrite(); - writeFillRectPreclipped(x, y, 1, h, color); - endWrite(); - } - } - } -} - -/*! - @brief Essentially writePixel() with a transaction around it. I don't - think this is in use by any of our code anymore (believe it was - for some older BMP-reading examples), but is kept here in case - any user code relies on it. Consider it DEPRECATED. - @param color 16-bit pixel color in '565' RGB format. -*/ -void Adafruit_SPITFT::pushColor(uint16_t color) { - startWrite(); - SPI_WRITE16(color); - endWrite(); -} - -/*! - @brief Draw a 16-bit image (565 RGB) at the specified (x,y) position. - For 16-bit display devices; no color reduction performed. - Adapted from https://github.com/PaulStoffregen/ILI9341_t3 - by Marc MERLIN. See examples/pictureEmbed to use this. - 5/6/2017: function name and arguments have changed for - compatibility with current GFX library and to avoid naming - problems in prior implementation. Formerly drawBitmap() with - arguments in different order. Handles its own transaction and - edge clipping/rejection. - @param x Top left corner horizontal coordinate. - @param y Top left corner vertical coordinate. - @param pcolors Pointer to 16-bit array of pixel values. - @param w Width of bitmap in pixels. - @param h Height of bitmap in pixels. -*/ -void Adafruit_SPITFT::drawRGBBitmap(int16_t x, int16_t y, - uint16_t *pcolors, int16_t w, int16_t h) { - - int16_t x2, y2; // Lower-right coord - if(( x >= _width ) || // Off-edge right - ( y >= _height) || // " top - ((x2 = (x+w-1)) < 0 ) || // " left - ((y2 = (y+h-1)) < 0) ) return; // " bottom - - int16_t bx1=0, by1=0, // Clipped top-left within bitmap - saveW=w; // Save original bitmap width value - if(x < 0) { // Clip left - w += x; - bx1 = -x; - x = 0; - } - if(y < 0) { // Clip top - h += y; - by1 = -y; - y = 0; - } - if(x2 >= _width ) w = _width - x; // Clip right - if(y2 >= _height) h = _height - y; // Clip bottom - - pcolors += by1 * saveW + bx1; // Offset bitmap ptr to clipped top-left - startWrite(); - setAddrWindow(x, y, w, h); // Clipped area - while(h--) { // For each (clipped) scanline... - writePixels(pcolors, w); // Push one (clipped) row - pcolors += saveW; // Advance pointer by one full (unclipped) line - } - endWrite(); -} - - -// ------------------------------------------------------------------------- -// Miscellaneous class member functions that don't draw anything. - -/*! - @brief Invert the colors of the display (if supported by hardware). - Self-contained, no transaction setup required. - @param i true = inverted display, false = normal display. -*/ -void Adafruit_SPITFT::invertDisplay(bool i) { - startWrite(); - writeCommand(i ? invertOnCommand : invertOffCommand); - endWrite(); -} - -/*! - @brief Given 8-bit red, green and blue values, return a 'packed' - 16-bit color value in '565' RGB format (5 bits red, 6 bits - green, 5 bits blue). This is just a mathematical operation, - no hardware is touched. - @param red 8-bit red brightnesss (0 = off, 255 = max). - @param green 8-bit green brightnesss (0 = off, 255 = max). - @param blue 8-bit blue brightnesss (0 = off, 255 = max). - @return 'Packed' 16-bit color value (565 format). -*/ -uint16_t Adafruit_SPITFT::color565(uint8_t red, uint8_t green, uint8_t blue) { - return ((red & 0xF8) << 8) | ((green & 0xFC) << 3) | (blue >> 3); -} - -/*! - @brief Adafruit_SPITFT Send Command handles complete sending of commands and data - @param commandByte The Command Byte - @param dataBytes A pointer to the Data bytes to send - @param numDataBytes The number of bytes we should send - */ -void Adafruit_SPITFT::sendCommand(uint8_t commandByte, uint8_t *dataBytes, uint8_t numDataBytes) { - SPI_BEGIN_TRANSACTION(); - if(_cs >= 0) SPI_CS_LOW(); - - SPI_DC_LOW(); // Command mode - spiWrite(commandByte); // Send the command byte - - SPI_DC_HIGH(); - for (int i=0; i= 0) SPI_CS_HIGH(); - SPI_END_TRANSACTION(); -} - -/*! - @brief Adafruit_SPITFT Send Command handles complete sending of commands and const data - @param commandByte The Command Byte - @param dataBytes A pointer to the Data bytes to send - @param numDataBytes The number of bytes we should send - */ -void Adafruit_SPITFT::sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes) { - SPI_BEGIN_TRANSACTION(); - if(_cs >= 0) SPI_CS_LOW(); - - SPI_DC_LOW(); // Command mode - spiWrite(commandByte); // Send the command byte - - SPI_DC_HIGH(); - for (int i=0; i= 0) SPI_CS_HIGH(); - SPI_END_TRANSACTION(); -} - -/*! - @brief Read 8 bits of data from display configuration memory (not RAM). - This is highly undocumented/supported and should be avoided, - function is only included because some of the examples use it. - @param commandByte - The command register to read data from. - @param index - The byte index into the command to read from. - @return Unsigned 8-bit data read from display register. - */ -/**************************************************************************/ -uint8_t Adafruit_SPITFT::readcommand8(uint8_t commandByte, uint8_t index) { - uint8_t result; - startWrite(); - SPI_DC_LOW(); // Command mode - spiWrite(commandByte); - SPI_DC_HIGH(); // Data mode - do { - result = spiRead(); - } while(index--); // Discard bytes up to index'th - endWrite(); - return result; -} - -// ------------------------------------------------------------------------- -// Lowest-level hardware-interfacing functions. Many of these are inline and -// compile to different things based on #defines -- typically just a few -// instructions. Others, not so much, those are not inlined. - -/*! - @brief Start an SPI transaction if using the hardware SPI interface to - the display. If using an earlier version of the Arduino platform - (before the addition of SPI transactions), this instead attempts - to set up the SPI clock and mode. No action is taken if the - connection is not hardware SPI-based. This does NOT include a - chip-select operation -- see startWrite() for a function that - encapsulated both actions. -*/ -inline void Adafruit_SPITFT::SPI_BEGIN_TRANSACTION(void) { - if(connection == TFT_HARD_SPI) { -#if defined(SPI_HAS_TRANSACTION) - hwspi._spi->beginTransaction(hwspi.settings); -#else // No transactions, configure SPI manually... - #if defined(__AVR__) || defined(TEENSYDUINO) || defined(ARDUINO_ARCH_STM32F1) - hwspi._spi->setClockDivider(SPI_CLOCK_DIV2); - #elif defined(__arm__) - hwspi._spi->setClockDivider(11); - #elif defined(ESP8266) || defined(ESP32) - hwspi._spi->setFrequency(hwspi._freq); - #elif defined(RASPI) || defined(ARDUINO_ARCH_STM32F1) - hwspi._spi->setClock(hwspi._freq); - #endif - hwspi._spi->setBitOrder(MSBFIRST); - hwspi._spi->setDataMode(hwspi._mode); -#endif // end !SPI_HAS_TRANSACTION - } -} - -/*! - @brief End an SPI transaction if using the hardware SPI interface to - the display. No action is taken if the connection is not - hardware SPI-based or if using an earlier version of the Arduino - platform (before the addition of SPI transactions). This does - NOT include a chip-deselect operation -- see endWrite() for a - function that encapsulated both actions. -*/ -inline void Adafruit_SPITFT::SPI_END_TRANSACTION(void) { -#if defined(SPI_HAS_TRANSACTION) - if(connection == TFT_HARD_SPI) { - hwspi._spi->endTransaction(); - } -#endif -} - -/*! - @brief Issue a single 8-bit value to the display. Chip-select, - transaction and data/command selection must have been - previously set -- this ONLY issues the byte. This is another of - those functions in the library with a now-not-accurate name - that's being maintained for compatibility with outside code. - This function is used even if display connection is parallel. - @param b 8-bit value to write. -*/ -void Adafruit_SPITFT::spiWrite(uint8_t b) { - if(connection == TFT_HARD_SPI) { -#if defined(__AVR__) - AVR_WRITESPI(b); -#elif defined(ESP8266) || defined(ESP32) - hwspi._spi->write(b); -#else - hwspi._spi->transfer(b); -#endif - } else if(connection == TFT_SOFT_SPI) { - for(uint8_t bit=0; bit<8; bit++) { - if(b & 0x80) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - b <<= 1; - SPI_SCK_LOW(); - } - } else { // TFT_PARALLEL -#if defined(__AVR__) - *tft8.writePort = b; -#elif defined(USE_FAST_PINIO) - if(!tft8.wide) *tft8.writePort = b; - else *(volatile uint16_t *)tft8.writePort = b; -#endif - TFT_WR_STROBE(); - } -} - -/*! - @brief Write a single command byte to the display. Chip-select and - transaction must have been previously set -- this ONLY sets - the device to COMMAND mode, issues the byte and then restores - DATA mode. There is no corresponding explicit writeData() - function -- just use spiWrite(). - @param cmd 8-bit command to write. -*/ -void Adafruit_SPITFT::writeCommand(uint8_t cmd) { - SPI_DC_LOW(); - spiWrite(cmd); - SPI_DC_HIGH(); -} - -/*! - @brief Read a single 8-bit value from the display. Chip-select and - transaction must have been previously set -- this ONLY reads - the byte. This is another of those functions in the library - with a now-not-accurate name that's being maintained for - compatibility with outside code. This function is used even if - display connection is parallel. - @return Unsigned 8-bit value read (always zero if USE_FAST_PINIO is - not supported by the MCU architecture). -*/ -uint8_t Adafruit_SPITFT::spiRead(void) { - uint8_t b = 0; - uint16_t w = 0; - if(connection == TFT_HARD_SPI) { - return hwspi._spi->transfer((uint8_t)0); - } else if(connection == TFT_SOFT_SPI) { - if(swspi._miso >= 0) { - for(uint8_t i=0; i<8; i++) { - SPI_SCK_HIGH(); - b <<= 1; - if(SPI_MISO_READ()) b++; - SPI_SCK_LOW(); - } - } - return b; - } else { // TFT_PARALLEL - if(tft8._rd >= 0) { -#if defined(USE_FAST_PINIO) - TFT_RD_LOW(); // Read line LOW - #if defined(__AVR__) - *tft8.portDir = 0x00; // Set port to input state - w = *tft8.readPort; // Read value from port - *tft8.portDir = 0xFF; // Restore port to output - #else // !__AVR__ - if(!tft8.wide) { // 8-bit TFT connection - #if defined(HAS_PORT_SET_CLR) - *tft8.dirClr = 0xFF; // Set port to input state - w = *tft8.readPort; // Read value from port - *tft8.dirSet = 0xFF; // Restore port to output - #else // !HAS_PORT_SET_CLR - *tft8.portDir = 0x00; // Set port to input state - w = *tft8.readPort; // Read value from port - *tft8.portDir = 0xFF; // Restore port to output - #endif // end HAS_PORT_SET_CLR - } else { // 16-bit TFT connection - #if defined(HAS_PORT_SET_CLR) - *(volatile uint16_t *)tft8.dirClr = 0xFFFF; // Input state - w = *(volatile uint16_t *)tft8.readPort; // 16-bit read - *(volatile uint16_t *)tft8.dirSet = 0xFFFF; // Output state - #else // !HAS_PORT_SET_CLR - *(volatile uint16_t *)tft8.portDir = 0x0000; // Input state - w = *(volatile uint16_t *)tft8.readPort; // 16-bit read - *(volatile uint16_t *)tft8.portDir = 0xFFFF; // Output state - #endif // end !HAS_PORT_SET_CLR - } - TFT_RD_HIGH(); // Read line HIGH - #endif // end !__AVR__ -#else // !USE_FAST_PINIO - w = 0; // Parallel TFT is NOT SUPPORTED without USE_FAST_PINIO -#endif // end !USE_FAST_PINIO - } - return w; - } -} - -/*! - @brief Set the software (bitbang) SPI MOSI line HIGH. -*/ -inline void Adafruit_SPITFT::SPI_MOSI_HIGH(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *swspi.mosiPortSet = 1; - #else // !KINETISK - *swspi.mosiPortSet = swspi.mosiPinMask; - #endif - #else // !HAS_PORT_SET_CLR - *swspi.mosiPort |= swspi.mosiPinMaskSet; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(swspi._mosi, HIGH); - #if defined(ESP32) - for(volatile uint8_t i=0; i<1; i++); - #endif // end ESP32 -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Set the software (bitbang) SPI MOSI line LOW. -*/ -inline void Adafruit_SPITFT::SPI_MOSI_LOW(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *swspi.mosiPortClr = 1; - #else // !KINETISK - *swspi.mosiPortClr = swspi.mosiPinMask; - #endif - #else // !HAS_PORT_SET_CLR - *swspi.mosiPort &= swspi.mosiPinMaskClr; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(swspi._mosi, LOW); - #if defined(ESP32) - for(volatile uint8_t i=0; i<1; i++); - #endif // end ESP32 -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Set the software (bitbang) SPI SCK line HIGH. -*/ -inline void Adafruit_SPITFT::SPI_SCK_HIGH(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *swspi.sckPortSet = 1; - #else // !KINETISK - *swspi.sckPortSet = swspi.sckPinMask; - #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x - for(volatile uint8_t i=0; i<1; i++); - #endif - #endif - #else // !HAS_PORT_SET_CLR - *swspi.sckPort |= swspi.sckPinMaskSet; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(swspi._sck, HIGH); - #if defined(ESP32) - for(volatile uint8_t i=0; i<1; i++); - #endif // end ESP32 -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Set the software (bitbang) SPI SCK line LOW. -*/ -inline void Adafruit_SPITFT::SPI_SCK_LOW(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *swspi.sckPortClr = 1; - #else // !KINETISK - *swspi.sckPortClr = swspi.sckPinMask; - #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x - for(volatile uint8_t i=0; i<1; i++); - #endif - #endif - #else // !HAS_PORT_SET_CLR - *swspi.sckPort &= swspi.sckPinMaskClr; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(swspi._sck, LOW); - #if defined(ESP32) - for(volatile uint8_t i=0; i<1; i++); - #endif // end ESP32 -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Read the state of the software (bitbang) SPI MISO line. - @return true if HIGH, false if LOW. -*/ -inline bool Adafruit_SPITFT::SPI_MISO_READ(void) { -#if defined(USE_FAST_PINIO) - #if defined(KINETISK) - return *swspi.misoPort; - #else // !KINETISK - return *swspi.misoPort & swspi.misoPinMask; - #endif // end !KINETISK -#else // !USE_FAST_PINIO - return digitalRead(swspi._miso); -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Issue a single 16-bit value to the display. Chip-select, - transaction and data/command selection must have been - previously set -- this ONLY issues the word. Despite the name, - this function is used even if display connection is parallel; - name was maintaned for backward compatibility. Naming is also - not consistent with the 8-bit version, spiWrite(). Sorry about - that. Again, staying compatible with outside code. - @param w 16-bit value to write. -*/ -void Adafruit_SPITFT::SPI_WRITE16(uint16_t w) { - if(connection == TFT_HARD_SPI) { -#if defined(__AVR__) - AVR_WRITESPI(w >> 8); - AVR_WRITESPI(w); -#elif defined(ESP8266) || defined(ESP32) - hwspi._spi->write16(w); -#else - hwspi._spi->transfer(w >> 8); - hwspi._spi->transfer(w); -#endif - } else if(connection == TFT_SOFT_SPI) { - for(uint8_t bit=0; bit<16; bit++) { - if(w & 0x8000) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - SPI_SCK_LOW(); - w <<= 1; - } - } else { // TFT_PARALLEL -#if defined(__AVR__) - *tft8.writePort = w >> 8; - TFT_WR_STROBE(); - *tft8.writePort = w; -#elif defined(USE_FAST_PINIO) - if(!tft8.wide) { - *tft8.writePort = w >> 8; - TFT_WR_STROBE(); - *tft8.writePort = w; - } else { - *(volatile uint16_t *)tft8.writePort = w; - } -#endif - TFT_WR_STROBE(); - } -} - -/*! - @brief Issue a single 32-bit value to the display. Chip-select, - transaction and data/command selection must have been - previously set -- this ONLY issues the longword. Despite the - name, this function is used even if display connection is - parallel; name was maintaned for backward compatibility. Naming - is also not consistent with the 8-bit version, spiWrite(). - Sorry about that. Again, staying compatible with outside code. - @param l 32-bit value to write. -*/ -void Adafruit_SPITFT::SPI_WRITE32(uint32_t l) { - if(connection == TFT_HARD_SPI) { -#if defined(__AVR__) - AVR_WRITESPI(l >> 24); - AVR_WRITESPI(l >> 16); - AVR_WRITESPI(l >> 8); - AVR_WRITESPI(l ); -#elif defined(ESP8266) || defined(ESP32) - hwspi._spi->write32(l); -#else - hwspi._spi->transfer(l >> 24); - hwspi._spi->transfer(l >> 16); - hwspi._spi->transfer(l >> 8); - hwspi._spi->transfer(l); -#endif - } else if(connection == TFT_SOFT_SPI) { - for(uint8_t bit=0; bit<32; bit++) { - if(l & 0x80000000) SPI_MOSI_HIGH(); - else SPI_MOSI_LOW(); - SPI_SCK_HIGH(); - SPI_SCK_LOW(); - l <<= 1; - } - } else { // TFT_PARALLEL -#if defined(__AVR__) - *tft8.writePort = l >> 24; - TFT_WR_STROBE(); - *tft8.writePort = l >> 16; - TFT_WR_STROBE(); - *tft8.writePort = l >> 8; - TFT_WR_STROBE(); - *tft8.writePort = l; -#elif defined(USE_FAST_PINIO) - if(!tft8.wide) { - *tft8.writePort = l >> 24; - TFT_WR_STROBE(); - *tft8.writePort = l >> 16; - TFT_WR_STROBE(); - *tft8.writePort = l >> 8; - TFT_WR_STROBE(); - *tft8.writePort = l; - } else { - *(volatile uint16_t *)tft8.writePort = l >> 16; - TFT_WR_STROBE(); - *(volatile uint16_t *)tft8.writePort = l; - } -#endif - TFT_WR_STROBE(); - } -} - -/*! - @brief Set the WR line LOW, then HIGH. Used for parallel-connected - interfaces when writing data. -*/ -inline void Adafruit_SPITFT::TFT_WR_STROBE(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *tft8.wrPortClr = 1; - *tft8.wrPortSet = 1; - #else // !KINETISK - *tft8.wrPortClr = tft8.wrPinMask; - *tft8.wrPortSet = tft8.wrPinMask; - #endif // end !KINETISK - #else // !HAS_PORT_SET_CLR - *tft8.wrPort &= tft8.wrPinMaskClr; - *tft8.wrPort |= tft8.wrPinMaskSet; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(tft8._wr, LOW); - digitalWrite(tft8._wr, HIGH); -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Set the RD line HIGH. Used for parallel-connected interfaces - when reading data. -*/ -inline void Adafruit_SPITFT::TFT_RD_HIGH(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - *tft8.rdPortSet = tft8.rdPinMask; - #else // !HAS_PORT_SET_CLR - *tft8.rdPort |= tft8.rdPinMaskSet; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(tft8._rd, HIGH); -#endif // end !USE_FAST_PINIO -} - -/*! - @brief Set the RD line LOW. Used for parallel-connected interfaces - when reading data. -*/ -inline void Adafruit_SPITFT::TFT_RD_LOW(void) { -#if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - *tft8.rdPortClr = tft8.rdPinMask; - #else // !HAS_PORT_SET_CLR - *tft8.rdPort &= tft8.rdPinMaskClr; - #endif // end !HAS_PORT_SET_CLR -#else // !USE_FAST_PINIO - digitalWrite(tft8._rd, LOW); -#endif // end !USE_FAST_PINIO -} - -#endif // end __AVR_ATtiny85__ diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h deleted file mode 100644 index dcfc1646b..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SPITFT_Renderer.h +++ /dev/null @@ -1,520 +0,0 @@ -/*! - * @file Adafruit_SPITFT.h - * - * Part of Adafruit's GFX graphics library. Originally this class was - * written to handle a range of color TFT displays connected via SPI, - * but over time this library and some display-specific subclasses have - * mutated to include some color OLEDs as well as parallel-interfaced - * displays. The name's been kept for the sake of older code. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * Written by Limor "ladyada" Fried for Adafruit Industries, - * with contributions from the open source community. - * - * BSD license, all text here must be included in any redistribution. - */ - -#ifndef _ADAFRUIT_SPITFT_H_ -#define _ADAFRUIT_SPITFT_H_ - -#if !defined(__AVR_ATtiny85__) // Not for ATtiny, at all - -#include -#include "Adafruit_GFX.h" -#include "renderer.h" - -// HARDWARE CONFIG --------------------------------------------------------- - -#if defined(__AVR__) - typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit - #define USE_FAST_PINIO ///< Use direct PORT register access -#elif defined(ARDUINO_STM32_FEATHER) // WICED - typedef class HardwareSPI SPIClass; ///< SPI is a bit odd on WICED - typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit -#elif defined(__arm__) - #if defined(ARDUINO_ARCH_SAMD) - // Adafruit M0, M4 - typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit - #define USE_FAST_PINIO ///< Use direct PORT register access - #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers - #elif defined(CORE_TEENSY) - // PJRC Teensy 4.x - #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x - typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit - // PJRC Teensy 3.x - #else - typedef uint8_t ADAGFX_PORT_t; ///< PORT values are 8-bit - #endif - #define USE_FAST_PINIO ///< Use direct PORT register access - #define HAS_PORT_SET_CLR ///< PORTs have set & clear registers - #else - // Arduino Due? - typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit - // USE_FAST_PINIO not available here (yet)...Due has a totally different - // GPIO register set and will require some changes elsewhere (e.g. in - // constructors especially). - #endif -#else // !ARM - // Probably ESP8266 or ESP32. USE_FAST_PINIO is not available here (yet) - // but don't worry about it too much...the digitalWrite() implementation - // on these platforms is reasonably efficient and already RAM-resident, - // only gotcha then is no parallel connection support for now. - typedef uint32_t ADAGFX_PORT_t; ///< PORT values are 32-bit -#endif // end !ARM -typedef volatile ADAGFX_PORT_t* PORTreg_t; ///< PORT register type - -#if defined(__AVR__) - #define DEFAULT_SPI_FREQ 8000000L ///< Hardware SPI default speed -#else - #define DEFAULT_SPI_FREQ 16000000L ///< Hardware SPI default speed -#endif - -#if defined(ADAFRUIT_PYPORTAL) || defined(ADAFRUIT_PYBADGE_M4_EXPRESS) || defined(ADAFRUIT_PYGAMER_M4_EXPRESS) - #define USE_SPI_DMA ///< Auto DMA if using PyPortal -#else - //#define USE_SPI_DMA ///< If set, use DMA if available -#endif -// Another "oops" name -- this now also handles parallel DMA. -// If DMA is enabled, Arduino sketch MUST #include -// Estimated RAM usage: -// 4 bytes/pixel on display major axis + 8 bytes/pixel on minor axis, -// e.g. 320x240 pixels = 320 * 4 + 240 * 8 = 3,200 bytes. - -#if !defined(ARDUINO_ARCH_SAMD) - #undef USE_SPI_DMA ///< DMA currently for SAMD chips only -#endif - -#if defined(USE_SPI_DMA) - #pragma message ("GFX DMA IS ENABLED. HIGHLY EXPERIMENTAL.") - #include -#endif - -// This is kind of a kludge. Needed a way to disambiguate the software SPI -// and parallel constructors via their argument lists. Originally tried a -// bool as the first argument to the parallel constructor (specifying 8-bit -// vs 16-bit interface) but the compiler regards this as equivalent to an -// integer and thus still ambiguous. SO...the parallel constructor requires -// an enumerated type as the first argument: tft8 (for 8-bit parallel) or -// tft16 (for 16-bit)...even though 16-bit isn't fully implemented or tested -// and might never be, still needed that disambiguation from soft SPI. -enum tftBusWidth { tft8bitbus, tft16bitbus }; ///< For first arg to parallel constructor - -// CLASS DEFINITION -------------------------------------------------------- - -/*! - @brief Adafruit_SPITFT is an intermediary class between Adafruit_GFX - and various hardware-specific subclasses for different displays. - It handles certain operations that are common to a range of - displays (address window, area fills, etc.). Originally these were - all color TFT displays interfaced via SPI, but it's since expanded - to include color OLEDs and parallel-interfaced TFTs. THE NAME HAS - BEEN KEPT TO AVOID BREAKING A LOT OF SUBCLASSES AND EXAMPLE CODE. - Many of the class member functions similarly live on with names - that don't necessarily accurately describe what they're doing, - again to avoid breaking a lot of other code. If in doubt, read - the comments. -*/ -class Adafruit_SPITFT : public Renderer { - - public: - - // CONSTRUCTORS -------------------------------------------------------- - - // Software SPI constructor: expects width & height (at default rotation - // setting 0), 4 signal pins (cs, dc, mosi, sclk), 2 optional pins - // (reset, miso). cs argument is required but can be -1 if unused -- - // rather than moving it to the optional arguments, it was done this way - // to avoid breaking existing code (-1 option was a later addition). - Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t mosi, int8_t sck, - int8_t rst = -1, int8_t miso = -1); - - // Hardware SPI constructor using the default SPI port: expects width & - // height (at default rotation setting 0), 2 signal pins (cs, dc), - // optional reset pin. cs is required but can be -1 if unused -- rather - // than moving it to the optional arguments, it was done this way to - // avoid breaking existing code (-1 option was a later addition). - Adafruit_SPITFT(uint16_t w, uint16_t h, - int8_t cs, int8_t dc, int8_t rst = -1); - -#if !defined(ESP8266) // See notes in .cpp - // Hardware SPI constructor using an arbitrary SPI peripheral: expects - // width & height (rotation 0), SPIClass pointer, 2 signal pins (cs, dc) - // and optional reset pin. cs is required but can be -1 if unused. - Adafruit_SPITFT(uint16_t w, uint16_t h, SPIClass *spiClass, - int8_t cs, int8_t dc, int8_t rst = -1); -#endif // end !ESP8266 - - // Parallel constructor: expects width & height (rotation 0), flag - // indicating whether 16-bit (true) or 8-bit (false) interface, 3 signal - // pins (d0, wr, dc), 3 optional pins (cs, rst, rd). 16-bit parallel - // isn't even fully implemented but the 'wide' flag was added as a - // required argument to avoid ambiguity with other constructors. - Adafruit_SPITFT(uint16_t w, uint16_t h, tftBusWidth busWidth, - int8_t d0, int8_t wr, int8_t dc, - int8_t cs = -1, int8_t rst = -1, int8_t rd = -1); - - // CLASS MEMBER FUNCTIONS ---------------------------------------------- - - // These first two functions MUST be declared by subclasses: - - /*! - @brief Display-specific initialization function. - @param freq SPI frequency, in hz (or 0 for default or unused). - */ - virtual void begin(uint32_t freq) = 0; - - /*! - @brief Set up the specific display hardware's "address window" - for subsequent pixel-pushing operations. - @param x Leftmost pixel of area to be drawn (MUST be within - display bounds at current rotation setting). - @param y Topmost pixel of area to be drawn (MUST be within - display bounds at current rotation setting). - @param w Width of area to be drawn, in pixels (MUST be >0 and, - added to x, within display bounds at current rotation). - @param h Height of area to be drawn, in pixels (MUST be >0 and, - added to x, within display bounds at current rotation). - */ - virtual void setAddrWindow( - uint16_t x, uint16_t y, uint16_t w, uint16_t h) = 0; - - // Remaining functions do not need to be declared in subclasses - // unless they wish to provide hardware-specific optimizations. - // Brief comments here...documented more thoroughly in .cpp file. - - // Subclass' begin() function invokes this to initialize hardware. - // freq=0 to use default SPI speed. spiMode must be one of the SPI_MODEn - // values defined in SPI.h, which are NOT the same as 0 for SPI_MODE0, - // 1 for SPI_MODE1, etc...use ONLY the SPI_MODEn defines! Only! - // Name is outdated (interface may be parallel) but for compatibility: - void initSPI(uint32_t freq = 0, uint8_t spiMode = SPI_MODE0); - // Chip select and/or hardware SPI transaction start as needed: - void startWrite(void); - // Chip deselect and/or hardware SPI transaction end as needed: - void endWrite(void); - void sendCommand(uint8_t commandByte, uint8_t *dataBytes = NULL, uint8_t numDataBytes = 0); - void sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes); - uint8_t readcommand8(uint8_t commandByte, uint8_t index = 0); - - // These functions require a chip-select and/or SPI transaction - // around them. Higher-level graphics primitives might start a - // single transaction and then make multiple calls to these functions - // (e.g. circle or text rendering might make repeated lines or rects) - // before ending the transaction. It's more efficient than starting a - // transaction every time. - void writePixel(int16_t x, int16_t y, uint16_t color); - void writePixels(uint16_t *colors, uint32_t len, - bool block=true, bool bigEndian=false); - void writeColor(uint16_t color, uint32_t len); - void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color); - void writeFastHLine(int16_t x, int16_t y, int16_t w, - uint16_t color); - void writeFastVLine(int16_t x, int16_t y, int16_t h, - uint16_t color); - // This is a new function, similar to writeFillRect() except that - // all arguments MUST be onscreen, sorted and clipped. If higher-level - // primitives can handle their own sorting/clipping, it avoids repeating - // such operations in the low-level code, making it potentially faster. - // CALLING THIS WITH UNCLIPPED OR NEGATIVE VALUES COULD BE DISASTROUS. - inline void writeFillRectPreclipped(int16_t x, int16_t y, - int16_t w, int16_t h, uint16_t color); - // Another new function, companion to the new non-blocking - // writePixels() variant. - void dmaWait(void); - - - // These functions are similar to the 'write' functions above, but with - // a chip-select and/or SPI transaction built-in. They're typically used - // solo -- that is, as graphics primitives in themselves, not invoked by - // higher-level primitives (which should use the functions above). - void drawPixel(int16_t x, int16_t y, uint16_t color); - void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color); - void drawFastHLine(int16_t x, int16_t y, int16_t w, - uint16_t color); - void drawFastVLine(int16_t x, int16_t y, int16_t h, - uint16_t color); - // A single-pixel push encapsulated in a transaction. I don't think - // this is used anymore (BMP demos might've used it?) but is provided - // for backward compatibility, consider it deprecated: - void pushColor(uint16_t color); - - using Adafruit_GFX::drawRGBBitmap; // Check base class first - void drawRGBBitmap(int16_t x, int16_t y, - uint16_t *pcolors, int16_t w, int16_t h); - - void invertDisplay(bool i); - uint16_t color565(uint8_t r, uint8_t g, uint8_t b); - - // Despite parallel additions, function names kept for compatibility: - void spiWrite(uint8_t b); // Write single byte as DATA - void writeCommand(uint8_t cmd); // Write single byte as COMMAND - uint8_t spiRead(void); // Read single byte of data - - // Most of these low-level functions were formerly macros in - // Adafruit_SPITFT_Macros.h. Some have been made into inline functions - // to avoid macro mishaps. Despite the addition of code for a parallel - // display interface, the names have been kept for backward - // compatibility (some subclasses may be invoking these): - void SPI_WRITE16(uint16_t w); // Not inline - void SPI_WRITE32(uint32_t l); // Not inline - // Old code had both a spiWrite16() function and SPI_WRITE16 macro - // in addition to the SPI_WRITE32 macro. The latter two have been - // made into functions here, and spiWrite16() removed (use SPI_WRITE16() - // instead). It looks like most subclasses had gotten comfortable with - // SPI_WRITE16 and SPI_WRITE32 anyway so those names were kept rather - // than the less-obnoxious camelcase variants, oh well. - - // Placing these functions entirely in the class definition inlines - // them implicitly them while allowing their use in other code: - - /*! - @brief Set the chip-select line HIGH. Does NOT check whether CS pin - is set (>=0), that should be handled in calling function. - Despite function name, this is used even if the display - connection is parallel. - */ - void SPI_CS_HIGH(void) { - #if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *csPortSet = 1; - #else // !KINETISK - *csPortSet = csPinMask; - #endif // end !KINETISK - #else // !HAS_PORT_SET_CLR - *csPort |= csPinMaskSet; - #endif // end !HAS_PORT_SET_CLR - #else // !USE_FAST_PINIO - digitalWrite(_cs, HIGH); - #endif // end !USE_FAST_PINIO - } - - /*! - @brief Set the chip-select line LOW. Does NOT check whether CS pin - is set (>=0), that should be handled in calling function. - Despite function name, this is used even if the display - connection is parallel. - */ - void SPI_CS_LOW(void) { - #if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *csPortClr = 1; - #else // !KINETISK - *csPortClr = csPinMask; - #endif // end !KINETISK - #else // !HAS_PORT_SET_CLR - *csPort &= csPinMaskClr; - #endif // end !HAS_PORT_SET_CLR - #else // !USE_FAST_PINIO - digitalWrite(_cs, LOW); - #endif // end !USE_FAST_PINIO - } - - /*! - @brief Set the data/command line HIGH (data mode). - */ - void SPI_DC_HIGH(void) { - #if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *dcPortSet = 1; - #else // !KINETISK - *dcPortSet = dcPinMask; - #endif // end !KINETISK - #else // !HAS_PORT_SET_CLR - *dcPort |= dcPinMaskSet; - #endif // end !HAS_PORT_SET_CLR - #else // !USE_FAST_PINIO - digitalWrite(_dc, HIGH); - #endif // end !USE_FAST_PINIO - } - - /*! - @brief Set the data/command line LOW (command mode). - */ - void SPI_DC_LOW(void) { - #if defined(USE_FAST_PINIO) - #if defined(HAS_PORT_SET_CLR) - #if defined(KINETISK) - *dcPortClr = 1; - #else // !KINETISK - *dcPortClr = dcPinMask; - #endif // end !KINETISK - #else // !HAS_PORT_SET_CLR - *dcPort &= dcPinMaskClr; - #endif // end !HAS_PORT_SET_CLR - #else // !USE_FAST_PINIO - digitalWrite(_dc, LOW); - #endif // end !USE_FAST_PINIO - } - - protected: - - // A few more low-level member functions -- some may have previously - // been macros. Shouldn't have a need to access these externally, so - // they've been moved to the protected section. Additionally, they're - // declared inline here and the code is in the .cpp file, since outside - // code doesn't need to see these. - inline void SPI_MOSI_HIGH(void); - inline void SPI_MOSI_LOW(void); - inline void SPI_SCK_HIGH(void); - inline void SPI_SCK_LOW(void); - inline bool SPI_MISO_READ(void); - inline void SPI_BEGIN_TRANSACTION(void); - inline void SPI_END_TRANSACTION(void); - inline void TFT_WR_STROBE(void); // Parallel interface write strobe - inline void TFT_RD_HIGH(void); // Parallel interface read high - inline void TFT_RD_LOW(void); // Parallel interface read low - - // CLASS INSTANCE VARIABLES -------------------------------------------- - - // Here be dragons! There's a big union of three structures here -- - // one each for hardware SPI, software (bitbang) SPI, and parallel - // interfaces. This is to save some memory, since a display's connection - // will be only one of these. The order of some things is a little weird - // in an attempt to get values to align and pack better in RAM. - -#if defined(USE_FAST_PINIO) -#if defined(HAS_PORT_SET_CLR) - PORTreg_t csPortSet; ///< PORT register for chip select SET - PORTreg_t csPortClr; ///< PORT register for chip select CLEAR - PORTreg_t dcPortSet; ///< PORT register for data/command SET - PORTreg_t dcPortClr; ///< PORT register for data/command CLEAR -#else // !HAS_PORT_SET_CLR - PORTreg_t csPort; ///< PORT register for chip select - PORTreg_t dcPort; ///< PORT register for data/command -#endif // end HAS_PORT_SET_CLR -#endif // end USE_FAST_PINIO -#if defined(__cplusplus) && (__cplusplus >= 201100) - union { -#endif - struct { // Values specific to HARDWARE SPI: - SPIClass *_spi; ///< SPI class pointer -#if defined(SPI_HAS_TRANSACTION) - SPISettings settings; ///< SPI transaction settings -#else - uint32_t _freq; ///< SPI bitrate (if no SPI transactions) -#endif - uint32_t _mode; ///< SPI data mode (transactions or no) - } hwspi; ///< Hardware SPI values - struct { // Values specific to SOFTWARE SPI: -#if defined(USE_FAST_PINIO) - PORTreg_t misoPort; ///< PORT (PIN) register for MISO -#if defined(HAS_PORT_SET_CLR) - PORTreg_t mosiPortSet; ///< PORT register for MOSI SET - PORTreg_t mosiPortClr; ///< PORT register for MOSI CLEAR - PORTreg_t sckPortSet; ///< PORT register for SCK SET - PORTreg_t sckPortClr; ///< PORT register for SCK CLEAR - #if !defined(KINETISK) - ADAGFX_PORT_t mosiPinMask; ///< Bitmask for MOSI - ADAGFX_PORT_t sckPinMask; ///< Bitmask for SCK - #endif // end !KINETISK -#else // !HAS_PORT_SET_CLR - PORTreg_t mosiPort; ///< PORT register for MOSI - PORTreg_t sckPort; ///< PORT register for SCK - ADAGFX_PORT_t mosiPinMaskSet; ///< Bitmask for MOSI SET (OR) - ADAGFX_PORT_t mosiPinMaskClr; ///< Bitmask for MOSI CLEAR (AND) - ADAGFX_PORT_t sckPinMaskSet; ///< Bitmask for SCK SET (OR bitmask) - ADAGFX_PORT_t sckPinMaskClr; ///< Bitmask for SCK CLEAR (AND) -#endif // end HAS_PORT_SET_CLR - #if !defined(KINETISK) - ADAGFX_PORT_t misoPinMask; ///< Bitmask for MISO - #endif // end !KINETISK -#endif // end USE_FAST_PINIO - int8_t _mosi; ///< MOSI pin # - int8_t _miso; ///< MISO pin # - int8_t _sck; ///< SCK pin # - } swspi; ///< Software SPI values - struct { // Values specific to 8-bit parallel: -#if defined(USE_FAST_PINIO) - - #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x - volatile uint32_t *writePort; ///< PORT register for DATA WRITE - volatile uint32_t *readPort; ///< PORT (PIN) register for DATA READ - #else - volatile uint8_t *writePort; ///< PORT register for DATA WRITE - volatile uint8_t *readPort; ///< PORT (PIN) register for DATA READ - #endif -#if defined(HAS_PORT_SET_CLR) - // Port direction register pointers are always 8-bit regardless of - // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits. - #if defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x - volatile uint32_t *dirSet; ///< PORT byte data direction SET - volatile uint32_t *dirClr; ///< PORT byte data direction CLEAR - #else - volatile uint8_t *dirSet; ///< PORT byte data direction SET - volatile uint8_t *dirClr; ///< PORT byte data direction CLEAR - #endif - PORTreg_t wrPortSet; ///< PORT register for write strobe SET - PORTreg_t wrPortClr; ///< PORT register for write strobe CLEAR - PORTreg_t rdPortSet; ///< PORT register for read strobe SET - PORTreg_t rdPortClr; ///< PORT register for read strobe CLEAR - #if !defined(KINETISK) - ADAGFX_PORT_t wrPinMask; ///< Bitmask for write strobe - #endif // end !KINETISK - ADAGFX_PORT_t rdPinMask; ///< Bitmask for read strobe -#else // !HAS_PORT_SET_CLR - // Port direction register pointer is always 8-bit regardless of - // PORTreg_t -- even if 32-bit port, we modify a byte-aligned 8 bits. - volatile uint8_t *portDir; ///< PORT direction register - PORTreg_t wrPort; ///< PORT register for write strobe - PORTreg_t rdPort; ///< PORT register for read strobe - ADAGFX_PORT_t wrPinMaskSet; ///< Bitmask for write strobe SET (OR) - ADAGFX_PORT_t wrPinMaskClr; ///< Bitmask for write strobe CLEAR (AND) - ADAGFX_PORT_t rdPinMaskSet; ///< Bitmask for read strobe SET (OR) - ADAGFX_PORT_t rdPinMaskClr; ///< Bitmask for read strobe CLEAR (AND) -#endif // end HAS_PORT_SET_CLR -#endif // end USE_FAST_PINIO - int8_t _d0; ///< Data pin 0 # - int8_t _wr; ///< Write strobe pin # - int8_t _rd; ///< Read strobe pin # (or -1) - bool wide = 0; ///< If true, is 16-bit interface - } tft8; ///< Parallel interface settings -#if defined(__cplusplus) && (__cplusplus >= 201100) - }; ///< Only one interface is active -#endif -#if defined(USE_SPI_DMA) // Used by hardware SPI and tft8 - Adafruit_ZeroDMA dma; ///< DMA instance - DmacDescriptor *dptr = NULL; ///< 1st descriptor - DmacDescriptor *descriptor = NULL; ///< Allocated descriptor list - uint16_t *pixelBuf[2]; ///< Working buffers - uint16_t maxFillLen; ///< Max pixels per DMA xfer - uint16_t lastFillColor = 0; ///< Last color used w/fill - uint32_t lastFillLen = 0; ///< # of pixels w/last fill - uint8_t onePixelBuf; ///< For hi==lo fill -#endif -#if defined(USE_FAST_PINIO) -#if defined(HAS_PORT_SET_CLR) - #if !defined(KINETISK) - ADAGFX_PORT_t csPinMask; ///< Bitmask for chip select - ADAGFX_PORT_t dcPinMask; ///< Bitmask for data/command - #endif // end !KINETISK -#else // !HAS_PORT_SET_CLR - ADAGFX_PORT_t csPinMaskSet; ///< Bitmask for chip select SET (OR) - ADAGFX_PORT_t csPinMaskClr; ///< Bitmask for chip select CLEAR (AND) - ADAGFX_PORT_t dcPinMaskSet; ///< Bitmask for data/command SET (OR) - ADAGFX_PORT_t dcPinMaskClr; ///< Bitmask for data/command CLEAR (AND) -#endif // end HAS_PORT_SET_CLR -#endif // end USE_FAST_PINIO - uint8_t connection; ///< TFT_HARD_SPI, TFT_SOFT_SPI, etc. - int8_t _rst; ///< Reset pin # (or -1) - int8_t _cs; ///< Chip select pin # (or -1) - int8_t _dc; ///< Data/command pin # - - int16_t _xstart = 0; ///< Internal framebuffer X offset - int16_t _ystart = 0; ///< Internal framebuffer Y offset - uint8_t invertOnCommand = 0; ///< Command to enable invert mode - uint8_t invertOffCommand = 0; ///< Command to disable invert mode - - uint32_t _freq = 0; ///< Dummy var to keep subclasses happy -}; - -#endif // end __AVR_ATtiny85__ -#endif // end _ADAFRUIT_SPITFT_H_ diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp deleted file mode 100644 index 78d9901d6..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/*! - * @file Adafruit_SSD1331.cpp - * - * @mainpage Adafruit SSD1331 Arduino Library - * - * @section intro_sec Introduction - * - * This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip - * - * Pick one up today in the adafruit shop! - * ------> http://www.adafruit.com/products/684 - * - * These displays use SPI to communicate, 4 or 5 pins are required to - * interface - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * @section author Author - * - * Written by Limor Fried/Ladyada for Adafruit Industries. - * - * @section license License - * - * BSD license, all text above must be included in any redistribution - */ - -#include "Adafruit_SSD1331.h" -#include "pins_arduino.h" -#include "wiring_private.h" - -/***********************************/ - -/*! - @brief SPI displays set an address window rectangle for blitting pixels - @param x Top left corner x coordinate - @param y Top left corner x coordinate - @param w Width of window - @param h Height of window -*/ -void Adafruit_SSD1331::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, - uint16_t h) { - - uint8_t x1 = x; - uint8_t y1 = y; - if (x1 > 95) - x1 = 95; - if (y1 > 63) - y1 = 63; - - uint8_t x2 = (x + w - 1); - uint8_t y2 = (y + h - 1); - if (x2 > 95) - x2 = 95; - if (y2 > 63) - y2 = 63; - - if (x1 > x2) { - uint8_t t = x2; - x2 = x1; - x1 = t; - } - if (y1 > y2) { - uint8_t t = y2; - y2 = y1; - y1 = t; - } - - sendCommand(0x15); // Column addr set - sendCommand(x1); - sendCommand(x2); - - sendCommand(0x75); // Column addr set - sendCommand(y1); - sendCommand(y2); - - startWrite(); -} - -/**************************************************************************/ -/*! - @brief Initialize SSD1331 chip - Connects to the SSD1331 over SPI and sends initialization procedure commands - @param freq Desired SPI clock frequency -*/ -/**************************************************************************/ -void Adafruit_SSD1331::begin(uint32_t freq) { - initSPI(freq); - - // Initialization Sequence - sendCommand(SSD1331_CMD_DISPLAYOFF); // 0xAE - sendCommand(SSD1331_CMD_SETREMAP); // 0xA0 -#if defined SSD1331_COLORORDER_RGB - sendCommand(0x72); // RGB Color -#else - sendCommand(0x76); // BGR Color -#endif - sendCommand(SSD1331_CMD_STARTLINE); // 0xA1 - sendCommand(0x0); - sendCommand(SSD1331_CMD_DISPLAYOFFSET); // 0xA2 - sendCommand(0x0); - sendCommand(SSD1331_CMD_NORMALDISPLAY); // 0xA4 - sendCommand(SSD1331_CMD_SETMULTIPLEX); // 0xA8 - sendCommand(0x3F); // 0x3F 1/64 duty - sendCommand(SSD1331_CMD_SETMASTER); // 0xAD - sendCommand(0x8E); - sendCommand(SSD1331_CMD_POWERMODE); // 0xB0 - sendCommand(0x0B); - sendCommand(SSD1331_CMD_PRECHARGE); // 0xB1 - sendCommand(0x31); - sendCommand(SSD1331_CMD_CLOCKDIV); // 0xB3 - sendCommand(0xF0); // 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio - // (A[3:0]+1 = 1..16) - sendCommand(SSD1331_CMD_PRECHARGEA); // 0x8A - sendCommand(0x64); - sendCommand(SSD1331_CMD_PRECHARGEB); // 0x8B - sendCommand(0x78); - sendCommand(SSD1331_CMD_PRECHARGEC); // 0x8C - sendCommand(0x64); - sendCommand(SSD1331_CMD_PRECHARGELEVEL); // 0xBB - sendCommand(0x3A); - sendCommand(SSD1331_CMD_VCOMH); // 0xBE - sendCommand(0x3E); - sendCommand(SSD1331_CMD_MASTERCURRENT); // 0x87 - sendCommand(0x06); - sendCommand(SSD1331_CMD_CONTRASTA); // 0x81 - sendCommand(0x91); - sendCommand(SSD1331_CMD_CONTRASTB); // 0x82 - sendCommand(0x50); - sendCommand(SSD1331_CMD_CONTRASTC); // 0x83 - sendCommand(0x7D); - sendCommand(SSD1331_CMD_DISPLAYON); //--turn on oled panel - _width = TFTWIDTH; - _height = TFTHEIGHT; -} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SSD1331 driver with software SPI - @param cs Chip select pin # - @param dc Data/Command pin # - @param mosi SPI MOSI pin # - @param sclk SPI Clock pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi, - int8_t sclk, int8_t rst) - : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, mosi, sclk, rst, -1) {} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SSD1331 driver with hardware SPI - @param cs Chip select pin # - @param dc Data/Command pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SSD1331::Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst) - : Adafruit_SPITFT(TFTWIDTH, TFTHEIGHT, cs, dc, rst) {} - -/**************************************************************************/ -/*! - @brief Instantiate Adafruit SSD1331 driver with hardware SPI - @param spi Pointer to an existing SPIClass instance (e.g. &SPI, the - microcontroller's primary SPI bus). - @param cs Chip select pin # - @param dc Data/Command pin # - @param rst Reset pin # (optional, pass -1 if unused) -*/ -/**************************************************************************/ -Adafruit_SSD1331::Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc, - int8_t rst) - : -#if defined(ESP8266) - Adafruit_SPITFT(TFTWIDTH, TFTWIDTH, cs, dc, rst) { -#else - Adafruit_SPITFT(TFTWIDTH, TFTWIDTH, spi, cs, dc, rst) { -#endif -} - -/**************************************************************************/ -/*! - @brief Change whether display is on or off - @param enable True if you want the display ON, false OFF -*/ -/**************************************************************************/ -void Adafruit_SSD1331::enableDisplay(boolean enable) { - sendCommand(enable ? SSD1331_CMD_DISPLAYON : SSD1331_CMD_DISPLAYOFF); -} diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h b/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h deleted file mode 100644 index 7d9bc85a0..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/Adafruit_SSD1331.h +++ /dev/null @@ -1,76 +0,0 @@ -/*! - * @file Adafruit_SSD1331.h - */ - -#include "Arduino.h" -#include -// Tasmota change: use custom version of Adafruit_SPITFT which extends Renderer instead of Adafruit_GFX -#include -#include -#include - -/*! - * @brief Select one of these defines to set the pixel color order - */ -#define SSD1331_COLORORDER_RGB -// #define SSD1331_COLORORDER_BGR - -#if defined SSD1331_COLORORDER_RGB && defined SSD1331_COLORORDER_BGR -#error "RGB and BGR can not both be defined for SSD1331_COLORODER." -#endif - -// Timing Delays -#define SSD1331_DELAYS_HWFILL (3) //!< Fill delay -#define SSD1331_DELAYS_HWLINE (1) //!< Line delay - -// SSD1331 Commands -#define SSD1331_CMD_DRAWLINE 0x21 //!< Draw line -#define SSD1331_CMD_DRAWRECT 0x22 //!< Draw rectangle -#define SSD1331_CMD_FILL 0x26 //!< Fill enable/disable -#define SSD1331_CMD_SETCOLUMN 0x15 //!< Set column address -#define SSD1331_CMD_SETROW 0x75 //!< Set row adress -#define SSD1331_CMD_CONTRASTA 0x81 //!< Set contrast for color A -#define SSD1331_CMD_CONTRASTB 0x82 //!< Set contrast for color B -#define SSD1331_CMD_CONTRASTC 0x83 //!< Set contrast for color C -#define SSD1331_CMD_MASTERCURRENT 0x87 //!< Master current control -#define SSD1331_CMD_SETREMAP 0xA0 //!< Set re-map & data format -#define SSD1331_CMD_STARTLINE 0xA1 //!< Set display start line -#define SSD1331_CMD_DISPLAYOFFSET 0xA2 //!< Set display offset -#define SSD1331_CMD_NORMALDISPLAY 0xA4 //!< Set display to normal mode -#define SSD1331_CMD_DISPLAYALLON 0xA5 //!< Set entire display ON -#define SSD1331_CMD_DISPLAYALLOFF 0xA6 //!< Set entire display OFF -#define SSD1331_CMD_INVERTDISPLAY 0xA7 //!< Invert display -#define SSD1331_CMD_SETMULTIPLEX 0xA8 //!< Set multiplex ratio -#define SSD1331_CMD_SETMASTER 0xAD //!< Set master configuration -#define SSD1331_CMD_DISPLAYOFF 0xAE //!< Display OFF (sleep mode) -#define SSD1331_CMD_DISPLAYON 0xAF //!< Normal Brightness Display ON -#define SSD1331_CMD_POWERMODE 0xB0 //!< Power save mode -#define SSD1331_CMD_PRECHARGE 0xB1 //!< Phase 1 and 2 period adjustment -#define SSD1331_CMD_CLOCKDIV \ - 0xB3 //!< Set display clock divide ratio/oscillator frequency -#define SSD1331_CMD_PRECHARGEA 0x8A //!< Set second pre-charge speed for color A -#define SSD1331_CMD_PRECHARGEB 0x8B //!< Set second pre-charge speed for color B -#define SSD1331_CMD_PRECHARGEC 0x8C //!< Set second pre-charge speed for color C -#define SSD1331_CMD_PRECHARGELEVEL 0xBB //!< Set pre-charge voltage -#define SSD1331_CMD_VCOMH 0xBE //!< Set Vcomh voltge - -/// Class to manage hardware interface with SSD1331 chipset -class Adafruit_SSD1331 : public Adafruit_SPITFT { -public: - Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk, int8_t rst); - Adafruit_SSD1331(int8_t cs, int8_t dc, int8_t rst); - // 3-4 args using hardware SPI (must specify peripheral) (reset optional) - Adafruit_SSD1331(SPIClass *spi, int8_t cs, int8_t dc, int8_t rst = -1); - - // commands - void begin(uint32_t begin = 8000000); - - void setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h); - - void enableDisplay(boolean enable); - - static const int16_t TFTWIDTH = 96; ///< The width of the display - static const int16_t TFTHEIGHT = 64; ///< The height of the display - -private: -}; diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/README.md b/lib/lib_display/Adafruit_SSD1331-1.2.0/README.md deleted file mode 100644 index 24c404c59..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Adafruit SSD1331 Arduino Library [![Build Status](https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/html/index.html) -This is a library for the 0.96" 16-bit Color OLED with SSD1331 driver chip - - Pick one up today in the adafruit shop! - ------> http://www.adafruit.com/products/684 - -These displays use SPI to communicate, 4 or 5 pins are required to -interface - -Adafruit invests time and resources providing this open source code, -please support Adafruit and open-source hardware by purchasing -products from Adafruit! - -Written by Limor Fried/Ladyada for Adafruit Industries. -BSD license, check license.txt for more information -All text above must be included in any redistribution - -To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_SSD1131. Check that the Adafruit_SSD1331 folder contains Adafruit_SSD1331.cpp and Adafruit_SSD1331.h - -Place the Adafruit_SSD1331 library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. - -You will also have to download the Adafruit GFX Graphics core which does all the circles, text, rectangles, etc. You can get it from -https://github.com/adafruit/Adafruit-GFX-Library -and download/install that library as well diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties b/lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties deleted file mode 100644 index 931f1aa38..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=Adafruit SSD1331 OLED Driver Library for Arduino -version=1.2.0 -author=Adafruit -maintainer=Adafruit -sentence=For 0.96" OLEDs in the Adafruit shop -paragraph=For 0.96" OLEDs in the Adafruit shop -category=Display -url=https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino -architectures=* -depends=Adafruit GFX Library diff --git a/lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt b/lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt deleted file mode 100644 index f6a0f22b8..000000000 --- a/lib/lib_display/Adafruit_SSD1331-1.2.0/license.txt +++ /dev/null @@ -1,26 +0,0 @@ -Software License Agreement (BSD License) - -Copyright (c) 2012, Adafruit Industries -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -3. Neither the name of the copyright holders nor the -names of its contributors may be used to endorse or promote products -derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.