Merge pull request #402 from MichaelDvP/v2

Uart mode 5
This commit is contained in:
Proddy
2020-06-19 20:29:38 +02:00
committed by GitHub
6 changed files with 76 additions and 12 deletions

View File

@@ -577,7 +577,6 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) {
if (((first_value & 0x7F) == txservice_.ems_bus_id()) && (length > 1)) {
// if we ask ourself at roomcontrol for version e.g. 0B 98 02 00 20
Roomctrl::check((data[1] ^ 0x80 ^ rxservice_.ems_mask()), data);
#ifdef EMSESP_DEBUG
// get_uptime is only updated once per loop, does not give the right time
LOG_DEBUG(F("[DEBUG] Echo after %d ms: %s"), ::millis() - tx_time_, Helpers::data_to_hex(data, length).c_str());

View File

@@ -359,11 +359,11 @@ bool Helpers::hasValue(const int8_t v) {
}
bool Helpers::hasValue(const int16_t v) {
return (v != EMS_VALUE_SHORT_NOTSET);
return (v != EMS_VALUE_SHORT_NOTSET && v != EMS_VALUE_USHORT_NOTSET && v != EMS_VALUE_SHORT_INVALID && v != EMS_VALUE_USHORT_INVALID);
}
bool Helpers::hasValue(const uint16_t v) {
return (v != EMS_VALUE_USHORT_NOTSET);
return (v != EMS_VALUE_SHORT_NOTSET && v != EMS_VALUE_USHORT_NOTSET && v != EMS_VALUE_SHORT_INVALID && v != EMS_VALUE_USHORT_INVALID);
}
bool Helpers::hasValue(const uint32_t v) {

View File

@@ -270,7 +270,10 @@ void RxService::add(uint8_t * data, uint8_t length) {
uint8_t message_length; // length of the message block, excluding CRC
// work out depending on the type, where the data message block starts and the message length
if (data[2] < 0xF0) {
// EMS 1 has type_id always in data[2], if it gets a ems+ inquiery it will reply with FF but short length
// i.e. sending 0B A1 FF 00 01 D8 20 CRC to a MM10 Mixer (ems1.0), the reply is 21 0B FF 00 CRC
// see: https://github.com/proddy/EMS-ESP/issues/380#issuecomment-633663007
if (data[2] < 0xF0 || length < 6) {
// EMS 1.0
type_id = data[2];
message_data = data + 4;

View File

@@ -61,13 +61,25 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
static uint8_t rxbuf[EMS_MAXBUFFERSIZE];
static uint8_t length;
if (EMS_UART.int_st.rxfifo_full) {
EMS_UART.int_clr.rxfifo_full = 1;
emsTxBufIdx++;
if (emsTxBufIdx < emsTxBufLen) {
EMS_UART.conf1.rxfifo_full_thrhd = emsTxBufIdx + 1;
EMS_UART.fifo.rw_byte = emsTxBuf[emsTxBufIdx];
} else if (emsTxBufIdx == emsTxBufLen) {
EMS_UART.conf0.txd_brk = 1; // <brk> after send
EMS_UART.int_ena.rxfifo_full = 0;
EMS_UART.conf1.rxfifo_full_thrhd = 0x7F;
}
}
if (EMS_UART.int_st.brk_det) {
EMS_UART.int_clr.brk_det = 1; // clear flag
if (emsTxBufIdx < emsTxBufLen) { // timer tx_mode is interrupted by <brk>
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) {
@@ -172,6 +184,12 @@ void EMSuart::send_poll(uint8_t data) {
emsTxBufLen = 1;
timerAlarmWrite(timer, emsTxWait, false);
timerAlarmEnable(timer);
} else if (tx_mode_ == 5) {
EMS_UART.fifo.rw_byte = data;
emsTxBufIdx = 0;
emsTxBufLen = 1;
EMS_UART.conf1.rxfifo_full_thrhd = 1;
EMS_UART.int_ena.rxfifo_full = 1;
} else if (tx_mode_ == EMS_TXMODE_NEW) {
EMS_UART.fifo.rw_byte = data;
EMS_UART.conf0.txd_brk = 1; // <brk> after send
@@ -190,7 +208,7 @@ void EMSuart::send_poll(uint8_t data) {
} else {
volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt;
EMS_UART.fifo.rw_byte = data;
uint8_t timeoutcnt = EMSUART_TX_TIMEOUT;
uint16_t timeoutcnt = EMSUART_TX_TIMEOUT;
while ((EMS_UART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) {
delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles...
}
@@ -219,6 +237,17 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
timerAlarmEnable(timer);
return EMS_TX_STATUS_OK;
}
if (tx_mode_ == 5) {
for (uint8_t i = 0; i < len; i++) {
emsTxBuf[i] = buf[i];
}
EMS_UART.fifo.rw_byte = buf[0];
emsTxBufIdx = 0;
emsTxBufLen = len;
EMS_UART.conf1.rxfifo_full_thrhd = 1;
EMS_UART.int_ena.rxfifo_full = 1;
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];
@@ -253,7 +282,7 @@ uint16_t EMSuart::transmit(uint8_t * buf, uint8_t len) {
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
uint8_t timeoutcnt = EMSUART_TX_TIMEOUT;
uint16_t timeoutcnt = EMSUART_TX_TIMEOUT;
while ((EMS_UART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) {
delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles...
}

View File

@@ -50,7 +50,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
#define EMSUART_TX_TIMEOUT (32 * EMSUART_TX_BIT_TIME / EMSUART_TX_BUSY_WAIT) // 256
// 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.
// since we use a faster processor the lag is negligible

View File

@@ -43,13 +43,26 @@ void ICACHE_RAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
static uint8_t length = 0;
static uint8_t uart_buffer[EMS_MAXBUFFERSIZE + 2];
if (USIS(EMSUART_UART) & ((1 << UIFF))) { // Fifo full, sending in Mode 5
USIC(EMSUART_UART) |= (1 << UIFF); // clear fifo interrupt
emsTxBufIdx++;
if (emsTxBufIdx < emsTxBufLen) {
USF(EMSUART_UART) = emsTxBuf[emsTxBufIdx]; // send next byte
USC1(EMSUART_UART) = ((emsTxBufIdx + 1) << UCFFT); // increase fifo full
} else if (emsTxBufIdx == emsTxBufLen) {
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
USIE(EMSUART_UART) &= ~(1 << UIFF); // disable fifo-full irq
USC1(EMSUART_UART) = (0x7F << UCFFT); // fifo full to max
}
}
if (USIS(EMSUART_UART) & ((1 << UIBD))) { // BREAK detection = End of EMS data block
USC0(EMSUART_UART) &= ~(1 << UCBRK); // reset tx-brk
if (emsTxBufIdx < emsTxBufLen) { // timer tx_mode is interrupted by <brk>
emsTxBufIdx = emsTxBufLen; // stop timer mode
drop_next_rx = true; // we have trash in buffer
}
USIC(EMSUART_UART) = (1 << UIBD); // INT clear the BREAK detect interrupt
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);
@@ -62,9 +75,9 @@ 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
system_os_post(EMSUART_recvTaskPrio, 0, 0); // call emsuart_recvTask() at next opportunity
}
drop_next_rx = false;
system_os_post(EMSUART_recvTaskPrio, 0, 0); // call emsuart_recvTask() at next opportunity
}
}
@@ -235,11 +248,18 @@ void EMSuart::send_poll(uint8_t data) {
// reset tx-brk, just in case it is accidentally set
USC0(EMSUART_UART) &= ~(1 << UCBRK);
if (tx_mode_ >= 5) { // timer controlled modes
if (tx_mode_ > 5) { // timer controlled modes
USF(EMSUART_UART) = data;
emsTxBufIdx = 0;
emsTxBufLen = 1;
timer1_write(emsTxWait);
} else if (tx_mode_ == 5) { // reload sendbuffer in irq
USIC(EMSUART_UART) |= (1 << UIFF); // clear fifo-full irq
USC1(EMSUART_UART) = (0x01 << UCFFT); // fifo full to 1
USF(EMSUART_UART) = data;
emsTxBufIdx = 0;
emsTxBufLen = 1;
USIE(EMSUART_UART) |= (1 << UIFF); // enable fifo-full irq
} else if (tx_mode_ == EMS_TXMODE_NEW) { // hardware controlled modes
USF(EMSUART_UART) = data;
USC0(EMSUART_UART) |= (1 << UCBRK); // brk after sendout
@@ -285,7 +305,7 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
USC0(EMSUART_UART) &= ~(1 << UCBRK);
// 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];
}
@@ -295,6 +315,19 @@ uint16_t ICACHE_FLASH_ATTR EMSuart::transmit(uint8_t * buf, uint8_t len) {
timer1_write(emsTxWait);
return EMS_TX_STATUS_OK;
}
// interrupt controlled mode: readback in rx-irq and send next byte
if (tx_mode_ == 5) {
for (uint8_t i = 0; i < len; i++) {
emsTxBuf[i] = buf[i];
}
USIC(EMSUART_UART) |= (1 << UIFF); // clear fifo-full irq
emsTxBufIdx = 0;
emsTxBufLen = len;
USF(EMSUART_UART) = buf[0];
USC1(EMSUART_UART) = (0x01 << UCFFT); // fifo full to 1
USIE(EMSUART_UART) |= (1 << UIFF); // enable fifo-full irq
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