mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
fixing tx_mode 2
° stabilize emsuart_rx... We can get more than 32 bytes because of the trailing BRK. So the buffersize for Rx interrupt is (for safety) increased to 36 bytes. If length exceeds 36 bytes we dump them to /dev/null ° reintroduced the phantomBreak flag again We _must_ signal to Rx that we have a double break, otherwise we get problems in emsuart_recvTask... ° add ems_dumpBuffer which shows TxBuffer before send and RxBuffer after receive and applying phantomBreak. The dump is activated in "log j" mode and used to debug the protocol problems. ° change handling of ID bit 7 on system start we listen for telegram until we receive a valid one, larger than 5 byte. Depending on the bit7 of the source address we decide if we have a Buderus EMS or a Junkers EMS bus. This decision is used to set the variables emsIDMask (0x00 for Buderus, 0x80 for Junkers) and the emsPollAck buffer, used to send the propper acknowledge, depending on EMS type. ° move poll acknowledge function (emsuart_tx_poll) from emsuart.cpp to ems.cpp and rename to ems_pollAck ° add EMS_TX_REV_DETECT status for detecting the SourceID.7 bit and setting emsIDMask and emsPollAck buffer accordingly ° set initial emsTxStatus to EMS_TX_REV_DETECT ° add 'log j' - jabber - for more extensive debug logs
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
137
src/ems.cpp
137
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_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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
10
src/ems.h
10
src/ems.h
@@ -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);
|
||||
|
||||
@@ -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 <BRK>
|
||||
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 <BRK>
|
||||
*/
|
||||
* *** 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};
|
||||
}
|
||||
*/
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user