diff --git a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino b/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino deleted file mode 100644 index 16ae49dda..000000000 --- a/tasmota/tasmota_xdrv_driver/xdrv_90_dingtian_relay.ino +++ /dev/null @@ -1,210 +0,0 @@ -/* - xdrv_90_dingtian_relay.ino - Dingtian 8, 16, 24 and 32 relays board based on 74x595+74x165 - - 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 ESP32 -#ifdef USE_DINGTIAN_RELAY - -#define XDRV_90 90 - -/******************************************************************************************************** - * Global private data - */ - -struct DINGTIAN_DATA { - uint32_t outputs; // keep ouputs state - uint32_t last_inputs; // previous inputs state - uint8_t count; // number of relay and input (8 * numver of shift registers) - uint8_t first; // index of 1st Tasmota relay assigned to 1st Dingtian relays - // pins - uint8_t pin_clk, pin_sdi, pin_q7, pin_pl, pin_rck; -} *Dingtian = nullptr; - - -/******************************************************************************************************** - * Low level operations - */ - -uint32_t DingtianReadWrite(uint32_t outputs) -{ - uint32_t inputs = 0; - uint32_t in_bit = 1; - - // setup - digitalWrite(Dingtian->pin_rck, 0); // rclk and clkinh to 0 - digitalWrite(Dingtian->pin_pl, 1); // load inputs in '165, ready for shift-in (side effect '595 in tri-state) - for ( int i = Dingtian->count ; i > 0 ; i-- ) { - // relay out to '595 - digitalWrite(Dingtian->pin_sdi, outputs & 1); - outputs >>= 1; - // input from '165 - inputs |= digitalRead(Dingtian->pin_q7) ? in_bit : 0; - in_bit <<= 1; - // generate CLK pulse - digitalWrite(Dingtian->pin_clk, 1); - digitalWrite(Dingtian->pin_clk, 0); - } - // ending - digitalWrite(Dingtian->pin_rck, 1); // rclk pulse to load '595 into output registers - digitalWrite(Dingtian->pin_pl, 0); // re-enable '595 ouputs - - return inputs; -} - -/******************************************************************************************************** - * Driver initialisation - */ - -#define DINGTIAN_SET_OUTPUT(pin,value) { pinMode((pin), OUTPUT); digitalWrite((pin), (value)); } -#define DINGTIAN_SET_INPUT(pin) { pinMode((pin), INPUT); } - -void DingtianInit(void) { - if (PinUsed(GPIO_DINGTIAN_CLK, GPIO_ANY) && PinUsed(GPIO_DINGTIAN_SDI) && PinUsed(GPIO_DINGTIAN_Q7) - && PinUsed(GPIO_DINGTIAN_PL) && PinUsed(GPIO_DINGTIAN_RCK)) { - // allocate Dingtian data structure - Dingtian = (struct DINGTIAN_DATA*)calloc(1, sizeof(struct DINGTIAN_DATA)); - if (Dingtian) { - // get pins - Dingtian->pin_clk = Pin(GPIO_DINGTIAN_CLK, GPIO_ANY); // shift clock : 595's SCLK & 165's CLK - Dingtian->pin_sdi = Pin(GPIO_DINGTIAN_SDI); // Serial out : 595's SER - Dingtian->pin_q7 = Pin(GPIO_DINGTIAN_Q7); // Serial in : 165's Q7 - Dingtian->pin_pl = Pin(GPIO_DINGTIAN_PL); // Input load : 595's nOE & 165's PL (or SH/LD on some datasheet) - Dingtian->pin_rck = Pin(GPIO_DINGTIAN_RCK); // Output load : 595's RCLK & 165's CLKINH - // number of shift registers is the CLK index - Dingtian->count = ((GetPin(Dingtian->pin_clk) - AGPIO(GPIO_DINGTIAN_CLK)) + 1) * 8; - - AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: clk:%d, sdi:%d, q7:%d, pl:%d, rck:%d, count:%d"), - Dingtian->pin_clk, Dingtian->pin_sdi, Dingtian->pin_q7, Dingtian->pin_pl, Dingtian->pin_rck, Dingtian->count); - - DINGTIAN_SET_OUTPUT(Dingtian->pin_clk, 0); - DINGTIAN_SET_OUTPUT(Dingtian->pin_sdi, 0); - DINGTIAN_SET_INPUT( Dingtian->pin_q7); - DINGTIAN_SET_OUTPUT(Dingtian->pin_pl, 0); - DINGTIAN_SET_OUTPUT(Dingtian->pin_rck, 0); - - Dingtian->first = TasmotaGlobal.devices_present; - TasmotaGlobal.devices_present += Dingtian->count; - if (TasGlobal.devices_present > POWER_SIZE) { - TasGlobal.devices_present = POWER_SIZE; - } - AddLog(LOG_LEVEL_DEBUG, PSTR("DNGT: Dingtian relays: POWER%d to POWER%d"), Dingtian->first + 1, TasGlobal.devices_present); - } - } -} - -/******************************************************************************************************** - * Driver operations - */ - -void DingtianLoop() -{ - uint32_t inputs = DingtianReadWrite(Dingtian->outputs); - uint32_t last_inputs = Dingtian->last_inputs; - Dingtian->last_inputs = inputs; - if (inputs != last_inputs) { - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DNGT: inputs=0x%08X, last=0x%08X"), inputs, last_inputs); - bool first_done = false; - ResponseTime_P(PSTR(",\"DINGTIAN_CHG\":{")); - for (int i = 0 ; i < Dingtian->count ; i++, last_inputs>>=1, inputs>>=1) { - if ((last_inputs & 1) != (inputs & 1)) { - if (first_done) ResponseAppend_P(PSTR(",")); - ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, (inputs & 1)); - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("\"IN%d\":%d"), i +1, (inputs & 1)); - first_done = true; - } - } - ResponseAppend_P(PSTR("}}")); - if (first_done) { - MqttPublishPrefixTopicRulesProcess_P(STAT, PSTR("DINGTIAN_CHG")); - } - } -} - -void DingtianSetPower(void) -{ - // store relay status in structure - Dingtian->outputs = (XdrvMailbox.index >> Dingtian->first) & ~(0xFFFFFFFF << Dingtian->count); - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DNGT: outputs=0x%08X"), Dingtian->outputs); - DingtianLoop(); -} - -/******************************************************************************************************** - * Driver Results - */ - -const char HTTP_DINGTIAN_INPUTS[] PROGMEM = "{s}DINGTIAN " D_SENSOR_INPUT "%d.." D_SENSOR_INPUT "%d{m}%s{e}"; - -void DingtianShow(bool json) -{ - if (json) { - bool first_done = false; - ResponseAppend_P(PSTR(",\"DINGTIAN\":{")); - for (int i = 0 ; i < Dingtian->count ; i++) { - if (first_done) ResponseAppend_P(PSTR(",")); - ResponseAppend_P(PSTR("\"IN%d\":%d"), i +1, bitRead(Dingtian->last_inputs, i)); - first_done = true; - } - ResponseAppend_P(PSTR("}")); - } -#ifdef USE_WEBSERVER - else { - char input_str[9]; - for (int block_input = 0 ; block_input < Dingtian->count ; block_input += 8 ) { - for (int i = 0 ; i < 8 ; i++ ) - input_str[i] = '0' + bitRead(Dingtian->last_inputs, block_input +i); - input_str[8] = '\0'; - WSContentSend_P(HTTP_DINGTIAN_INPUTS, block_input, block_input +7, input_str); - } - } -#endif -} - - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv90(uint32_t function) { - bool result = false; - - if (FUNC_PRE_INIT == function) { - DingtianInit(); - } else if (Dingtian) { - switch (function) { - case FUNC_SET_POWER: - DingtianSetPower(); - break; - case FUNC_EVERY_50_MSECOND: - //case FUNC_EVERY_250_MSECOND: - DingtianLoop(); - break; - case FUNC_JSON_APPEND: - DingtianShow(1); - break; -#ifdef USE_WEBSERVER - case FUNC_WEB_SENSOR: - DingtianShow(0); - break; -#endif // USE_WEBSERVER - } - } - return result; -} - -#endif // USE_DINGTIAN_RELAY -#endif // ESP32