From 01ce088791a5dc9a4fef3d88fb0aaa1786e8f314 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 21 Jul 2020 14:02:35 +0200 Subject: [PATCH] update uart --- src/uart/emsuart_esp32.cpp | 129 ++++++++++++++++----------------- src/uart/emsuart_esp32.h | 1 + src/uart/emsuart_esp8266.cpp | 134 ++++++++++------------------------- 3 files changed, 103 insertions(+), 161 deletions(-) diff --git a/src/uart/emsuart_esp32.cpp b/src/uart/emsuart_esp32.cpp index 660728929..b827d2328 100644 --- a/src/uart/emsuart_esp32.cpp +++ b/src/uart/emsuart_esp32.cpp @@ -28,8 +28,8 @@ namespace emsesp { -static intr_handle_t uart_handle; static RingbufHandle_t buf_handle = NULL; +portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; static hw_timer_t * timer = NULL; bool drop_next_rx = true; uint8_t tx_mode_ = 0xFF; @@ -46,7 +46,6 @@ void EMSuart::emsuart_recvTask(void * para) { size_t item_size; uint8_t * telegram = (uint8_t *)xRingbufferReceive(buf_handle, &item_size, portMAX_DELAY); uint8_t telegramSize = item_size; - if (telegram) { EMSESP::incoming_telegram(telegram, telegramSize); vRingbufferReturnItem(buf_handle, (void *)telegram); @@ -60,15 +59,10 @@ void EMSuart::emsuart_recvTask(void * para) { void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { static uint8_t rxbuf[EMS_MAXBUFFERSIZE]; static uint8_t length; - + portENTER_CRITICAL(&mux); if (EMS_UART.int_st.brk_det) { EMS_UART.int_clr.brk_det = 1; // clear flag - EMS_UART.conf0.txd_brk = 0; // disable - if (emsTxBufIdx < emsTxBufLen) { // timer tx_mode is interrupted by - emsTxBufIdx = emsTxBufLen; // stop timer mode - drop_next_rx = true; // we have trash in buffer - } - length = 0; + length = 0; while (EMS_UART.status.rxfifo_cnt) { uint8_t rx = EMS_UART.fifo.rw_byte; // read all bytes from fifo if (length < EMS_MAXBUFFERSIZE) { @@ -83,6 +77,7 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { } drop_next_rx = false; } + portEXIT_CRITICAL(&mux); } @@ -90,22 +85,19 @@ void IRAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() { if (emsTxBufLen == 0) { return; } - if (tx_mode_ > 50) { - for (uint8_t i = 0; i < emsTxBufLen; i++) { - EMS_UART.fifo.rw_byte = emsTxBuf[i]; - } - EMS_UART.conf0.txd_brk = 1; // after send - } else { - if (emsTxBufIdx + 1 < emsTxBufLen) { - EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx]; - timerAlarmWrite(timer, emsTxWait, false); - timerAlarmEnable(timer); - } else if (emsTxBufIdx + 1 == emsTxBufLen) { - EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx]; - EMS_UART.conf0.txd_brk = 1; // after send - } - emsTxBufIdx++; + portENTER_CRITICAL(&mux); + if (emsTxBufIdx < emsTxBufLen) { + EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx]; + } else if (emsTxBufIdx == emsTxBufLen) { + EMS_UART.conf0.txd_inv = 1; + timerAlarmWrite(timer, EMSUART_TX_WAIT_BRK, true); + } else if (emsTxBufIdx == emsTxBufLen + 1) { + // delayMicroseconds(EMSUART_TX_WAIT_BRK); + EMS_UART.conf0.txd_inv = 0; + timerAlarmDisable(timer); } + emsTxBufIdx++; + portEXIT_CRITICAL(&mux); } /* @@ -134,7 +126,7 @@ void EMSuart::start(const uint8_t tx_mode) { EMS_UART.idle_conf.rx_idle_thrhd = 256; drop_next_rx = true; buf_handle = xRingbufferCreate(128, RINGBUF_TYPE_NOSPLIT); - 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, NULL); xTaskCreate(emsuart_recvTask, "emsuart_recvTask", 2048, NULL, configMAX_PRIORITIES - 1, NULL); timer = timerBegin(1, 80, true); // timer prescale to 1 µs, countup @@ -154,39 +146,59 @@ void EMSuart::stop() { * Restart Interrupt */ void EMSuart::restart() { - if (EMS_UART.int_raw.brk_det) { + if (EMS_UART.int_raw.brk_det) { // we received a break in the meantime EMS_UART.int_clr.brk_det = 1; // clear flag drop_next_rx = true; // and drop first frame } EMS_UART.int_ena.brk_det = 1; // activate only break emsTxBufIdx = 0; emsTxBufLen = 0; - if (tx_mode_ == 1) { - EMS_UART.idle_conf.tx_idle_num = 5; - } else if (tx_mode_ == 2) { - EMS_UART.idle_conf.tx_idle_num = 10; - } else if (tx_mode_ == 3) { - EMS_UART.idle_conf.tx_idle_num = 7; - } else if (tx_mode_ == 4) { - EMS_UART.idle_conf.tx_idle_num = 2; - } else if (tx_mode_ == 5) { - EMS_UART.idle_conf.tx_idle_num = 2; - } else if (tx_mode_ <= 50) { - EMS_UART.idle_conf.tx_idle_num = tx_mode_; - emsTxWait = EMSUART_TX_BIT_TIME * (tx_mode_ + 10); + emsTxWait = EMSUART_TX_BIT_TIME * (tx_mode_ + 10); + if(tx_mode_ == EMS_TXMODE_NEW) { + EMS_UART.conf0.txd_brk = 1; } else { - EMS_UART.idle_conf.tx_idle_num = 2; - emsTxWait = EMSUART_TX_BIT_TIME * (tx_mode_ - 50); + EMS_UART.conf0.txd_brk = 0; } } +/* + * Sends a 11-bit break by inverting the tx-port + */ +void EMSuart::tx_brk() { + EMS_UART.conf0.txd_inv = 1; + delayMicroseconds(EMSUART_TX_WAIT_BRK); + EMS_UART.conf0.txd_inv = 0; +} + /* * Sends a 1-byte poll, ending with a */ void EMSuart::send_poll(const uint8_t data) { - EMS_UART.fifo.rw_byte = data; - EMS_UART.conf0.txd_brk = 1; // after send - return; + if (tx_mode_ > 5) { // timer controlled modes + emsTxBuf[0] = data; + emsTxBufIdx = 0; + emsTxBufLen = 1; + timerAlarmWrite(timer, emsTxWait, true); // start timer with autoreload + timerAlarmEnable(timer); // first interrupt comes immediately + } else if (tx_mode_ == EMS_TXMODE_DEFAULT) { + volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt; + uint16_t timeoutcnt = EMSUART_TX_TIMEOUT; + EMS_UART.fifo.rw_byte = data; + while ((EMS_UART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) { + delayMicroseconds(EMSUART_TX_BUSY_WAIT); + } + tx_brk(); + } else if (tx_mode_ == EMS_TXMODE_EMSPLUS) { + EMS_UART.fifo.rw_byte = data; + delayMicroseconds(EMSUART_TX_WAIT_PLUS); + tx_brk(); + } else if (tx_mode_ == EMS_TXMODE_HT3) { + EMS_UART.fifo.rw_byte = data; + delayMicroseconds(EMSUART_TX_WAIT_HT3); + tx_brk(); + } else { + EMS_UART.fifo.rw_byte = data; + } } /* @@ -198,8 +210,6 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { if (len == 0 || len >= EMS_MAXBUFFERSIZE) { return EMS_TX_STATUS_ERR; } - // needs to be disabled for the delayed modes otherwise the uart makes a after every byte - EMS_UART.conf0.txd_brk = 0; if (tx_mode_ > 5) { // timer controlled modes for (uint8_t i = 0; i < len; i++) { @@ -207,45 +217,33 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { } emsTxBufIdx = 0; emsTxBufLen = len; - timerAlarmWrite(timer, emsTxWait, false); + timerAlarmWrite(timer, emsTxWait, true); // start with autoreload timerAlarmEnable(timer); return EMS_TX_STATUS_OK; } - if (tx_mode_ == 5) { // wait before sending - //vTaskDelay(4 / portTICK_PERIOD_MS); - delayMicroseconds(4000); - 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_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 - 1; i++) { + for (uint8_t i = 0; i < len; i++) { EMS_UART.fifo.rw_byte = buf[i]; delayMicroseconds(EMSUART_TX_WAIT_PLUS); } - EMS_UART.fifo.rw_byte = buf[len - 1]; - EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send + tx_brk(); return EMS_TX_STATUS_OK; } if (tx_mode_ == EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay - for (uint8_t i = 0; i < len - 1; i++) { + for (uint8_t i = 0; i < len; i++) { EMS_UART.fifo.rw_byte = buf[i]; delayMicroseconds(EMSUART_TX_WAIT_HT3); } - EMS_UART.fifo.rw_byte = buf[len - 1]; - EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send + tx_brk(); return EMS_TX_STATUS_OK; } @@ -253,7 +251,7 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { // 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 - 1; i++) { + 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 uint16_t timeoutcnt = EMSUART_TX_TIMEOUT; @@ -261,8 +259,7 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) { delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles... } } - EMS_UART.fifo.rw_byte = buf[len - 1]; // send each Tx byte - EMS_UART.conf0.txd_brk = 1; // after send, cleard by hardware after send + tx_brk(); return EMS_TX_STATUS_OK; } diff --git a/src/uart/emsuart_esp32.h b/src/uart/emsuart_esp32.h index 086a20224..043a0ae4c 100644 --- a/src/uart/emsuart_esp32.h +++ b/src/uart/emsuart_esp32.h @@ -90,6 +90,7 @@ class EMSuart { static void emsuart_recvTask(void * para); static void IRAM_ATTR emsuart_rx_intr_handler(void * para); static void IRAM_ATTR emsuart_tx_timer_intr_handler(); + static void tx_brk(); }; } // namespace emsesp diff --git a/src/uart/emsuart_esp8266.cpp b/src/uart/emsuart_esp8266.cpp index 4ea40fe7a..dfc0f758f 100644 --- a/src/uart/emsuart_esp8266.cpp +++ b/src/uart/emsuart_esp8266.cpp @@ -47,11 +47,10 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk if (emsTxBufIdx < emsTxBufLen) { // irq tx_mode is interrupted by - emsTxBufIdx = emsTxBufLen; // stop tx - drop_next_rx = true; // we have trash in buffer + emsTxBufIdx = emsTxBufLen + 1; // stop tx + // drop_next_rx = true; // we have trash in buffer } USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt - USIE(EMSUART_UART) &= ~(1 << UIFF); // disable fifo-full irq length = 0; while ((USS(EMSUART_UART) >> USRXC) & 0x0FF) { // read fifo into buffer uint8_t rx = USF(EMSUART_UART); @@ -88,6 +87,21 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_recvTask(os_event_t * events) { } } +// ISR to Fire when Timer is triggered +void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() { + emsTxBufIdx++; + if (emsTxBufIdx < emsTxBufLen) { + USF(EMSUART_UART) = emsTxBuf[emsTxBufIdx]; + timer1_write(emsTxWait); + } else if (emsTxBufIdx == emsTxBufLen) { + USC0(EMSUART_UART) |= (1 << UCBRK); // set + timer1_write(EMSUART_TX_WAIT_BRK * 5); + } else { + USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset + sending_ = false; + } +} + /* * flush everything left over in buffer, this clears both rx and tx FIFOs */ @@ -96,36 +110,11 @@ void ICACHE_FLASH_ATTR EMSuart::emsuart_flush_fifos() { USC0(EMSUART_UART) &= ~((1 << UCRXRST) | (1 << UCTXRST)); // clear bits } -// ISR to Fire when Timer is triggered -void ICACHE_RAM_ATTR EMSuart::emsuart_tx_timer_intr_handler() { - if (tx_mode_ > 50) { - for (uint8_t i = 0; i < emsTxBufLen; i++) { - USF(EMSUART_UART) = emsTxBuf[i]; - } - USC0(EMSUART_UART) |= (1 << UCBRK); // set - } else { - if (emsTxBufIdx > emsTxBufLen) { - return; - } - if (emsTxBufIdx < emsTxBufLen) { - USF(EMSUART_UART) = emsTxBuf[emsTxBufIdx]; - timer1_write(emsTxWait); - } else if (emsTxBufIdx == emsTxBufLen) { - USC0(EMSUART_UART) |= (1 << UCBRK); // set - } - emsTxBufIdx++; - } -} - /* * init UART0 driver */ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) { - if (tx_mode > 50) { - emsTxWait = 5 * EMSUART_TX_BIT_TIME * (tx_mode - 50); // bittimes wait before sending - } else if (tx_mode > 5) { - emsTxWait = 5 * EMSUART_TX_BIT_TIME * (tx_mode + 10); // bittimes wait between bytes - } + emsTxWait = 5 * EMSUART_TX_BIT_TIME * (tx_mode + 10); // bittimes wait between bytes if (tx_mode_ != 0xFF) { // it's a restart no need to configure uart tx_mode_ = tx_mode; restart(); @@ -151,11 +140,7 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) { // set 9600, 8 bits, no parity check, 1 stop bit USD(EMSUART_UART) = (UART_CLK_FREQ / EMSUART_BAUD); - if (tx_mode_ == 5) { - USC0(EMSUART_UART) = 0x2C; // 8N1.5 - } else { - USC0(EMSUART_UART) = EMSUART_CONFIG; // 8N1 - } + USC0(EMSUART_UART) = EMSUART_CONFIG; // 8N1 emsuart_flush_fifos(); // conf1 params @@ -190,12 +175,13 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) { system_uart_swap(); ETS_UART_INTR_ATTACH(emsuart_rx_intr_handler, nullptr); - ETS_UART_INTR_ENABLE(); + // ETS_UART_INTR_ENABLE(); drop_next_rx = true; // for sending with large delay in EMS+ mode we use a timer interrupt timer1_attachInterrupt(emsuart_tx_timer_intr_handler); // Add ISR Function timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); // 5 MHz timer + USIE(EMSUART_UART) = (1 << UIBD); } /* @@ -203,8 +189,8 @@ void ICACHE_FLASH_ATTR EMSuart::start(uint8_t tx_mode) { * This is called prior to an OTA upload and also before a save to the filesystem to prevent conflicts */ void ICACHE_FLASH_ATTR EMSuart::stop() { - ETS_UART_INTR_DISABLE(); - timer1_disable(); + USIE(EMSUART_UART) = 0; + // timer1_disable(); } /* @@ -215,10 +201,10 @@ void ICACHE_FLASH_ATTR EMSuart::restart() { USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt drop_next_rx = true; } - ETS_UART_INTR_ENABLE(); emsTxBufIdx = 0; emsTxBufLen = 0; - timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); + // timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE); + USIE(EMSUART_UART) = (1 << UIBD); } /* @@ -229,17 +215,10 @@ void ICACHE_FLASH_ATTR EMSuart::tx_brk() { // 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 - ETS_UART_INTR_DISABLE(); USC0(EMSUART_UART) |= (1 << UCBRK); // set bit - // also for EMS+ there is no need to wait longer, we are finished and can free the bus. delayMicroseconds(EMSUART_TX_WAIT_BRK); // 1144 - USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear BRK bit - ETS_UART_INTR_ENABLE(); } /* @@ -251,19 +230,11 @@ void EMSuart::send_poll(uint8_t data) { USC0(EMSUART_UART) &= ~(1 << UCBRK); sending_ = true; - if (tx_mode_ > 50) { // timer controlled modes - emsTxBuf[0] = data; - emsTxBufLen = 1; - timer1_write(emsTxWait); - } else if (tx_mode_ > 5) { // timer controlled modes + if (tx_mode_ >= 5) { // timer controlled modes emsTxBuf[0] = data; emsTxBufIdx = 0; emsTxBufLen = 1; timer1_write(emsTxWait); - } else if (tx_mode_ == 5) { - delayMicroseconds(3000); - USF(EMSUART_UART) = data; - USC0(EMSUART_UART) |= (1 << UCBRK); } else if (tx_mode_ == EMS_TXMODE_NEW) { // hardware controlled modes USF(EMSUART_UART) = data; USC0(EMSUART_UART) |= (1 << UCBRK); @@ -271,27 +242,22 @@ void EMSuart::send_poll(uint8_t data) { USF(EMSUART_UART) = data; delayMicroseconds(EMSUART_TX_WAIT_HT3); tx_brk(); // send + sending_ = false; } else if (tx_mode_ == EMS_TXMODE_EMSPLUS) { USF(EMSUART_UART) = data; delayMicroseconds(EMSUART_TX_WAIT_PLUS); tx_brk(); // send + sending_ = false; } else { // tx_mode 1 - // EMS1.0, same logic as in transmit - ETS_UART_INTR_DISABLE(); volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF; USF(EMSUART_UART) = data; uint16_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 - 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(); + tx_brk(); // send + sending_ = false; } } @@ -308,34 +274,17 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { USC0(EMSUART_UART) &= ~(1 << UCBRK); sending_ = true; - // all at once after a initial timer delay - if (tx_mode_ > 50) { - for (uint8_t i = 0; i < len; i++) { - emsTxBuf[i] = buf[i]; - } - emsTxBufLen = len; - timer1_write(emsTxWait); - return EMS_TX_STATUS_OK; - } // timer controlled modes with extra delay - if (tx_mode_ > 5) { + if (tx_mode_ >= 5) { for (uint8_t i = 0; i < len; i++) { emsTxBuf[i] = buf[i]; } + USF(EMSUART_UART) = buf[0]; // send first byte emsTxBufIdx = 0; emsTxBufLen = len; timer1_write(emsTxWait); return EMS_TX_STATUS_OK; } - // fixed delay before sending - if (tx_mode_ == 5) { - delayMicroseconds(3000); - for (uint8_t i = 0; i < len; i++) { - USF(EMSUART_UART) = buf[i]; - } - USC0(EMSUART_UART) |= (1 << UCBRK); // send at the end - return EMS_TX_STATUS_OK; - } // new code from Michael. See https://github.com/proddy/EMS-ESP/issues/380 if (tx_mode_ == EMS_TXMODE_NEW) { // tx_mode 4 @@ -353,6 +302,7 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { delayMicroseconds(EMSUART_TX_WAIT_PLUS); // 2070 } tx_brk(); // send + sending_ = false; return EMS_TX_STATUS_OK; } @@ -367,6 +317,7 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { delayMicroseconds(EMSUART_TX_WAIT_HT3); } tx_brk(); // send + sending_ = false; return EMS_TX_STATUS_OK; } @@ -397,7 +348,7 @@ 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 - ETS_UART_INTR_DISABLE(); + // ETS_UART_INTR_DISABLE(); emsuart_flush_fifos(); // send the bytes along the serial line @@ -413,22 +364,15 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) { // we got the whole telegram in the Rx buffer // on Rx-BRK (bus collision), we simply enable Rx and leave it - // otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT. + // otherwise we send the final Tx-BRK // worst case, we'll see an additional Rx-BRK... // 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 << UCBRK); // set - uint16_t timeoutcnt = EMSUART_TX_TIMEOUT; - // wait until BRK detected... - while (!(USIR(EMSUART_UART) & (1 << UIBD)) && (--timeoutcnt > 0)) { - delayMicroseconds(EMSUART_TX_BUSY_WAIT); - } - - USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear + tx_brk(); } - - ETS_UART_INTR_ENABLE(); // open up the FIFO again to start receiving + // ETS_UART_INTR_ENABLE(); // open up the FIFO again to start receiving + sending_ = false; return EMS_TX_STATUS_OK; // send the Tx ok status back }