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_CAN_ID = 'can_id'
|
||||
CONF_SENDER_ID = 'sender_id'
|
||||
CONF_BIT_RATE = 'bit_rate'
|
||||
|
||||
CONF_CANBUS_SEND_ACTION = 'canbus.send'
|
||||
|
||||
|
||||
def validate_raw_data(value):
|
||||
if isinstance(value, text_type):
|
||||
return value.encode('utf-8')
|
||||
@ -34,10 +36,31 @@ CanbusComponent = canbus_ns.class_('CanbusComponent', cg.Component)
|
||||
CanbusTrigger = canbus_ns.class_('CanbusTrigger',
|
||||
automation.Trigger.template(cg.std_string),
|
||||
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({
|
||||
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
||||
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.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
||||
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),
|
||||
})
|
||||
|
||||
|
||||
@coroutine
|
||||
def setup_canbus_core_(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
|
||||
|
||||
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
def to_code(config):
|
||||
cg.add_global(canbus_ns.using)
|
||||
|
@ -3,13 +3,14 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/components/canbus/canbus.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace canbus {
|
||||
|
||||
template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public Parented<Canbus> {
|
||||
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->static_ = false;
|
||||
}
|
||||
@ -18,33 +19,27 @@ template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public P
|
||||
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)
|
||||
|
||||
// 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 {
|
||||
if (this->static_) {
|
||||
this->parent_->write_array(this->data_static_);
|
||||
this->parent_->send_data(this->can_id_, this->data_static_);
|
||||
} else {
|
||||
auto val = this->data_func_(x...);
|
||||
this->parent_->write_array(val);
|
||||
this->parent_->send_data(this->can_id_, val);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
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::vector<uint8_t> data_static_{};
|
||||
};
|
||||
|
||||
|
||||
} // namespace canbus
|
||||
} // 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::send(int can_id, uint8_t *data) {
|
||||
int size = (sizeof data/ sizeof *data);
|
||||
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);
|
||||
};
|
||||
void Canbus::send_data(uint32_t can_id, const std::vector<uint8_t> data) {
|
||||
struct can_frame can_message;
|
||||
|
||||
//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() {
|
||||
// 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 esphome
|
@ -8,24 +8,19 @@
|
||||
namespace esphome {
|
||||
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 {
|
||||
public:
|
||||
explicit CanCall(Canbus *parent, int can_id) : parent_(parent), can_id_(can_id) {}
|
||||
CanCall &set_data(optional<float> data);
|
||||
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;
|
||||
struct can_frame {
|
||||
uint32_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)));
|
||||
};
|
||||
|
||||
class Canbus;
|
||||
|
||||
class Canbus : public Component {
|
||||
friend CanCall;
|
||||
public:
|
||||
/* special address description flags for the CAN_ID */
|
||||
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_EFF_MASK = 0x1FFFFFFFUL; /* extended frame format (EFF) */
|
||||
static const uint32_t CAN_ERR_MASK = 0x1FFFFFFFUL; /* omit EFF, RTR, ERR flags */
|
||||
|
||||
/*
|
||||
* Controller Area Network Identifier structure
|
||||
*
|
||||
@ -44,13 +40,8 @@ class Canbus : public Component {
|
||||
* bit 30 : remote transmission request flag (1 = rtr frame)
|
||||
* 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 */
|
||||
static const uint8_t CAN_MAX_DLC = 8;
|
||||
static const uint8_t CAN_MAX_DLEN = 8;
|
||||
|
||||
enum CAN_SPEED {
|
||||
enum CANSPEED : uint8_t {
|
||||
CAN_5KBPS,
|
||||
CAN_10KBPS,
|
||||
CAN_20KBPS,
|
||||
@ -84,32 +75,30 @@ class Canbus : public Component {
|
||||
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
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; }
|
||||
|
||||
CanCall make_call(int can_id){ return CanCall(this, can_id); }
|
||||
void set_bitrate(uint8_t bit_rate) { this->bit_rate_ = bit_rate; }
|
||||
|
||||
protected:
|
||||
int sender_id_{0};
|
||||
virtual bool send_internal_(int can_id, uint8_t *data);
|
||||
uint32_t sender_id_{0};
|
||||
uint8_t bit_rate_{CAN_125KBPS};
|
||||
|
||||
void dump_frame_(const struct can_frame *data_frame);
|
||||
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 {
|
||||
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 dump_config() override;
|
||||
float get_setup_priority() const override;
|
||||
|
||||
protected:
|
||||
std::string can_id_;
|
||||
optional<std::string> payload_;
|
||||
uint32_t can_id_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace canbus
|
||||
} // namespace esphome
|
@ -6,53 +6,34 @@ namespace 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_TXB2CTRL, MCP_TXB2SIDH, MCP_TXB2DATA}};
|
||||
|
||||
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}};
|
||||
|
||||
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_() {
|
||||
ESP_LOGD(TAG, "setup_internal_()");
|
||||
this->spi_setup();
|
||||
|
||||
if (this->reset_() == ERROR_FAIL)
|
||||
return false;
|
||||
this->set_bitrate_(CAN_125KBPS);
|
||||
this->set_bitrate_(this->bit_rate_);
|
||||
this->set_normal_mode_();
|
||||
ESP_LOGD(TAG, "setup done send test message");
|
||||
struct can_frame canMsg1;
|
||||
canMsg1.can_dlc = 8;
|
||||
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;
|
||||
this->send_message_(&canMsg1);
|
||||
ESP_LOGD(TAG, "setup done send test message");
|
||||
struct canbus::can_frame can_message;
|
||||
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->send_message_(&can_message);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -292,7 +273,7 @@ MCP2515::ERROR MCP2515::set_filter_(const RXF num, const bool ext, const uint32_
|
||||
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];
|
||||
|
||||
uint8_t data[13];
|
||||
@ -309,19 +290,19 @@ MCP2515::ERROR MCP2515::send_message_(const TXBn txbn, const struct can_frame *f
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
MCP2515::ERROR MCP2515::send_message_(const struct can_frame *frame) {
|
||||
ESP_LOGD(TAG, "send_message_: frame.id = %d", frame->can_id);
|
||||
if (frame->can_dlc > CAN_MAX_DLEN) {
|
||||
MCP2515::ERROR MCP2515::send_message_(const struct canbus::can_frame *frame) {
|
||||
//ESP_LOGD(TAG, "send_message_: frame.id = %d", frame->can_id);
|
||||
if (frame->can_dlc > canbus::CAN_MAX_DLEN) {
|
||||
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};
|
||||
|
||||
for (int i = 0; i < N_TXBUFFERS; i++) {
|
||||
const struct TXBn_REGS *txbuf = &TXB[txBuffers[i]];
|
||||
uint8_t ctrlval = read_register_(txbuf->CTRL);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -329,7 +310,7 @@ MCP2515::ERROR MCP2515::send_message_(const struct can_frame *frame) {
|
||||
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];
|
||||
|
||||
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);
|
||||
if (dlc > CAN_MAX_DLEN) {
|
||||
if (dlc > canbus::CAN_MAX_DLEN) {
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
@ -365,7 +346,7 @@ MCP2515::ERROR MCP2515::read_message_(const RXBn rxbn, struct can_frame *frame)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
MCP2515::ERROR MCP2515::read_message_(struct can_frame *frame) {
|
||||
MCP2515::ERROR MCP2515::read_message_(struct canbus::can_frame *frame) {
|
||||
ERROR rc;
|
||||
uint8_t stat = get_status_();
|
||||
|
||||
@ -434,9 +415,9 @@ void MCP2515::clearERRIF() {
|
||||
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_();
|
||||
if (error != ERROR_OK) {
|
||||
return error;
|
||||
@ -444,9 +425,9 @@ MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canCloc
|
||||
|
||||
uint8_t set, cfg1, cfg2, cfg3;
|
||||
set = 1;
|
||||
switch (canClock) {
|
||||
switch (can_clock) {
|
||||
case (MCP_8MHZ):
|
||||
switch (canSpeed) {
|
||||
switch (can_speed) {
|
||||
case (CAN_5KBPS): // 5KBPS
|
||||
cfg1 = MCP_8MHz_5kBPS_CFG1;
|
||||
cfg2 = MCP_8MHz_5kBPS_CFG2;
|
||||
@ -524,7 +505,7 @@ MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canCloc
|
||||
break;
|
||||
|
||||
case (MCP_16MHZ):
|
||||
switch (canSpeed) {
|
||||
switch (can_speed) {
|
||||
case (CAN_5KBPS): // 5Kbps
|
||||
cfg1 = MCP_16MHz_5kBPS_CFG1;
|
||||
cfg2 = MCP_16MHz_5kBPS_CFG2;
|
||||
@ -601,7 +582,7 @@ MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canCloc
|
||||
break;
|
||||
|
||||
case (MCP_20MHZ):
|
||||
switch (canSpeed) {
|
||||
switch (can_speed) {
|
||||
case (CAN_33KBPS): // 33.333Kbps
|
||||
cfg1 = MCP_20MHz_33k3BPS_CFG1;
|
||||
cfg2 = MCP_20MHz_33k3BPS_CFG2;
|
||||
|
@ -7,65 +7,56 @@
|
||||
|
||||
namespace esphome {
|
||||
namespace mcp2515 {
|
||||
static const uint32_t SPI_CLOCK = 10000000; // 10MHz
|
||||
|
||||
static const int N_TXBUFFERS = 3;
|
||||
static const int N_RXBUFFERS = 2;
|
||||
enum CAN_CLOCK { MCP_20MHZ, MCP_16MHZ, MCP_8MHZ };
|
||||
enum MASK { MASK0, MASK1 };
|
||||
enum RXF { RXF0 = 0, RXF1 = 1, RXF2 = 2, RXF3 = 3, RXF4 = 4, RXF5 = 5 };
|
||||
enum RXBn { RXB0 = 0, RXB1 = 1 };
|
||||
enum TXBn { TXB0 = 0, TXB1 = 1, TXB2 = 2 };
|
||||
|
||||
enum CAN_CLKOUT {
|
||||
CLKOUT_DISABLE = -1,
|
||||
CLKOUT_DIV1 = 0x0,
|
||||
CLKOUT_DIV2 = 0x1,
|
||||
CLKOUT_DIV4 = 0x2,
|
||||
CLKOUT_DIV8 = 0x3,
|
||||
};
|
||||
|
||||
enum /*class*/ CANINTF : uint8_t {
|
||||
CANINTF_RX0IF = 0x01,
|
||||
CANINTF_RX1IF = 0x02,
|
||||
CANINTF_TX0IF = 0x04,
|
||||
CANINTF_TX1IF = 0x08,
|
||||
CANINTF_TX2IF = 0x10,
|
||||
CANINTF_ERRIF = 0x20,
|
||||
CANINTF_WAKIF = 0x40,
|
||||
CANINTF_MERRF = 0x80
|
||||
};
|
||||
|
||||
enum /*class*/ EFLG : uint8_t {
|
||||
EFLG_RX1OVR = (1 << 7),
|
||||
EFLG_RX0OVR = (1 << 6),
|
||||
EFLG_TXBO = (1 << 5),
|
||||
EFLG_TXEP = (1 << 4),
|
||||
EFLG_RXEP = (1 << 3),
|
||||
EFLG_TXWAR = (1 << 2),
|
||||
EFLG_RXWAR = (1 << 1),
|
||||
EFLG_EWARN = (1 << 0)
|
||||
};
|
||||
|
||||
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 uint32_t SPI_CLOCK = 10000000; // 10MHz
|
||||
|
||||
static const int N_TXBUFFERS = 3;
|
||||
static const int N_RXBUFFERS = 2;
|
||||
|
||||
enum CAN_CLOCK { MCP_20MHZ, MCP_16MHZ, MCP_8MHZ };
|
||||
enum MASK { MASK0, MASK1 };
|
||||
|
||||
enum RXF { RXF0 = 0, RXF1 = 1, RXF2 = 2, RXF3 = 3, RXF4 = 4, RXF5 = 5 };
|
||||
|
||||
enum RXBn { RXB0 = 0, RXB1 = 1 };
|
||||
|
||||
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 {
|
||||
CLKOUT_DISABLE = -1,
|
||||
CLKOUT_DIV1 = 0x0,
|
||||
CLKOUT_DIV2 = 0x1,
|
||||
CLKOUT_DIV4 = 0x2,
|
||||
CLKOUT_DIV8 = 0x3,
|
||||
};
|
||||
|
||||
enum /*class*/ CANINTF : uint8_t {
|
||||
CANINTF_RX0IF = 0x01,
|
||||
CANINTF_RX1IF = 0x02,
|
||||
CANINTF_TX0IF = 0x04,
|
||||
CANINTF_TX1IF = 0x08,
|
||||
CANINTF_TX2IF = 0x10,
|
||||
CANINTF_ERRIF = 0x20,
|
||||
CANINTF_WAKIF = 0x40,
|
||||
CANINTF_MERRF = 0x80
|
||||
};
|
||||
|
||||
enum /*class*/ EFLG : uint8_t {
|
||||
EFLG_RX1OVR = (1 << 7),
|
||||
EFLG_RX0OVR = (1 << 6),
|
||||
EFLG_TXBO = (1 << 5),
|
||||
EFLG_TXEP = (1 << 4),
|
||||
EFLG_RXEP = (1 << 3),
|
||||
EFLG_TXWAR = (1 << 2),
|
||||
EFLG_RXWAR = (1 << 1),
|
||||
EFLG_EWARN = (1 << 0)
|
||||
};
|
||||
|
||||
enum /*class*/ STAT : uint8_t { STAT_RX0IF = (1 << 0), STAT_RX1IF = (1 << 1) };
|
||||
|
||||
static const struct TXBn_REGS {
|
||||
REGISTER CTRL;
|
||||
REGISTER SIDH;
|
||||
@ -79,11 +70,7 @@ class MCP2515 : public canbus::Canbus,
|
||||
CANINTF CANINTF_RXnIF;
|
||||
} 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:
|
||||
bool send_internal_(int can_id, uint8_t *data) override;
|
||||
bool setup_internal_() override;
|
||||
ERROR set_mode_(const CANCTRL_REQOP_MODE mode);
|
||||
|
||||
@ -101,14 +88,14 @@ class MCP2515 : public canbus::Canbus,
|
||||
ERROR set_loop_back_mode_();
|
||||
ERROR set_normal_mode_();
|
||||
ERROR set_clk_out_(const CAN_CLKOUT divisor);
|
||||
ERROR set_bitrate_(const CAN_SPEED canSpeed) override;
|
||||
ERROR set_bitrate_(const CAN_SPEED canSpeed, const CAN_CLOCK canClock);
|
||||
ERROR set_bitrate_(uint8_t can_speed);
|
||||
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_(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 struct can_frame *frame);
|
||||
ERROR read_message_(const RXBn rxbn, struct can_frame *frame);
|
||||
ERROR read_message_(struct can_frame *frame);
|
||||
ERROR send_message_(const TXBn txbn, const struct canbus::can_frame *frame);
|
||||
ERROR send_message_(const struct canbus::can_frame *frame);
|
||||
ERROR read_message_(const RXBn rxbn, struct canbus::can_frame *frame);
|
||||
ERROR read_message_(struct canbus::can_frame *frame);
|
||||
bool check_receive_(void);
|
||||
bool check_error_(void);
|
||||
uint8_t get_error_flags_(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user