diff --git a/sonoff/settings.h b/sonoff/settings.h index 3b368585f..8af704831 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -394,6 +394,7 @@ struct TIME_T { struct XDRVMAILBOX { bool grpflg; bool usridx; + uint16_t command_code; uint32_t index; uint32_t data_len; int32_t payload; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index c1bbba867..ddc95f0ad 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1327,11 +1327,6 @@ void GpioInit(void) } #endif // USE_LIGHT - if (SONOFF_BRIDGE == my_module_type) { - Settings.flag.mqtt_serial = 0; - baudrate = 19200; - } - if (XdrvCall(FUNC_MODULE_INIT)) { // Serviced } diff --git a/sonoff/support.ino b/sonoff/support.ino index 9a2fee883..519b0f1e3 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -738,16 +738,15 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl bool DecodeCommand(const char* haystack, void (* const MyCommand[])(void)) { - bool result = false; - GetTextIndexed(XdrvMailbox.command, CMDSZ, 0, haystack); // Get prefix if available int prefix_length = strlen(XdrvMailbox.command); int command_code = GetCommandCode(XdrvMailbox.command + prefix_length, CMDSZ, XdrvMailbox.topic + prefix_length, haystack); if (command_code > 0) { // Skip prefix - MyCommand[command_code -1](); - result = true; + XdrvMailbox.command_code = command_code -1; + MyCommand[XdrvMailbox.command_code](); + return true; } - return result; + return false; } int GetStateNumber(char *state_text) diff --git a/sonoff/xdrv_06_snfbridge.ino b/sonoff/xdrv_06_snfbridge.ino index 4818c7be2..db786d3b5 100644 --- a/sonoff/xdrv_06_snfbridge.ino +++ b/sonoff/xdrv_06_snfbridge.ino @@ -25,23 +25,26 @@ const uint32_t SFB_TIME_AVOID_DUPLICATE = 2000; // Milliseconds -enum SonoffBridgeCommands { CMND_RFSYNC, CMND_RFLOW, CMND_RFHIGH, CMND_RFHOST, CMND_RFCODE }; +enum SonoffBridgeCommands { + CMND_RFSYNC, CMND_RFLOW, CMND_RFHIGH, CMND_RFHOST, CMND_RFCODE }; const char kSonoffBridgeCommands[] PROGMEM = "|" // No prefix D_CMND_RFSYNC "|" D_CMND_RFLOW "|" D_CMND_RFHIGH "|" D_CMND_RFHOST "|" D_CMND_RFCODE "|" D_CMND_RFKEY "|" D_CMND_RFRAW; void (* const SonoffBridgeCommand[])(void) PROGMEM = { - &CmndRfSync, &CmndRfLow, &CmndRfHigh, &CmndRfHost, &CmndRfCode, &CmndRfKey, &CmndRfRaw }; + &CmndRfBridge, &CmndRfBridge, &CmndRfBridge, &CmndRfBridge, &CmndRfBridge, &CmndRfKey, &CmndRfRaw }; -uint8_t sonoff_bridge_receive_flag = 0; -uint8_t sonoff_bridge_receive_raw_flag = 0; -uint8_t sonoff_bridge_learn_key = 1; -uint8_t sonoff_bridge_learn_active = 0; -uint8_t sonoff_bridge_expected_bytes = 0; -uint32_t sonoff_bridge_last_received_id = 0; -uint32_t sonoff_bridge_last_send_code = 0; -unsigned long sonoff_bridge_last_time = 0; -unsigned long sonoff_bridge_last_learn_time = 0; +struct SONOFFBRIDGE { + uint32_t last_received_id = 0; + uint32_t last_send_code = 0; + uint32_t last_time = 0; + uint32_t last_learn_time = 0; + uint8_t receive_flag = 0; + uint8_t receive_raw_flag = 0; + uint8_t learn_key = 1; + uint8_t learn_active = 0; + uint8_t expected_bytes = 0; +} SnfBridge; #ifdef USE_RF_FLASH /*********************************************************************************************\ @@ -230,8 +233,8 @@ void SonoffBridgeReceivedRaw(void) void SonoffBridgeLearnFailed(void) { - sonoff_bridge_learn_active = 0; - Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARN_FAILED); + SnfBridge.learn_active = 0; + Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, SnfBridge.learn_key, D_JSON_LEARN_FAILED); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY)); } @@ -250,21 +253,21 @@ void SonoffBridgeReceived(void) SonoffBridgeLearnFailed(); } else if (0xA3 == serial_in_buffer[0]) { // Learned A3 20 F8 01 18 03 3E 2E 1A 22 55 - sonoff_bridge_learn_active = 0; + SnfBridge.learn_active = 0; low_time = serial_in_buffer[3] << 8 | serial_in_buffer[4]; // Low time in uSec high_time = serial_in_buffer[5] << 8 | serial_in_buffer[6]; // High time in uSec if (low_time && high_time) { for (uint32_t i = 0; i < 9; i++) { - Settings.rf_code[sonoff_bridge_learn_key][i] = serial_in_buffer[i +1]; + Settings.rf_code[SnfBridge.learn_key][i] = serial_in_buffer[i +1]; } - Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, sonoff_bridge_learn_key, D_JSON_LEARNED); + Response_P(S_JSON_COMMAND_INDEX_SVALUE, D_CMND_RFKEY, SnfBridge.learn_key, D_JSON_LEARNED); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_CMND_RFKEY)); } else { SonoffBridgeLearnFailed(); } } else if (0xA4 == serial_in_buffer[0]) { // Received RF data A4 20 EE 01 18 03 3E 2E 1A 22 55 - if (sonoff_bridge_learn_active) { + if (SnfBridge.learn_active) { SonoffBridgeLearnFailed(); } else { sync_time = serial_in_buffer[1] << 8 | serial_in_buffer[2]; // Sync time in uSec @@ -273,9 +276,9 @@ void SonoffBridgeReceived(void) received_id = serial_in_buffer[7] << 16 | serial_in_buffer[8] << 8 | serial_in_buffer[9]; unsigned long now = millis(); - if (!((received_id == sonoff_bridge_last_received_id) && (now - sonoff_bridge_last_time < SFB_TIME_AVOID_DUPLICATE))) { - sonoff_bridge_last_received_id = received_id; - sonoff_bridge_last_time = now; + if (!((received_id == SnfBridge.last_received_id) && (now - SnfBridge.last_time < SFB_TIME_AVOID_DUPLICATE))) { + SnfBridge.last_received_id = received_id; + SnfBridge.last_time = now; strncpy_P(rfkey, PSTR("\"" D_JSON_NONE "\""), sizeof(rfkey)); for (uint32_t i = 1; i <= 16; i++) { if (Settings.rf_code[i][0]) { @@ -308,8 +311,8 @@ bool SonoffBridgeSerialInput(void) // iTead Rf Universal Transceiver Module Serial Protocol Version 1.0 (20170420) static int8_t receive_len = 0; - if (sonoff_bridge_receive_flag) { - if (sonoff_bridge_receive_raw_flag) { + if (SnfBridge.receive_flag) { + if (SnfBridge.receive_raw_flag) { if (!serial_in_byte_counter) { serial_in_buffer[serial_in_byte_counter++] = 0xAA; } @@ -321,26 +324,26 @@ bool SonoffBridgeSerialInput(void) } if ((!receive_len && (0x55 == serial_in_byte)) || (receive_len && (serial_in_byte_counter == receive_len))) { // 0x55 - End of text SonoffBridgeReceivedRaw(); - sonoff_bridge_receive_flag = 0; + SnfBridge.receive_flag = 0; return 1; } } else if (!((0 == serial_in_byte_counter) && (0 == serial_in_byte))) { // Skip leading 0 if (0 == serial_in_byte_counter) { - sonoff_bridge_expected_bytes = 2; // 0xA0, 0xA1, 0xA2 + SnfBridge.expected_bytes = 2; // 0xA0, 0xA1, 0xA2 if (serial_in_byte >= 0xA3) { - sonoff_bridge_expected_bytes = 11; // 0xA3, 0xA4, 0xA5 + SnfBridge.expected_bytes = 11; // 0xA3, 0xA4, 0xA5 } if (serial_in_byte == 0xA6) { - sonoff_bridge_expected_bytes = 0; // 0xA6 and up supported by Portisch firmware only + SnfBridge.expected_bytes = 0; // 0xA6 and up supported by Portisch firmware only serial_in_buffer[serial_in_byte_counter++] = 0xAA; - sonoff_bridge_receive_raw_flag = 1; + SnfBridge.receive_raw_flag = 1; } } serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; - if ((sonoff_bridge_expected_bytes == serial_in_byte_counter) && (0x55 == serial_in_byte)) { // 0x55 - End of text + if ((SnfBridge.expected_bytes == serial_in_byte_counter) && (0x55 == serial_in_byte)) { // 0x55 - End of text SonoffBridgeReceived(); - sonoff_bridge_receive_flag = 0; + SnfBridge.receive_flag = 0; return 1; } } @@ -349,7 +352,7 @@ bool SonoffBridgeSerialInput(void) if (0xAA == serial_in_byte) { // 0xAA - Start of text serial_in_byte_counter = 0; serial_in_byte = 0; - sonoff_bridge_receive_flag = 1; + SnfBridge.receive_flag = 1; receive_len = 0; } return 0; @@ -409,9 +412,9 @@ void SonoffBridgeSend(uint8_t idx, uint8_t key) void SonoffBridgeLearn(uint8_t key) { - sonoff_bridge_learn_key = key; - sonoff_bridge_learn_active = 1; - sonoff_bridge_last_learn_time = millis(); + SnfBridge.learn_key = key; + SnfBridge.learn_active = 1; + SnfBridge.last_learn_time = millis(); Serial.write(0xAA); // Start of Text Serial.write(0xA1); // Start learning Serial.write(0x55); // End of Text @@ -421,14 +424,14 @@ void SonoffBridgeLearn(uint8_t key) * Commands \*********************************************************************************************/ -void SonoffBridgeCmnd(uint32_t command_code) // RfSync, RfLow, RfHigh, RfHost and RfCode +void CmndRfBridge() // RfSync, RfLow, RfHigh, RfHost and RfCode { char *p; char stemp [10]; uint32_t code = 0; uint8_t radix = 10; - uint32_t set_index = command_code *2; + uint32_t set_index = XdrvMailbox.command_code *2; if (XdrvMailbox.data[0] == '#') { XdrvMailbox.data++; @@ -439,8 +442,8 @@ void SonoffBridgeCmnd(uint32_t command_code) // RfSync, RfLow, RfHigh, RfHost a if (XdrvMailbox.data_len) { code = strtol(XdrvMailbox.data, &p, radix); if (code) { - if (CMND_RFCODE == command_code) { - sonoff_bridge_last_send_code = code; + if (CMND_RFCODE == XdrvMailbox.command_code) { + SnfBridge.last_send_code = code; SonoffBridgeSendCode(code); } else { if (1 == XdrvMailbox.payload) { @@ -455,8 +458,8 @@ void SonoffBridgeCmnd(uint32_t command_code) // RfSync, RfLow, RfHigh, RfHost a } } } - if (CMND_RFCODE == command_code) { - code = sonoff_bridge_last_send_code; + if (CMND_RFCODE == XdrvMailbox.command_code) { + code = SnfBridge.last_send_code; } else { code = Settings.rf_code[0][set_index] << 8 | Settings.rf_code[0][set_index +1]; } @@ -468,37 +471,12 @@ void SonoffBridgeCmnd(uint32_t command_code) // RfSync, RfLow, RfHigh, RfHost a Response_P(S_JSON_COMMAND_XVALUE, XdrvMailbox.command, stemp); } -void CmndRfSync(void) -{ - SonoffBridgeCmnd(CMND_RFSYNC); -} - -void CmndRfLow(void) -{ - SonoffBridgeCmnd(CMND_RFLOW); -} - -void CmndRfHigh(void) -{ - SonoffBridgeCmnd(CMND_RFHIGH); -} - -void CmndRfHost(void) -{ - SonoffBridgeCmnd(CMND_RFHOST); -} - -void CmndRfCode(void) -{ - SonoffBridgeCmnd(CMND_RFCODE); -} - void CmndRfKey(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 16)) { unsigned long now = millis(); - if ((!sonoff_bridge_learn_active) || (now - sonoff_bridge_last_learn_time > 60100)) { - sonoff_bridge_learn_active = 0; + if ((!SnfBridge.learn_active) || (now - SnfBridge.last_learn_time > 60100)) { + SnfBridge.learn_active = 0; if (2 == XdrvMailbox.payload) { // Learn RF data SonoffBridgeLearn(XdrvMailbox.index); ResponseCmndIdxChar(D_JSON_START_LEARNING); @@ -511,9 +489,9 @@ void CmndRfKey(void) for (uint32_t i = 0; i < 6; i++) { Settings.rf_code[XdrvMailbox.index][i] = Settings.rf_code[0][i]; } - Settings.rf_code[XdrvMailbox.index][6] = (sonoff_bridge_last_send_code >> 16) & 0xff; - Settings.rf_code[XdrvMailbox.index][7] = (sonoff_bridge_last_send_code >> 8) & 0xff; - Settings.rf_code[XdrvMailbox.index][8] = sonoff_bridge_last_send_code & 0xff; + Settings.rf_code[XdrvMailbox.index][6] = (SnfBridge.last_send_code >> 16) & 0xff; + Settings.rf_code[XdrvMailbox.index][7] = (SnfBridge.last_send_code >> 8) & 0xff; + Settings.rf_code[XdrvMailbox.index][8] = SnfBridge.last_send_code & 0xff; ResponseCmndIdxChar(D_JSON_SAVED); } else if (5 == XdrvMailbox.payload) { // Show default or learned RF data uint8_t key = XdrvMailbox.index; @@ -540,7 +518,7 @@ void CmndRfKey(void) } } } else { - Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, sonoff_bridge_learn_key, D_JSON_LEARNING_ACTIVE); + Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, SnfBridge.learn_key, D_JSON_LEARNING_ACTIVE); } } } @@ -553,7 +531,7 @@ void CmndRfRaw(void) case 0: // Receive Raw Off SonoffBridgeSendCommand(0xA7); // Stop reading RF signals enabling iTead default RF handling case 1: // Receive Raw On - sonoff_bridge_receive_raw_flag = XdrvMailbox.payload; + SnfBridge.receive_raw_flag = XdrvMailbox.payload; break; case 166: // 0xA6 - Start reading RF signals disabling iTead default RF handling case 167: // 0xA7 - Stop reading RF signals enabling iTead default RF handling @@ -562,7 +540,7 @@ void CmndRfRaw(void) case 177: // 0xB1 - Start sniffing case 255: // 0xFF - Show firmware version SonoffBridgeSendCommand(XdrvMailbox.payload); - sonoff_bridge_receive_raw_flag = 1; + SnfBridge.receive_raw_flag = 1; break; case 192: // 0xC0 - Beep char beep[] = "AAC000C055\0"; @@ -571,18 +549,10 @@ void CmndRfRaw(void) } } else { SerialSendRaw(RemoveSpace(XdrvMailbox.data)); - sonoff_bridge_receive_raw_flag = 1; + SnfBridge.receive_raw_flag = 1; } } - ResponseCmndStateText(sonoff_bridge_receive_raw_flag); -} - -/*********************************************************************************************/ - -void SonoffBridgeInit(void) -{ - sonoff_bridge_receive_raw_flag = 0; - SonoffBridgeSendCommand(0xA7); // Stop reading RF signals enabling iTead default RF handling + ResponseCmndStateText(SnfBridge.receive_raw_flag); } /*********************************************************************************************\ @@ -598,12 +568,17 @@ bool Xdrv06(uint8_t function) case FUNC_SERIAL: result = SonoffBridgeSerialInput(); break; - case FUNC_INIT: - SonoffBridgeInit(); - break; case FUNC_COMMAND: result = DecodeCommand(kSonoffBridgeCommands, SonoffBridgeCommand); break; + case FUNC_INIT: + SnfBridge.receive_raw_flag = 0; + SonoffBridgeSendCommand(0xA7); // Stop reading RF signals enabling iTead default RF handling + break; + case FUNC_PRE_INIT: + Settings.flag.mqtt_serial = 0; + baudrate = 19200; + break; } } return result; diff --git a/sonoff/xdrv_24_buzzer.ino b/sonoff/xdrv_24_buzzer.ino index c7b6fac68..8646c099c 100644 --- a/sonoff/xdrv_24_buzzer.ino +++ b/sonoff/xdrv_24_buzzer.ino @@ -1,5 +1,5 @@ /* - xdrv_24_buzzer.ino - buzzer support for Sonoff-Tasmota + xdrv_24_Buzzer.ino - buzzer support for Sonoff-Tasmota Copyright (C) 2019 Theo Arends @@ -21,6 +21,7 @@ /*********************************************************************************************\ * Buzzer support \*********************************************************************************************/ + #define XDRV_24 24 struct BUZZER { @@ -32,17 +33,17 @@ struct BUZZER { uint8_t set[2]; uint8_t duration; uint8_t state = 0; -} buzzer; +} Buzzer; /*********************************************************************************************/ //void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0); void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune) { - buzzer.set[0] = off; - buzzer.set[1] = on; - buzzer.duration = 1; // Start buzzer on first step - buzzer.tune = 0; + Buzzer.set[0] = off; + Buzzer.set[1] = on; + Buzzer.duration = 1; // Start buzzer on first step + Buzzer.tune = 0; if (tune) { uint32_t tune1 = tune; uint32_t tune2 = tune; @@ -50,19 +51,19 @@ void BuzzerBeep(uint32_t count, uint32_t on, uint32_t off, uint32_t tune) if (!(tune2 & 0x80000000)) { tune2 <<= 1; // Skip leading silence } else { - buzzer.tune <<= 1; // Add swapped tune - buzzer.tune |= tune1 & 1; + Buzzer.tune <<= 1; // Add swapped tune + Buzzer.tune |= tune1 & 1; tune1 >>= 1; } } - buzzer.count = 1; // Allow tune only once + Buzzer.count = 1; // Allow tune only once } else { - buzzer.count = count * 2; // Start buzzer + Buzzer.count = count * 2; // Start buzzer } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BUZ: %d(%d),%d,%d,0x%08X(0x%08X)"), count, buzzer.count, on, off, tune, buzzer.tune); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BUZ: %d(%d),%d,%d,0x%08X(0x%08X)"), count, Buzzer.count, on, off, tune, Buzzer.tune); - buzzer.enable = true; + Buzzer.enable = true; } void BuzzerBeep(uint32_t count) { @@ -81,7 +82,7 @@ void BuzzerEnabledBeep(uint32_t count) bool BuzzerPinState() { if (XdrvMailbox.index == GPIO_BUZZER_INV) { - buzzer.inverted = 1; + Buzzer.inverted = 1; XdrvMailbox.index -= (GPIO_BUZZER_INV - GPIO_BUZZER); return true; } @@ -92,32 +93,32 @@ void BuzzerInit(void) { if (pin[GPIO_BUZZER] < 99) { pinMode(pin[GPIO_BUZZER], OUTPUT); - digitalWrite(pin[GPIO_BUZZER], buzzer.inverted); // Buzzer Off + digitalWrite(pin[GPIO_BUZZER], Buzzer.inverted); // Buzzer Off } else { - buzzer.active = false; + Buzzer.active = false; } } void BuzzerEvery100mSec(void) { - if (buzzer.enable) { - if (buzzer.count) { - if (buzzer.duration) { - buzzer.duration--; - if (!buzzer.duration) { - if (buzzer.tune) { - buzzer.state = buzzer.tune & 1; - buzzer.tune >>= 1; + if (Buzzer.enable) { + if (Buzzer.count) { + if (Buzzer.duration) { + Buzzer.duration--; + if (!Buzzer.duration) { + if (Buzzer.tune) { + Buzzer.state = Buzzer.tune & 1; + Buzzer.tune >>= 1; } else { - buzzer.count--; - buzzer.state = buzzer.count & 1; + Buzzer.count--; + Buzzer.state = Buzzer.count & 1; } - buzzer.duration = buzzer.set[buzzer.state]; + Buzzer.duration = Buzzer.set[Buzzer.state]; } } - digitalWrite(pin[GPIO_BUZZER], (buzzer.inverted) ? !buzzer.state : buzzer.state); + digitalWrite(pin[GPIO_BUZZER], (Buzzer.inverted) ? !Buzzer.state : Buzzer.state); } else { - buzzer.enable = false; + Buzzer.enable = false; } } } @@ -169,7 +170,7 @@ bool Xdrv24(uint8_t function) { bool result = false; - if (buzzer.active) { + if (Buzzer.active) { switch (function) { case FUNC_EVERY_100_MSECOND: BuzzerEvery100mSec();