Compare commits
3 commits
b5c9e36c29
...
c74c1a6970
Author | SHA1 | Date | |
---|---|---|---|
c74c1a6970 | |||
afd998adb6 | |||
381c994449 |
8 changed files with 208 additions and 250 deletions
|
@ -3,23 +3,24 @@ UseTab: Never
|
|||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
BreakBeforeBraces: Custom
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortLambdasOnASingleLine: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
IndentCaseLabels: true
|
||||
AccessModifierOffset: -4
|
||||
NamespaceIndentation: All
|
||||
NamespaceIndentation: None
|
||||
FixNamespaceComments: false
|
||||
PackConstructorInitializers: Never
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
InsertBraces: true
|
||||
BraceWrapping:
|
||||
AfterClass: true # false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: true # false
|
||||
AfterFunction: true # false
|
||||
AfterNamespace: true # false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true # false
|
||||
AfterStruct: true # false
|
||||
AfterUnion: true # false
|
||||
|
|
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -1,5 +1,7 @@
|
|||
.devcontainer
|
||||
.vscode
|
||||
.cache
|
||||
build
|
||||
sdkconfig.old
|
||||
.devcontainer/
|
||||
.cache/
|
||||
build/
|
||||
CMakeFiles/
|
||||
|
||||
CMakeCache.txt
|
||||
sdkconfig.old
|
||||
|
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"sonarlint.pathToCompileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||
}
|
|
@ -5,34 +5,35 @@
|
|||
* @licence MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "opentherm.h"
|
||||
#include "esp_log.h"
|
||||
#include "hal/gpio_types.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static const char *TAG = "ot-example";
|
||||
|
||||
#define OT_IN_PIN 4;
|
||||
#define OT_OUT_PIN 5;
|
||||
|
||||
gpio_num_t pin_in = OT_IN_PIN;
|
||||
gpio_num_t pin_out = OT_OUT_PIN;
|
||||
gpio_num_t g_pin_in = OT_IN_PIN;
|
||||
gpio_num_t g_pin_out = OT_OUT_PIN;
|
||||
|
||||
typedef uint8_t byte;
|
||||
|
||||
bool esp_ot_is_slave;
|
||||
bool g_esp_ot_is_slave;
|
||||
|
||||
void (*esp_ot_process_response_callback)(unsigned long, open_therm_response_status_t);
|
||||
|
||||
volatile unsigned long response;
|
||||
volatile unsigned long g_response;
|
||||
|
||||
volatile esp_ot_opentherm_status_t esp_ot_status;
|
||||
volatile esp_ot_opentherm_status_t g_esp_ot_status;
|
||||
|
||||
volatile open_therm_response_status_t esp_ot_response_status;
|
||||
volatile open_therm_response_status_t g_esp_ot_response_status;
|
||||
|
||||
volatile unsigned long esp_ot_response_timestamp;
|
||||
volatile unsigned long g_esp_ot_response_timestamp;
|
||||
|
||||
volatile byte esp_ot_response_bit_index;
|
||||
volatile byte g_esp_ot_response_bit_index;
|
||||
|
||||
/**
|
||||
* Initialize opentherm: gpio, install isr, basic data
|
||||
|
@ -40,54 +41,51 @@ volatile byte esp_ot_response_bit_index;
|
|||
* @return void
|
||||
*/
|
||||
esp_err_t esp_ot_init(
|
||||
gpio_num_t _pin_in,
|
||||
gpio_num_t _pin_out,
|
||||
bool _esp_ot_is_slave,
|
||||
gpio_num_t _pin_in, gpio_num_t _pin_out, bool _esp_ot_is_slave,
|
||||
void (*esp_ot_process_responseCallback)(unsigned long, open_therm_response_status_t))
|
||||
{
|
||||
|
||||
esp_err_t err = gpio_install_isr_service(0);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE("ISR", "Error with state %s", esp_err_to_name(err));
|
||||
}
|
||||
|
||||
pin_in = _pin_in;
|
||||
pin_out = _pin_out;
|
||||
g_pin_in = _pin_in;
|
||||
g_pin_out = _pin_out;
|
||||
|
||||
// Initialize the GPIO
|
||||
gpio_config_t io_conf;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << pin_in);
|
||||
io_conf.pin_bit_mask = (1ULL << g_pin_in);
|
||||
io_conf.intr_type = GPIO_INTR_ANYEDGE;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << pin_out);
|
||||
io_conf.pin_bit_mask = (1ULL << g_pin_out);
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
gpio_isr_handler_add(pin_in, esp_ot_handle_interrupt, NULL);
|
||||
gpio_isr_handler_add(g_pin_in, esp_ot_handle_interrupt, NULL);
|
||||
|
||||
esp_ot_is_slave = _esp_ot_is_slave;
|
||||
g_esp_ot_is_slave = _esp_ot_is_slave;
|
||||
|
||||
esp_ot_process_response_callback = esp_ot_process_responseCallback;
|
||||
|
||||
response = 0;
|
||||
g_response = 0;
|
||||
|
||||
esp_ot_response_status = OT_STATUS_NONE;
|
||||
g_esp_ot_response_status = OT_STATUS_NONE;
|
||||
|
||||
esp_ot_response_timestamp = 0;
|
||||
g_esp_ot_response_timestamp = 0;
|
||||
|
||||
gpio_intr_enable(pin_in);
|
||||
gpio_intr_enable(g_pin_in);
|
||||
|
||||
esp_ot_status = OT_READY;
|
||||
g_esp_ot_status = OT_READY;
|
||||
|
||||
ESP_LOGI(TAG, "Initialize opentherm with in: %d out: %d", pin_in, pin_out);
|
||||
ESP_LOGI(TAG, "Initialize opentherm with in: %d out: %d", g_pin_in, g_pin_out);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -99,15 +97,17 @@ esp_err_t esp_ot_init(
|
|||
*/
|
||||
void esp_ot_send_bit(bool high)
|
||||
{
|
||||
if (high)
|
||||
if (high) {
|
||||
esp_ot_set_active_state();
|
||||
else
|
||||
} else {
|
||||
esp_ot_set_idle_state();
|
||||
}
|
||||
ets_delay_us(500);
|
||||
if (high)
|
||||
if (high) {
|
||||
esp_ot_set_idle_state();
|
||||
else
|
||||
} else {
|
||||
esp_ot_set_active_state();
|
||||
}
|
||||
ets_delay_us(500);
|
||||
}
|
||||
|
||||
|
@ -116,9 +116,12 @@ void esp_ot_send_bit(bool high)
|
|||
*
|
||||
* @return long
|
||||
*/
|
||||
unsigned long esp_ot_build_set_boiler_status_request(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2)
|
||||
unsigned long esp_ot_build_set_boiler_status_request(
|
||||
bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation,
|
||||
bool enableCentralHeating2)
|
||||
{
|
||||
unsigned int data = enableCentralHeating | (enableHotWater << 1) | (enableCooling << 2) | (enableOutsideTemperatureCompensation << 3) | (enableCentralHeating2 << 4);
|
||||
unsigned int data = enableCentralHeating | (enableHotWater << 1) | (enableCooling << 2) | (enableOutsideTemperatureCompensation << 3) |
|
||||
(enableCentralHeating2 << 4);
|
||||
data <<= 8;
|
||||
return esp_ot_build_request(OT_READ_DATA, MSG_ID_STATUS, data);
|
||||
}
|
||||
|
@ -153,7 +156,7 @@ unsigned long esp_ot_build_get_boiler_temperature_request()
|
|||
*/
|
||||
bool IRAM_ATTR esp_ot_is_ready()
|
||||
{
|
||||
return esp_ot_status == OT_READY;
|
||||
return g_esp_ot_status == OT_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,7 +166,7 @@ bool IRAM_ATTR esp_ot_is_ready()
|
|||
*/
|
||||
int IRAM_ATTR esp_ot_read_state()
|
||||
{
|
||||
return gpio_get_level(pin_in);
|
||||
return gpio_get_level(g_pin_in);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +176,7 @@ int IRAM_ATTR esp_ot_read_state()
|
|||
*/
|
||||
void esp_ot_set_active_state()
|
||||
{
|
||||
gpio_set_level(pin_out, 0);
|
||||
gpio_set_level(g_pin_out, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,7 +186,7 @@ void esp_ot_set_active_state()
|
|||
*/
|
||||
void esp_ot_set_idle_state()
|
||||
{
|
||||
gpio_set_level(pin_out, 1);
|
||||
gpio_set_level(g_pin_out, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,10 +206,9 @@ void esp_ot_activate_boiler()
|
|||
*/
|
||||
void esp_ot_process_response()
|
||||
{
|
||||
if (esp_ot_process_response_callback != NULL)
|
||||
{
|
||||
if (esp_ot_process_response_callback != NULL) {
|
||||
// ESP_LOGI("PROCESS RESPONSE", "esp_ot_process_response, %ld, %d", response, esp_ot_response_status);
|
||||
esp_ot_process_response_callback(response, esp_ot_response_status);
|
||||
esp_ot_process_response_callback(g_response, g_esp_ot_response_status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,13 +247,11 @@ open_therm_message_id_t esp_ot_get_data_id(unsigned long frame)
|
|||
unsigned long esp_ot_build_request(open_therm_message_type_t type, open_therm_message_id_t id, unsigned int data)
|
||||
{
|
||||
unsigned long request = data;
|
||||
if (type == OT_WRITE_DATA)
|
||||
{
|
||||
if (type == OT_WRITE_DATA) {
|
||||
request |= 1ul << 28;
|
||||
}
|
||||
request |= ((unsigned long)id) << 16;
|
||||
if (parity(request))
|
||||
{
|
||||
if (parity(request)) {
|
||||
request |= (1ul << 31);
|
||||
}
|
||||
return request;
|
||||
|
@ -269,8 +269,9 @@ unsigned long esp_ot_build_response(open_therm_message_type_t type, open_therm_m
|
|||
unsigned long response = data;
|
||||
response |= ((unsigned long)type) << 28;
|
||||
response |= ((unsigned long)id) << 16;
|
||||
if (parity(response))
|
||||
if (parity(response)) {
|
||||
response |= (1ul << 31);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
|
@ -283,8 +284,9 @@ unsigned long esp_ot_build_response(open_therm_message_type_t type, open_therm_m
|
|||
*/
|
||||
bool esp_ot_is_valid_request(unsigned long request)
|
||||
{
|
||||
if (parity(request))
|
||||
if (parity(request)) {
|
||||
return false;
|
||||
}
|
||||
byte msgType = (request << 1) >> 29;
|
||||
return msgType == (byte)OT_READ_DATA || msgType == (byte)OT_WRITE_DATA;
|
||||
}
|
||||
|
@ -298,8 +300,9 @@ bool esp_ot_is_valid_request(unsigned long request)
|
|||
*/
|
||||
bool esp_ot_is_valid_response(unsigned long response)
|
||||
{
|
||||
if (parity(response))
|
||||
if (parity(response)) {
|
||||
return false;
|
||||
}
|
||||
byte msgType = (response << 1) >> 29;
|
||||
return msgType == (byte)OT_READ_ACK || msgType == (byte)OT_WRITE_ACK;
|
||||
}
|
||||
|
@ -314,10 +317,10 @@ bool esp_ot_is_valid_response(unsigned long response)
|
|||
bool parity(unsigned long frame) // odd parity
|
||||
{
|
||||
byte p = 0;
|
||||
while (frame > 0)
|
||||
{
|
||||
if (frame & 1)
|
||||
while (frame > 0) {
|
||||
if (frame & 1) {
|
||||
p++;
|
||||
}
|
||||
frame = frame >> 1;
|
||||
}
|
||||
return (p & 1);
|
||||
|
@ -383,65 +386,50 @@ float esp_ot_get_slave_ot_version()
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
#define OT_INPUT_ACTIVE 0
|
||||
#define OT_INPUT_INACTIVE 1
|
||||
|
||||
void IRAM_ATTR esp_ot_handle_interrupt()
|
||||
{
|
||||
// ESP_DRAM_LOGI("esp_ot_handle_interrupt", "%ld", status);
|
||||
if (esp_ot_is_ready())
|
||||
{
|
||||
if (esp_ot_is_slave && esp_ot_read_state() == 1)
|
||||
{
|
||||
esp_ot_status = OT_RESPONSE_WAITING;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (esp_ot_is_ready()) {
|
||||
if (g_esp_ot_is_slave && esp_ot_read_state() == OT_INPUT_ACTIVE) {
|
||||
g_esp_ot_status = OT_RESPONSE_WAITING;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long newTs = esp_timer_get_time();
|
||||
if (esp_ot_status == OT_RESPONSE_WAITING)
|
||||
{
|
||||
if (esp_ot_read_state() == 1)
|
||||
{
|
||||
if (g_esp_ot_status == OT_RESPONSE_WAITING) {
|
||||
if (esp_ot_read_state() == OT_INPUT_ACTIVE) {
|
||||
// ESP_DRAM_LOGI("BIT", "Set start bit");
|
||||
esp_ot_status = OT_RESPONSE_START_BIT;
|
||||
esp_ot_response_timestamp = newTs;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_esp_ot_status = OT_RESPONSE_START_BIT;
|
||||
g_esp_ot_response_timestamp = newTs;
|
||||
} else {
|
||||
// ESP_DRAM_LOGI("BIT", "Set OT_RESPONSE_INVALID");
|
||||
esp_ot_status = OT_RESPONSE_INVALID;
|
||||
esp_ot_response_timestamp = newTs;
|
||||
g_esp_ot_status = OT_RESPONSE_INVALID;
|
||||
g_esp_ot_response_timestamp = newTs;
|
||||
}
|
||||
}
|
||||
else if (esp_ot_status == OT_RESPONSE_START_BIT)
|
||||
{
|
||||
if ((newTs - esp_ot_response_timestamp < 750) && esp_ot_read_state() == 0)
|
||||
{
|
||||
esp_ot_status = OT_RESPONSE_RECEIVING;
|
||||
esp_ot_response_timestamp = newTs;
|
||||
esp_ot_response_bit_index = 0;
|
||||
} else if (g_esp_ot_status == OT_RESPONSE_START_BIT) {
|
||||
if ((newTs - g_esp_ot_response_timestamp < 750) && esp_ot_read_state() == OT_INPUT_INACTIVE) {
|
||||
g_esp_ot_status = OT_RESPONSE_RECEIVING;
|
||||
g_esp_ot_response_timestamp = newTs;
|
||||
g_esp_ot_response_bit_index = 0;
|
||||
} else {
|
||||
g_esp_ot_status = OT_RESPONSE_INVALID;
|
||||
g_esp_ot_response_timestamp = newTs;
|
||||
}
|
||||
else
|
||||
{
|
||||
esp_ot_status = OT_RESPONSE_INVALID;
|
||||
esp_ot_response_timestamp = newTs;
|
||||
}
|
||||
}
|
||||
else if (esp_ot_status == OT_RESPONSE_RECEIVING)
|
||||
{
|
||||
if ((newTs - esp_ot_response_timestamp) > 750)
|
||||
{
|
||||
if (esp_ot_response_bit_index < 32)
|
||||
{
|
||||
response = (response << 1) | !esp_ot_read_state();
|
||||
esp_ot_response_timestamp = newTs;
|
||||
esp_ot_response_bit_index++;
|
||||
}
|
||||
else
|
||||
{ // stop bit
|
||||
esp_ot_status = OT_RESPONSE_READY;
|
||||
esp_ot_response_timestamp = newTs;
|
||||
} else if (g_esp_ot_status == OT_RESPONSE_RECEIVING) {
|
||||
if ((newTs - g_esp_ot_response_timestamp) > 750) {
|
||||
if (g_esp_ot_response_bit_index < 32) {
|
||||
g_response = (g_response << 1) | (esp_ot_read_state() == OT_INPUT_INACTIVE);
|
||||
g_esp_ot_response_timestamp = newTs;
|
||||
g_esp_ot_response_bit_index++;
|
||||
} else { // stop bit
|
||||
g_esp_ot_status = OT_RESPONSE_READY;
|
||||
g_esp_ot_response_timestamp = newTs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -455,40 +443,33 @@ void IRAM_ATTR esp_ot_handle_interrupt()
|
|||
void process()
|
||||
{
|
||||
PORT_ENTER_CRITICAL;
|
||||
esp_ot_opentherm_status_t st = esp_ot_status;
|
||||
unsigned long ts = esp_ot_response_timestamp;
|
||||
esp_ot_opentherm_status_t st = g_esp_ot_status;
|
||||
unsigned long ts = g_esp_ot_response_timestamp;
|
||||
PORT_EXIT_CRITICAL;
|
||||
|
||||
if (st == OT_READY)
|
||||
{
|
||||
if (st == OT_READY) {
|
||||
return;
|
||||
}
|
||||
unsigned long newTs = esp_timer_get_time();
|
||||
if (st != OT_NOT_INITIALIZED && st != OT_DELAY && (newTs - ts) > 1000000)
|
||||
{
|
||||
esp_ot_status = OT_READY;
|
||||
if (st != OT_NOT_INITIALIZED && st != OT_DELAY && (newTs - ts) > 1000000) {
|
||||
g_esp_ot_status = OT_READY;
|
||||
ESP_LOGI("SET STATUS", "set status to READY"); // here READY
|
||||
esp_ot_response_status = OT_STATUS_TIMEOUT;
|
||||
g_esp_ot_response_status = OT_STATUS_TIMEOUT;
|
||||
esp_ot_process_response();
|
||||
}
|
||||
else if (st == OT_RESPONSE_INVALID)
|
||||
{
|
||||
} else if (st == OT_RESPONSE_INVALID) {
|
||||
ESP_LOGE("SET STATUS", "set status to OT_RESPONSE_INVALID"); // here OT_RESPONSE_INVALID
|
||||
esp_ot_status = OT_DELAY;
|
||||
esp_ot_response_status = OT_STATUS_INVALID;
|
||||
g_esp_ot_status = OT_DELAY;
|
||||
g_esp_ot_response_status = OT_STATUS_INVALID;
|
||||
esp_ot_process_response();
|
||||
}
|
||||
else if (st == OT_RESPONSE_READY)
|
||||
{
|
||||
esp_ot_status = OT_DELAY;
|
||||
esp_ot_response_status = (esp_ot_is_slave ? esp_ot_is_valid_request(response) : esp_ot_is_valid_response(response)) ? OT_STATUS_SUCCESS : OT_STATUS_INVALID;
|
||||
} else if (st == OT_RESPONSE_READY) {
|
||||
g_esp_ot_status = OT_DELAY;
|
||||
g_esp_ot_response_status = (g_esp_ot_is_slave ? esp_ot_is_valid_request(g_response) : esp_ot_is_valid_response(g_response))
|
||||
? OT_STATUS_SUCCESS
|
||||
: OT_STATUS_INVALID;
|
||||
esp_ot_process_response();
|
||||
}
|
||||
else if (st == OT_DELAY)
|
||||
{
|
||||
if ((newTs - ts) > (esp_ot_is_slave ? 20000 : 100000))
|
||||
{
|
||||
esp_ot_status = OT_READY;
|
||||
} else if (st == OT_DELAY) {
|
||||
if ((newTs - ts) > (g_esp_ot_is_slave ? 20000 : 100000)) {
|
||||
g_esp_ot_status = OT_READY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,28 +486,26 @@ bool esp_ot_send_request_async(unsigned long request)
|
|||
PORT_ENTER_CRITICAL;
|
||||
const bool ready = esp_ot_is_ready();
|
||||
PORT_EXIT_CRITICAL;
|
||||
if (!ready)
|
||||
{
|
||||
if (!ready) {
|
||||
return false;
|
||||
}
|
||||
PORT_ENTER_CRITICAL;
|
||||
esp_ot_status = OT_REQUEST_SENDING;
|
||||
response = 0;
|
||||
esp_ot_response_status = OT_STATUS_NONE;
|
||||
g_esp_ot_status = OT_REQUEST_SENDING;
|
||||
g_response = 0;
|
||||
g_esp_ot_response_status = OT_STATUS_NONE;
|
||||
PORT_EXIT_CRITICAL;
|
||||
|
||||
// vTaskSuspendAll();
|
||||
|
||||
esp_ot_send_bit(1); // start bit
|
||||
for (int i = 31; i >= 0; i--)
|
||||
{
|
||||
for (int i = 31; i >= 0; i--) {
|
||||
esp_ot_send_bit(ESP_OT_BIT_READ(request, i));
|
||||
}
|
||||
esp_ot_send_bit(1); // stop bit
|
||||
esp_ot_set_idle_state();
|
||||
|
||||
esp_ot_response_timestamp = esp_timer_get_time();
|
||||
esp_ot_status = OT_RESPONSE_WAITING;
|
||||
g_esp_ot_response_timestamp = esp_timer_get_time();
|
||||
g_esp_ot_status = OT_RESPONSE_WAITING;
|
||||
|
||||
// xTaskResumeAll();
|
||||
|
||||
|
@ -542,17 +521,15 @@ bool esp_ot_send_request_async(unsigned long request)
|
|||
*/
|
||||
unsigned long esp_ot_send_request(unsigned long request)
|
||||
{
|
||||
if (!esp_ot_send_request_async(request))
|
||||
{
|
||||
if (!esp_ot_send_request_async(request)) {
|
||||
return 0;
|
||||
}
|
||||
// ESP_LOGI("STATUS", "esp_ot_send_request with status %d", status); // here WAITING
|
||||
while (!esp_ot_is_ready())
|
||||
{
|
||||
while (!esp_ot_is_ready()) {
|
||||
process();
|
||||
vPortYield();
|
||||
}
|
||||
return response;
|
||||
return g_response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -663,13 +640,11 @@ float esp_ot_get_float(const unsigned long response)
|
|||
*/
|
||||
unsigned int esp_ot_temperature_to_data(float temperature)
|
||||
{
|
||||
if (temperature < 0)
|
||||
{
|
||||
if (temperature < 0) {
|
||||
temperature = 0;
|
||||
}
|
||||
|
||||
if (temperature > 100)
|
||||
{
|
||||
if (temperature > 100) {
|
||||
temperature = 100;
|
||||
}
|
||||
|
||||
|
@ -689,13 +664,11 @@ unsigned int esp_ot_temperature_to_data(float temperature)
|
|||
* @return long boiler status
|
||||
*/
|
||||
unsigned long esp_ot_set_boiler_status(
|
||||
bool enableCentralHeating,
|
||||
bool enableHotWater,
|
||||
bool enableCooling,
|
||||
bool enableOutsideTemperatureCompensation,
|
||||
bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation,
|
||||
bool enableCentralHeating2)
|
||||
{
|
||||
return esp_ot_send_request(esp_ot_build_set_boiler_status_request(enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2));
|
||||
return esp_ot_send_request(esp_ot_build_set_boiler_status_request(
|
||||
enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -765,9 +738,7 @@ esp_ot_min_max_t esp_ot_get_ch_upper_lower_bounds()
|
|||
|
||||
uint8_t min = (uint8_t)(result & 0x00FF);
|
||||
uint8_t max = (uint8_t)((result & 0xFF00) >> 8);
|
||||
esp_ot_min_max_t min_max = {
|
||||
.min = min,
|
||||
.max = max};
|
||||
esp_ot_min_max_t min_max = {.min = min, .max = max};
|
||||
return min_max;
|
||||
}
|
||||
|
||||
|
@ -777,9 +748,7 @@ esp_ot_min_max_t esp_ot_get_dhw_upper_lower_bounds()
|
|||
uint16_t result = esp_ot_is_valid_response(response) ? esp_ot_get_uint(response) : 0;
|
||||
uint8_t min = (uint8_t)(result & 0x00FF);
|
||||
uint8_t max = (uint8_t)((result & 0xFF00) >> 8);
|
||||
esp_ot_min_max_t min_max = {
|
||||
.min = min,
|
||||
.max = max};
|
||||
esp_ot_min_max_t min_max = {.min = min, .max = max};
|
||||
return min_max;
|
||||
}
|
||||
|
||||
|
@ -793,9 +762,7 @@ esp_ot_min_max_t esp_ot_get_heat_curve_ul_bounds()
|
|||
uint16_t result = esp_ot_is_valid_response(response) ? esp_ot_get_uint(response) : 0;
|
||||
uint8_t min = (uint8_t)(result & 0x00FF);
|
||||
uint8_t max = (uint8_t)((result & 0xFF00) >> 8);
|
||||
esp_ot_min_max_t min_max = {
|
||||
.min = min,
|
||||
.max = max};
|
||||
esp_ot_min_max_t min_max = {.min = min, .max = max};
|
||||
return min_max;
|
||||
}
|
||||
|
||||
|
@ -809,9 +776,7 @@ esp_ot_cap_mod_t esp_ot_get_max_capacity_min_modulation()
|
|||
uint16_t result = esp_ot_is_valid_response(response) ? esp_ot_get_uint(response) : 0;
|
||||
uint8_t mod = (uint8_t)(result & 0x00FF);
|
||||
uint8_t kw = (uint8_t)((result & 0xFF00) >> 8);
|
||||
esp_ot_cap_mod_t cap_mod = {
|
||||
.kw = kw,
|
||||
.min_modulation = mod};
|
||||
esp_ot_cap_mod_t cap_mod = {.kw = kw, .min_modulation = mod};
|
||||
return cap_mod;
|
||||
}
|
||||
|
||||
|
@ -948,8 +913,7 @@ float esp_ot_get_modulation()
|
|||
bool esp_ot_set_modulation_level(int percent)
|
||||
{
|
||||
unsigned int data = percent;
|
||||
unsigned long response = esp_ot_send_request(
|
||||
esp_ot_build_request(OT_WRITE_DATA, MSG_ID_MAX_REL_MOD_LEVEL_SETTING, data));
|
||||
unsigned long response = esp_ot_send_request(esp_ot_build_request(OT_WRITE_DATA, MSG_ID_MAX_REL_MOD_LEVEL_SETTING, data));
|
||||
return esp_ot_is_valid_response(response);
|
||||
}
|
||||
|
||||
|
@ -986,7 +950,7 @@ uint16_t esp_ot_get_fault_code()
|
|||
*/
|
||||
open_therm_response_status_t esp_ot_get_last_response_status()
|
||||
{
|
||||
return esp_ot_response_status;
|
||||
return g_esp_ot_response_status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1001,28 +965,26 @@ bool esp_ot_send_response(unsigned long request)
|
|||
PORT_ENTER_CRITICAL;
|
||||
const bool ready = esp_ot_is_ready();
|
||||
|
||||
if (!ready)
|
||||
{
|
||||
if (!ready) {
|
||||
PORT_EXIT_CRITICAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
esp_ot_status = OT_REQUEST_SENDING;
|
||||
response = 0;
|
||||
esp_ot_response_status = OT_STATUS_NONE;
|
||||
g_esp_ot_status = OT_REQUEST_SENDING;
|
||||
g_response = 0;
|
||||
g_esp_ot_response_status = OT_STATUS_NONE;
|
||||
|
||||
// vTaskSuspendAll();
|
||||
|
||||
PORT_EXIT_CRITICAL;
|
||||
|
||||
esp_ot_send_bit(1); // start bit
|
||||
for (int i = 31; i >= 0; i--)
|
||||
{
|
||||
for (int i = 31; i >= 0; i--) {
|
||||
esp_ot_send_bit(ESP_OT_BIT_READ(request, i));
|
||||
}
|
||||
esp_ot_send_bit(1); // stop bit
|
||||
esp_ot_set_idle_state();
|
||||
esp_ot_status = OT_READY;
|
||||
g_esp_ot_status = OT_READY;
|
||||
// xTaskResumeAll();
|
||||
|
||||
return true;
|
||||
|
@ -1035,5 +997,5 @@ bool esp_ot_send_response(unsigned long request)
|
|||
*/
|
||||
unsigned long esp_ot_get_last_response()
|
||||
{
|
||||
return response;
|
||||
return g_response;
|
||||
}
|
|
@ -5,11 +5,11 @@
|
|||
* @licence MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "opentherm_struct.h"
|
||||
|
||||
|
@ -45,6 +45,7 @@ typedef enum OpenThermMessageType // old name OpenThermRequestType; // for backw
|
|||
OT_UNKNOWN_DATA_ID = 0b111
|
||||
} open_therm_message_type_t;
|
||||
|
||||
// clang-format off
|
||||
typedef enum OpenThermMessageID
|
||||
{
|
||||
MSG_ID_STATUS = 0, // flag8/flag8 |R-| Master and Slave Status flags.
|
||||
|
@ -169,6 +170,7 @@ typedef enum OpenThermMessageID
|
|||
MSG_ID_MASTER_VERSION = 126, // u8/u8 |-W| Master product version number and type
|
||||
MSG_ID_SLAVE_VERSION = 127, // u8/u8 |R-| Slave product version number and type
|
||||
} open_therm_message_id_t;
|
||||
// clang-format on
|
||||
|
||||
typedef enum OpenThermStatus
|
||||
{
|
||||
|
@ -185,9 +187,7 @@ typedef enum OpenThermStatus
|
|||
// ENUMS
|
||||
|
||||
esp_err_t esp_ot_init(
|
||||
gpio_num_t _pin_in,
|
||||
gpio_num_t _pin_out,
|
||||
bool _esp_ot_is_slave,
|
||||
gpio_num_t _pin_in, gpio_num_t _pin_out, bool _esp_ot_is_slave,
|
||||
void (*esp_ot_process_responseCallback)(unsigned long, open_therm_response_status_t));
|
||||
|
||||
bool esp_ot_is_ready();
|
||||
|
@ -232,7 +232,9 @@ void esp_ot_send_bit(bool high);
|
|||
|
||||
void esp_ot_process_response();
|
||||
|
||||
unsigned long esp_ot_build_set_boiler_status_request(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2);
|
||||
unsigned long esp_ot_build_set_boiler_status_request(
|
||||
bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation,
|
||||
bool enableCentralHeating2);
|
||||
|
||||
unsigned long esp_ot_build_set_boiler_temperature_request(float temperature);
|
||||
|
||||
|
@ -256,7 +258,9 @@ float esp_ot_get_float(const unsigned long response);
|
|||
|
||||
unsigned int esp_ot_temperature_to_data(float temperature);
|
||||
|
||||
unsigned long esp_ot_set_boiler_status(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2);
|
||||
unsigned long esp_ot_set_boiler_status(
|
||||
bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation,
|
||||
bool enableCentralHeating2);
|
||||
|
||||
bool esp_ot_set_boiler_temperature(float temperature);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
/**
|
||||
* @package Opentherm library for ESP-IDF framework - EXAMPLE
|
||||
* @author: Mikhail Sazanof
|
||||
* @copyright Copyright (C) 2024 - Sazanof.ru
|
||||
* @licence MIT
|
||||
*/
|
||||
* @package Opentherm library for ESP-IDF framework - EXAMPLE
|
||||
* @author: Mikhail Sazanof
|
||||
* @copyright Copyright (C) 2024 - Sazanof.ru
|
||||
* @licence MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "opentherm.h"
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
#include <esp_log.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define GPIO_OT_IN CONFIG_OT_IN_PIN
|
||||
#define GPIO_OT_OUT CONFIG_OT_OUT_PIN
|
||||
#define ESP_INTR_FLAG_DEFAULT 0
|
||||
|
||||
volatile float dhwTemp = 0;
|
||||
volatile float chTemp = 0;
|
||||
volatile bool fault = false;
|
||||
static int targetDHWTemp = 59;
|
||||
static int targetCHTemp = 60;
|
||||
volatile float g_dhwTemp = 0;
|
||||
volatile float g_chTemp = 0;
|
||||
volatile bool g_fault = false;
|
||||
static int g_targetDHWTemp = 59;
|
||||
static int g_targetCHTemp = 60;
|
||||
|
||||
static const char *T = "OT";
|
||||
static const char *g_T = "OT";
|
||||
|
||||
static void IRAM_ATTR esp_ot_process_response_callback(unsigned long response, open_therm_response_status_t esp_ot_response_status)
|
||||
{
|
||||
|
@ -33,64 +33,54 @@ static void IRAM_ATTR esp_ot_process_response_callback(unsigned long response, o
|
|||
|
||||
void esp_ot_control_task_handler(void *pvParameter)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
unsigned long status = esp_ot_set_boiler_status(false, true, false, false, false);
|
||||
while (1) {
|
||||
unsigned long status = esp_ot_set_boiler_status(false, false, false, false, false);
|
||||
|
||||
ESP_LOGI(T, "====== OPENTHERM =====");
|
||||
ESP_LOGI(T, "Free heap size before: %ld", esp_get_free_heap_size());
|
||||
ESP_LOGI(g_T, "====== OPENTHERM =====");
|
||||
ESP_LOGI(g_T, "Free heap size before: %ld", esp_get_free_heap_size());
|
||||
open_therm_response_status_t esp_ot_response_status = esp_ot_get_last_response_status();
|
||||
if (esp_ot_response_status == OT_STATUS_SUCCESS)
|
||||
{
|
||||
ESP_LOGI(T, "Central Heating: %s", esp_ot_is_central_heating_active(status) ? "ON" : "OFF");
|
||||
ESP_LOGI(T, "Hot Water: %s", esp_ot_is_hot_water_active(status) ? "ON" : "OFF");
|
||||
ESP_LOGI(T, "Flame: %s", esp_ot_is_flame_on(status) ? "ON" : "OFF");
|
||||
fault = esp_ot_is_fault(status);
|
||||
ESP_LOGI(T, "Fault: %s", fault ? "YES" : "NO");
|
||||
if (fault)
|
||||
{
|
||||
if (esp_ot_response_status == OT_STATUS_SUCCESS) {
|
||||
ESP_LOGI(g_T, "Central Heating: %s", esp_ot_is_central_heating_active(status) ? "ON" : "OFF");
|
||||
ESP_LOGI(g_T, "Hot Water: %s", esp_ot_is_hot_water_active(status) ? "ON" : "OFF");
|
||||
ESP_LOGI(g_T, "Flame: %s", esp_ot_is_flame_on(status) ? "ON" : "OFF");
|
||||
g_fault = esp_ot_is_fault(status);
|
||||
ESP_LOGI(g_T, "Fault: %s", g_fault ? "YES" : "NO");
|
||||
if (g_fault) {
|
||||
ot_reset();
|
||||
}
|
||||
esp_ot_set_boiler_temperature(targetCHTemp);
|
||||
ESP_LOGI(T, "Set CH Temp to: %i", targetCHTemp);
|
||||
esp_ot_set_boiler_temperature(g_targetCHTemp);
|
||||
ESP_LOGI(g_T, "Set CH Temp to: %i", g_targetCHTemp);
|
||||
|
||||
esp_ot_set_dhw_setpoint(targetDHWTemp);
|
||||
ESP_LOGI(T, "Set DHW Temp to: %i", targetDHWTemp);
|
||||
esp_ot_set_dhw_setpoint(g_targetDHWTemp);
|
||||
ESP_LOGI(g_T, "Set DHW Temp to: %i", g_targetDHWTemp);
|
||||
|
||||
dhwTemp = esp_ot_get_dhw_temperature();
|
||||
ESP_LOGI(T, "DHW Temp: %.1f", dhwTemp);
|
||||
g_dhwTemp = esp_ot_get_dhw_temperature();
|
||||
ESP_LOGI(g_T, "DHW Temp: %.1f", g_dhwTemp);
|
||||
|
||||
chTemp = esp_ot_get_boiler_temperature();
|
||||
ESP_LOGI(T, "CH Temp: %.1f", chTemp);
|
||||
g_chTemp = esp_ot_get_boiler_temperature();
|
||||
ESP_LOGI(g_T, "CH Temp: %.1f", g_chTemp);
|
||||
|
||||
float pressure = esp_ot_get_pressure();
|
||||
ESP_LOGI(T, "Slave OT Version: %.1f", pressure);
|
||||
ESP_LOGI(g_T, "Pressure: %.1f", pressure);
|
||||
|
||||
unsigned long slaveProductVersion = esp_ot_get_slave_product_version();
|
||||
ESP_LOGI(T, "Slave Version: %08lX", slaveProductVersion);
|
||||
ESP_LOGI(g_T, "Slave Version: %08lX", slaveProductVersion);
|
||||
|
||||
float slaveOTVersion = esp_ot_get_slave_ot_version();
|
||||
ESP_LOGI(T, "Slave OT Version: %.1f", slaveOTVersion);
|
||||
}
|
||||
else if (esp_ot_response_status == OT_STATUS_TIMEOUT)
|
||||
{
|
||||
ESP_LOGE(T, "OT Communication Timeout");
|
||||
}
|
||||
else if (esp_ot_response_status == OT_STATUS_INVALID)
|
||||
{
|
||||
ESP_LOGE(T, "OT Communication Invalid");
|
||||
}
|
||||
else if (esp_ot_response_status == OT_STATUS_NONE)
|
||||
{
|
||||
ESP_LOGE(T, "OpenTherm not initialized");
|
||||
ESP_LOGI(g_T, "Slave OT Version: %.1f", slaveOTVersion);
|
||||
} else if (esp_ot_response_status == OT_STATUS_TIMEOUT) {
|
||||
ESP_LOGE(g_T, "OT Communication Timeout");
|
||||
} else if (esp_ot_response_status == OT_STATUS_INVALID) {
|
||||
ESP_LOGE(g_T, "OT Communication Invalid");
|
||||
} else if (esp_ot_response_status == OT_STATUS_NONE) {
|
||||
ESP_LOGE(g_T, "OpenTherm not initialized");
|
||||
}
|
||||
|
||||
if (fault)
|
||||
{
|
||||
ESP_LOGE(T, "Fault Code: %i", esp_ot_get_fault());
|
||||
if (g_fault) {
|
||||
ESP_LOGE(g_T, "Fault Code: %i", esp_ot_get_fault());
|
||||
}
|
||||
ESP_LOGI(T, "Free heap size after: %ld", esp_get_free_heap_size());
|
||||
ESP_LOGI(T, "====== OPENTHERM =====\r\n\r\n");
|
||||
ESP_LOGI(g_T, "Free heap size after: %ld", esp_get_free_heap_size());
|
||||
ESP_LOGI(g_T, "====== OPENTHERM =====\r\n\r\n");
|
||||
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
@ -98,12 +88,8 @@ void esp_ot_control_task_handler(void *pvParameter)
|
|||
|
||||
void app_main()
|
||||
{
|
||||
esp_ot_init(
|
||||
GPIO_OT_IN,
|
||||
GPIO_OT_OUT,
|
||||
false,
|
||||
esp_ot_process_response_callback);
|
||||
esp_ot_init(GPIO_OT_IN, GPIO_OT_OUT, false, esp_ot_process_response_callback);
|
||||
|
||||
xTaskCreate(esp_ot_control_task_handler, T, configMINIMAL_STACK_SIZE * 4, NULL, 3, NULL);
|
||||
xTaskCreate(esp_ot_control_task_handler, g_T, configMINIMAL_STACK_SIZE * 4, NULL, 3, NULL);
|
||||
vTaskSuspend(NULL);
|
||||
}
|
||||
|
|
|
@ -561,8 +561,8 @@ CONFIG_PARTITION_TABLE_MD5=y
|
|||
#
|
||||
# OpenTherm Configuration
|
||||
#
|
||||
CONFIG_OT_IN_PIN=21
|
||||
CONFIG_OT_OUT_PIN=22
|
||||
CONFIG_OT_IN_PIN=17
|
||||
CONFIG_OT_OUT_PIN=16
|
||||
# end of OpenTherm Configuration
|
||||
|
||||
#
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue