mirror of
https://github.com/esphome/esphome.git
synced 2025-07-27 13:46:48 +00:00
[esp32_can] Configurable enqueue timeout (#8453)
This commit is contained in:
parent
bb988604c8
commit
4bb59ce1d1
@ -1,3 +1,4 @@
|
|||||||
|
import re
|
||||||
from esphome import automation
|
from esphome import automation
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
@ -68,6 +69,16 @@ CAN_SPEEDS = {
|
|||||||
"800KBPS": CanSpeed.CAN_800KBPS,
|
"800KBPS": CanSpeed.CAN_800KBPS,
|
||||||
"1000KBPS": CanSpeed.CAN_1000KBPS,
|
"1000KBPS": CanSpeed.CAN_1000KBPS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_rate(value):
|
||||||
|
match = re.match(r"(\d+)(?:K(\d+)?)?BPS", value, re.IGNORECASE)
|
||||||
|
if not match:
|
||||||
|
raise ValueError(f"Invalid rate format: {value}")
|
||||||
|
fraction = match.group(2) or "0"
|
||||||
|
return int((float(match.group(1)) + float(f"0.{fraction}")) * 1000)
|
||||||
|
|
||||||
|
|
||||||
CANBUS_SCHEMA = cv.Schema(
|
CANBUS_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
||||||
|
@ -46,7 +46,13 @@ void Canbus::send_data(uint32_t can_id, bool use_extended_id, bool remote_transm
|
|||||||
ESP_LOGVV(TAG, " data[%d]=%02x", i, can_message.data[i]);
|
ESP_LOGVV(TAG, " data[%d]=%02x", i, can_message.data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->send_message(&can_message);
|
if (this->send_message(&can_message) != canbus::ERROR_OK) {
|
||||||
|
if (use_extended_id) {
|
||||||
|
ESP_LOGW(TAG, "send to extended id=0x%08" PRIx32 " failed!", can_id);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "send to standard id=0x%03" PRIx32 " failed!", can_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canbus::add_trigger(CanbusTrigger *trigger) {
|
void Canbus::add_trigger(CanbusTrigger *trigger) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import canbus
|
from esphome.components import canbus
|
||||||
@ -23,6 +25,8 @@ from esphome.const import (
|
|||||||
CODEOWNERS = ["@Sympatron"]
|
CODEOWNERS = ["@Sympatron"]
|
||||||
DEPENDENCIES = ["esp32"]
|
DEPENDENCIES = ["esp32"]
|
||||||
|
|
||||||
|
CONF_TX_ENQUEUE_TIMEOUT = "tx_enqueue_timeout"
|
||||||
|
|
||||||
esp32_can_ns = cg.esphome_ns.namespace("esp32_can")
|
esp32_can_ns = cg.esphome_ns.namespace("esp32_can")
|
||||||
esp32_can = esp32_can_ns.class_("ESP32Can", CanbusComponent)
|
esp32_can = esp32_can_ns.class_("ESP32Can", CanbusComponent)
|
||||||
|
|
||||||
@ -84,10 +88,20 @@ CONFIG_SCHEMA = canbus.CANBUS_SCHEMA.extend(
|
|||||||
cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_number,
|
cv.Required(CONF_TX_PIN): pins.internal_gpio_output_pin_number,
|
||||||
cv.Optional(CONF_RX_QUEUE_LEN): cv.uint32_t,
|
cv.Optional(CONF_RX_QUEUE_LEN): cv.uint32_t,
|
||||||
cv.Optional(CONF_TX_QUEUE_LEN): cv.uint32_t,
|
cv.Optional(CONF_TX_QUEUE_LEN): cv.uint32_t,
|
||||||
|
cv.Optional(CONF_TX_ENQUEUE_TIMEOUT): cv.positive_time_period_milliseconds,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_default_tx_enqueue_timeout(bit_rate):
|
||||||
|
bit_rate_numeric = canbus.get_rate(bit_rate)
|
||||||
|
bits_per_packet = 140 # ~max CAN message length
|
||||||
|
ms_per_packet = bits_per_packet / bit_rate_numeric * 1000
|
||||||
|
return int(
|
||||||
|
max(min(math.ceil(10 * ms_per_packet), 1000), 1)
|
||||||
|
) # ~10 packet lengths, min 1ms, max 1000ms
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await canbus.register_canbus(var, config)
|
await canbus.register_canbus(var, config)
|
||||||
@ -98,3 +112,10 @@ async def to_code(config):
|
|||||||
cg.add(var.set_rx_queue_len(rx_queue_len))
|
cg.add(var.set_rx_queue_len(rx_queue_len))
|
||||||
if (tx_queue_len := config.get(CONF_TX_QUEUE_LEN)) is not None:
|
if (tx_queue_len := config.get(CONF_TX_QUEUE_LEN)) is not None:
|
||||||
cg.add(var.set_tx_queue_len(tx_queue_len))
|
cg.add(var.set_tx_queue_len(tx_queue_len))
|
||||||
|
|
||||||
|
if CONF_TX_ENQUEUE_TIMEOUT in config:
|
||||||
|
tx_enqueue_timeout_ms = config[CONF_TX_ENQUEUE_TIMEOUT].total_milliseconds
|
||||||
|
else:
|
||||||
|
tx_enqueue_timeout_ms = get_default_tx_enqueue_timeout(config[CONF_BIT_RATE])
|
||||||
|
|
||||||
|
cg.add(var.set_tx_enqueue_timeout_ms(tx_enqueue_timeout_ms))
|
||||||
|
@ -124,7 +124,7 @@ canbus::Error ESP32Can::send_message(struct canbus::CanFrame *frame) {
|
|||||||
memcpy(message.data, frame->data, frame->can_data_length_code);
|
memcpy(message.data, frame->data, frame->can_data_length_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
|
if (twai_transmit(&message, this->tx_enqueue_timeout_ticks_) == ESP_OK) {
|
||||||
return canbus::ERROR_OK;
|
return canbus::ERROR_OK;
|
||||||
} else {
|
} else {
|
||||||
return canbus::ERROR_ALLTXBUSY;
|
return canbus::ERROR_ALLTXBUSY;
|
||||||
|
@ -14,6 +14,9 @@ class ESP32Can : public canbus::Canbus {
|
|||||||
void set_tx(int tx) { tx_ = tx; }
|
void set_tx(int tx) { tx_ = tx; }
|
||||||
void set_tx_queue_len(uint32_t tx_queue_len) { this->tx_queue_len_ = tx_queue_len; }
|
void set_tx_queue_len(uint32_t tx_queue_len) { this->tx_queue_len_ = tx_queue_len; }
|
||||||
void set_rx_queue_len(uint32_t rx_queue_len) { this->rx_queue_len_ = rx_queue_len; }
|
void set_rx_queue_len(uint32_t rx_queue_len) { this->rx_queue_len_ = rx_queue_len; }
|
||||||
|
void set_tx_enqueue_timeout_ms(uint32_t tx_enqueue_timeout_ms) {
|
||||||
|
this->tx_enqueue_timeout_ticks_ = pdMS_TO_TICKS(tx_enqueue_timeout_ms);
|
||||||
|
}
|
||||||
ESP32Can(){};
|
ESP32Can(){};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -23,6 +26,7 @@ class ESP32Can : public canbus::Canbus {
|
|||||||
|
|
||||||
int rx_{-1};
|
int rx_{-1};
|
||||||
int tx_{-1};
|
int tx_{-1};
|
||||||
|
TickType_t tx_enqueue_timeout_ticks_{};
|
||||||
optional<uint32_t> tx_queue_len_{};
|
optional<uint32_t> tx_queue_len_{};
|
||||||
optional<uint32_t> rx_queue_len_{};
|
optional<uint32_t> rx_queue_len_{};
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user