From 8b5adb309583f93116ff3845abab2ee53b30d618 Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Sat, 26 Dec 2020 09:44:01 +0100 Subject: [PATCH 1/4] 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 2/4] 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 3/4] 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 4/4] 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;