mirror of
https://github.com/esphome/esphome.git
synced 2025-03-15 15:18:16 +00:00
automation and send_data
This commit is contained in:
parent
f87043fac0
commit
6ac80483f4
@ -16,9 +16,11 @@ CONF_ON_RECEIVE = 'on_receive'
|
|||||||
CONF_CANBUS_ID = 'canbus_id'
|
CONF_CANBUS_ID = 'canbus_id'
|
||||||
CONF_CAN_ID = 'can_id'
|
CONF_CAN_ID = 'can_id'
|
||||||
CONF_SENDER_ID = 'sender_id'
|
CONF_SENDER_ID = 'sender_id'
|
||||||
|
CONF_BIT_RATE = 'bit_rate'
|
||||||
|
|
||||||
CONF_CANBUS_SEND_ACTION = 'canbus.send'
|
CONF_CANBUS_SEND_ACTION = 'canbus.send'
|
||||||
|
|
||||||
|
|
||||||
def validate_raw_data(value):
|
def validate_raw_data(value):
|
||||||
if isinstance(value, text_type):
|
if isinstance(value, text_type):
|
||||||
return value.encode('utf-8')
|
return value.encode('utf-8')
|
||||||
@ -34,10 +36,31 @@ CanbusComponent = canbus_ns.class_('CanbusComponent', cg.Component)
|
|||||||
CanbusTrigger = canbus_ns.class_('CanbusTrigger',
|
CanbusTrigger = canbus_ns.class_('CanbusTrigger',
|
||||||
automation.Trigger.template(cg.std_string),
|
automation.Trigger.template(cg.std_string),
|
||||||
cg.Component)
|
cg.Component)
|
||||||
|
CanSpeed = canbus_ns.enum('CanSpeed')
|
||||||
|
|
||||||
|
CAN_SPEEDS = {
|
||||||
|
'5KBPS': CanSpeed.CAN_5KBPS,
|
||||||
|
'10KBPS': CanSpeed.CAN_10KBPS,
|
||||||
|
'20KBPS': CanSpeed.CAN_20KBPS,
|
||||||
|
'31K25BPS': CanSpeed.CAN_31K25BPS,
|
||||||
|
'33KBPS': CanSpeed.CAN_33KBPS,
|
||||||
|
'40KBPS': CanSpeed.CAN_40KBPS,
|
||||||
|
'50KBPS': CanSpeed.CAN_50KBPS,
|
||||||
|
'80KBPS': CanSpeed.CAN_80KBPS,
|
||||||
|
'83K3BPS': CanSpeed.CAN_83K3BPS,
|
||||||
|
'95KBPS': CanSpeed.CAN_95KBPS,
|
||||||
|
'100KBPS': CanSpeed.CAN_100KBPS,
|
||||||
|
'125KBPS': CanSpeed.CAN_125KBPS,
|
||||||
|
'200KBPS': CanSpeed.CAN_200KBPS,
|
||||||
|
'250KBPS': CanSpeed.CAN_250KBPS,
|
||||||
|
'500KBPS': CanSpeed.CAN_500KBPS,
|
||||||
|
'1000KBPS': CanSpeed.CAN_1000KBPS,
|
||||||
|
}
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Schema({
|
CONFIG_SCHEMA = cv.Schema({
|
||||||
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
||||||
cv.Required(CONF_SENDER_ID): cv.int_range(min=0, max=255),
|
cv.Required(CONF_SENDER_ID): cv.int_range(min=0, max=255),
|
||||||
|
cv.Optional(CONF_BIT_RATE, default='125KBPS'): cv.enum(CAN_SPEEDS, upper=True),
|
||||||
cv.Optional(CONF_ON_RECEIVE): automation.validate_automation({
|
cv.Optional(CONF_ON_RECEIVE): automation.validate_automation({
|
||||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
||||||
cv.GenerateID(CONF_CAN_ID): cv.int_range(min=1, max=4096),
|
cv.GenerateID(CONF_CAN_ID): cv.int_range(min=1, max=4096),
|
||||||
@ -53,6 +76,7 @@ CANBUS_ACTION_SCHEMA = maybe_simple_id({
|
|||||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def setup_canbus_core_(var, config):
|
def setup_canbus_core_(var, config):
|
||||||
yield cg.register_component(var, config)
|
yield cg.register_component(var, config)
|
||||||
@ -90,7 +114,6 @@ def canbus_action_to_code(config, action_id, template_arg, args):
|
|||||||
yield var
|
yield var
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@coroutine_with_priority(100.0)
|
@coroutine_with_priority(100.0)
|
||||||
def to_code(config):
|
def to_code(config):
|
||||||
cg.add_global(canbus_ns.using)
|
cg.add_global(canbus_ns.using)
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/automation.h"
|
#include "esphome/core/automation.h"
|
||||||
#include "esphome/components/canbus/canbus.h"
|
#include "esphome/components/canbus/canbus.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace canbus {
|
namespace canbus {
|
||||||
|
|
||||||
template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public Parented<Canbus> {
|
template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public Parented<Canbus> {
|
||||||
public:
|
public:
|
||||||
void set_data_template(std::function<std::vector<uint8_t>(Ts...)> func) {
|
void set_data_template(const std::function<std::vector<uint8_t>(Ts...)> func) {
|
||||||
this->data_func_ = func;
|
this->data_func_ = func;
|
||||||
this->static_ = false;
|
this->static_ = false;
|
||||||
}
|
}
|
||||||
@ -18,33 +19,27 @@ template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public P
|
|||||||
this->static_ = true;
|
this->static_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_can_id(int can_id) {this->can_id_ = can_id;}
|
void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
|
||||||
|
|
||||||
TEMPLATABLE_VALUE(float, data)
|
TEMPLATABLE_VALUE(float, data)
|
||||||
|
|
||||||
// void play(Ts... x) override {
|
|
||||||
// auto call = this->parent_->make_call(this->can_id_);
|
|
||||||
// //unsigned uint const * p = reinterpret_cast<unsigned char const *>(&f);
|
|
||||||
// call.set_data(this->data_.optional_value(x...));
|
|
||||||
// // call.perform(this->parent_, this->can_id_);
|
|
||||||
// }
|
|
||||||
void play(Ts... x) override {
|
void play(Ts... x) override {
|
||||||
if (this->static_) {
|
if (this->static_) {
|
||||||
this->parent_->write_array(this->data_static_);
|
this->parent_->send_data(this->can_id_, this->data_static_);
|
||||||
} else {
|
} else {
|
||||||
auto val = this->data_func_(x...);
|
auto val = this->data_func_(x...);
|
||||||
this->parent_->write_array(val);
|
this->parent_->send_data(this->can_id_, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Canbus *parent_;
|
Canbus *parent_;
|
||||||
int can_id_;
|
uint32_t can_id_;
|
||||||
|
|
||||||
bool static_{false};
|
bool static_{false};
|
||||||
std::function<std::vector<uint8_t>(Ts...)> data_func_{};
|
std::function<std::vector<uint8_t>(Ts...)> data_func_{};
|
||||||
std::vector<uint8_t> data_static_{};
|
std::vector<uint8_t> data_static_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace canbus
|
} // namespace canbus
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
@ -16,31 +16,49 @@ void Canbus::setup() {
|
|||||||
|
|
||||||
void Canbus::dump_config() { ESP_LOGCONFIG(TAG, "Canbus: sender_id=%d", this->sender_id_); }
|
void Canbus::dump_config() { ESP_LOGCONFIG(TAG, "Canbus: sender_id=%d", this->sender_id_); }
|
||||||
|
|
||||||
void Canbus::send(int can_id, uint8_t *data) {
|
void Canbus::send_data(uint32_t can_id, const std::vector<uint8_t> data) {
|
||||||
int size = (sizeof data/ sizeof *data);
|
struct can_frame can_message;
|
||||||
ESP_LOGD(TAG, "send: sender_id=%d, can_id=%d, data=%d data_size=%d", this->sender_id_, can_id, data[0],size);
|
|
||||||
//this->send_internal_(can_id, data);
|
//uint8_t size = static_cast<uint8_t>(data.size());
|
||||||
};
|
//ESP_LOGD(TAG, "size=%d", size);
|
||||||
|
// if (size > CAN_MAX_DLC)
|
||||||
|
// size = CAN_MAX_DLC;
|
||||||
|
// can_message.can_dlc = size;
|
||||||
|
// can_message.can_id = this->sender_id_;
|
||||||
|
|
||||||
|
// for (int i = 0; i < size; i++) {
|
||||||
|
// can_message.data[i] = data[i];
|
||||||
|
// ESP_LOGD(TAG, "data[%d] = %02x", i, can_message.data[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
can_message.can_id = this->sender_id_;
|
||||||
|
can_message.can_dlc = 8;
|
||||||
|
can_message.data[0] = 0x00;
|
||||||
|
can_message.data[1] = 0x01;
|
||||||
|
can_message.data[2] = 0x02;
|
||||||
|
can_message.data[3] = 0x03;
|
||||||
|
can_message.data[4] = 0x04;
|
||||||
|
can_message.data[5] = 0x05;
|
||||||
|
can_message.data[6] = 0x06;
|
||||||
|
can_message.data[7] = 0x07;
|
||||||
|
//this->dump_frame_(&can_message);
|
||||||
|
|
||||||
|
this->send_message_(&can_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canbus::dump_frame_(const struct can_frame *data_frame) {
|
||||||
|
//ESP_LOGD(TAG, "dump_frame");
|
||||||
|
//ESP_LOGD(TAG, "canid %d", frame.can_id);
|
||||||
|
//ESP_LOGD(TAG, "can_id %02x", data_frame->can_id);
|
||||||
|
// for (int i = 0; i < 8; i++) {
|
||||||
|
// data_frame->data[i];
|
||||||
|
// }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void Canbus::loop() {
|
void Canbus::loop() {
|
||||||
// check harware inputbuffer and process to esphome outputs
|
// check harware inputbuffer and process to esphome outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
CanCall &CanCall::set_data(optional<float> data) {
|
|
||||||
this->float_data_ = data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
CanCall &CanCall::set_data(float data) {
|
|
||||||
this->float_data_ = data;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanCall::perform() {
|
|
||||||
ESP_LOGD(TAG,"parent_id=%d can_id= %d data=%f",this->parent_->sender_id_,this->can_id_,this->float_data_);
|
|
||||||
uint8_t *p = reinterpret_cast<uint8_t *>(&this->float_data_);
|
|
||||||
//here we start the canbus->send
|
|
||||||
this->parent_->send(this->can_id_,p);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace canbus
|
} // namespace canbus
|
||||||
} // namespace esphome
|
} // namespace esphome
|
@ -8,24 +8,19 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace canbus {
|
namespace canbus {
|
||||||
|
|
||||||
class Canbus;
|
/* CAN payload length and DLC definitions according to ISO 11898-1 */
|
||||||
|
static const uint8_t CAN_MAX_DLC = 8;
|
||||||
|
static const uint8_t CAN_MAX_DLEN = 8;
|
||||||
|
|
||||||
class CanCall {
|
struct can_frame {
|
||||||
public:
|
uint32_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
|
||||||
explicit CanCall(Canbus *parent, int can_id) : parent_(parent), can_id_(can_id) {}
|
uint8_t can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
|
||||||
CanCall &set_data(optional<float> data);
|
uint8_t data[CAN_MAX_DLEN] __attribute__((aligned(8)));
|
||||||
CanCall &set_data(float data);
|
|
||||||
void perform();
|
|
||||||
protected:
|
|
||||||
Canbus *parent_;
|
|
||||||
int can_id_;
|
|
||||||
optional<float> float_data_;
|
|
||||||
optional<bool> bool_data_;
|
|
||||||
optional<long> long_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Canbus;
|
||||||
|
|
||||||
class Canbus : public Component {
|
class Canbus : public Component {
|
||||||
friend CanCall;
|
|
||||||
public:
|
public:
|
||||||
/* special address description flags for the CAN_ID */
|
/* special address description flags for the CAN_ID */
|
||||||
static const uint32_t CAN_EFF_FLAG = 0x80000000UL; /* EFF/SFF is set in the MSB */
|
static const uint32_t CAN_EFF_FLAG = 0x80000000UL; /* EFF/SFF is set in the MSB */
|
||||||
@ -36,6 +31,7 @@ class Canbus : public Component {
|
|||||||
static const uint32_t CAN_SFF_MASK = 0x000007FFUL; /* standard frame format (SFF) */
|
static const uint32_t CAN_SFF_MASK = 0x000007FFUL; /* standard frame format (SFF) */
|
||||||
static const uint32_t CAN_EFF_MASK = 0x1FFFFFFFUL; /* extended frame format (EFF) */
|
static const uint32_t CAN_EFF_MASK = 0x1FFFFFFFUL; /* extended frame format (EFF) */
|
||||||
static const uint32_t CAN_ERR_MASK = 0x1FFFFFFFUL; /* omit EFF, RTR, ERR flags */
|
static const uint32_t CAN_ERR_MASK = 0x1FFFFFFFUL; /* omit EFF, RTR, ERR flags */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Controller Area Network Identifier structure
|
* Controller Area Network Identifier structure
|
||||||
*
|
*
|
||||||
@ -44,13 +40,8 @@ class Canbus : public Component {
|
|||||||
* bit 30 : remote transmission request flag (1 = rtr frame)
|
* bit 30 : remote transmission request flag (1 = rtr frame)
|
||||||
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
|
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
|
||||||
*/
|
*/
|
||||||
typedef uint32_t canid_t;
|
|
||||||
|
|
||||||
/* CAN payload length and DLC definitions according to ISO 11898-1 */
|
enum CANSPEED : uint8_t {
|
||||||
static const uint8_t CAN_MAX_DLC = 8;
|
|
||||||
static const uint8_t CAN_MAX_DLEN = 8;
|
|
||||||
|
|
||||||
enum CAN_SPEED {
|
|
||||||
CAN_5KBPS,
|
CAN_5KBPS,
|
||||||
CAN_10KBPS,
|
CAN_10KBPS,
|
||||||
CAN_20KBPS,
|
CAN_20KBPS,
|
||||||
@ -84,32 +75,30 @@ class Canbus : public Component {
|
|||||||
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
void send(int can_id, uint8_t *data);
|
void send_data(uint32_t can_id, const std::vector<uint8_t> data);
|
||||||
void set_sender_id(int sender_id) { this->sender_id_ = sender_id; }
|
void set_sender_id(int sender_id) { this->sender_id_ = sender_id; }
|
||||||
|
void set_bitrate(uint8_t bit_rate) { this->bit_rate_ = bit_rate; }
|
||||||
CanCall make_call(int can_id){ return CanCall(this, can_id); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int sender_id_{0};
|
uint32_t sender_id_{0};
|
||||||
virtual bool send_internal_(int can_id, uint8_t *data);
|
uint8_t bit_rate_{CAN_125KBPS};
|
||||||
|
|
||||||
|
void dump_frame_(const struct can_frame *data_frame);
|
||||||
virtual bool setup_internal_();
|
virtual bool setup_internal_();
|
||||||
virtual ERROR set_bitrate_(const CAN_SPEED canSpeed);
|
virtual ERROR send_message_(const struct can_frame *frame);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CanbusTrigger : public Trigger<int>, public Component {
|
class CanbusTrigger : public Trigger<int>, public Component {
|
||||||
public:
|
public:
|
||||||
explicit CanbusTrigger(const int &can_id);
|
explicit CanbusTrigger(const uint32_t &can_id);
|
||||||
|
|
||||||
void set_payload(const std::string &payload);
|
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string can_id_;
|
uint32_t can_id_;
|
||||||
optional<std::string> payload_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace canbus
|
} // namespace canbus
|
||||||
} // namespace esphome
|
} // namespace esphome
|
@ -6,53 +6,34 @@ namespace mcp2515 {
|
|||||||
|
|
||||||
static const char *TAG = "mcp2515";
|
static const char *TAG = "mcp2515";
|
||||||
|
|
||||||
const struct MCP2515::TXBn_REGS MCP2515::TXB[MCP2515::N_TXBUFFERS] = {{MCP_TXB0CTRL, MCP_TXB0SIDH, MCP_TXB0DATA},
|
const struct MCP2515::TXBn_REGS MCP2515::TXB[N_TXBUFFERS] = {{MCP_TXB0CTRL, MCP_TXB0SIDH, MCP_TXB0DATA},
|
||||||
{MCP_TXB1CTRL, MCP_TXB1SIDH, MCP_TXB1DATA},
|
{MCP_TXB1CTRL, MCP_TXB1SIDH, MCP_TXB1DATA},
|
||||||
{MCP_TXB2CTRL, MCP_TXB2SIDH, MCP_TXB2DATA}};
|
{MCP_TXB2CTRL, MCP_TXB2SIDH, MCP_TXB2DATA}};
|
||||||
|
|
||||||
const struct MCP2515::RXBn_REGS MCP2515::RXB[N_RXBUFFERS] = {{MCP_RXB0CTRL, MCP_RXB0SIDH, MCP_RXB0DATA, CANINTF_RX0IF},
|
const struct MCP2515::RXBn_REGS MCP2515::RXB[N_RXBUFFERS] = {{MCP_RXB0CTRL, MCP_RXB0SIDH, MCP_RXB0DATA, CANINTF_RX0IF},
|
||||||
{MCP_RXB1CTRL, MCP_RXB1SIDH, MCP_RXB1DATA, CANINTF_RX1IF}};
|
{MCP_RXB1CTRL, MCP_RXB1SIDH, MCP_RXB1DATA, CANINTF_RX1IF}};
|
||||||
|
|
||||||
bool MCP2515::send_internal_(int can_id, uint8_t *data) {
|
|
||||||
struct can_frame canMsg1;
|
|
||||||
canMsg1.can_id = can_id;
|
|
||||||
canMsg1.can_dlc = CAN_MAX_DLEN;
|
|
||||||
canMsg1.data[0] = 0x8E;
|
|
||||||
canMsg1.data[1] = 0x87;
|
|
||||||
canMsg1.data[2] = 0x32;
|
|
||||||
canMsg1.data[3] = 0xFA;
|
|
||||||
canMsg1.data[4] = 0x26;
|
|
||||||
canMsg1.data[5] = 0x8E;
|
|
||||||
canMsg1.data[6] = 0xBE;
|
|
||||||
canMsg1.data[7] = 0x86;
|
|
||||||
if (this->send_message_(&canMsg1) == ERROR_FAILTX) {
|
|
||||||
ESP_LOGE(TAG, "transmit error %d", can_id);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool MCP2515::setup_internal_() {
|
bool MCP2515::setup_internal_() {
|
||||||
ESP_LOGD(TAG, "setup_internal_()");
|
ESP_LOGD(TAG, "setup_internal_()");
|
||||||
this->spi_setup();
|
this->spi_setup();
|
||||||
|
|
||||||
if (this->reset_() == ERROR_FAIL)
|
if (this->reset_() == ERROR_FAIL)
|
||||||
return false;
|
return false;
|
||||||
this->set_bitrate_(CAN_125KBPS);
|
this->set_bitrate_(this->bit_rate_);
|
||||||
this->set_normal_mode_();
|
this->set_normal_mode_();
|
||||||
ESP_LOGD(TAG, "setup done send test message");
|
ESP_LOGD(TAG, "setup done send test message");
|
||||||
struct can_frame canMsg1;
|
struct canbus::can_frame can_message;
|
||||||
canMsg1.can_dlc = 8;
|
can_message.can_id = this->sender_id_;
|
||||||
canMsg1.data[0] = 0x8E;
|
can_message.can_dlc = 8;
|
||||||
canMsg1.data[1] = 0x87;
|
can_message.data[0] = 0x00;
|
||||||
canMsg1.data[2] = 0x32;
|
can_message.data[1] = 0x01;
|
||||||
canMsg1.data[3] = 0xFA;
|
can_message.data[2] = 0x02;
|
||||||
canMsg1.data[4] = 0x26;
|
can_message.data[3] = 0x03;
|
||||||
canMsg1.data[5] = 0x8E;
|
can_message.data[4] = 0x04;
|
||||||
canMsg1.data[6] = 0xBE;
|
can_message.data[5] = 0x05;
|
||||||
canMsg1.data[7] = 0x86;
|
can_message.data[6] = 0x06;
|
||||||
this->send_message_(&canMsg1);
|
can_message.data[7] = 0x07;
|
||||||
|
this->send_message_(&can_message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +273,7 @@ MCP2515::ERROR MCP2515::set_filter_(const RXF num, const bool ext, const uint32_
|
|||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCP2515::ERROR MCP2515::send_message_(const TXBn txbn, const struct can_frame *frame) {
|
MCP2515::ERROR MCP2515::send_message_(const TXBn txbn, const struct canbus::can_frame *frame) {
|
||||||
const struct TXBn_REGS *txbuf = &TXB[txbn];
|
const struct TXBn_REGS *txbuf = &TXB[txbn];
|
||||||
|
|
||||||
uint8_t data[13];
|
uint8_t data[13];
|
||||||
@ -309,19 +290,19 @@ MCP2515::ERROR MCP2515::send_message_(const TXBn txbn, const struct can_frame *f
|
|||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCP2515::ERROR MCP2515::send_message_(const struct can_frame *frame) {
|
MCP2515::ERROR MCP2515::send_message_(const struct canbus::can_frame *frame) {
|
||||||
ESP_LOGD(TAG, "send_message_: frame.id = %d", frame->can_id);
|
//ESP_LOGD(TAG, "send_message_: frame.id = %d", frame->can_id);
|
||||||
if (frame->can_dlc > CAN_MAX_DLEN) {
|
if (frame->can_dlc > canbus::CAN_MAX_DLEN) {
|
||||||
return ERROR_FAILTX;
|
return ERROR_FAILTX;
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "send_message_: size = %d is OK", frame->can_dlc);
|
//ESP_LOGD(TAG, "send_message_: size = %d is OK", frame->can_dlc);
|
||||||
TXBn txBuffers[N_TXBUFFERS] = {TXB0, TXB1, TXB2};
|
TXBn txBuffers[N_TXBUFFERS] = {TXB0, TXB1, TXB2};
|
||||||
|
|
||||||
for (int i = 0; i < N_TXBUFFERS; i++) {
|
for (int i = 0; i < N_TXBUFFERS; i++) {
|
||||||
const struct TXBn_REGS *txbuf = &TXB[txBuffers[i]];
|
const struct TXBn_REGS *txbuf = &TXB[txBuffers[i]];
|
||||||
uint8_t ctrlval = read_register_(txbuf->CTRL);
|
uint8_t ctrlval = read_register_(txbuf->CTRL);
|
||||||
if ((ctrlval & TXB_TXREQ) == 0) {
|
if ((ctrlval & TXB_TXREQ) == 0) {
|
||||||
ESP_LOGD(TAG, "send buffer: %d, ctrl_val = %d", i, ctrlval);
|
// ESP_LOGD(TAG, "send buffer: %d, ctrl_val = %d", i, ctrlval);
|
||||||
return send_message_(txBuffers[i], frame);
|
return send_message_(txBuffers[i], frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +310,7 @@ MCP2515::ERROR MCP2515::send_message_(const struct can_frame *frame) {
|
|||||||
return ERROR_FAILTX;
|
return ERROR_FAILTX;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCP2515::ERROR MCP2515::read_message_(const RXBn rxbn, struct can_frame *frame) {
|
MCP2515::ERROR MCP2515::read_message_(const RXBn rxbn, struct canbus::can_frame *frame) {
|
||||||
const struct RXBn_REGS *rxb = &RXB[rxbn];
|
const struct RXBn_REGS *rxb = &RXB[rxbn];
|
||||||
|
|
||||||
uint8_t tbufdata[5];
|
uint8_t tbufdata[5];
|
||||||
@ -346,7 +327,7 @@ MCP2515::ERROR MCP2515::read_message_(const RXBn rxbn, struct can_frame *frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t dlc = (tbufdata[MCP_DLC] & DLC_MASK);
|
uint8_t dlc = (tbufdata[MCP_DLC] & DLC_MASK);
|
||||||
if (dlc > CAN_MAX_DLEN) {
|
if (dlc > canbus::CAN_MAX_DLEN) {
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +346,7 @@ MCP2515::ERROR MCP2515::read_message_(const RXBn rxbn, struct can_frame *frame)
|
|||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCP2515::ERROR MCP2515::read_message_(struct can_frame *frame) {
|
MCP2515::ERROR MCP2515::read_message_(struct canbus::can_frame *frame) {
|
||||||
ERROR rc;
|
ERROR rc;
|
||||||
uint8_t stat = get_status_();
|
uint8_t stat = get_status_();
|
||||||
|
|
||||||
@ -434,9 +415,9 @@ void MCP2515::clearERRIF() {
|
|||||||
modify_register_(MCP_CANINTF, CANINTF_ERRIF, 0);
|
modify_register_(MCP_CANINTF, CANINTF_ERRIF, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed) { return set_bitrate_(canSpeed, MCP_16MHZ); }
|
MCP2515::ERROR MCP2515::set_bitrate_(uint8_t can_speed) { return this->set_bitrate_(can_speed, MCP_16MHZ); }
|
||||||
|
|
||||||
MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canClock) {
|
MCP2515::ERROR MCP2515::set_bitrate_(uint8_t can_speed, CAN_CLOCK can_clock) {
|
||||||
ERROR error = set_config_mode_();
|
ERROR error = set_config_mode_();
|
||||||
if (error != ERROR_OK) {
|
if (error != ERROR_OK) {
|
||||||
return error;
|
return error;
|
||||||
@ -444,9 +425,9 @@ MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canCloc
|
|||||||
|
|
||||||
uint8_t set, cfg1, cfg2, cfg3;
|
uint8_t set, cfg1, cfg2, cfg3;
|
||||||
set = 1;
|
set = 1;
|
||||||
switch (canClock) {
|
switch (can_clock) {
|
||||||
case (MCP_8MHZ):
|
case (MCP_8MHZ):
|
||||||
switch (canSpeed) {
|
switch (can_speed) {
|
||||||
case (CAN_5KBPS): // 5KBPS
|
case (CAN_5KBPS): // 5KBPS
|
||||||
cfg1 = MCP_8MHz_5kBPS_CFG1;
|
cfg1 = MCP_8MHz_5kBPS_CFG1;
|
||||||
cfg2 = MCP_8MHz_5kBPS_CFG2;
|
cfg2 = MCP_8MHz_5kBPS_CFG2;
|
||||||
@ -524,7 +505,7 @@ MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canCloc
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case (MCP_16MHZ):
|
case (MCP_16MHZ):
|
||||||
switch (canSpeed) {
|
switch (can_speed) {
|
||||||
case (CAN_5KBPS): // 5Kbps
|
case (CAN_5KBPS): // 5Kbps
|
||||||
cfg1 = MCP_16MHz_5kBPS_CFG1;
|
cfg1 = MCP_16MHz_5kBPS_CFG1;
|
||||||
cfg2 = MCP_16MHz_5kBPS_CFG2;
|
cfg2 = MCP_16MHz_5kBPS_CFG2;
|
||||||
@ -601,7 +582,7 @@ MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canCloc
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case (MCP_20MHZ):
|
case (MCP_20MHZ):
|
||||||
switch (canSpeed) {
|
switch (can_speed) {
|
||||||
case (CAN_33KBPS): // 33.333Kbps
|
case (CAN_33KBPS): // 33.333Kbps
|
||||||
cfg1 = MCP_20MHz_33k3BPS_CFG1;
|
cfg1 = MCP_20MHz_33k3BPS_CFG1;
|
||||||
cfg2 = MCP_20MHz_33k3BPS_CFG2;
|
cfg2 = MCP_20MHz_33k3BPS_CFG2;
|
||||||
|
@ -7,33 +7,16 @@
|
|||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace mcp2515 {
|
namespace mcp2515 {
|
||||||
|
|
||||||
class MCP2515 : public canbus::Canbus,
|
|
||||||
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
|
|
||||||
spi::DATA_RATE_8MHZ> {
|
|
||||||
public:
|
|
||||||
MCP2515(){};
|
|
||||||
|
|
||||||
static const uint32_t SPI_CLOCK = 10000000; // 10MHz
|
static const uint32_t SPI_CLOCK = 10000000; // 10MHz
|
||||||
|
|
||||||
static const int N_TXBUFFERS = 3;
|
static const int N_TXBUFFERS = 3;
|
||||||
static const int N_RXBUFFERS = 2;
|
static const int N_RXBUFFERS = 2;
|
||||||
|
|
||||||
enum CAN_CLOCK { MCP_20MHZ, MCP_16MHZ, MCP_8MHZ };
|
enum CAN_CLOCK { MCP_20MHZ, MCP_16MHZ, MCP_8MHZ };
|
||||||
enum MASK { MASK0, MASK1 };
|
enum MASK { MASK0, MASK1 };
|
||||||
|
|
||||||
enum RXF { RXF0 = 0, RXF1 = 1, RXF2 = 2, RXF3 = 3, RXF4 = 4, RXF5 = 5 };
|
enum RXF { RXF0 = 0, RXF1 = 1, RXF2 = 2, RXF3 = 3, RXF4 = 4, RXF5 = 5 };
|
||||||
|
|
||||||
enum RXBn { RXB0 = 0, RXB1 = 1 };
|
enum RXBn { RXB0 = 0, RXB1 = 1 };
|
||||||
|
|
||||||
enum TXBn { TXB0 = 0, TXB1 = 1, TXB2 = 2 };
|
enum TXBn { TXB0 = 0, TXB1 = 1, TXB2 = 2 };
|
||||||
|
|
||||||
struct can_frame {
|
|
||||||
canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
|
|
||||||
uint8_t can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
|
|
||||||
uint8_t data[CAN_MAX_DLEN] __attribute__((aligned(8)));
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CAN_CLKOUT {
|
enum CAN_CLKOUT {
|
||||||
CLKOUT_DISABLE = -1,
|
CLKOUT_DISABLE = -1,
|
||||||
CLKOUT_DIV1 = 0x0,
|
CLKOUT_DIV1 = 0x0,
|
||||||
@ -66,6 +49,14 @@ class MCP2515 : public canbus::Canbus,
|
|||||||
|
|
||||||
enum /*class*/ STAT : uint8_t { STAT_RX0IF = (1 << 0), STAT_RX1IF = (1 << 1) };
|
enum /*class*/ STAT : uint8_t { STAT_RX0IF = (1 << 0), STAT_RX1IF = (1 << 1) };
|
||||||
|
|
||||||
|
static const uint8_t STAT_RXIF_MASK = STAT_RX0IF | STAT_RX1IF;
|
||||||
|
static const uint8_t EFLG_ERRORMASK = EFLG_RX1OVR | EFLG_RX0OVR | EFLG_TXBO | EFLG_TXEP | EFLG_RXEP;
|
||||||
|
class MCP2515 : public canbus::Canbus,
|
||||||
|
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
|
||||||
|
spi::DATA_RATE_8MHZ> {
|
||||||
|
public:
|
||||||
|
MCP2515(){};
|
||||||
|
|
||||||
static const struct TXBn_REGS {
|
static const struct TXBn_REGS {
|
||||||
REGISTER CTRL;
|
REGISTER CTRL;
|
||||||
REGISTER SIDH;
|
REGISTER SIDH;
|
||||||
@ -79,11 +70,7 @@ class MCP2515 : public canbus::Canbus,
|
|||||||
CANINTF CANINTF_RXnIF;
|
CANINTF CANINTF_RXnIF;
|
||||||
} RXB[N_RXBUFFERS];
|
} RXB[N_RXBUFFERS];
|
||||||
|
|
||||||
static const uint8_t STAT_RXIF_MASK = STAT_RX0IF | STAT_RX1IF;
|
|
||||||
static const uint8_t EFLG_ERRORMASK = EFLG_RX1OVR | EFLG_RX0OVR | EFLG_TXBO | EFLG_TXEP | EFLG_RXEP;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool send_internal_(int can_id, uint8_t *data) override;
|
|
||||||
bool setup_internal_() override;
|
bool setup_internal_() override;
|
||||||
ERROR set_mode_(const CANCTRL_REQOP_MODE mode);
|
ERROR set_mode_(const CANCTRL_REQOP_MODE mode);
|
||||||
|
|
||||||
@ -101,14 +88,14 @@ class MCP2515 : public canbus::Canbus,
|
|||||||
ERROR set_loop_back_mode_();
|
ERROR set_loop_back_mode_();
|
||||||
ERROR set_normal_mode_();
|
ERROR set_normal_mode_();
|
||||||
ERROR set_clk_out_(const CAN_CLKOUT divisor);
|
ERROR set_clk_out_(const CAN_CLKOUT divisor);
|
||||||
ERROR set_bitrate_(const CAN_SPEED canSpeed) override;
|
ERROR set_bitrate_(uint8_t can_speed);
|
||||||
ERROR set_bitrate_(const CAN_SPEED canSpeed, const CAN_CLOCK canClock);
|
ERROR set_bitrate_(uint8_t can_speed, const CAN_CLOCK can_clock);
|
||||||
ERROR set_filter_mask_(const MASK num, const bool ext, const uint32_t ulData);
|
ERROR set_filter_mask_(const MASK num, const bool ext, const uint32_t ulData);
|
||||||
ERROR set_filter_(const RXF num, const bool ext, const uint32_t ulData);
|
ERROR set_filter_(const RXF num, const bool ext, const uint32_t ulData);
|
||||||
ERROR send_message_(const TXBn txbn, const struct can_frame *frame);
|
ERROR send_message_(const TXBn txbn, const struct canbus::can_frame *frame);
|
||||||
ERROR send_message_(const struct can_frame *frame);
|
ERROR send_message_(const struct canbus::can_frame *frame);
|
||||||
ERROR read_message_(const RXBn rxbn, struct can_frame *frame);
|
ERROR read_message_(const RXBn rxbn, struct canbus::can_frame *frame);
|
||||||
ERROR read_message_(struct can_frame *frame);
|
ERROR read_message_(struct canbus::can_frame *frame);
|
||||||
bool check_receive_(void);
|
bool check_receive_(void);
|
||||||
bool check_error_(void);
|
bool check_error_(void);
|
||||||
uint8_t get_error_flags_(void);
|
uint8_t get_error_flags_(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user