diff --git a/tasmota/include/tasmota_configurations_ESP32.h b/tasmota/include/tasmota_configurations_ESP32.h index 4a9716d16..06891b607 100644 --- a/tasmota/include/tasmota_configurations_ESP32.h +++ b/tasmota/include/tasmota_configurations_ESP32.h @@ -606,6 +606,9 @@ #define USE_LIGHT_PALETTE // Add support for color palette (+0k9 code) #define USE_LIGHT_ARTNET // Add support for DMX/ArtNet via UDP on port 6454 (+3.5k code) +#ifdef CONFIG_IDF_TARGET_ESP32C3 +#define USE_MAGIC_SWITCH // Add Sonoff MagicSwitch support as implemented in Sonoff Basic R4 +#endif #define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code) diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index 260e59a46..63779e918 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -214,6 +214,7 @@ enum UserSelectablePins { GPIO_HDMI_CEC, // Support for HDMI CEC GPIO_HC8_RXD, // HC8 Serial interface GPIO_I2S_DAC, // Audio DAC support for ESP32 and ESP32S2 + GPIO_MAGIC_SWITCH, // MagicSwitch as in Sonoff BasicR4 GPIO_SENSOR_END }; // Error as warning to rethink GPIO usage with max 2045 @@ -475,6 +476,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_HDMI_CEC "|" D_SENSOR_HC8_RX "|" D_SENSOR_I2S_DAC "|" + D_GPIO_MAGIC_SWITCH "|" ; const char kSensorNamesFixed[] PROGMEM = @@ -493,6 +495,7 @@ const char kSensorNamesFixed[] PROGMEM = #define MAX_DSB 4 #define MAX_BP1658CJ_DAT 16 #define MAX_DINGTIAN_SHIFT 4 +#define MAX_MAGIC_SWITCH_MODES 2 #define MAX_BL0942_RX 4 // Baudrates 1 (4800), 2 (9600), 3 (19200), 4 (38400) const uint16_t kGpioNiceList[] PROGMEM = { @@ -1143,6 +1146,10 @@ const uint16_t kGpioNiceList[] PROGMEM = { AGPIO(GPIO_DINGTIAN_RCK), #endif +#ifdef USE_MAGIC_SWITCH + AGPIO(GPIO_MAGIC_SWITCH) + MAX_MAGIC_SWITCH_MODES, +#endif + /*-------------------------------------------------------------------------------------------*\ * ESP32 specifics \*-------------------------------------------------------------------------------------------*/ diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 95a4ff647..d90ee06c7 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -288,7 +288,7 @@ #define D_RESET_CONFIGURATION "Stel die konfigurasie terug" #define D_BACKUP_CONFIGURATION "Rugsteun die konfigurasie" #define D_RESTORE_CONFIGURATION "Herstel die konfigurasie" -#define D_START_RESTORE "Start restore" +#define D_START_RESTORE "Start restore" #define D_MAIN_MENU "Hoofkieslys" #define D_MODULE_PARAMETERS "Moduleparameters" @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index b7f00e51a..bffd921e2 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/ca_AD.h b/tasmota/language/ca_AD.h index 4683b5c55..834481513 100644 --- a/tasmota/language/ca_AD.h +++ b/tasmota/language/ca_AD.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 1441d328d..9a8197a40 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 8d5ef0279..c76ddbb29 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 4cf6fc13e..1edf65357 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index aa91d4c55..139316d74 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index 06add4a53..8c0ed3475 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index 861fe57cb..0e89c0560 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index cf4d8a187..436782c93 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index e4199ab15..d489b2f64 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 914ae053a..a9715ef10 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -960,6 +960,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 46b6a50cd..1a412fcff 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -956,7 +956,8 @@ #define D_SENSOR_BIOPDU_PZEM0XX_TX "BioPDU PZEM0XX - TX" #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 - RX" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" -#define D_SENSOR_LOX_O2_RX "LoxO2 - RX" +#define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 9ceffb0ab..8fe87643b 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 9927eb5e0..1ad5fa61f 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index 1f1f44bef..7693b986d 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index 3dac6d2bc..0ee9a4433 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 8ae556c7e..e94a640f2 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index 6f09c9a27..b90c3a960 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index 9de1e95cb..82f01ca3f 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -958,6 +958,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index e943a2438..5ea1875bd 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 72e940b12..99d27f132 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index 259825231..3377a17f6 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index ad9834916..d8b33392d 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "А" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 4f4297646..990f558a0 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index 1c49fd023..dc0a6ec4c 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "A" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index f45bb2b90..992838e00 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -957,6 +957,7 @@ #define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" #define D_SENSOR_BIOPDU_BIT "BioPDU Bit" #define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" // Units #define D_UNIT_AMPERE "安培" diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 2f5543e15..22a7fb877 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -538,6 +538,9 @@ #define SHELLY_CMDS // Add command to send co-processor commands (+0k3 code) #define SHELLY_FW_UPGRADE // Add firmware upgrade option for co-processor (+3k4 code) // #define SHELLY_VOLTAGE_MON // Add support for reading voltage and current measurment (-0k0 code) +//#define USE_MAGIC_SWITCH // Add Sonoff MagicSwitch support as implemented in Sonoff Basic R4 (+612B flash, +64B IRAM for intr) +// #define MAGICSWITCH_MIN_PULSE 4000 // Overridable minimum pulse, also overridable by command MagicSwitchPulse (not saved to flash) +// #define MAGICSWITCH_MASKING_WINDOW_LEN 5 // Overridable masking window (in number of 50ms loops) // -- Optional light modules ---------------------- #define USE_LIGHT // Add support for light control diff --git a/tasmota/tasmota_xdrv_driver/xdrv_91_magic_switch.ino b/tasmota/tasmota_xdrv_driver/xdrv_91_magic_switch.ino new file mode 100644 index 000000000..5356ada69 --- /dev/null +++ b/tasmota/tasmota_xdrv_driver/xdrv_91_magic_switch.ino @@ -0,0 +1,187 @@ +/* + xdrv_91_magic_switch.ino - Driver for MagicSwitch as implemented in Sonoff BasicR4 + + Copyright (C) 2021 Barbudor + + 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_MAGIC_SWITCH + +#define XDRV_91 91 + +/******************************************************************************************************** + * Check defines + */ + +#ifndef MAGICSWITCH_MIN_PULSE +#define MAGICSWITCH_MIN_PULSE 4000 +#endif + +#ifndef MAGICSWITCH_MASKING_WINDOW_LEN +#define MAGICSWITCH_MASKING_WINDOW_LEN 5 +#endif + +/******************************************************************************************************** + * Global private data + */ + +// MagicSwitch Index => Mode +// +// +// +// Index Mode Pull-Up +// 1 0 Pull-Up +// 2 1 No Pull-up +// 3 2 Pull-Up +// 4 3 No Pull-up +// 5 4 Pull-Up +// 6 5 No Pull-up +// 7 6 Pull-Up +// 8 7 No Pull-up + +#define MAGICSWITCH_MODE_NO_PULLUP 0x01 + + +struct MAGICSWITCH_DATA { + uint32_t start_time; // timestamp at rising edge + uint32_t pulse_len; // measured pulse length + uint32_t min_pulse; // minimum pulse length + uint8_t switch_state; // switch state - count down for masking window + uint8_t pin; // the GPIO of the input + uint8_t mode; // mode + int8_t key_offset; // index of the MagicSwitch in the list of Switches +} *MagicSwitch = nullptr; + + +/******************************************************************************************************** + * Interrupt level operations + */ + +extern "C" void IRAM_ATTR MagicSwitch_intr(void *arg) { + struct MAGICSWITCH_DATA* ms = (struct MAGICSWITCH_DATA*)arg; + uint32_t now = micros(); + bool pin_state = digitalRead(ms->pin); + if (ms->pulse_len) { // previous pulse not aknowledged, ignoring the edge + return; + } else if (pin_state) { // rising edge (hopefully if we didn't missed), record start time + ms->start_time = now | 1; // "| 1" => avoid 1 in 4M chance to get 0 + } else if (ms->start_time) { // falling edge, compute pulse length + uint32_t pulse_len = now - ms->start_time; + ms->start_time = 0; // in case of missing an rising edge, avoid triggering false detection + if (pulse_len >= ms->min_pulse) + ms->pulse_len = pulse_len; + } +} + +/******************************************************************************************************** + * Driver operations + */ + +void MagicSwitchLoop() +{ + if (MagicSwitch->switch_state) { + MagicSwitch->switch_state--; + if (!MagicSwitch->switch_state) { + SwitchSetVirtualPinState(MagicSwitch->key_offset, 0); + MagicSwitch->pulse_len = 0; // acknowledge the pulse, close the masking window + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MSW: end")); + } + } else if (MagicSwitch->pulse_len) { + SwitchSetVirtualPinState(MagicSwitch->key_offset, 1); + MagicSwitch->switch_state = MAGICSWITCH_MASKING_WINDOW_LEN; + AddLog(LOG_LEVEL_DEBUG, PSTR("MSW: length:%d, window:%d"), MagicSwitch->pulse_len, MagicSwitch->switch_state); + } +} + +/******************************************************************************************************** + * Driver initialisation + */ + +void MagicSwitchInit(void) { + if (PinUsed(GPIO_MAGIC_SWITCH, GPIO_ANY)) { + // allocate data structure + MagicSwitch = (struct MAGICSWITCH_DATA*)calloc(1, sizeof(struct MAGICSWITCH_DATA)); + if (MagicSwitch) { + // get pins + MagicSwitch->pin = Pin(GPIO_MAGIC_SWITCH, GPIO_ANY); // input + MagicSwitch->mode = GetPin(MagicSwitch->pin) - AGPIO(GPIO_MAGIC_SWITCH); // Index 1 => mode 0, etc... + MagicSwitch->key_offset = -1; // means not yet configured + MagicSwitch->min_pulse = MAGICSWITCH_MIN_PULSE; + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MSW: pin:%d, mode:%d"), MagicSwitch->pin, MagicSwitch->mode); + + pinMode(MagicSwitch->pin, (MagicSwitch->mode & MAGICSWITCH_MODE_NO_PULLUP) ? INPUT : INPUT_PULLUP); + attachInterruptArg(MagicSwitch->pin, MagicSwitch_intr, MagicSwitch, CHANGE); + } + } +} + +bool MagicSwitchAddSwitch(void) { + if (MagicSwitch->key_offset < 0) { + MagicSwitch->key_offset = XdrvMailbox.index; + Settings->switchmode[MagicSwitch->key_offset] = 4; + AddLog(LOG_LEVEL_INFO, PSTR("MSW: Switch %d, Switchmode 4"), MagicSwitch->key_offset + 1); + return true; + } + return false; +} + +/******************************************************************************************************** + * Commands + */ + +const char kMagicSwitchCommands[] PROGMEM = "MagicSwitch|" + "Pulse" + ; + +void (* const MagicSwitchCommand[])(void) PROGMEM = { + &CmndMagicSwitchPulse + }; + +void CmndMagicSwitchPulse(void) +{ + if ((XdrvMailbox.payload >= 1000) && (XdrvMailbox.payload < 500000)) { + MagicSwitch->min_pulse = XdrvMailbox.payload; + } + ResponseCmndNumber(MagicSwitch->min_pulse); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv91(uint32_t function) { + bool result = false; + + if (FUNC_SETUP_RING2 == function) { + MagicSwitchInit(); + } else if (MagicSwitch) { + switch (function) { + case FUNC_EVERY_50_MSECOND: + //case FUNC_EVERY_250_MSECOND: + MagicSwitchLoop(); + break; + case FUNC_ADD_SWITCH: + result = MagicSwitchAddSwitch(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kMagicSwitchCommands, MagicSwitchCommand); + break; + } + } + return result; +} + +#endif // USE_MAGIC_SWITCH