1
0
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:
mvturnho 2019-07-31 22:04:21 +02:00
parent f87043fac0
commit 6ac80483f4
6 changed files with 170 additions and 177 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);