mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
add tx_mode back
This commit is contained in:
@@ -128,13 +128,26 @@
|
|||||||
data-content="Select the main heating circuit to use. Default is HC1."></i></label>
|
data-content="Select the main heating circuit to use. Default is HC1."></i></label>
|
||||||
<span class="col-xs-9 col-md-5">
|
<span class="col-xs-9 col-md-5">
|
||||||
<select class="form-control input-sm" id="heating_circuit">
|
<select class="form-control input-sm" id="heating_circuit">
|
||||||
<option selected="selected" value="1">HC1 (default)</option>
|
<option selected="selected" value="1">HC1</option>
|
||||||
<option value="2">HC2</option>
|
<option value="2">HC2</option>
|
||||||
<option value="3">HC3</option>
|
<option value="3">HC3</option>
|
||||||
</select>
|
</select>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row form-group">
|
||||||
|
<label class="col-xs-3">TX mode<i style="margin-left: 10px;" class="glyphicon glyphicon-info-sign"
|
||||||
|
aria-hidden="true" data-toggle="popover" data-trigger="hover" data-placement="right"
|
||||||
|
data-content="Tx mode settings for various EMS brands"></i></label>
|
||||||
|
<span class="col-xs-9 col-md-5">
|
||||||
|
<select class="form-control input-sm" id="tx_mode">
|
||||||
|
<option selected="selected" value="1">1 (EMS generic)</option>
|
||||||
|
<option value="2">2 (EMS+/EMS2.0)</option>
|
||||||
|
<option value="3">3 (Junkers HT3)</option>
|
||||||
|
</select>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<div class="row form-group">
|
<div class="row form-group">
|
||||||
<div class="col-xs-9 col-md-8">
|
<div class="col-xs-9 col-md-8">
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ function listcustom() {
|
|||||||
document.getElementById("dallas_gpio").value = custom_config.settings.dallas_gpio;
|
document.getElementById("dallas_gpio").value = custom_config.settings.dallas_gpio;
|
||||||
document.getElementById("publish_time").value = custom_config.settings.publish_time;
|
document.getElementById("publish_time").value = custom_config.settings.publish_time;
|
||||||
document.getElementById("heating_circuit").value = custom_config.settings.heating_circuit;
|
document.getElementById("heating_circuit").value = custom_config.settings.heating_circuit;
|
||||||
|
document.getElementById("tx_mode").value = custom_config.settings.tx_mode;
|
||||||
|
|
||||||
if (custom_config.settings.led) {
|
if (custom_config.settings.led) {
|
||||||
$("input[name=\"led\"][value=\"1\"]").prop("checked", true);
|
$("input[name=\"led\"][value=\"1\"]").prop("checked", true);
|
||||||
@@ -72,6 +73,7 @@ function savecustom() {
|
|||||||
|
|
||||||
custom_config.settings.publish_time = parseInt(document.getElementById("publish_time").value);
|
custom_config.settings.publish_time = parseInt(document.getElementById("publish_time").value);
|
||||||
custom_config.settings.heating_circuit = parseInt(document.getElementById("heating_circuit").value);
|
custom_config.settings.heating_circuit = parseInt(document.getElementById("heating_circuit").value);
|
||||||
|
custom_config.settings.tx_mode = parseInt(document.getElementById("tx_mode").value);
|
||||||
|
|
||||||
custom_uncommited();
|
custom_uncommited();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// local libraries
|
// local libraries
|
||||||
|
#include "MyESP.h"
|
||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
#include "ems_devices.h"
|
#include "ems_devices.h"
|
||||||
#include "emsuart.h"
|
#include "emsuart.h"
|
||||||
#include "my_config.h"
|
#include "my_config.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "MyESP.h"
|
|
||||||
|
|
||||||
// Dallas external temp sensors
|
// Dallas external temp sensors
|
||||||
#include "ds18.h"
|
#include "ds18.h"
|
||||||
@@ -88,6 +88,7 @@ typedef struct {
|
|||||||
uint8_t dallas_gpio; // pin for attaching external dallas temperature sensors
|
uint8_t dallas_gpio; // pin for attaching external dallas temperature sensors
|
||||||
bool dallas_parasite; // on/off is using parasite
|
bool dallas_parasite; // on/off is using parasite
|
||||||
uint8_t heating_circuit; // number of heating circuit, 1 or 2
|
uint8_t heating_circuit; // number of heating circuit, 1 or 2
|
||||||
|
uint8_t tx_mode; // TX mode 1,2 or 3
|
||||||
} _EMSESP_Status;
|
} _EMSESP_Status;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -109,6 +110,7 @@ static const command_t project_cmds[] PROGMEM = {
|
|||||||
{true, "shower_alert <on | off>", "stop hot water to send 3 cold burst warnings after max shower time is exceeded"},
|
{true, "shower_alert <on | off>", "stop hot water to send 3 cold burst warnings after max shower time is exceeded"},
|
||||||
{true, "publish_time <seconds>", "set frequency for publishing data to MQTT (0=off)"},
|
{true, "publish_time <seconds>", "set frequency for publishing data to MQTT (0=off)"},
|
||||||
{true, "heating_circuit <1 | 2>", "set the main thermostat HC to work with (if using multiple heating circuits)"},
|
{true, "heating_circuit <1 | 2>", "set the main thermostat HC to work with (if using multiple heating circuits)"},
|
||||||
|
{true, "tx_mode <n>", "changes Tx logic. 1=ems generic, 2=ems+, 3=Junkers HT3"},
|
||||||
|
|
||||||
{false, "info", "show current captured on the devices"},
|
{false, "info", "show current captured on the devices"},
|
||||||
{false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
|
{false, "log <n | b | t | r | v>", "set logging mode to none, basic, thermostat only, raw or verbose"},
|
||||||
@@ -1166,6 +1168,9 @@ bool LoadSaveCallback(MYESP_FSACTION action, JsonObject json) {
|
|||||||
EMSESP_Status.heating_circuit = settings["heating_circuit"] | DEFAULT_HEATINGCIRCUIT;
|
EMSESP_Status.heating_circuit = settings["heating_circuit"] | DEFAULT_HEATINGCIRCUIT;
|
||||||
ems_setThermostatHC(EMSESP_Status.heating_circuit);
|
ems_setThermostatHC(EMSESP_Status.heating_circuit);
|
||||||
|
|
||||||
|
EMSESP_Status.tx_mode = settings["tx_mode"] | 1; // default to 1 (generic)
|
||||||
|
ems_setTxMode(EMSESP_Status.tx_mode);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1181,6 +1186,7 @@ bool LoadSaveCallback(MYESP_FSACTION action, JsonObject json) {
|
|||||||
settings["shower_alert"] = EMSESP_Status.shower_alert;
|
settings["shower_alert"] = EMSESP_Status.shower_alert;
|
||||||
settings["publish_time"] = EMSESP_Status.publish_time;
|
settings["publish_time"] = EMSESP_Status.publish_time;
|
||||||
settings["heating_circuit"] = EMSESP_Status.heating_circuit;
|
settings["heating_circuit"] = EMSESP_Status.heating_circuit;
|
||||||
|
settings["tx_mode"] = EMSESP_Status.tx_mode;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1298,6 +1304,18 @@ bool SetListCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, co
|
|||||||
myDebug_P(PSTR("Error. Usage: set heating_circuit <1 | 2>"));
|
myDebug_P(PSTR("Error. Usage: set heating_circuit <1 | 2>"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tx_mode
|
||||||
|
if ((strcmp(setting, "tx_mode") == 0) && (wc == 2)) {
|
||||||
|
uint8_t mode = atoi(value);
|
||||||
|
if ((mode >= 1) && (mode <= 3)) {
|
||||||
|
EMSESP_Status.tx_mode = mode;
|
||||||
|
ems_setTxMode(mode);
|
||||||
|
ok = true;
|
||||||
|
} else {
|
||||||
|
myDebug_P(PSTR("Error. Usage: set tx_mode <1 | 2 | 3>"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == MYESP_FSACTION_LIST) {
|
if (action == MYESP_FSACTION_LIST) {
|
||||||
@@ -1306,6 +1324,7 @@ bool SetListCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, co
|
|||||||
myDebug_P(PSTR(" dallas_gpio=%d"), EMSESP_Status.dallas_gpio);
|
myDebug_P(PSTR(" dallas_gpio=%d"), EMSESP_Status.dallas_gpio);
|
||||||
myDebug_P(PSTR(" dallas_parasite=%s"), EMSESP_Status.dallas_parasite ? "on" : "off");
|
myDebug_P(PSTR(" dallas_parasite=%s"), EMSESP_Status.dallas_parasite ? "on" : "off");
|
||||||
myDebug_P(PSTR(" heating_circuit=%d"), EMSESP_Status.heating_circuit);
|
myDebug_P(PSTR(" heating_circuit=%d"), EMSESP_Status.heating_circuit);
|
||||||
|
myDebug_P(PSTR(" tx_mode=%d"), EMSESP_Status.tx_mode);
|
||||||
myDebug_P(PSTR(" listen_mode=%s"), EMSESP_Status.listen_mode ? "on" : "off");
|
myDebug_P(PSTR(" listen_mode=%s"), EMSESP_Status.listen_mode ? "on" : "off");
|
||||||
myDebug_P(PSTR(" shower_timer=%s"), EMSESP_Status.shower_timer ? "on" : "off");
|
myDebug_P(PSTR(" shower_timer=%s"), EMSESP_Status.shower_timer ? "on" : "off");
|
||||||
myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Status.shower_alert ? "on" : "off");
|
myDebug_P(PSTR(" shower_alert=%s"), EMSESP_Status.shower_alert ? "on" : "off");
|
||||||
|
|||||||
52
src/ems.cpp
52
src/ems.cpp
@@ -7,10 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
|
#include "MyESP.h"
|
||||||
#include "ems_devices.h"
|
#include "ems_devices.h"
|
||||||
#include "emsuart.h"
|
#include "emsuart.h"
|
||||||
#include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer
|
#include <CircularBuffer.h> // https://github.com/rlogiacco/CircularBuffer
|
||||||
#include "MyESP.h"
|
|
||||||
|
|
||||||
#ifdef TESTS
|
#ifdef TESTS
|
||||||
#include "test_data.h"
|
#include "test_data.h"
|
||||||
@@ -508,6 +508,11 @@ int _ems_findType(uint16_t type) {
|
|||||||
return (typeFound ? i : -1);
|
return (typeFound ? i : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ems_setTxMode(uint8_t mode) {
|
||||||
|
EMS_Sys_Status.emsTxMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* debug print a telegram to telnet/serial including the CRC
|
* debug print a telegram to telnet/serial including the CRC
|
||||||
*/
|
*/
|
||||||
@@ -1408,33 +1413,34 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
|||||||
* EMS+ messages may come in with different offsets so handle them here
|
* EMS+ messages may come in with different offsets so handle them here
|
||||||
*/
|
*/
|
||||||
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||||
if (EMS_RxTelegram->offset == 0) {
|
// handle single data values
|
||||||
|
if (EMS_RxTelegram->data_length == 1) {
|
||||||
|
switch (EMS_RxTelegram->offset) {
|
||||||
|
case EMS_OFFSET_RCPLUSStatusMessage_curr: // setpoint target temp
|
||||||
|
EMS_Thermostat.curr_roomTemp = _toShort(0); // value is * 10
|
||||||
|
break;
|
||||||
|
case EMS_OFFSET_RCPLUSStatusMessage_setpoint: // current target temp
|
||||||
|
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
|
||||||
|
break;
|
||||||
|
case EMS_OFFSET_RCPLUSStatusMessage_currsetpoint: // current setpoint temp, e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22
|
||||||
|
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
|
||||||
|
break;
|
||||||
|
case EMS_OFFSET_RCPLUSStatusMessage_mode: // thermostat mode auto/manual
|
||||||
|
// manual : 10 00 FF 0A 01 A5 02
|
||||||
|
// auto : Thermostat -> all, type 0x01A5 telegram: 10 00 FF 0A 01 A5 03
|
||||||
|
EMS_Thermostat.mode = _bitRead(0, 0); // bit 1, mode (auto=1 or manual=0)
|
||||||
|
EMS_Thermostat.day_mode = _bitRead(0, 1); // get day mode flag
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (EMS_RxTelegram->data_length > 20) {
|
||||||
// the whole telegram
|
// the whole telegram
|
||||||
// e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
|
// e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
|
||||||
// 10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00
|
// 10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00
|
||||||
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10
|
EMS_Thermostat.curr_roomTemp = _toShort(EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10
|
||||||
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RCPLUSStatusMessage_setpoint); // value is * 2
|
EMS_Thermostat.setpoint_roomTemp = _toByte(EMS_OFFSET_RCPLUSStatusMessage_setpoint); // value is * 2
|
||||||
|
EMS_Thermostat.day_mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 1); // get day mode flag
|
||||||
EMS_Thermostat.day_mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 1); // get day mode flag
|
EMS_Thermostat.mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 0); // bit 1, mode (auto=1 or manual=0)
|
||||||
|
|
||||||
EMS_Thermostat.mode = _bitRead(EMS_OFFSET_RCPLUSStatusMessage_mode, 0); // bit 1, mode (auto=1 or manual=0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// current target temp
|
|
||||||
if (EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSStatusMessage_setpoint) {
|
|
||||||
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// current setpoint temp, e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22
|
|
||||||
if (EMS_RxTelegram->offset == 6) {
|
|
||||||
EMS_Thermostat.setpoint_roomTemp = _toByte(0); // value is * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// thermostat mode auto/manual, examples:
|
|
||||||
// manual : 10 00 FF 0A 01 A5 02 (CRC=16) #data=1
|
|
||||||
// auto : Thermostat -> all, type 0x01A5 telegram: 10 00 FF 0A 01 A5 03 (CRC=17) #data=1
|
|
||||||
if (EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSStatusMessage_mode) {
|
|
||||||
EMS_Thermostat.mode = _bitRead(0, 0); // bit 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
|
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ typedef struct {
|
|||||||
uint8_t txRetryCount; // # times the last Tx was re-sent
|
uint8_t txRetryCount; // # times the last Tx was re-sent
|
||||||
uint8_t emsIDMask; // Buderus: 0x00, Junkers: 0x80
|
uint8_t emsIDMask; // Buderus: 0x00, Junkers: 0x80
|
||||||
uint8_t emsPollAck[1]; // acknowledge buffer for Poll
|
uint8_t emsPollAck[1]; // acknowledge buffer for Poll
|
||||||
|
uint8_t emsTxMode; // Tx mode 1, 2 or 3
|
||||||
} _EMS_Sys_Status;
|
} _EMS_Sys_Status;
|
||||||
|
|
||||||
// The Tx send package
|
// The Tx send package
|
||||||
@@ -425,6 +426,7 @@ void ems_setWarmWaterModeComfort(uint8_t comfort);
|
|||||||
void ems_setModels();
|
void ems_setModels();
|
||||||
void ems_setTxDisabled(bool b);
|
void ems_setTxDisabled(bool b);
|
||||||
bool ems_getTxDisabled();
|
bool ems_getTxDisabled();
|
||||||
|
void ems_setTxMode(uint8_t mode);
|
||||||
|
|
||||||
char * ems_getThermostatDescription(char * buffer, bool name_only = false);
|
char * ems_getThermostatDescription(char * buffer, bool name_only = false);
|
||||||
char * ems_getBoilerDescription(char * buffer, bool name_only = false);
|
char * ems_getBoilerDescription(char * buffer, bool name_only = false);
|
||||||
|
|||||||
147
src/emsuart.cpp
147
src/emsuart.cpp
@@ -170,6 +170,37 @@ void ICACHE_FLASH_ATTR emsuart_start() {
|
|||||||
ETS_UART_INTR_ENABLE();
|
ETS_UART_INTR_ENABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send a BRK signal
|
||||||
|
* Which is a 11-bit set of zero's (11 cycles)
|
||||||
|
*/
|
||||||
|
void ICACHE_FLASH_ATTR emsuart_tx_brk() {
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
// must make sure Tx FIFO is empty
|
||||||
|
while (((USS(EMSUART_UART) >> USTXC) & 0xFF) != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
tmp = ((1 << UCRXRST) | (1 << UCTXRST)); // bit mask
|
||||||
|
USC0(EMSUART_UART) |= (tmp); // set bits
|
||||||
|
USC0(EMSUART_UART) &= ~(tmp); // clear bits
|
||||||
|
|
||||||
|
// To create a 11-bit <BRK> we set TXD_BRK bit so the break signal will
|
||||||
|
// automatically be sent when the tx fifo is empty
|
||||||
|
tmp = (1 << UCBRK);
|
||||||
|
GPIO_H(TX_MARK_MASK);
|
||||||
|
USC0(EMSUART_UART) |= (tmp); // set bit
|
||||||
|
|
||||||
|
if (EMS_Sys_Status.emsTxMode <= 1) { // classic mode and ems+ (0, 1)
|
||||||
|
delayMicroseconds(EMSUART_TX_BRK_WAIT);
|
||||||
|
} else if (EMS_Sys_Status.emsTxMode == 3) { // junkers mode
|
||||||
|
delayMicroseconds(EMSUART_TX_WAIT_BRK - EMSUART_TX_LAG); // 1144 (11 Bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
USC0(EMSUART_UART) &= ~(tmp); // clear bit
|
||||||
|
GPIO_L(TX_MARK_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send to Tx, ending with a <BRK>
|
* Send to Tx, ending with a <BRK>
|
||||||
*/
|
*/
|
||||||
@@ -182,8 +213,29 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
|||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
LA_PULSE(50);
|
LA_PULSE(50);
|
||||||
/*
|
|
||||||
*
|
if (EMS_Sys_Status.emsTxMode == 2) { // With extra tx delay for EMS+
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
TX_PULSE(EMSUART_BIT_TIME / 4);
|
||||||
|
USF(EMSUART_UART) = buf[i];
|
||||||
|
delayMicroseconds(EMSUART_TX_BRK_WAIT); // https://github.com/proddy/EMS-ESP/issues/23#
|
||||||
|
}
|
||||||
|
emsuart_tx_brk(); // send <BRK>
|
||||||
|
} else if (EMS_Sys_Status.emsTxMode == 3) { // Junkers logic by @philrich
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
TX_PULSE(EMSUART_BIT_TIME / 4);
|
||||||
|
USF(EMSUART_UART) = buf[i];
|
||||||
|
|
||||||
|
// just to be safe wait for tx fifo empty (needed?)
|
||||||
|
while (((USS(EMSUART_UART) >> USTXC) & 0xff) != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
// wait until bits are sent on wire
|
||||||
|
delayMicroseconds(EMSUART_TX_WAIT_BYTE - EMSUART_TX_LAG + EMSUART_TX_WAIT_GAP);
|
||||||
|
}
|
||||||
|
emsuart_tx_brk(); // send <BRK>
|
||||||
|
} else if (EMS_Sys_Status.emsTxMode == 1) {
|
||||||
|
/*
|
||||||
* based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch
|
* based on code from https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch
|
||||||
* we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO.
|
* we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO.
|
||||||
* after sending the last char we poll the Rx status until either
|
* after sending the last char we poll the Rx status until either
|
||||||
@@ -209,61 +261,62 @@ _EMS_TX_STATUS ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
|||||||
#define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8)
|
#define EMSUART_BUSY_WAIT (EMSUART_BIT_TIME / 8)
|
||||||
#define EMS_TX_TO_CHARS (2 + 20)
|
#define EMS_TX_TO_CHARS (2 + 20)
|
||||||
#define EMS_TX_TO_COUNT ((EMS_TX_TO_CHARS)*10 * 8)
|
#define EMS_TX_TO_COUNT ((EMS_TX_TO_CHARS)*10 * 8)
|
||||||
uint16_t wdc = EMS_TX_TO_COUNT;
|
uint16_t wdc = EMS_TX_TO_COUNT;
|
||||||
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
||||||
|
|
||||||
// clear Rx status register
|
// clear Rx status register
|
||||||
USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo
|
USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo
|
||||||
emsuart_flush_fifos();
|
emsuart_flush_fifos();
|
||||||
|
|
||||||
// throw out the telegram...
|
// throw out the telegram...
|
||||||
for (uint8_t i = 0; i < len && result == EMS_TX_STATUS_OK;) {
|
for (uint8_t i = 0; i < len && result == EMS_TX_STATUS_OK;) {
|
||||||
GPIO_H(TX_MARK_MASK);
|
GPIO_H(TX_MARK_MASK);
|
||||||
|
|
||||||
wdc = EMS_TX_TO_COUNT;
|
wdc = EMS_TX_TO_COUNT;
|
||||||
volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF;
|
volatile uint8_t _usrxc = (USS(EMSUART_UART) >> USRXC) & 0xFF;
|
||||||
USF(EMSUART_UART) = buf[i++]; // send each Tx byte
|
USF(EMSUART_UART) = buf[i++]; // send each Tx byte
|
||||||
// wait for echo from busmaster
|
// wait for echo from busmaster
|
||||||
GPIO_L(TX_MARK_MASK);
|
GPIO_L(TX_MARK_MASK);
|
||||||
while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) {
|
while (((USS(EMSUART_UART) >> USRXC) & 0xFF) == _usrxc) {
|
||||||
delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles...
|
delayMicroseconds(EMSUART_BUSY_WAIT); // burn CPU cycles...
|
||||||
if (--wdc == 0) {
|
if (--wdc == 0) {
|
||||||
EMS_Sys_Status.emsTxStatus = result = EMS_TX_WTD_TIMEOUT;
|
EMS_Sys_Status.emsTxStatus = result = EMS_TX_WTD_TIMEOUT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (USIR(EMSUART_UART) & (1 << UIBD)) {
|
if (USIR(EMSUART_UART) & (1 << UIBD)) {
|
||||||
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
USIC(EMSUART_UART) = (1 << UIBD); // clear BRK detect IRQ
|
||||||
EMS_Sys_Status.emsTxStatus = result = EMS_TX_BRK_DETECT;
|
EMS_Sys_Status.emsTxStatus = result = EMS_TX_BRK_DETECT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// we got the whole telegram in the Rx buffer
|
// we got the whole telegram in the Rx buffer
|
||||||
// on Rx-BRK (bus collision), we simply enable Rx and leave it
|
// 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 in the loopback and re=enable Rx-INT.
|
||||||
// worst case, we'll see an additional Rx-BRK...
|
// worst case, we'll see an additional Rx-BRK...
|
||||||
if (result != EMS_TX_STATUS_OK) {
|
if (result != EMS_TX_STATUS_OK) {
|
||||||
LA_PULSE(200); // mark Tx error
|
LA_PULSE(200); // mark Tx error
|
||||||
} else {
|
} else {
|
||||||
// neither bus collision nor timeout - send terminating BRK signal
|
// neither bus collision nor timeout - send terminating BRK signal
|
||||||
GPIO_H(TX_MARK_MASK);
|
GPIO_H(TX_MARK_MASK);
|
||||||
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
||||||
// no bus collision - send terminating BRK signal
|
// no bus collision - send terminating BRK signal
|
||||||
USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK>
|
USC0(EMSUART_UART) |= (1 << UCLBE) | (1 << UCBRK); // enable loopback & set <BRK>
|
||||||
|
|
||||||
// wait until BRK detected...
|
// wait until BRK detected...
|
||||||
while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
|
while (!(USIR(EMSUART_UART) & (1 << UIBD))) {
|
||||||
// delayMicroseconds(EMSUART_BUSY_WAIT);
|
// delayMicroseconds(EMSUART_BUSY_WAIT);
|
||||||
delayMicroseconds(EMSUART_BIT_TIME);
|
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);
|
||||||
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);
|
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
||||||
}
|
}
|
||||||
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ var custom_configfile = {
|
|||||||
"shower_timer": false,
|
"shower_timer": false,
|
||||||
"shower_alert": false,
|
"shower_alert": false,
|
||||||
"publish_time": 120,
|
"publish_time": 120,
|
||||||
"heating_circuit": 1
|
"heating_circuit": 1,
|
||||||
|
"tx_mode": 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user