1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-15 07:08:20 +00:00

added mode, clock to mcp2515

This commit is contained in:
mvturnho 2019-08-02 10:15:15 +02:00
parent 12121d0d3f
commit dd31f92c00
4 changed files with 66 additions and 79 deletions

View File

@ -16,46 +16,45 @@ struct can_frame {
uint8_t can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */ uint8_t can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
uint8_t data[CAN_MAX_DLEN] __attribute__((aligned(8))); uint8_t data[CAN_MAX_DLEN] __attribute__((aligned(8)));
}; };
enum CAN_SPEED : uint8_t { enum CAN_SPEED : uint8_t {
CAN_5KBPS, CAN_5KBPS,
CAN_10KBPS, CAN_10KBPS,
CAN_20KBPS, CAN_20KBPS,
CAN_31K25BPS, CAN_31K25BPS,
CAN_33KBPS, CAN_33KBPS,
CAN_40KBPS, CAN_40KBPS,
CAN_50KBPS, CAN_50KBPS,
CAN_80KBPS, CAN_80KBPS,
CAN_83K3BPS, CAN_83K3BPS,
CAN_95KBPS, CAN_95KBPS,
CAN_100KBPS, CAN_100KBPS,
CAN_125KBPS, CAN_125KBPS,
CAN_200KBPS, CAN_200KBPS,
CAN_250KBPS, CAN_250KBPS,
CAN_500KBPS, CAN_500KBPS,
CAN_1000KBPS CAN_1000KBPS
}; };
enum ERROR : uint8_t { enum ERROR : uint8_t {
ERROR_OK = 0, ERROR_OK = 0,
ERROR_FAIL = 1, ERROR_FAIL = 1,
ERROR_ALLTXBUSY = 2, ERROR_ALLTXBUSY = 2,
ERROR_FAILINIT = 3, ERROR_FAILINIT = 3,
ERROR_FAILTX = 4, ERROR_FAILTX = 4,
ERROR_NOMSG = 5 ERROR_NOMSG = 5
}; };
/* 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 */
static const uint32_t CAN_RTR_FLAG = 0x40000000UL; /* remote transmission request */ static const uint32_t CAN_RTR_FLAG = 0x40000000UL; /* remote transmission request */
static const uint32_t CAN_ERR_FLAG = 0x20000000UL; /* error message frame */ static const uint32_t CAN_ERR_FLAG = 0x20000000UL; /* error message frame */
/* valid bits in CAN ID for frame formats */ /* valid bits in CAN ID for frame formats */
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 */
class Canbus : public Component { class Canbus : public Component {
public: public:
Canbus(){}; Canbus(){};
Canbus(const std::string &name){}; Canbus(const std::string &name){};
void setup() override; void setup() override;

View File

@ -2,25 +2,35 @@ import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import spi, canbus from esphome.components import spi, canbus
from esphome.const import CONF_ID from esphome.const import CONF_ID
from esphome.components.canbus import CanbusComponent, CAN_SPEEDS, CONF_BIT_RATE from esphome.components.canbus import CanbusComponent
AUTO_LOAD = ['canbus'] AUTO_LOAD = ['canbus']
DEPENDENCIES = ['spi'] DEPENDENCIES = ['spi']
CONF_MCP_CLOCK = 'clock' CONF_MCP_CLOCK = 'clock'
CONF_MCP_MODE = 'mode'
mcp2515_ns = cg.esphome_ns.namespace('mcp2515') mcp2515_ns = cg.esphome_ns.namespace('mcp2515')
mcp2515 = mcp2515_ns.class_('MCP2515', CanbusComponent, spi.SPIDevice) mcp2515 = mcp2515_ns.class_('MCP2515', CanbusComponent, spi.SPIDevice)
CanClock = mcp2515_ns.enum('CAN_CLOCK') CanClock = mcp2515_ns.enum('CAN_CLOCK')
McpMode = mcp2515_ns.enum('CANCTRL_REQOP_MODE')
CAN_CLOCK = { CAN_CLOCK = {
'20MHZ': CanClock.MCP_20MHZ, '20MHZ': CanClock.MCP_20MHZ,
'16MHZ': CanClock.MCP_16MHZ, '16MHZ': CanClock.MCP_16MHZ,
'8MHZ':CanClock.MCP_8MHZ, '8MHZ': CanClock.MCP_8MHZ,
}
MCP_MODE = {
'NORMAL': McpMode.CANCTRL_REQOP_NORMAL,
'LOOPBACK': McpMode.CANCTRL_REQOP_LOOPBACK,
'LISTENONLY': McpMode.CANCTRL_REQOP_LISTENONLY,
} }
CONFIG_SCHEMA = canbus.CONFIG_SCHEMA.extend({ CONFIG_SCHEMA = canbus.CONFIG_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(mcp2515), cv.GenerateID(): cv.declare_id(mcp2515),
cv.Optional(CONF_MCP_CLOCK, default='8MHZ'): cv.enum(CAN_CLOCK, upper=True), cv.Optional(CONF_MCP_CLOCK, default='8MHZ'): cv.enum(CAN_CLOCK, upper=True),
cv.Optional(CONF_MCP_MODE, default='NORMAL'): cv.enum(MCP_MODE, upper=True),
}).extend(spi.SPI_DEVICE_SCHEMA) }).extend(spi.SPI_DEVICE_SCHEMA)
@ -28,9 +38,11 @@ def to_code(config):
rhs = mcp2515.new() rhs = mcp2515.new()
var = cg.Pvariable(config[CONF_ID], rhs) var = cg.Pvariable(config[CONF_ID], rhs)
yield canbus.register_canbus(var, config) yield canbus.register_canbus(var, config)
# canclock = CAN_CLOCK[config[CONF_MCP_CLOCK]] if CONF_MCP_CLOCK in config:
# bitrate = CAN_SPEEDS[config[CONF_BIT_RATE]] canclock = CAN_CLOCK[config[CONF_MCP_CLOCK]]
# cg.add(var.set_bitrate(bitrate,canclock)) cg.add(var.set_mcp_clock(canclock))
if CONF_MCP_MODE in config:
mode = MCP_MODE[config[CONF_MCP_MODE]]
cg.add(var.set_mcp_mode(mode))
yield spi.register_spi_device(var, config) yield spi.register_spi_device(var, config)

