From 8b6adf56ec91ec5b626123efe4784a344c011990 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Jun 2020 16:14:29 +0200 Subject: [PATCH 1/3] uart fixes, no logging while tx sends --- src/telegram.cpp | 22 +++------ src/uart/emsuart_esp32.cpp | 60 +++++++++++++++-------- src/uart/emsuart_esp32.h | 13 +++++ src/uart/emsuart_esp8266.cpp | 95 ++++++++++-------------------------- src/uart/emsuart_esp8266.h | 2 - 5 files changed, 89 insertions(+), 103 deletions(-) diff --git a/src/telegram.cpp b/src/telegram.cpp index a393093bc..d5da2ad11 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -461,25 +461,19 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { length++; // add one since we want to now include the CRC - LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"), - (telegram->operation == Telegram::Operation::TX_WRITE) ? F("write") : F("read"), - tx_telegram.id_, - telegram->to_string(telegram_raw, length).c_str()); - // send the telegram to the UART Tx uint16_t status = EMSuart::transmit(telegram_raw, length); -#ifdef EMSESP_DEBUG - // if watching in 'raw' mode - if (EMSESP::watch() == 2) { - LOG_INFO(F("[DEBUG] Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); - } -#endif if (status == EMS_TX_STATUS_ERR) { LOG_ERROR(F("Failed to transmit Tx via UART.")); increment_telegram_fail_count(); // another Tx fail tx_waiting(false); // nothing send, tx not in wait state return; +// } else { +// LOG_DEBUG(F("Send %s Tx [#%d], telegram: %s"), +// (telegram->operation == Telegram::Operation::TX_WRITE) ? F("write") : F("read"), +// tx_telegram.id_, +// telegram->to_string(telegram_raw, length).c_str()); } tx_waiting(true); // tx now in a wait state @@ -496,17 +490,17 @@ void TxService::send_telegram(const uint8_t * data, const uint8_t length) { } telegram_raw[length] = calculate_crc(telegram_raw, length); // apppend CRC - LOG_DEBUG(F("Sending Raw telegram: %s (length=%d)"), Helpers::data_to_hex(telegram_raw, length).c_str(), length); - tx_waiting(false); // no post validation // send the telegram to the UART Tx uint16_t status = EMSuart::transmit(telegram_raw, length); - //LOG_DEBUG(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); + if (status == EMS_TX_STATUS_ERR) { LOG_ERROR(F("Failed to transmit Tx via UART.")); increment_telegram_fail_count(); // another Tx fail +// } else { +// LOG_DEBUG(F("Send Raw telegram: %s (length=%d)"), Helpers::data_to_hex(telegram_raw, length).c_str(), length); } } diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index d4dc5d2b5..6d0040874 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -33,7 +33,6 @@ static RingbufHandle_t buf_handle = NULL; static hw_timer_t * timer = NULL; bool drop_next_rx = true; uint8_t tx_mode_ = 0xFF; -//portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; uint8_t emsTxBuf[EMS_MAXBUFFERSIZE]; uint8_t emsTxBufIdx; uint8_t emsTxBufLen; @@ -99,13 +98,7 @@ void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() { * init UART driver */ void EMSuart::start(uint8_t tx_mode) { - if (tx_mode == EMS_TXMODE_DEFAULT) { - emsTxWait = EMSUART_BIT_TIME * 11; - } else if (tx_mode == EMS_TXMODE_EMSPLUS) { - emsTxWait = EMSUART_BIT_TIME * 20; - } else if (tx_mode == EMS_TXMODE_HT3) { - emsTxWait = EMSUART_BIT_TIME * 17; - } else if(tx_mode > 10 ) { + if(tx_mode > 10 ) { emsTxWait = EMSUART_BIT_TIME * tx_mode; } else if(tx_mode > 5 ) { emsTxWait = EMSUART_BIT_TIME * tx_mode * 2; @@ -123,13 +116,10 @@ void EMSuart::start(uint8_t tx_mode) { .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, } + ESP_ERROR_CHECK(uart_param_config(EMSUART_UART, &uart_config)); if (tx_mode_ == 5) { EMS_UART.conf0.stop_bit_num = UART_STOP_BITS_1_5; - } else { - EMS_UART.conf0.stop_bit_num = UART_STOP_BITS_1; } - - ESP_ERROR_CHECK(uart_param_config(EMSUART_UART, &uart_config)); ESP_ERROR_CHECK(uart_set_pin(EMSUART_UART, EMSUART_TXPIN, EMSUART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); EMS_UART.int_ena.val = 0; // disable all intr. EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags @@ -195,15 +185,10 @@ void EMSuart::send_poll(uint8_t data) { * returns code, 1=success */ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) { - if (len == 0 || len > 32) { + if (len == 0 || len >= EMS_MAXBUFFERSIZE) { return EMS_TX_STATUS_ERR; } - if (tx_mode_ == EMS_TXMODE_NEW || tx_mode_ == 5) { - for (uint8_t i = 0; i < len; i++) { - EMS_UART.fifo.rw_byte = buf[i]; - } - EMS_UART.conf0.txd_brk = 1; // after send - } else { + if (tx_mode_ > 5) { // timer controlled modes for (uint8_t i = 0; i < len; i++) { emsTxBuf[i] = buf[i]; } @@ -212,7 +197,44 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) { emsTxBufLen = len; timerAlarmWrite(timer, emsTxWait, false); timerAlarmEnable(timer); + return EMS_TX_STATUS_OK; } + if (tx_mode_ >= EMS_TXMODE_NEW) { // hardware controlled modes + for (uint8_t i = 0; i < len; i++) { + EMS_UART.fifo.rw_byte = buf[i]; + } + EMS_UART.conf0.txd_brk = 1; // after send + return EMS_TX_STATUS_OK; + } + if (tx_mode_ >= EMS_TXMODE_EMSPLUS) { // EMS+ with long delay + for (uint8_t i = 0; i < len; i++) { + EMS_UART.fifo.rw_byte = buf[i]; + delaymicroseconds(EMSUART_TX_WAIT_PLUS); + } + EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send + return EMS_TX_STATUS_OK; + } + if (tx_mode_ >= EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay + for (uint8_t i = 0; i < len; i++) { + EMS_UART.fifo.rw_byte = buf[i]; + delayMicroseconds(EMSUART_TX_WAIT_HT3); + } + EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send + return EMS_TX_STATUS_OK; + } + // mode 1 + // flush fifos -- not supported in ESP32 uart #2! + // EMS_UART.conf0.rxfifo_rst = 1; + // EMS_UART.conf0.txfifo_rst = 1; + for (uint8_t i = 0; i < len; i++) { + volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt; + EMS_UART.fifo.rw_byte = buf[i]; // send each Tx byte + // wait for echo + while (EMS_UART.status.rxfifo_cnt == _usrxc) { + delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles... + } + } + EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send return EMS_TX_STATUS_OK; } diff --git a/src/uart/emsuart_esp32.h b/src/uart/emsuart_esp32.h index 000a20c00..763bc491b 100644 --- a/src/uart/emsuart_esp32.h +++ b/src/uart/emsuart_esp32.h @@ -45,6 +45,19 @@ #define EMS_TXMODE_HT3 3 #define EMS_TXMODE_NEW 4 // for michael's testing +// LEGACY +#define EMSUART_TX_BIT_TIME 104 // bit time @9600 baud +#define EMSUART_TX_WAIT_BRK (EMSUART_TX_BIT_TIME * 11) // 1144 + +// EMS 1.0 +#define EMSUART_TX_BUSY_WAIT (EMSUART_TX_BIT_TIME / 8) // 13 + +// HT3/Junkers - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) plus 7 bit delay. The -8 is for lag compensation. +#define EMSUART_TX_WAIT_HT3 (EMSUART_TX_BIT_TIME * 17) - 8 // 1760 + +// EMS+ - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) and delay of another Bytetime. +#define EMSUART_TX_WAIT_PLUS 2070 + // customize the GPIO pins for RX and TX here #ifdef WEMOS_D1_32 diff --git a/src/uart/emsuart_esp8266.cpp b/src/uart/emsuart_esp8266.cpp index 1b1468f89..c071585f7 100644 --- a/src/uart/emsuart_esp8266.cpp +++ b/src/uart/emsuart_esp8266.cpp @@ -24,18 +24,12 @@ namespace emsesp { -MAKE_PSTR(logger_name, "emsuart") - -uuid::log::Logger EMSuart::logger_{F_(logger_name), uuid::log::Facility::CONSOLE}; os_event_t recvTaskQueue[EMSUART_recvTaskQueueLen]; // our Rx queue EMSuart::EMSRxBuf_t * pEMSRxBuf; EMSuart::EMSRxBuf_t * paEMSRxBuf[EMS_MAXBUFFERS]; uint8_t emsRxBufIdx = 0; -uint8_t phantomBreak = 0; uint8_t tx_mode_ = 0xFF; bool drop_next_rx = true; -uint32_t emsRxTime; -// uint32_t emsTxTime = 0; uint8_t emsTxBuf[EMS_MAXBUFFERSIZE]; uint8_t emsTxBufIdx; uint8_t emsTxBufLen; @@ -67,7 +61,6 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { if (!drop_next_rx) { pEMSRxBuf->length = length; os_memcpy((void *)pEMSRxBuf->buffer, (void *)&uart_buffer, pEMSRxBuf->length); // copy data into transfer buffer, including the BRK 0x00 at the end - emsRxTime = uuid::get_uptime(); } drop_next_rx = false; system_os_post(EMSUART_recvTaskPrio, 0, 0); // call emsuart_recvTask() at next opportunity @@ -85,24 +78,8 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_recvTask(os_event_t * events) { uint8_t length = pCurrent->length; // number of bytes including the BRK at the end pCurrent->length = 0; - if (phantomBreak) { - phantomBreak = 0; - length--; // remove phantom break from Rx buffer - } - // if (emsTxTime > 0) { - // LOG_INFO(F("tx duration: %d ms"), uuid::get_uptime() - emsTxTime); - // emsTxTime = 0; - // } - // it's a poll or status code, single byte and ok to send on, then quit - if (length == 2) { - EMSESP::incoming_telegram((uint8_t *)pCurrent->buffer, 1); - return; - } - - // ignore double BRK at the end, possibly from the Tx loopback - // also telegrams with no data value - // then transmit EMS buffer, excluding the BRK - if (length > 4) { + // Ignore telegrams with no data value, then transmit EMS buffer, excluding the BRK + if (length > 4 || length == 2) { EMSESP::incoming_telegram((uint8_t *)pCurrent->buffer, length - 1); } } @@ -111,9 +88,8 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_recvTask(os_event_t * events) { * flush everything left over in buffer, this clears both rx and tx FIFOs */ void ICACHE_FLASH_ATTR EMSuart::emsuart_flush_fifos() { - uint32_t tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask - USC0(EMSUART_UART) |= (tmp); // set bits - USC0(EMSUART_UART) &= ~(tmp); // clear bits + USC0(EMSUART_UART) |= ((1 << UCRXRST) | (1 << UCTXRST)); // set bits + USC0(EMSUART_UART) &= ~((1 << UCRXRST) | (1 << UCTXRST)); // clear bits } // ISR to Fire when Timer is triggered @@ -128,7 +104,7 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() { } else if (emsTxBufIdx == emsTxBufLen) { USC0(EMSUART_UART) |= (1 << UCBRK); // set if (tx_mode_ > 5 || tx_mode_ < 11) { - timer1_write(5 * EMSUART_TX_BIT_TIME * 12); + timer1_write(5 * EMSUART_TX_BIT_TIME * 11); USIE(EMSUART_UART) &= ~(1 << UIBD); // disable break interrupt } } else if (USC0(EMSUART_UART) & (1 << UCBRK)) { @@ -141,9 +117,9 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() { */ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) { if (tx_mode > 10) { - emsTxWait = 5 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode + emsTxWait = 5 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode } else if (tx_mode > 5) { - emsTxWait = 10 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode + emsTxWait = 10 * EMSUART_TX_BIT_TIME * tx_mode; // bittimes for tx_mode } if (tx_mode == 5) { USC0(EMSUART_UART) = 0x2C; // 8N1,5 @@ -249,13 +225,9 @@ void ICACHE_FLASH_ATTR EMSuart::restart() { */ void ICACHE_FLASH_ATTR EMSuart::tx_brk() { - // must make sure Tx FIFO is empty - while (((USS(EMSUART_UART) >> USTXC) & 0xFF)) - ; - // do not clear buffers to get a echo back - // tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask - // USC0(EMSUART_UART) |= (tmp); // set bits - // USC0(EMSUART_UART) &= ~(tmp); // clear bits + // make sure Tx FIFO is empty + while (((USS(EMSUART_UART) >> USTXC) & 0xFF)) { + } // To create a 11-bit we set TXD_BRK bit so the break signal will // automatically be sent when the tx fifo is empty @@ -264,8 +236,11 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() { if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ mode delayMicroseconds(EMSUART_TX_WAIT_PLUS); // 2070 - } else { // junkers and EMS1.0 + } else if (tx_mode_ == EMS_TXMODE_HT3) { // junkers delayMicroseconds(EMSUART_TX_WAIT_BRK); // 1144 + } else { // EMS1.0 + while (!(USIR(EMSUART_UART) & (1 << UIBD))) { + } } USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear BRK bit @@ -279,14 +254,15 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() { void EMSuart::send_poll(uint8_t data) { // reset tx-brk, just in case it is accidently set USC0(EMSUART_UART) &= ~(1 << UCBRK); + if (tx_mode_ > 5) { // timer controlled modes USF(EMSUART_UART) = data; - emsTxBufIdx = 0; - emsTxBufLen = 1; + emsTxBufIdx = 0; + emsTxBufLen = 1; timer1_write(emsTxWait); } else if (tx_mode_ >= EMS_TXMODE_NEW) { // hardware controlled modes USF(EMSUART_UART) = data; - USC0(EMSUART_UART) |= (1 << UCBRK); // send at the end + USC0(EMSUART_UART) |= (1 << UCBRK); // brk after sendout } else if (tx_mode_ == EMS_TXMODE_HT3) { USF(EMSUART_UART) = data; delayMicroseconds(EMSUART_TX_WAIT_HT3); @@ -308,16 +284,10 @@ void EMSuart::send_poll(uint8_t data) { * returns code, 0=success, 1=brk error, 2=watchdog timeout */ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { - if (len == 0 || len > 32) { + if (len == 0 || len >= EMS_MAXBUFFERSIZE) { return EMS_TX_STATUS_ERR; // nothing or to much to send } -#ifdef EMSESP_DEBUG - // LOG_INFO(F("[DEBUG] UART Response time: %d ms"), uuid::get_uptime() - emsRxTime); -#endif - // emsTxTime = uuid::get_uptime(); - // if ((uuid::get_uptime() - emsRxTime) > EMS_RX_TO_TX_TIMEOUT)) { // send allowed within 20 ms - // return EMS_TX_STATUS_ERR; - // } + // reset tx-brk, just in case it is accidently set USC0(EMSUART_UART) &= ~(1 << UCBRK); @@ -326,16 +296,14 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { for (uint8_t i = 0; i < len; i++) { emsTxBuf[i] = buf[i]; } - emsTxBufIdx = 0; - emsTxBufLen = len; + emsTxBufIdx = 0; + emsTxBufLen = len; USF(EMSUART_UART) = buf[0]; - // timer1_attachInterrupt(emsuart_tx_timer_intr_handler); // Add ISR Function - // timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); // 5 MHz timer timer1_write(emsTxWait); return EMS_TX_STATUS_OK; } - // new code from Michael. See https://github.com/proddy/EMS-ESP/issues/380 + // hardware controlled modes with 1 and 1,5 stopbits if (tx_mode_ >= EMS_TXMODE_NEW) { for (uint8_t i = 0; i < len; i++) { USF(EMSUART_UART) = buf[i]; @@ -358,11 +326,9 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { if (tx_mode_ == EMS_TXMODE_HT3) { for (uint8_t i = 0; i < len; i++) { USF(EMSUART_UART) = buf[i]; - // just to be safe wait for tx fifo empty (still needed?) - while (((USS(EMSUART_UART) >> USTXC) & 0xff)) - ; - + while (((USS(EMSUART_UART) >> USTXC) & 0xff)) { + } // wait until bits are sent on wire delayMicroseconds(EMSUART_TX_WAIT_HT3); } @@ -397,16 +363,14 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { // disable rx interrupt // clear Rx status register, resetting the Rx FIFO and flush it - // noInterrupts(); ETS_UART_INTR_DISABLE(); - // USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo emsuart_flush_fifos(); // send the bytes along the serial line for (uint8_t i = 0; i < len; i++) { volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF; USF(EMSUART_UART) = buf[i]; // send each Tx byte - // wait for echo from the busmaster + // wait for echo while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) { delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles... } @@ -419,21 +383,16 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { // neither bus collision nor timeout - send terminating BRK signal if (!(USIS(EMSUART_UART) & (1 << UIBD))) { // no bus collision - send terminating BRK signal - // USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set USC0(EMSUART_UART) |= (1 << UCBRK); // set // wait until BRK detected... while (!(USIR(EMSUART_UART) & (1 << UIBD))) { - delayMicroseconds(EMSUART_TX_BIT_TIME); + // delayMicroseconds(EMSUART_TX_BIT_TIME); } USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear - // USC0(EMSUART_UART) &= ~((1 << UCBRK) | (1 << UCLBE)); // disable loopback & clear - // USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ - // phantomBreak = 1; } - // interrupts(); ETS_UART_INTR_ENABLE(); // open up the FIFO again to start receiving return EMS_TX_STATUS_OK; // send the Tx ok status back diff --git a/src/uart/emsuart_esp8266.h b/src/uart/emsuart_esp8266.h index 1923b2f2e..e3ba11e30 100644 --- a/src/uart/emsuart_esp8266.h +++ b/src/uart/emsuart_esp8266.h @@ -75,8 +75,6 @@ class EMSuart { } EMSRxBuf_t; private: - // static constexpr uint32_t EMS_RX_TO_TX_TIMEOUT = 20; - static uuid::log::Logger logger_; static void ICACHE_RAM_ATTR emsuart_rx_intr_handler(void * para); static void ICACHE_FLASH_ATTR emsuart_recvTask(os_event_t * events); static void ICACHE_FLASH_ATTR emsuart_flush_fifos(); From 10607a912582bfdad4553a092d50b7e0e5f442c8 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 15 Jun 2020 17:59:06 +0200 Subject: [PATCH 2/3] esp32 uart modes with delay included, but failed --- src/console.cpp | 4 ++++ src/console.h | 2 +- src/uart/emsuart_esp32.cpp | 42 +++++++++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 419eb8082..fa3992ae6 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -65,7 +65,11 @@ void EMSESPShell::display_banner() { println(); printfln(F("┌──────────────────────────────────────────┐")); +#if defined(ESP32) + printfln(F("│ %sEMS-ESP version %-10s ESP32%s │"), COLOR_BOLD_ON, settings.app_version().c_str(), COLOR_BOLD_OFF); +#else printfln(F("│ %sEMS-ESP version %-10s%s │"), COLOR_BOLD_ON, settings.app_version().c_str(), COLOR_BOLD_OFF); +#endif printfln(F("│ %s%shttps://github.com/proddy/EMS-ESP%s │"), COLOR_BRIGHT_GREEN, COLOR_UNDERLINE, COLOR_RESET); printfln(F("│ │")); diff --git a/src/console.h b/src/console.h index 69ad657f4..8035021cf 100644 --- a/src/console.h +++ b/src/console.h @@ -41,7 +41,7 @@ using uuid::log::Level; // clang-format off -#define LOG_DEBUG(...) if (logger_.enabled(Level::DEBUG)) {logger_.debug(__VA_ARGS__);} +#define LOG_DEBUG(...) logger_.debug(__VA_ARGS__) #define LOG_INFO(...) logger_.info(__VA_ARGS__) #define LOG_TRACE(...) logger_.trace(__VA_ARGS__) #define LOG_NOTICE(...) logger_.notice(__VA_ARGS__) diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index 6d0040874..4d4dee782 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -102,6 +102,12 @@ void EMSuart::start(uint8_t tx_mode) { emsTxWait = EMSUART_BIT_TIME * tx_mode; } else if(tx_mode > 5 ) { emsTxWait = EMSUART_BIT_TIME * tx_mode * 2; + } else if(tx_mode == 3) { + emsTxWait = EMSUART_BIT_TIME * 17; + } else if(tx_mode == 2) { + emsTxWait = EMSUART_BIT_TIME * 20; + } else if(tx_mode == 1) { + emsTxWait = EMSUART_BIT_TIME * 11; } if (tx_mode_ != 0xFF) { // uart already initialized tx_mode_ = tx_mode; @@ -115,19 +121,19 @@ void EMSuart::start(uint8_t tx_mode) { .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - } - ESP_ERROR_CHECK(uart_param_config(EMSUART_UART, &uart_config)); + }; + uart_param_config(EMSUART_UART, &uart_config); if (tx_mode_ == 5) { EMS_UART.conf0.stop_bit_num = UART_STOP_BITS_1_5; } - ESP_ERROR_CHECK(uart_set_pin(EMSUART_UART, EMSUART_TXPIN, EMSUART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + uart_set_pin(EMSUART_UART, EMSUART_TXPIN, EMSUART_RXPIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); EMS_UART.int_ena.val = 0; // disable all intr. EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags EMS_UART.idle_conf.tx_brk_num = 11; // breaklength 11 bit EMS_UART.idle_conf.rx_idle_thrhd = 256; drop_next_rx = true; buf_handle = xRingbufferCreate(128, RINGBUF_TYPE_NOSPLIT); - ESP_ERROR_CHECK(uart_isr_register(EMSUART_UART, emsuart_rx_intr_handler, NULL, ESP_INTR_FLAG_IRAM, &uart_handle)); + uart_isr_register(EMSUART_UART, emsuart_rx_intr_handler, NULL, ESP_INTR_FLAG_IRAM, &uart_handle); xTaskCreate(emsuart_recvTask, "emsuart_recvTask", 2048, NULL, configMAX_PRIORITIES - 1, NULL); EMS_UART.int_ena.brk_det = 1; // activate only break @@ -167,15 +173,27 @@ void EMSuart::restart() { * Sends a 1-byte poll, ending with a */ void EMSuart::send_poll(uint8_t data) { - if (tx_mode_ == EMS_TXMODE_NEW || tx_mode_ == 5) { - EMS_UART.fifo.rw_byte = data; - EMS_UART.conf0.txd_brk = 1; // after send - } else { + if (tx_mode_ > 5 || tx_mode_ < 4) { EMS_UART.fifo.rw_byte = data; emsTxBufIdx = 0; emsTxBufLen = 1; timerAlarmWrite(timer, emsTxWait, false); timerAlarmEnable(timer); + } else if (tx_mode_ >= EMS_TXMODE_NEW) { + EMS_UART.fifo.rw_byte = data; + EMS_UART.conf0.txd_brk = 1; // after send + } else if (tx_mode_ == EMS_TXMODE_HT3) { + EMS_UART.fifo.rw_byte = data; + delayMicroseconds(EMSUART_TX_WAIT_HT3); + EMS_UART.conf0.txd_brk = 1; // + } else if (tx_mode_ == EMS_TXMODE_EMSPLUS) { + EMS_UART.fifo.rw_byte = data; + delayMicroseconds(EMSUART_TX_WAIT_PLUS); + EMS_UART.conf0.txd_brk = 1; // + } else { + EMS_UART.fifo.rw_byte = data; + delayMicroseconds(EMSUART_TX_WAIT_BRK); + EMS_UART.conf0.txd_brk = 1; // } } @@ -188,7 +206,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) { if (len == 0 || len >= EMS_MAXBUFFERSIZE) { return EMS_TX_STATUS_ERR; } - if (tx_mode_ > 5) { // timer controlled modes + if (tx_mode_ > 5 || tx_mode_ < 4) { // timer controlled modes for (uint8_t i = 0; i < len; i++) { emsTxBuf[i] = buf[i]; } @@ -206,15 +224,15 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) { EMS_UART.conf0.txd_brk = 1; // after send return EMS_TX_STATUS_OK; } - if (tx_mode_ >= EMS_TXMODE_EMSPLUS) { // EMS+ with long delay + if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ with long delay for (uint8_t i = 0; i < len; i++) { EMS_UART.fifo.rw_byte = buf[i]; - delaymicroseconds(EMSUART_TX_WAIT_PLUS); + delayMicroseconds(EMSUART_TX_WAIT_PLUS); } EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send return EMS_TX_STATUS_OK; } - if (tx_mode_ >= EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay + if (tx_mode_ == EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay for (uint8_t i = 0; i < len; i++) { EMS_UART.fifo.rw_byte = buf[i]; delayMicroseconds(EMSUART_TX_WAIT_HT3); From 01de545b41f737e672f70e5bfb0b5e91b3de320f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 16 Jun 2020 07:55:21 +0200 Subject: [PATCH 3/3] Timeout back to tx_mode 1 --- src/telegram.cpp | 7 ++++++- src/uart/emsuart_esp8266.cpp | 17 +++++++++++------ src/uart/emsuart_esp8266.h | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/telegram.cpp b/src/telegram.cpp index e4c67a7b8..9e63b9bf5 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -461,7 +461,10 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { length++; // add one since we want to now include the CRC -#if defined(ESP32) +#if defined(ESP8266) + Settings settings; + if (settings.ems_tx_mode() <= 5) { +#endif // This logging causes errors with timer based tx-modes on esp8266! LOG_DEBUG(F("Sending %s Tx [#%d], telegram: %s"), (telegram->operation == Telegram::Operation::TX_WRITE) ? F("write") : F("read"), @@ -474,6 +477,8 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { LOG_NOTICE(F("[DEBUG] Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); } #endif +#if defined(ESP8266) + } #endif // send the telegram to the UART Tx uint16_t status = EMSuart::transmit(telegram_raw, length); diff --git a/src/uart/emsuart_esp8266.cpp b/src/uart/emsuart_esp8266.cpp index 11e2ae0fe..f261dbcb1 100644 --- a/src/uart/emsuart_esp8266.cpp +++ b/src/uart/emsuart_esp8266.cpp @@ -275,10 +275,14 @@ void EMSuart::send_poll(uint8_t data) { ETS_UART_INTR_DISABLE(); volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF; USF(EMSUART_UART) = data; - while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) { + uint8_t timeoutcnt = EMSUART_TX_TIMEOUT; + while ((((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) && (--timeoutcnt > 0)) { + delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles... } USC0(EMSUART_UART) |= (1 << UCBRK); // set - while (!(USIR(EMSUART_UART) & (1 << UIBD))) { + timeoutcnt = EMSUART_TX_TIMEOUT; + while (!(USIR(EMSUART_UART) & (1 << UIBD)) && (--timeoutcnt > 0)) { + delayMicroseconds(EMSUART_TX_BUSY_WAIT); } USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear ETS_UART_INTR_ENABLE(); @@ -376,9 +380,10 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { // send the bytes along the serial line for (uint8_t i = 0; i < len; i++) { volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF; + uint8_t timeoutcnt = EMSUART_TX_TIMEOUT; USF(EMSUART_UART) = buf[i]; // send each Tx byte // wait for echo - while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) { + while ((((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) && (--timeoutcnt > 0)) { delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles... } } @@ -391,10 +396,10 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { if (!(USIS(EMSUART_UART) & (1 << UIBD))) { // no bus collision - send terminating BRK signal USC0(EMSUART_UART) |= (1 << UCBRK); // set - + uint8_t timeoutcnt = EMSUART_TX_TIMEOUT; // wait until BRK detected... - while (!(USIR(EMSUART_UART) & (1 << UIBD))) { - // delayMicroseconds(EMSUART_TX_BIT_TIME); + while (!(USIR(EMSUART_UART) & (1 << UIBD)) && (--timeoutcnt > 0)) { + delayMicroseconds(EMSUART_TX_BUSY_WAIT); } USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear diff --git a/src/uart/emsuart_esp8266.h b/src/uart/emsuart_esp8266.h index e3ba11e30..48de6bdb7 100644 --- a/src/uart/emsuart_esp8266.h +++ b/src/uart/emsuart_esp8266.h @@ -46,6 +46,7 @@ // EMS 1.0 #define EMSUART_TX_BUSY_WAIT (EMSUART_TX_BIT_TIME / 8) // 13 +#define EMSUART_TX_TIMEOUT (22 * EMSUART_TX_BIT_TIME / EMSUART_TX_BUSY_WAIT) // 176 // HT3/Junkers - Time to send one Byte (8 Bits, 1 Start Bit, 1 Stop Bit) plus 7 bit delay. The -8 is for lag compensation. #define EMSUART_TX_WAIT_HT3 (EMSUART_TX_BIT_TIME * 17) - 8 // 1760