mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 02:36:35 +00:00
Fix TUYA state machine (in TUYA v1) (#20110)
* rework state machine * some comments * wip * looks good now * little updates
This commit is contained in:
parent
faa29b2e57
commit
73268e4bb6
@ -78,7 +78,6 @@ struct TUYA {
|
||||
bool SuspendTopic = false; // Used to reduce the load at init time or when polling the configuraton on demand
|
||||
uint32_t ignore_topic_timeout = 0; // Suppress the /STAT topic (if enabled) to avoid data overflow until the configuration is over
|
||||
bool ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction
|
||||
uint8_t cmd_status = 0; // Current status of serial-read
|
||||
uint8_t cmd_checksum = 0; // Checksum of tuya command
|
||||
uint8_t data_len = 0; // Data lenght of command
|
||||
uint8_t wifi_state = -2; // Keep MCU wifi-status in sync with WifiState()
|
||||
@ -1262,36 +1261,7 @@ void TuyaInit(void) {
|
||||
Tuya.active = false;
|
||||
}
|
||||
|
||||
void TuyaSerialInput(void)
|
||||
{
|
||||
while (TuyaSerial->available()) {
|
||||
yield();
|
||||
uint8_t serial_in_byte = TuyaSerial->read();
|
||||
|
||||
if (serial_in_byte == 0x55) { // Start TUYA Packet
|
||||
Tuya.cmd_status = 1;
|
||||
Tuya.buffer[Tuya.byte_counter++] = serial_in_byte;
|
||||
Tuya.cmd_checksum += serial_in_byte;
|
||||
}
|
||||
else if (Tuya.cmd_status == 1 && serial_in_byte == 0xAA) { // Only packtes with header 0x55AA are valid
|
||||
Tuya.cmd_status = 2;
|
||||
|
||||
Tuya.byte_counter = 0;
|
||||
Tuya.buffer[Tuya.byte_counter++] = 0x55;
|
||||
Tuya.buffer[Tuya.byte_counter++] = 0xAA;
|
||||
Tuya.cmd_checksum = 0xFF;
|
||||
}
|
||||
else if (Tuya.cmd_status == 2) {
|
||||
if (Tuya.byte_counter == 5) { // Get length of data
|
||||
Tuya.cmd_status = 3;
|
||||
Tuya.data_len = serial_in_byte;
|
||||
}
|
||||
Tuya.cmd_checksum += serial_in_byte;
|
||||
Tuya.buffer[Tuya.byte_counter++] = serial_in_byte;
|
||||
}
|
||||
else if ((Tuya.cmd_status == 3) && (Tuya.byte_counter == (6 + Tuya.data_len)) && (Tuya.cmd_checksum == serial_in_byte)) { // Compare checksum and process packet
|
||||
Tuya.buffer[Tuya.byte_counter++] = serial_in_byte;
|
||||
|
||||
void TuyaProcessMessage(void) {
|
||||
char hex_char[(Tuya.byte_counter * 2) + 2];
|
||||
uint16_t len = Tuya.buffer[4] << 8 | Tuya.buffer[5];
|
||||
|
||||
@ -1350,14 +1320,6 @@ void TuyaSerialInput(void)
|
||||
ResponseAppend_P(PSTR("}}"));
|
||||
|
||||
if (Settings->flag3.tuya_serial_mqtt_publish) { // SetOption66 - Enable TuyaMcuReceived messages over Mqtt
|
||||
/*
|
||||
for (uint8_t cmdsID = 0; sizeof(TuyaExcludeCMDsFromMQTT) > cmdsID; cmdsID++){
|
||||
if (TuyaExcludeCMDsFromMQTT[cmdsID] == Tuya.buffer[3]) {
|
||||
isCmdToSuppress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
for (uint8_t cmdsID = 0; cmdsID < sizeof(TuyaExcludeCMDsFromMQTT); cmdsID++) {
|
||||
if (pgm_read_byte(TuyaExcludeCMDsFromMQTT +cmdsID) == Tuya.buffer[3]) {
|
||||
isCmdToSuppress = true;
|
||||
@ -1390,21 +1352,72 @@ void TuyaSerialInput(void)
|
||||
} else {
|
||||
TuyaLowPowerModePacketProcess();
|
||||
}
|
||||
}
|
||||
|
||||
void TuyaSerialInput(void)
|
||||
{
|
||||
/* /-------------------------------- header 55
|
||||
* | /----------------------------- header AA
|
||||
* | | /-------------------------- version, always 00
|
||||
* | | | /----------------------- command byte
|
||||
* | | | | /--+----------------- data length in bytes, big endian (high then low)
|
||||
* | | | | | | /-+-+-+-+------ data bytes
|
||||
* | | | | | | | | | | | /--- checksum (sum of all bytes except checksum)
|
||||
* 55 AA 00 cc lh ll dd .... dd xx
|
||||
* 0 1 2 3 4 5 6 .... index in Tuya buffer
|
||||
* 0 1 2 2 2 2 3 3 3 3 3 Tuya.cmd_status
|
||||
*/
|
||||
|
||||
static unsigned long time_last_byte_received = 0;
|
||||
|
||||
while (TuyaSerial->available()) {
|
||||
yield();
|
||||
uint8_t serial_in_byte = TuyaSerial->read();
|
||||
time_last_byte_received = millis();
|
||||
if (Tuya.byte_counter == 0) {
|
||||
if (serial_in_byte == 0x55) { // Start TUYA Packet
|
||||
Tuya.buffer[Tuya.byte_counter++] = 0x55;
|
||||
}
|
||||
}
|
||||
else if (Tuya.byte_counter == 1) {
|
||||
if (serial_in_byte == 0xAA) { // Only packets with header 0x55AA are valid
|
||||
Tuya.buffer[Tuya.byte_counter++] = 0xAA;
|
||||
Tuya.cmd_checksum = 0xFF;
|
||||
} else {
|
||||
Tuya.byte_counter = 0; // if not received 0xAA right after the 0x55, reset the state machine
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("TYA: 0x55 without 0xAA - resync"));
|
||||
}
|
||||
}
|
||||
else if (Tuya.byte_counter < 6) {
|
||||
Tuya.buffer[Tuya.byte_counter++] = serial_in_byte;
|
||||
Tuya.cmd_checksum += serial_in_byte;
|
||||
if (Tuya.byte_counter == 6) {
|
||||
// Get length of data, max buffer is 256 bytes, so only taking into account lowest byte of length
|
||||
Tuya.data_len = serial_in_byte + 6;
|
||||
}
|
||||
}
|
||||
else if (Tuya.byte_counter == Tuya.data_len) {
|
||||
Tuya.buffer[Tuya.byte_counter++] = serial_in_byte;
|
||||
if (Tuya.cmd_checksum == serial_in_byte) { // Compare checksum and process packet
|
||||
AddLogBuffer(LOG_LEVEL_DEBUG_MORE,(uint8_t*)Tuya.buffer,Tuya.byte_counter);
|
||||
TuyaProcessMessage();
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("TYA: checksum error: 0x%02X instead of 0x%02X"), serial_in_byte, Tuya.cmd_checksum);
|
||||
}
|
||||
Tuya.byte_counter = 0;
|
||||
Tuya.cmd_status = 0;
|
||||
Tuya.cmd_checksum = 0;
|
||||
Tuya.data_len = 0;
|
||||
} // read additional packets from TUYA
|
||||
}
|
||||
else if (Tuya.byte_counter < TUYA_BUFFER_SIZE -1) { // add char to string if it still fits
|
||||
Tuya.buffer[Tuya.byte_counter++] = serial_in_byte;
|
||||
Tuya.cmd_checksum += serial_in_byte;
|
||||
} else {
|
||||
Tuya.byte_counter = 0;
|
||||
Tuya.cmd_status = 0;
|
||||
Tuya.cmd_checksum = 0;
|
||||
Tuya.data_len = 0;
|
||||
}
|
||||
else { // buffer overflow, reset the state machine
|
||||
Tuya.byte_counter = 0;
|
||||
}
|
||||
}
|
||||
// reset the state machine if no bytes received since a long time
|
||||
if (Tuya.byte_counter > 0 && (millis() - time_last_byte_received) > TUYA_CMD_TIMEOUT) {
|
||||
Tuya.byte_counter = 0;
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE,PSTR("TYA: serial receive timeout"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1651,6 +1664,7 @@ bool Xdrv16(uint32_t function) {
|
||||
if (FUNC_MODULE_INIT == function) {
|
||||
result = TuyaModuleSelected();
|
||||
Tuya.active = result;
|
||||
AddLog(LOG_LEVEL_DEBUG,PSTR("TYA: Active=%d"),Tuya.active);
|
||||
}
|
||||
else if (Tuya.active) {
|
||||
switch (function) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user