View File

@ -7,8 +7,8 @@ namespace mcp2515 {
static const char *TAG = "mcp2515"; static const char *TAG = "mcp2515";
const struct MCP2515::TXBn_REGS MCP2515::TXB[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}};
@ -19,21 +19,9 @@ bool MCP2515::setup_internal_() {
if (this->reset_() == canbus::ERROR_FAIL) if (this->reset_() == canbus::ERROR_FAIL)
return false; return false;
this->set_bitrate_(this->bit_rate_); this->set_bitrate_(this->bit_rate_, this->mcp_clock_);
this->set_normal_mode_(); this->set_mode_(this->mcp_mode_);
ESP_LOGD(TAG, "setup done send test message"); 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; return true;
} }
@ -140,16 +128,6 @@ uint8_t MCP2515::get_status_(void) {
return i; return i;
} }
canbus::ERROR MCP2515::set_config_mode_() { return set_mode_(CANCTRL_REQOP_CONFIG); }
canbus::ERROR MCP2515::set_listen_only_() { return set_mode_(CANCTRL_REQOP_LISTENONLY); }
canbus::ERROR MCP2515::set_sleep_mode_() { return set_mode_(CANCTRL_REQOP_SLEEP); }
canbus::ERROR MCP2515::set_loop_back_mode_() { return set_mode_(CANCTRL_REQOP_LOOPBACK); }
canbus::ERROR MCP2515::set_normal_mode_() { return set_mode_(CANCTRL_REQOP_NORMAL); }
canbus::ERROR MCP2515::set_mode_(const CANCTRL_REQOP_MODE mode) { canbus::ERROR MCP2515::set_mode_(const CANCTRL_REQOP_MODE mode) {
modify_register_(MCP_CANCTRL, CANCTRL_REQOP, mode); modify_register_(MCP_CANCTRL, CANCTRL_REQOP, mode);
@ -210,7 +188,7 @@ void MCP2515::prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id) {
} }
canbus::ERROR MCP2515::set_filter_mask_(const MASK mask, const bool ext, const uint32_t ulData) { canbus::ERROR MCP2515::set_filter_mask_(const MASK mask, const bool ext, const uint32_t ulData) {
canbus::ERROR res = set_config_mode_(); canbus::ERROR res = set_mode_(CANCTRL_REQOP_CONFIG);
if (res != canbus::ERROR_OK) { if (res != canbus::ERROR_OK) {
return res; return res;
} }
@ -236,7 +214,7 @@ canbus::ERROR MCP2515::set_filter_mask_(const MASK mask, const bool ext, const u
} }
canbus::ERROR MCP2515::set_filter_(const RXF num, const bool ext, const uint32_t ulData) { canbus::ERROR MCP2515::set_filter_(const RXF num, const bool ext, const uint32_t ulData) {
canbus::ERROR res = set_config_mode_(); canbus::ERROR res = set_mode_(CANCTRL_REQOP_CONFIG);
if (res != canbus::ERROR_OK) { if (res != canbus::ERROR_OK) {
return res; return res;
} }
@ -291,18 +269,18 @@ canbus::ERROR MCP2515::send_message_(const TXBn txbn, const struct canbus::can_f
} }
canbus::ERROR MCP2515::send_message_(const struct canbus::can_frame *frame) { canbus::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 > canbus::CAN_MAX_DLEN) { if (frame->can_dlc > canbus::CAN_MAX_DLEN) {
return canbus::ERROR_FAILTX; return canbus::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);
} }
} }
@ -418,7 +396,7 @@ void MCP2515::clearERRIF() {
canbus::ERROR MCP2515::set_bitrate_(canbus::CAN_SPEED can_speed) { return this->set_bitrate_(can_speed, MCP_16MHZ); } canbus::ERROR MCP2515::set_bitrate_(canbus::CAN_SPEED can_speed) { return this->set_bitrate_(can_speed, MCP_16MHZ); }
canbus::ERROR MCP2515::set_bitrate_(canbus::CAN_SPEED can_speed, CAN_CLOCK can_clock) { canbus::ERROR MCP2515::set_bitrate_(canbus::CAN_SPEED can_speed, CAN_CLOCK can_clock) {
canbus::ERROR error = set_config_mode_(); canbus::ERROR error = set_mode_(CANCTRL_REQOP_CONFIG);
if (error != canbus::ERROR_OK) { if (error != canbus::ERROR_OK) {
return error; return error;
} }

View File

@ -57,7 +57,8 @@ class MCP2515 : public canbus::Canbus,
spi::DATA_RATE_8MHZ> { spi::DATA_RATE_8MHZ> {
public: public:
MCP2515(){}; MCP2515(){};
void set_mcp_clock(CAN_CLOCK clock) { this->mcp_clock_ = clock; };
void set_mcp_mode(const CANCTRL_REQOP_MODE mode) { this->mcp_mode_ = mode; }
static const struct TXBn_REGS { static const struct TXBn_REGS {
REGISTER CTRL; REGISTER CTRL;
REGISTER SIDH; REGISTER SIDH;
@ -72,6 +73,8 @@ class MCP2515 : public canbus::Canbus,
} RXB[N_RXBUFFERS]; } RXB[N_RXBUFFERS];
protected: protected:
CAN_CLOCK mcp_clock_{MCP_8MHZ};
CANCTRL_REQOP_MODE mcp_mode_ = CANCTRL_REQOP_NORMAL;
bool setup_internal_() override; bool setup_internal_() override;
canbus::ERROR set_mode_(const CANCTRL_REQOP_MODE mode); canbus::ERROR set_mode_(const CANCTRL_REQOP_MODE mode);
@ -83,11 +86,6 @@ class MCP2515 : public canbus::Canbus,
void prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id); void prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id);
canbus::ERROR reset_(void); canbus::ERROR reset_(void);
canbus::ERROR set_config_mode_();
canbus::ERROR set_listen_only_();
canbus::ERROR set_sleep_mode_();
canbus::ERROR set_loop_back_mode_();
canbus::ERROR set_normal_mode_();
canbus::ERROR set_clk_out_(const CAN_CLKOUT divisor); canbus::ERROR set_clk_out_(const CAN_CLKOUT divisor);
canbus::ERROR set_bitrate_(canbus::CAN_SPEED can_speed); canbus::ERROR set_bitrate_(canbus::CAN_SPEED can_speed);
canbus::ERROR set_bitrate_(canbus::CAN_SPEED can_speed, const CAN_CLOCK can_clock); canbus::ERROR set_bitrate_(canbus::CAN_SPEED can_speed, const CAN_CLOCK can_clock);