diff --git a/src/ems-esp.cpp b/src/ems-esp.cpp index 5733a8367..3632f6644 100644 --- a/src/ems-esp.cpp +++ b/src/ems-esp.cpp @@ -1467,6 +1467,9 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) { } else if (strcmp(second_cmd, "n") == 0) { ems_setLogging(EMS_SYS_LOGGING_NONE); ok = true; + } else if (strcmp(second_cmd, "j") == 0) { + ems_setLogging(EMS_SYS_LOGGING_NONE); + ok = true; } } diff --git a/src/ems.cpp b/src/ems.cpp index b33c6c597..6bc10ddf9 100644 --- a/src/ems.cpp +++ b/src/ems.cpp @@ -226,7 +226,7 @@ void ems_init() { EMS_Sys_Status.emsTxPkgs = 0; EMS_Sys_Status.emxCrcErr = 0; EMS_Sys_Status.emsRxStatus = EMS_RX_STATUS_IDLE; - EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE; + EMS_Sys_Status.emsTxStatus = EMS_TX_REV_DETECT; EMS_Sys_Status.emsRefreshed = false; EMS_Sys_Status.emsPollEnabled = false; // start up with Poll disabled EMS_Sys_Status.emsBusConnected = false; @@ -235,8 +235,9 @@ void ems_init() { EMS_Sys_Status.emsTxDisabled = false; EMS_Sys_Status.emsPollFrequency = 0; EMS_Sys_Status.txRetryCount = 0; - EMS_Sys_Status.emsReverse = false; EMS_Sys_Status.emsTxMode = 0; + EMS_Sys_Status.emsIDMask = 0x00; + EMS_Sys_Status.emsPollAck[0] = EMS_ID_ME; // thermostat EMS_Thermostat.setpoint_roomTemp = EMS_VALUE_SHORT_NOTSET; @@ -361,11 +362,12 @@ void ems_setTxMode(uint8_t mode) { // special case for Junkers. If tx_mode is 3 then set the reverse poll flag // https://github.com/proddy/EMS-ESP/issues/103#issuecomment-495945850 if (mode == 3) { - EMS_Sys_Status.emsReverse = true; + EMS_Sys_Status.emsIDMask = 0x80; myDebug_P(PSTR("Forcing emsReverse for Junkers")); } else { - EMS_Sys_Status.emsReverse = false; + EMS_Sys_Status.emsIDMask = 0x00; } + EMS_Sys_Status.emsPollAck[0] = EMS_ID_ME ^ EMS_Sys_Status.emsIDMask; } uint8_t ems_getTxMode() { @@ -453,10 +455,19 @@ void ems_setLogging(_EMS_SYS_LOGGING loglevel) { myDebug_P(PSTR("System Logging set to Solar Module only")); } else if (loglevel == EMS_SYS_LOGGING_RAW) { myDebug_P(PSTR("System Logging set to Raw mode")); + } else if (loglevel == EMS_SYS_LOGGING_JABBER) { + myDebug_P(PSTR("System Logging set to Jabber mode")); } } } +/** + * send a poll acknowledge + */ +void ems_tx_pollAck() { + emsuart_tx_buffer(&EMS_Sys_Status.emsPollAck[0], 1); +} + /** * Calculate CRC checksum using lookup table for speed * len is length of all the data in bytes (including the header & CRC byte at end) @@ -615,20 +626,26 @@ void _ems_sendTelegram() { } EMS_TxTelegram.data[EMS_TxTelegram.length - 1] = _crcCalculator(EMS_TxTelegram.data, EMS_TxTelegram.length); // add the CRC - emsuart_tx_buffer(EMS_TxTelegram.data, EMS_TxTelegram.length); // send the telegram to the UART Tx - EMS_TxQueue.shift(); // and remove from queue + _EMS_TX_STATUS _txStatus = emsuart_tx_buffer(EMS_TxTelegram.data, EMS_TxTelegram.length); // send the telegram to the UART Tx + if (EMS_TX_BRK_DETECT == _txStatus || EMS_TX_WTD_TIMEOUT == _txStatus) { + // Tx Error! + myDebug_P(PSTR("** error sending buffer: %s"),_txStatus == EMS_TX_BRK_DETECT ? + "BRK" : "WDTO"); + // EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE; + } + EMS_TxQueue.shift(); // and remove from queue return; } // create the header - EMS_TxTelegram.data[0] = (EMS_Sys_Status.emsReverse) ? EMS_ID_ME | 0x80 : EMS_ID_ME; // src + EMS_TxTelegram.data[0] = EMS_ID_ME ^ EMS_Sys_Status.emsIDMask; // src // dest if (EMS_TxTelegram.action == EMS_TX_TELEGRAM_WRITE) { EMS_TxTelegram.data[1] = EMS_TxTelegram.dest; } else { // for a READ or VALIDATE - EMS_TxTelegram.data[1] = EMS_TxTelegram.dest | 0x80; // read has 8th bit set + EMS_TxTelegram.data[1] = (EMS_TxTelegram.dest ^ 0x80 ^ EMS_Sys_Status.emsIDMask); // read has 8th bit set } // complete the rest of the header depending on EMS or EMS+ @@ -671,9 +688,17 @@ void _ems_sendTelegram() { } // send the telegram to the UART Tx - emsuart_tx_buffer(EMS_TxTelegram.data, EMS_TxTelegram.length); + _EMS_TX_STATUS _txStatus = emsuart_tx_buffer(EMS_TxTelegram.data, EMS_TxTelegram.length); // send the telegram to the UART Tx + if (EMS_TX_STATUS_OK == _txStatus || EMS_TX_STATUS_IDLE == _txStatus) + EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_WAIT; + else { + // Tx Error! + // Tx Error! + myDebug_P(PSTR("** error sending buffer: %s"),_txStatus == EMS_TX_BRK_DETECT ? + "BRK" : "WDTO"); + EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE; + } - EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_WAIT; } @@ -720,6 +745,57 @@ void _createValidate() { EMS_TxQueue.unshift(new_EMS_TxTelegram); // add back to queue making it first to be picked up next (FIFO) } +/** + * dump a UART Tx or Rx buffer to console... + */ +void ems_dumpBuffer(const char *prefix, uint8_t *telegram, uint8_t length) { + uint32_t timestamp = millis(); + static char output_str[200] = {0}; + static char buffer[16] = {0}; + + if (EMS_Sys_Status.emsLogging != EMS_SYS_LOGGING_JABBER) + return; + + // we only care about known devices + if (length) { + uint8_t dev = telegram[0] & 0x7F; + if (!((dev == 0x04)||(dev == 0x08)||(dev == 0x09)||(dev == 0x0a) + ||(dev == 0x01)||(dev == 0x0b)||(dev == 0x10))) + return; + } + + strlcpy(output_str, "(", sizeof(output_str)); + strlcat(output_str, COLOR_CYAN, sizeof(output_str)); + strlcat(output_str, _smallitoa((uint8_t)((timestamp / 3600000) % 24), buffer), sizeof(output_str)); + strlcat(output_str, ":", sizeof(output_str)); + strlcat(output_str, _smallitoa((uint8_t)((timestamp / 60000) % 60), buffer), sizeof(output_str)); + strlcat(output_str, ":", sizeof(output_str)); + strlcat(output_str, _smallitoa((uint8_t)((timestamp / 1000) % 60), buffer), sizeof(output_str)); + strlcat(output_str, ".", sizeof(output_str)); + strlcat(output_str, _smallitoa3(timestamp % 1000, buffer), sizeof(output_str)); + strlcat(output_str, COLOR_RESET, sizeof(output_str)); + strlcat(output_str, ") ", sizeof(output_str)); + + strlcat(output_str, COLOR_YELLOW, sizeof(output_str)); + strlcat(output_str, prefix, sizeof(output_str)); + + // show some EMS_Sys_Status entries + strlcat(output_str, _hextoa(EMS_Sys_Status.emsRxStatus, buffer), sizeof(output_str)); + strlcat(output_str, " ", sizeof(output_str)); + strlcat(output_str, _hextoa(EMS_Sys_Status.emsTxStatus, buffer), sizeof(output_str)); + strlcat(output_str, ": ", sizeof(output_str)); + + + // print whole buffer, don't interpret any data + for (int i = 0; i < (length); i++) { + strlcat(output_str, _hextoa(telegram[i], buffer), sizeof(output_str)); + strlcat(output_str, " ", sizeof(output_str)); + } + + strlcat(output_str, COLOR_RESET, sizeof(output_str)); + + myDebug(output_str); +} /** * Entry point triggered by an interrupt in emsuart.cpp * length is the number of all the telegram bytes up to and including the CRC at the end @@ -729,16 +805,28 @@ void _createValidate() { void ems_parseTelegram(uint8_t * telegram, uint8_t length) { static uint32_t _last_emsPollFrequency = 0; + ems_dumpBuffer("** [DEBUG MODE] ems_parseTelegram: ", telegram, length); /* * check if we just received a single byte * it could well be a Poll request from the boiler for us, which will have a value of 0x8B (0x0B | 0x80) * or either a return code like 0x01 or 0x04 from the last Write command - * Roger Wilco: we have different types here: - * EMS_ID_ME && length == 1 && EMS_TX_STATUS_IDLE && EMS_RX_STATUS_IDLE: polling request - * EMS_ID_ME && length > 1 && EMS_TX_STATUS_IDLE && EMS_RX_STATUS_IDLE: direct telegram - * (EMS_TX_SUCCESS || EMS_TX_ERROR) && EMS_TX_STATUS_WAIT: response, free the EMS bus - * - * In addition, it may happen that we where interrupted (f.e. by WIFI activity) and the + */ + + /* + * Detect the EMS bus type - Buderus or Junkers - and set emsIDMask accordingly. + * we wait for the first valid telegram and look at the SourceID. + * If Bit 7 is set we have a Buderus, otherwise a Junkers + */ + if (EMS_Sys_Status.emsTxStatus == EMS_TX_REV_DETECT) { + if ((length >= 5) && (telegram[length - 1] == _crcCalculator(telegram, length))) { + EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE; + EMS_Sys_Status.emsIDMask = telegram[0] & 0x80; + EMS_Sys_Status.emsPollAck[0] = EMS_ID_ME ^ EMS_Sys_Status.emsIDMask; + } else + return; // ignore the whole telegram Rx Telegram while in DETECT mode + } + + /* It may happen that we where interrupted (f.e. by WIFI activity) and the * buffer isn't valid anymore, so we must not answer at all... */ if (EMS_Sys_Status.emsRxStatus != EMS_RX_STATUS_IDLE) { @@ -752,8 +840,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) { uint8_t value = telegram[0]; // 1st byte of data package // check first for a Poll for us - // the poll has the MSB set - seems to work on both EMS and Junkers - if ((value & 0x7F) == EMS_ID_ME) { + if ((value ^ 0x80 ^ EMS_Sys_Status.emsIDMask) == EMS_ID_ME) { EMS_Sys_Status.emsTxCapable = true; uint32_t timenow_microsecs = micros(); EMS_Sys_Status.emsPollFrequency = (timenow_microsecs - _last_emsPollFrequency); @@ -766,7 +853,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) { } else { // nothing to send so just send a poll acknowledgement back if (EMS_Sys_Status.emsPollEnabled) { - emsuart_tx_poll(); + ems_tx_pollAck(); } } } else if (EMS_Sys_Status.emsTxStatus == EMS_TX_STATUS_WAIT) { @@ -774,14 +861,14 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) { if (value == EMS_TX_SUCCESS) { EMS_Sys_Status.emsTxPkgs++; // got a success 01. Send a validate to check the value of the last write - emsuart_tx_poll(); // send a poll to free the EMS bus + ems_tx_pollAck(); // send a poll to free the EMS bus _createValidate(); // create a validate Tx request (if needed) } else if (value == EMS_TX_ERROR) { // last write failed (04), delete it from queue and dont bother to retry if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) { myDebug_P(PSTR("** Write command failed from host")); } - emsuart_tx_poll(); // send a poll to free the EMS bus + ems_tx_pollAck(); // send a poll to free the EMS bus _removeTxQueue(); // remove from queue } } @@ -792,7 +879,7 @@ void ems_parseTelegram(uint8_t * telegram, uint8_t length) { // ignore anything that doesn't resemble a proper telegram package // minimal is 5 bytes, excluding CRC at the end if (length <= 4) { - //_debugPrintTelegram("Noisy data:", &EMS_RxTelegram COLOR_RED); + _debugPrintTelegram("Noisy data:", &EMS_RxTelegram, COLOR_RED); return; } @@ -1035,7 +1122,7 @@ void _processType(_EMS_RxTelegram * EMS_RxTelegram) { // if its an echo of ourselves from the master UBA, ignore. This should never happen mind you if (EMS_RxTelegram->src == EMS_ID_ME) { - // _debugPrintTelegram("echo:", EMS_RxTelegram, COLOR_WHITE); + _debugPrintTelegram("echo:", EMS_RxTelegram, COLOR_WHITE); return; } @@ -1143,10 +1230,9 @@ void _processType(_EMS_RxTelegram * EMS_RxTelegram) { } } - emsuart_tx_poll(); // send Acknowledgement back to free the EMS bus since we have the telegram + ems_tx_pollAck(); // send Acknowledgement back to free the EMS bus since we have the telegram } - /** * Check if hot tap water or heating is active * using a quick hack for checking the heating. Selected Flow Temp >= 70 @@ -1684,7 +1770,8 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) { // check to see if its a Junkers Heatronic3, which has a different poll'ing logic if (EMS_Boiler.product_id == EMS_PRODUCTID_HEATRONICS) { - EMS_Sys_Status.emsReverse = true; + EMS_Sys_Status.emsIDMask = 0x80; + EMS_Sys_Status.emsPollAck[0] = EMS_ID_ME ^ EMS_Sys_Status.emsIDMask; } myESP.fs_saveConfig(); // save config to SPIFFS diff --git a/src/ems.h b/src/ems.h index 800577200..d06ba7f19 100644 --- a/src/ems.h +++ b/src/ems.h @@ -29,39 +29,39 @@ #define GPIO_H(mask) (GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, (mask))) #define GPIO_L(mask) (GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, (mask))) -#define RX_PULSE(pulse) \ - do { \ - GPIO_H(RX_MARK_MASK); \ - delayMicroseconds(pulse); \ - GPIO_L(RX_MARK_MASK); \ +#define RX_PULSE(pulse) \ + do { \ + GPIO_H(RX_MARK_MASK); \ + delayMicroseconds(pulse); \ + GPIO_L(RX_MARK_MASK); \ } while (0) -#define TX_PULSE(pulse) \ - do { \ - GPIO_H(TX_MARK_MASK); \ - delayMicroseconds(pulse); \ - GPIO_L(TX_MARK_MASK); \ +#define TX_PULSE(pulse) \ + do { \ + GPIO_H(TX_MARK_MASK); \ + delayMicroseconds(pulse); \ + GPIO_L(TX_MARK_MASK); \ } while (0) -#define LA_PULSE(pulse) \ - do { \ - GPIO_H(MARKERS_MASK); \ - delayMicroseconds(pulse); \ - GPIO_L(MARKERS_MASK); \ +#define LA_PULSE(pulse) \ + do { \ + GPIO_H(MARKERS_MASK); \ + delayMicroseconds(pulse); \ + GPIO_L(MARKERS_MASK); \ } while (0) -#define INIT_MARKERS(void) \ - do { \ - pinMode(RX_MARK_PIN, OUTPUT); \ - pinMode(TX_MARK_PIN, OUTPUT); \ - GPIO_L(MARKERS_MASK); \ +#define INIT_MARKERS(void) \ + do { \ + pinMode(RX_MARK_PIN, OUTPUT); \ + pinMode(TX_MARK_PIN, OUTPUT); \ + GPIO_L(MARKERS_MASK); \ } while (0) #else -#define RX_PULSE(pulse) \ +#define RX_PULSE(pulse) \ {} -#define TX_PULSE(pulse) \ +#define TX_PULSE(pulse) \ {} -#define LA_PULSE(pulse) \ +#define LA_PULSE(pulse) \ {} -#define INIT_MARKERS(void) \ +#define INIT_MARKERS(void) \ {} #define RX_MARK_MASK #define TX_MARK_MASK @@ -124,7 +124,8 @@ typedef enum { EMS_TX_STATUS_IDLE, // ready EMS_TX_STATUS_WAIT, // waiting for response from last Tx EMS_TX_WTD_TIMEOUT, // watchdog timeout during send - EMS_TX_BRK_DETECT // incoming BRK during Tx + EMS_TX_BRK_DETECT, // incoming BRK during Tx + EMS_TX_REV_DETECT // waiting to detect reverse bit } _EMS_TX_STATUS; #define EMS_TX_SUCCESS 0x01 // EMS single byte after a Tx Write indicating a success @@ -145,7 +146,8 @@ typedef enum { EMS_SYS_LOGGING_BASIC, // only basic read/write messages EMS_SYS_LOGGING_THERMOSTAT, // only telegrams sent from thermostat EMS_SYS_LOGGING_SOLARMODULE, // only telegrams sent from thermostat - EMS_SYS_LOGGING_VERBOSE // everything + EMS_SYS_LOGGING_VERBOSE, // everything + EMS_SYS_LOGGING_JABBER // lots of debug output... } _EMS_SYS_LOGGING; // status/counters since last power on @@ -164,8 +166,9 @@ typedef struct { bool emsTxCapable; // able to send via Tx bool emsTxDisabled; // true to prevent all Tx uint8_t txRetryCount; // # times the last Tx was re-sent - bool emsReverse; // if true, poll logic is reversed uint8_t emsTxMode; // handles Tx logic + uint8_t emsIDMask; // Buderus: 0x00, Junkers: 0x80 + uint8_t emsPollAck[1]; // acknowledge buffer } _EMS_Sys_Status; // The Tx send package @@ -390,6 +393,7 @@ typedef struct { } _EMS_Type; // function definitions +extern void ems_dumpBuffer(const char *prefix, uint8_t *telegram, uint8_t length); extern void ems_parseTelegram(uint8_t * telegram, uint8_t len); void ems_init(); void ems_doReadCommand(uint16_t type, uint8_t dest, bool forceRefresh = false); diff --git a/src/emsuart.cpp b/src/emsuart.cpp index a701d25c3..a0bb11411 100644 --- a/src/emsuart.cpp +++ b/src/emsuart.cpp @@ -13,6 +13,7 @@ _EMSRxBuf * pEMSRxBuf; _EMSRxBuf * paEMSRxBuf[EMS_MAXBUFFERS]; uint8_t emsRxBufIdx = 0; +uint8_t phantomBreak= 0; os_event_t recvTaskQueue[EMSUART_recvTaskQueueLen]; // our Rx queue @@ -22,7 +23,7 @@ os_event_t recvTaskQueue[EMSUART_recvTaskQueueLen]; // our Rx queue // static void emsuart_rx_intr_handler(void * para) { static uint8_t length; - static uint8_t uart_buffer[EMS_MAXBUFFERSIZE]; + static uint8_t uart_buffer[EMS_MAXBUFFERSIZE + 2]; // is a new buffer? if so init the thing for a new telegram if (EMS_Sys_Status.emsRxStatus == EMS_RX_STATUS_IDLE) { @@ -33,7 +34,9 @@ static void emsuart_rx_intr_handler(void * para) { // fill IRQ buffer, by emptying Rx FIFO if (USIS(EMSUART_UART) & ((1 << UIFF) | (1 << UITO) | (1 << UIBD))) { while ((USS(EMSUART_UART) >> USRXC) & 0xFF) { - uart_buffer[length++] = USF(EMSUART_UART); + uint8_t rx = USF(EMSUART_UART); + if (length < EMS_MAXBUFFERSIZE) + uart_buffer[length++] = rx; } // clear Rx FIFO full and Rx FIFO timeout interrupts @@ -46,8 +49,9 @@ static void emsuart_rx_intr_handler(void * para) { ETS_UART_INTR_DISABLE(); // disable all interrupts and clear them USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt - pEMSRxBuf->length = length; - os_memcpy((void *)pEMSRxBuf->buffer, (void *)&uart_buffer, length); // copy data into transfer buffer, including the BRK 0x00 at the end + pEMSRxBuf->length = (length > EMS_MAXBUFFERSIZE) ? EMS_MAXBUFFERSIZE : length; + os_memcpy((void *)pEMSRxBuf->buffer, (void *)&uart_buffer, pEMSRxBuf->length); // copy data into transfer buffer, including the BRK 0x00 at the end + length = 0; EMS_Sys_Status.emsRxStatus = EMS_RX_STATUS_IDLE; // set the status flag stating BRK has been received and we can start a new package ETS_UART_INTR_ENABLE(); // re-enable UART interrupts @@ -67,18 +71,21 @@ static void ICACHE_FLASH_ATTR emsuart_recvTask(os_event_t * events) { uint8_t length = pCurrent->length; // number of bytes including the BRK at the end pCurrent->length = 0; - // validate and transmit the EMS buffer, excluding the BRK + if (phantomBreak) { + phantomBreak = 0; + length--; // remove phantom break from Rx buffer + } + if (length == 2) { RX_PULSE(20); // it's a poll or status code, single byte and ok to send on ems_parseTelegram((uint8_t *)pCurrent->buffer, 1); - } else if ((length > 4) && (length <= EMS_MAXBUFFERSIZE + 1) && (pCurrent->buffer[length - 2] != 0x00)) { + } else if ((length > 4) && (length <= EMS_MAXBUFFERSIZE + 1)) { // ignore double BRK at the end, possibly from the Tx loopback // also telegrams with no data value RX_PULSE(40); ems_parseTelegram((uint8_t *)pCurrent->buffer, length - 1); // transmit EMS buffer, excluding the BRK } - // memset(pCurrent->buffer, 0x00, EMS_MAXBUFFERSIZE); // wipe memory just to be safe } /* @@ -122,10 +129,10 @@ void ICACHE_FLASH_ATTR emsuart_init() { // UCFFT = RX FIFO Full Threshold (7 bit) = want this to be 31 for 32 bytes of buffer (default was 127) // see https://www.espressif.com/sites/default/files/documentation/esp8266-technical_reference_en.pdf // - // change: we set UCFFT to 1 to get an immediate indicator about incoming trafffic. + // change: we set UCFFT to 1 to get an immediate indicator about incoming traffic. // Otherwise, we're only noticed by UCTOT or RxBRK! USC1(EMSUART_UART) = 0; // reset config first - USC1(EMSUART_UART) = (0x01 << UCFFT) | (0x01 << UCTOT) | (1 << UCTOE); // enable interupts + USC1(EMSUART_UART) = (0x01 << UCFFT) | (0x01 << UCTOT) | (0 << UCTOE); // enable interupts // set interrupts for triggers USIC(EMSUART_UART) = 0xFFFF; // clear all interupts @@ -133,7 +140,8 @@ void ICACHE_FLASH_ATTR emsuart_init() { // enable rx break, fifo full and timeout. // but not frame error UIFR (because they are too frequent) or overflow UIOF because our buffer is only max 32 bytes - USIE(EMSUART_UART) = (1 << UIBD) | (1 << UIFF) | (1 << UITO); + // change: we don't care about Rx Timeout - it may lead to wrong readouts + USIE(EMSUART_UART) = (1 << UIBD) | (1 << UIFF) | (0 << UITO); // set up interrupt callbacks for Rx system_os_task(emsuart_recvTask, EMSUART_recvTaskPrio, recvTaskQueue, EMSUART_recvTaskQueueLen); @@ -199,6 +207,7 @@ void ICACHE_FLASH_ATTR emsuart_tx_brk() { */ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) { _EMS_TX_STATUS result = EMS_TX_STATUS_OK; + ems_dumpBuffer("emsuart_tx_buffer: ", buf, len); // validate and transmit the EMS buffer, excluding the BRK if (len) { LA_PULSE(50); // temp code until we get mode 2 working without resets @@ -254,9 +263,9 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) { // shorter busy poll... #define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8) -#define EMS_TX_TO_COUNT ((20 + 10000 / EMSUART_BIT_TIME) * 8) +#define EMS_TX_TO_CHARS (2 + 20) +#define EMS_TX_TO_COUNT ( (EMS_TX_TO_CHARS) * 10 * 8) uint16_t wdc = EMS_TX_TO_COUNT; - ETS_UART_INTR_DISABLE(); // disable rx interrupt // clear Rx status register @@ -272,7 +281,6 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) { USF(EMSUART_UART) = buf[i++]; // send each Tx byte // wait for echo from busmaster GPIO_L(TX_MARK_MASK); - while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) { delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles... if (--wdc == 0) { @@ -301,11 +309,13 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) { // wait until BRK detected... while (!(USIR(EMSUART_UART) & (1 << UIBD))) { - delayMicroseconds(EMSUART_BUSY_WAIT); + // delayMicroseconds(EMSUART_BUSY_WAIT); + delayMicroseconds(EMSUART_BIT_TIME); } USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ + phantomBreak = 1; } GPIO_L(TX_MARK_MASK); } @@ -317,13 +327,8 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) { /* * Send the Poll (our own ID) to Tx as a single byte and end with a - */ + * *** moved to ems.cpp, renamed to ems_tx_pollAck void ICACHE_FLASH_ATTR emsuart_tx_poll() { - static uint8_t buf[1]; - if (EMS_Sys_Status.emsReverse) { - buf[0] = {EMS_ID_ME | 0x80}; - } else { - buf[0] = {EMS_ID_ME}; - } - emsuart_tx_buffer(buf, 1); + static uint8_t buf[1] = {EMS_ID_ME ^ EMS_Sys_Status.emsIDMask}; } + */ \ No newline at end of file diff --git a/src/emsuart.h b/src/emsuart.h index 0777dcfd5..3a4f9da7e 100644 --- a/src/emsuart.h +++ b/src/emsuart.h @@ -37,4 +37,3 @@ void ICACHE_FLASH_ATTR emsuart_init(); void ICACHE_FLASH_ATTR emsuart_stop(); void ICACHE_FLASH_ATTR emsuart_start(); _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len); -void ICACHE_FLASH_ATTR emsuart_tx_poll();