diff --git a/esphome/components/canbus/canbus.cpp b/esphome/components/canbus/canbus.cpp index 2f0db425f8..b6f1f19548 100644 --- a/esphome/components/canbus/canbus.cpp +++ b/esphome/components/canbus/canbus.cpp @@ -6,7 +6,13 @@ namespace canbus { static const char *TAG = "canbus"; -void Canbus::setup() { ESP_LOGCONFIG(TAG, "Setting up Canbus..."); } +void Canbus::setup() { + ESP_LOGCONFIG(TAG, "Setting up Canbus..."); + if (!this->setup_internal_()) { + ESP_LOGE(TAG, "Canbus setup error!"); + this->mark_failed(); + } +} void Canbus::dump_config() { ESP_LOGCONFIG(TAG, "Canbus: sender_id=%d", this->sender_id_); } @@ -16,7 +22,7 @@ void Canbus::send(int can_id, uint8_t *data) { }; void Canbus::loop() { - //check harware inputbuffer and process to esphome outputs + // check harware inputbuffer and process to esphome outputs } } // namespace canbus diff --git a/esphome/components/canbus/canbus.h b/esphome/components/canbus/canbus.h index 4e520cb316..bb10f287d5 100644 --- a/esphome/components/canbus/canbus.h +++ b/esphome/components/canbus/canbus.h @@ -21,17 +21,30 @@ class CanbusBinarySensor : public CanbusSensor, public binary_sensor::BinarySens class Canbus : public Component { public: - Canbus(){}; - Canbus(const std::string &name){}; - void setup() override; - void dump_config() override; - float get_setup_priority() const override { return setup_priority::HARDWARE; } - void loop() override; + /* 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_RTR_FLAG = 0x40000000UL; /* remote transmission request */ + static const uint32_t CAN_ERR_FLAG = 0x20000000UL; /* error message frame */ - void send(int can_id, uint8_t *data); - void register_can_device(CanbusSensor *component){}; - void set_sender_id(int sender_id) { this->sender_id_ = sender_id; } - enum CAN_SPEED { + /* 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_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 + * + * bit 0-28 : CAN identifier (11/29 bit) + * bit 29 : error message frame flag (0 = data frame, 1 = error message) + * 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 { CAN_5KBPS, CAN_10KBPS, CAN_20KBPS, @@ -48,15 +61,27 @@ class Canbus : public Component { CAN_250KBPS, CAN_500KBPS, CAN_1000KBPS -}; - enum ERROR : uint8_t { - ERROR_OK = 0, - ERROR_FAIL = 1, - ERROR_ALLTXBUSY = 2, - ERROR_FAILINIT = 3, - ERROR_FAILTX = 4, - ERROR_NOMSG = 5 - }; + }; + enum ERROR : uint8_t { + ERROR_OK = 0, + ERROR_FAIL = 1, + ERROR_ALLTXBUSY = 2, + ERROR_FAILINIT = 3, + ERROR_FAILTX = 4, + ERROR_NOMSG = 5 + }; + + Canbus(){}; + Canbus(const std::string &name){}; + void setup() override; + void dump_config() override; + float get_setup_priority() const override { return setup_priority::HARDWARE; } + void loop() override; + + void send(int can_id, uint8_t *data); + void register_can_device(CanbusSensor *component){}; + void set_sender_id(int sender_id) { this->sender_id_ = sender_id; } + protected: int sender_id_{0}; virtual bool send_internal_(int can_id, uint8_t *data); diff --git a/esphome/components/mcp2515/canbus.py b/esphome/components/mcp2515/canbus.py index 03dee9c66f..754550ff41 100644 --- a/esphome/components/mcp2515/canbus.py +++ b/esphome/components/mcp2515/canbus.py @@ -1,9 +1,8 @@ import esphome.codegen as cg import esphome.config_validation as cv -from esphome import pins from esphome.components import spi, canbus -from esphome.const import CONF_CS_PIN, CONF_ID -from esphome.components.canbus import CanbusComponent, CONF_CAN_ID +from esphome.const import CONF_ID +from esphome.components.canbus import CanbusComponent print("mcp2515.canbus.py") AUTO_LOAD = ['canbus'] @@ -14,7 +13,6 @@ mcp2515 = mcp2515_ns.class_('MCP2515', CanbusComponent, spi.SPIDevice) CONFIG_SCHEMA = canbus.CONFIG_SCHEMA.extend({ cv.GenerateID(): cv.declare_id(mcp2515), - cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, }).extend(spi.SPI_DEVICE_SCHEMA) diff --git a/esphome/components/mcp2515/mcp2515.cpp b/esphome/components/mcp2515/mcp2515.cpp index acb5ab1882..c949e3a900 100644 --- a/esphome/components/mcp2515/mcp2515.cpp +++ b/esphome/components/mcp2515/mcp2515.cpp @@ -6,680 +6,676 @@ namespace mcp2515 { static const char *TAG = "mcp2515"; -bool MCP2515::send_internal_(int can_id, uint8_t *data) { return true; }; +const struct MCP2515::TXBn_REGS MCP2515::TXB[MCP2515::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_() { - this->reset_(); + ESP_LOGD(TAG, "setup_internal_()"); + this->spi_setup(); + + if (this->reset_() == ERROR_FAIL) + return false; + this->set_bitrate_(CAN_125KBPS); + 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); return true; } MCP2515::ERROR MCP2515::reset_(void) { - this->enable(); - this->transfer_byte(INSTRUCTION_RESET); - this->disable(); + this->enable(); + this->transfer_byte(INSTRUCTION_RESET); + this->disable(); + ESP_LOGD(TAG, "reset_()"); + delay(10); - delay(10); + ESP_LOGD(TAG, "reset() CLEAR ALL TXB registers"); - uint8_t zeros[14]; - memset(zeros, 0, sizeof(zeros)); - set_registers_(MCP_TXB0CTRL, zeros, 14); - set_registers_(MCP_TXB1CTRL, zeros, 14); - set_registers_(MCP_TXB2CTRL, zeros, 14); + uint8_t zeros[14]; + memset(zeros, 0, sizeof(zeros)); + set_registers_(MCP_TXB0CTRL, zeros, 14); + set_registers_(MCP_TXB1CTRL, zeros, 14); + set_registers_(MCP_TXB2CTRL, zeros, 14); + ESP_LOGD(TAG, "reset() CLEARED TXB registers"); - set_register_(MCP_RXB0CTRL, 0); - set_register_(MCP_RXB1CTRL, 0); + set_register_(MCP_RXB0CTRL, 0); + set_register_(MCP_RXB1CTRL, 0); - set_register_(MCP_CANINTE, CANINTF_RX0IF | CANINTF_RX1IF | CANINTF_ERRIF | CANINTF_MERRF); + set_register_(MCP_CANINTE, CANINTF_RX0IF | CANINTF_RX1IF | CANINTF_ERRIF | CANINTF_MERRF); - modify_register_(MCP_RXB0CTRL, - RXBnCTRL_RXM_MASK | RXB0CTRL_BUKT, - RXBnCTRL_RXM_STDEXT | RXB0CTRL_BUKT); - modify_register_(MCP_RXB1CTRL, RXBnCTRL_RXM_MASK, RXBnCTRL_RXM_STDEXT); + modify_register_(MCP_RXB0CTRL, RXBnCTRL_RXM_MASK | RXB0CTRL_BUKT, RXBnCTRL_RXM_STDEXT | RXB0CTRL_BUKT); + modify_register_(MCP_RXB1CTRL, RXBnCTRL_RXM_MASK, RXBnCTRL_RXM_STDEXT); - // clear filters and masks - /*RXF filters[] = {RXF0, RXF1, RXF2, RXF3, RXF4, RXF5}; - for (int i=0; i<6; i++) { - ERROR result = set_filter_(filters[i], true, 0); - if (result != ERROR_OK) { - return result; - } + // clear filters and masks + /*RXF filters[] = {RXF0, RXF1, RXF2, RXF3, RXF4, RXF5}; + for (int i=0; i<6; i++) { + ERROR result = set_filter_(filters[i], true, 0); + if (result != ERROR_OK) { + return result; + } + } + + MASK masks[] = {MASK0, MASK1}; + for (int i=0; i<2; i++) { + ERROR result = set_filter_mask_(masks[i], true, 0); + if (result != ERROR_OK) { + return result; + } + }*/ + + return ERROR_OK; +} + +uint8_t MCP2515::read_register_(const REGISTER reg) { + this->enable(); + this->transfer_byte(INSTRUCTION_READ); + this->transfer_byte(reg); + uint8_t ret = this->transfer_byte(0x00); + this->disable(); + + return ret; +} + +void MCP2515::read_registers_(const REGISTER reg, uint8_t values[], const uint8_t n) { + this->enable(); + this->transfer_byte(INSTRUCTION_READ); + this->transfer_byte(reg); + // this->transfer_array(values, n); + // mcp2515 has auto - increment of address - pointer + for (uint8_t i = 0; i < n; i++) { + values[i] = this->transfer_byte(0x00); + } + this->disable(); +} + +void MCP2515::set_register_(const REGISTER reg, const uint8_t value) { + this->enable(); + this->transfer_byte(INSTRUCTION_WRITE); + this->transfer_byte(reg); + this->transfer_byte(value); + this->disable(); +} + +void MCP2515::set_registers_(const REGISTER reg, uint8_t values[], const uint8_t n) { + this->enable(); + this->transfer_byte(INSTRUCTION_WRITE); + this->transfer_byte(reg); + // this->transfer_array(values, n); + for (uint8_t i = 0; i < n; i++) { + this->transfer_byte(values[i]); + } + this->disable(); +} + +void MCP2515::modify_register_(const REGISTER reg, const uint8_t mask, const uint8_t data) { + this->enable(); + this->transfer_byte(INSTRUCTION_BITMOD); + this->transfer_byte(reg); + this->transfer_byte(mask); + this->transfer_byte(data); + this->disable(); +} + +uint8_t MCP2515::get_status_(void) { + this->enable(); + this->transfer_byte(INSTRUCTION_READ_STATUS); + uint8_t i = this->transfer_byte(0x00); + this->disable(); + + return i; +} + +MCP2515::ERROR MCP2515::set_config_mode_() { return set_mode_(CANCTRL_REQOP_CONFIG); } + +MCP2515::ERROR MCP2515::set_listen_only_() { return set_mode_(CANCTRL_REQOP_LISTENONLY); } + +MCP2515::ERROR MCP2515::set_sleep_mode_() { return set_mode_(CANCTRL_REQOP_SLEEP); } + +MCP2515::ERROR MCP2515::set_loop_back_mode_() { return set_mode_(CANCTRL_REQOP_LOOPBACK); } + +MCP2515::ERROR MCP2515::set_normal_mode_() { return set_mode_(CANCTRL_REQOP_NORMAL); } + +MCP2515::ERROR MCP2515::set_mode_(const CANCTRL_REQOP_MODE mode) { + modify_register_(MCP_CANCTRL, CANCTRL_REQOP, mode); + + unsigned long endTime = millis() + 10; + bool modeMatch = false; + while (millis() < endTime) { + uint8_t newmode = read_register_(MCP_CANSTAT); + newmode &= CANSTAT_OPMOD; + modeMatch = newmode == mode; + if (modeMatch) { + break; } + } + return modeMatch ? ERROR_OK : ERROR_FAIL; +} - MASK masks[] = {MASK0, MASK1}; - for (int i=0; i<2; i++) { - ERROR result = set_filter_mask_(masks[i], true, 0); - if (result != ERROR_OK) { - return result; - } - }*/ +MCP2515::ERROR MCP2515::set_clk_out_(const CAN_CLKOUT divisor) { + ERROR res; + uint8_t cfg3; + if (divisor == CLKOUT_DISABLE) { + /* Turn off CLKEN */ + modify_register_(MCP_CANCTRL, CANCTRL_CLKEN, 0x00); + + /* Turn on CLKOUT for SOF */ + modify_register_(MCP_CNF3, CNF3_SOF, CNF3_SOF); return ERROR_OK; + } + + /* Set the prescaler (CLKPRE) */ + modify_register_(MCP_CANCTRL, CANCTRL_CLKPRE, divisor); + + /* Turn on CLKEN */ + modify_register_(MCP_CANCTRL, CANCTRL_CLKEN, CANCTRL_CLKEN); + + /* Turn off CLKOUT for SOF */ + modify_register_(MCP_CNF3, CNF3_SOF, 0x00); + return ERROR_OK; } -uint8_t MCP2515::read_register_(const REGISTER reg) -{ - this->enable(); - this->transfer_byte(INSTRUCTION_READ); - this->transfer_byte(reg); - uint8_t ret = this->transfer_byte(0x00); - this->disable(); +void MCP2515::prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id) { + uint16_t canid = (uint16_t)(id & 0x0FFFF); - return ret; + if (ext) { + buffer[MCP_EID0] = (uint8_t)(canid & 0xFF); + buffer[MCP_EID8] = (uint8_t)(canid >> 8); + canid = (uint16_t)(id >> 16); + buffer[MCP_SIDL] = (uint8_t)(canid & 0x03); + buffer[MCP_SIDL] += (uint8_t)((canid & 0x1C) << 3); + buffer[MCP_SIDL] |= TXB_EXIDE_MASK; + buffer[MCP_SIDH] = (uint8_t)(canid >> 5); + } else { + buffer[MCP_SIDH] = (uint8_t)(canid >> 3); + buffer[MCP_SIDL] = (uint8_t)((canid & 0x07) << 5); + buffer[MCP_EID0] = 0; + buffer[MCP_EID8] = 0; + } } -void MCP2515::read_registers_(const REGISTER reg, uint8_t values[], const uint8_t n) -{ - this->enable(); - this->transfer_byte(INSTRUCTION_READ); - this->transfer_byte(reg); - this->transfer_array(values,n); - // mcp2515 has auto-increment of address-pointer - // for (uint8_t i=0; itransfer_byte(0x00); - // } - this->disable(); +MCP2515::ERROR MCP2515::set_filter_mask_(const MASK mask, const bool ext, const uint32_t ulData) { + ERROR res = set_config_mode_(); + if (res != ERROR_OK) { + return res; + } + + uint8_t tbufdata[4]; + prepare_id_(tbufdata, ext, ulData); + + REGISTER reg; + switch (mask) { + case MASK0: + reg = MCP_RXM0SIDH; + break; + case MASK1: + reg = MCP_RXM1SIDH; + break; + default: + return ERROR_FAIL; + } + + set_registers_(reg, tbufdata, 4); + + return ERROR_OK; } -void MCP2515::set_register_(const REGISTER reg, const uint8_t value) -{ - this->enable(); - this->transfer_byte(INSTRUCTION_WRITE); - this->transfer_byte(reg); - this->transfer_byte(value); - this->disable(); +MCP2515::ERROR MCP2515::set_filter_(const RXF num, const bool ext, const uint32_t ulData) { + ERROR res = set_config_mode_(); + if (res != ERROR_OK) { + return res; + } + + REGISTER reg; + + switch (num) { + case RXF0: + reg = MCP_RXF0SIDH; + break; + case RXF1: + reg = MCP_RXF1SIDH; + break; + case RXF2: + reg = MCP_RXF2SIDH; + break; + case RXF3: + reg = MCP_RXF3SIDH; + break; + case RXF4: + reg = MCP_RXF4SIDH; + break; + case RXF5: + reg = MCP_RXF5SIDH; + break; + default: + return ERROR_FAIL; + } + + uint8_t tbufdata[4]; + prepare_id_(tbufdata, ext, ulData); + set_registers_(reg, tbufdata, 4); + + return ERROR_OK; } -void MCP2515::set_registers_(const REGISTER reg, uint8_t values[], const uint8_t n) -{ - this->enable(); - this->transfer_byte(INSTRUCTION_WRITE); - this->transfer_byte(reg); - this->transfer_array(values,n); - // for (uint8_t i=0; itransfer_byte(values[i]); - // } - this->disable(); +MCP2515::ERROR MCP2515::send_message_(const TXBn txbn, const struct can_frame *frame) { + const struct TXBn_REGS *txbuf = &TXB[txbn]; + + uint8_t data[13]; + + bool ext = (frame->can_id & CAN_EFF_FLAG); + bool rtr = (frame->can_id & CAN_RTR_FLAG); + uint32_t id = (frame->can_id & (ext ? CAN_EFF_MASK : CAN_SFF_MASK)); + prepare_id_(data, ext, id); + data[MCP_DLC] = rtr ? (frame->can_dlc | RTR_MASK) : frame->can_dlc; + memcpy(&data[MCP_DATA], frame->data, frame->can_dlc); + set_registers_(txbuf->SIDH, data, 5 + frame->can_dlc); + modify_register_(txbuf->CTRL, TXB_TXREQ, TXB_TXREQ); + + return ERROR_OK; } -void MCP2515::modify_register_(const REGISTER reg, const uint8_t mask, const uint8_t data) -{ - this->enable(); - this->transfer_byte(INSTRUCTION_BITMOD); - this->transfer_byte(reg); - this->transfer_byte(mask); - this->transfer_byte(data); - this->disable(); -} - -uint8_t MCP2515::get_status_(void) -{ - this->enable(); - this->transfer_byte(INSTRUCTION_READ_STATUS); - uint8_t i = this->transfer_byte(0x00); - this->disable(); - - return i; -} - -MCP2515::ERROR MCP2515::set_config_mode_() -{ - return set_mode_(CANCTRL_REQOP_CONFIG); -} - -MCP2515::ERROR MCP2515::set_listen_only_() -{ - return set_mode_(CANCTRL_REQOP_LISTENONLY); -} - -MCP2515::ERROR MCP2515::set_sleep_mode_() -{ - return set_mode_(CANCTRL_REQOP_SLEEP); -} - -MCP2515::ERROR MCP2515::set_loop_back_mode_() -{ - return set_mode_(CANCTRL_REQOP_LOOPBACK); -} - -MCP2515::ERROR MCP2515::set_normal_mode_() -{ - return set_mode_(CANCTRL_REQOP_NORMAL); -} - -MCP2515::ERROR MCP2515::set_mode_(const CANCTRL_REQOP_MODE mode) -{ - modify_register_(MCP_CANCTRL, CANCTRL_REQOP, mode); - - unsigned long endTime = millis() + 10; - bool modeMatch = false; - while (millis() < endTime) { - uint8_t newmode = read_register_(MCP_CANSTAT); - newmode &= CANSTAT_OPMOD; - modeMatch = newmode == mode; - if (modeMatch) { - break; - } - } - return modeMatch ? ERROR_OK : ERROR_FAIL; -} - -MCP2515::ERROR MCP2515::set_clk_out_(const CAN_CLKOUT divisor) -{ - ERROR res; - uint8_t cfg3; - - if (divisor == CLKOUT_DISABLE) { - /* Turn off CLKEN */ - modify_register_(MCP_CANCTRL, CANCTRL_CLKEN, 0x00); - - /* Turn on CLKOUT for SOF */ - modify_register_(MCP_CNF3, CNF3_SOF, CNF3_SOF); - return ERROR_OK; - } - - /* Set the prescaler (CLKPRE) */ - modify_register_(MCP_CANCTRL, CANCTRL_CLKPRE, divisor); - - /* Turn on CLKEN */ - modify_register_(MCP_CANCTRL, CANCTRL_CLKEN, CANCTRL_CLKEN); - - /* Turn off CLKOUT for SOF */ - modify_register_(MCP_CNF3, CNF3_SOF, 0x00); - return ERROR_OK; -} - -void MCP2515::prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id) -{ - uint16_t canid = (uint16_t)(id & 0x0FFFF); - - if (ext) { - buffer[MCP_EID0] = (uint8_t) (canid & 0xFF); - buffer[MCP_EID8] = (uint8_t) (canid >> 8); - canid = (uint16_t)(id >> 16); - buffer[MCP_SIDL] = (uint8_t) (canid & 0x03); - buffer[MCP_SIDL] += (uint8_t) ((canid & 0x1C) << 3); - buffer[MCP_SIDL] |= TXB_EXIDE_MASK; - buffer[MCP_SIDH] = (uint8_t) (canid >> 5); - } else { - buffer[MCP_SIDH] = (uint8_t) (canid >> 3); - buffer[MCP_SIDL] = (uint8_t) ((canid & 0x07 ) << 5); - buffer[MCP_EID0] = 0; - buffer[MCP_EID8] = 0; - } -} - -MCP2515::ERROR MCP2515::set_filter_mask_(const MASK mask, const bool ext, const uint32_t ulData) -{ - ERROR res = set_config_mode_(); - if (res != ERROR_OK) { - return res; - } - - uint8_t tbufdata[4]; - prepare_id_(tbufdata, ext, ulData); - - REGISTER reg; - switch (mask) { - case MASK0: reg = MCP_RXM0SIDH; break; - case MASK1: reg = MCP_RXM1SIDH; break; - default: - return ERROR_FAIL; - } - - set_registers_(reg, tbufdata, 4); - - return ERROR_OK; -} - -MCP2515::ERROR MCP2515::set_filter_(const RXF num, const bool ext, const uint32_t ulData) -{ - ERROR res = set_config_mode_(); - if (res != ERROR_OK) { - return res; - } - - REGISTER reg; - - switch (num) { - case RXF0: reg = MCP_RXF0SIDH; break; - case RXF1: reg = MCP_RXF1SIDH; break; - case RXF2: reg = MCP_RXF2SIDH; break; - case RXF3: reg = MCP_RXF3SIDH; break; - case RXF4: reg = MCP_RXF4SIDH; break; - case RXF5: reg = MCP_RXF5SIDH; break; - default: - return ERROR_FAIL; - } - - uint8_t tbufdata[4]; - prepare_id_(tbufdata, ext, ulData); - set_registers_(reg, tbufdata, 4); - - return ERROR_OK; -} - -MCP2515::ERROR MCP2515::send_message_(const TXBn txbn, const struct can_frame *frame) -{ - const struct TXBn_REGS *txbuf = &TXB[txbn]; - - uint8_t data[13]; - - bool ext = (frame->can_id & CAN_EFF_FLAG); - bool rtr = (frame->can_id & CAN_RTR_FLAG); - uint32_t id = (frame->can_id & (ext ? CAN_EFF_MASK : CAN_SFF_MASK)); - - prepare_id_(data, ext, id); - - data[MCP_DLC] = rtr ? (frame->can_dlc | RTR_MASK) : frame->can_dlc; - - memcpy(&data[MCP_DATA], frame->data, frame->can_dlc); - - set_registers_(txbuf->SIDH, data, 5 + frame->can_dlc); - - modify_register_(txbuf->CTRL, TXB_TXREQ, TXB_TXREQ); - - return ERROR_OK; -} - -MCP2515::ERROR MCP2515::send_message_(const struct can_frame *frame) -{ - if (frame->can_dlc > CAN_MAX_DLEN) { - return ERROR_FAILTX; - } - - TXBn txBuffers[N_TXBUFFERS] = {TXB0, TXB1, TXB2}; - - for (int i=0; iCTRL); - if ( (ctrlval & TXB_TXREQ) == 0 ) { - return send_message_(txBuffers[i], frame); - } - } - +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) { return ERROR_FAILTX; -} + } + ESP_LOGD(TAG, "send_message_: size = %d is OK", frame->can_dlc); + TXBn txBuffers[N_TXBUFFERS] = {TXB0, TXB1, TXB2}; -MCP2515::ERROR MCP2515::readMessage(const RXBn rxbn, struct can_frame *frame) -{ - const struct RXBn_REGS *rxb = &RXB[rxbn]; - - uint8_t tbufdata[5]; - - read_registers_(rxb->SIDH, tbufdata, 5); - - uint32_t id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5); - - if ( (tbufdata[MCP_SIDL] & TXB_EXIDE_MASK) == TXB_EXIDE_MASK ) { - id = (id<<2) + (tbufdata[MCP_SIDL] & 0x03); - id = (id<<8) + tbufdata[MCP_EID8]; - id = (id<<8) + tbufdata[MCP_EID0]; - id |= CAN_EFF_FLAG; + 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); + return send_message_(txBuffers[i], frame); } + } - uint8_t dlc = (tbufdata[MCP_DLC] & DLC_MASK); - if (dlc > CAN_MAX_DLEN) { - return ERROR_FAIL; - } - - uint8_t ctrl = read_register_(rxb->CTRL); - if (ctrl & RXBnCTRL_RTR) { - id |= CAN_RTR_FLAG; - } - - frame->can_id = id; - frame->can_dlc = dlc; - - read_registers_(rxb->DATA, frame->data, dlc); - - modify_register_(MCP_CANINTF, rxb->CANINTF_RXnIF, 0); - - return ERROR_OK; + return ERROR_FAILTX; } -MCP2515::ERROR MCP2515::readMessage(struct can_frame *frame) -{ - ERROR rc; - uint8_t stat = get_status_(); +MCP2515::ERROR MCP2515::read_message_(const RXBn rxbn, struct can_frame *frame) { + const struct RXBn_REGS *rxb = &RXB[rxbn]; - if ( stat & STAT_RX0IF ) { - rc = readMessage(RXB0, frame); - } else if ( stat & STAT_RX1IF ) { - rc = readMessage(RXB1, frame); - } else { - rc = ERROR_NOMSG; - } + uint8_t tbufdata[5]; - return rc; + read_registers_(rxb->SIDH, tbufdata, 5); + + uint32_t id = (tbufdata[MCP_SIDH] << 3) + (tbufdata[MCP_SIDL] >> 5); + + if ((tbufdata[MCP_SIDL] & TXB_EXIDE_MASK) == TXB_EXIDE_MASK) { + id = (id << 2) + (tbufdata[MCP_SIDL] & 0x03); + id = (id << 8) + tbufdata[MCP_EID8]; + id = (id << 8) + tbufdata[MCP_EID0]; + id |= CAN_EFF_FLAG; + } + + uint8_t dlc = (tbufdata[MCP_DLC] & DLC_MASK); + if (dlc > CAN_MAX_DLEN) { + return ERROR_FAIL; + } + + uint8_t ctrl = read_register_(rxb->CTRL); + if (ctrl & RXBnCTRL_RTR) { + id |= CAN_RTR_FLAG; + } + + frame->can_id = id; + frame->can_dlc = dlc; + + read_registers_(rxb->DATA, frame->data, dlc); + + modify_register_(MCP_CANINTF, rxb->CANINTF_RXnIF, 0); + + return ERROR_OK; } -bool MCP2515::check_receive_(void) -{ - uint8_t res = get_status_(); - if ( res & STAT_RXIF_MASK ) { - return true; - } else { - return false; - } +MCP2515::ERROR MCP2515::read_message_(struct can_frame *frame) { + ERROR rc; + uint8_t stat = get_status_(); + + if (stat & STAT_RX0IF) { + rc = read_message_(RXB0, frame); + } else if (stat & STAT_RX1IF) { + rc = read_message_(RXB1, frame); + } else { + rc = ERROR_NOMSG; + } + + return rc; } -bool MCP2515::check_error_(void) -{ - uint8_t eflg = get_error_flags_(); - - if ( eflg & EFLG_ERRORMASK ) { - return true; - } else { - return false; - } +bool MCP2515::check_receive_(void) { + uint8_t res = get_status_(); + if (res & STAT_RXIF_MASK) { + return true; + } else { + return false; + } } -uint8_t MCP2515::get_error_flags_(void) -{ - return read_register_(MCP_EFLG); +bool MCP2515::check_error_(void) { + uint8_t eflg = get_error_flags_(); + + if (eflg & EFLG_ERRORMASK) { + return true; + } else { + return false; + } } -void MCP2515::clearRXnOVRFlags(void) -{ - modify_register_(MCP_EFLG, EFLG_RX0OVR | EFLG_RX1OVR, 0); +uint8_t MCP2515::get_error_flags_(void) { return read_register_(MCP_EFLG); } + +void MCP2515::clearRXnOVRFlags(void) { modify_register_(MCP_EFLG, EFLG_RX0OVR | EFLG_RX1OVR, 0); } + +uint8_t MCP2515::getInterrupts(void) { return read_register_(MCP_CANINTF); } + +void MCP2515::clearInterrupts(void) { set_register_(MCP_CANINTF, 0); } + +uint8_t MCP2515::getInterruptMask(void) { return read_register_(MCP_CANINTE); } + +void MCP2515::clearTXInterrupts(void) { + modify_register_(MCP_CANINTF, (CANINTF_TX0IF | CANINTF_TX1IF | CANINTF_TX2IF), 0); } -uint8_t MCP2515::getInterrupts(void) -{ - return read_register_(MCP_CANINTF); +void MCP2515::clearRXnOVR(void) { + uint8_t eflg = get_error_flags_(); + if (eflg != 0) { + clearRXnOVRFlags(); + clearInterrupts(); + // modify_register_(MCP_CANINTF, CANINTF_ERRIF, 0); + } } -void MCP2515::clearInterrupts(void) -{ - set_register_(MCP_CANINTF, 0); +void MCP2515::clearMERR() { + // modify_register_(MCP_EFLG, EFLG_RX0OVR | EFLG_RX1OVR, 0); + // clearInterrupts(); + modify_register_(MCP_CANINTF, CANINTF_MERRF, 0); } -uint8_t MCP2515::getInterruptMask(void) -{ - return read_register_(MCP_CANINTE); +void MCP2515::clearERRIF() { + // modify_register_(MCP_EFLG, EFLG_RX0OVR | EFLG_RX1OVR, 0); + // clearInterrupts(); + modify_register_(MCP_CANINTF, CANINTF_ERRIF, 0); } -void MCP2515::clearTXInterrupts(void) -{ - modify_register_(MCP_CANINTF, (CANINTF_TX0IF | CANINTF_TX1IF | CANINTF_TX2IF), 0); -} +MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed) { return set_bitrate_(canSpeed, MCP_16MHZ); } -void MCP2515::clearRXnOVR(void) -{ - uint8_t eflg = get_error_flags_(); - if (eflg != 0) { - clearRXnOVRFlags(); - clearInterrupts(); - //modify_register_(MCP_CANINTF, CANINTF_ERRIF, 0); - } - -} - -void MCP2515::clearMERR() -{ - //modify_register_(MCP_EFLG, EFLG_RX0OVR | EFLG_RX1OVR, 0); - //clearInterrupts(); - modify_register_(MCP_CANINTF, CANINTF_MERRF, 0); -} - -void MCP2515::clearERRIF() -{ - //modify_register_(MCP_EFLG, EFLG_RX0OVR | EFLG_RX1OVR, 0); - //clearInterrupts(); - 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_(const CAN_SPEED canSpeed, CAN_CLOCK canClock) -{ - ERROR error = set_config_mode_(); - if (error != ERROR_OK) { - return error; - } - - uint8_t set, cfg1, cfg2, cfg3; - set = 1; - switch (canClock) - { - case (MCP_8MHZ): - switch (canSpeed) - { - case (CAN_5KBPS): // 5KBPS - cfg1 = MCP_8MHz_5kBPS_CFG1; - cfg2 = MCP_8MHz_5kBPS_CFG2; - cfg3 = MCP_8MHz_5kBPS_CFG3; - break; - case (CAN_10KBPS): // 10KBPS - cfg1 = MCP_8MHz_10kBPS_CFG1; - cfg2 = MCP_8MHz_10kBPS_CFG2; - cfg3 = MCP_8MHz_10kBPS_CFG3; - break; - case (CAN_20KBPS): // 20KBPS - cfg1 = MCP_8MHz_20kBPS_CFG1; - cfg2 = MCP_8MHz_20kBPS_CFG2; - cfg3 = MCP_8MHz_20kBPS_CFG3; - break; - case (CAN_31K25BPS): // 31.25KBPS - cfg1 = MCP_8MHz_31k25BPS_CFG1; - cfg2 = MCP_8MHz_31k25BPS_CFG2; - cfg3 = MCP_8MHz_31k25BPS_CFG3; - break; - case (CAN_33KBPS): // 33.333KBPS - cfg1 = MCP_8MHz_33k3BPS_CFG1; - cfg2 = MCP_8MHz_33k3BPS_CFG2; - cfg3 = MCP_8MHz_33k3BPS_CFG3; - break; - case (CAN_40KBPS): // 40Kbps - cfg1 = MCP_8MHz_40kBPS_CFG1; - cfg2 = MCP_8MHz_40kBPS_CFG2; - cfg3 = MCP_8MHz_40kBPS_CFG3; - break; - case (CAN_50KBPS): // 50Kbps - cfg1 = MCP_8MHz_50kBPS_CFG1; - cfg2 = MCP_8MHz_50kBPS_CFG2; - cfg3 = MCP_8MHz_50kBPS_CFG3; - break; - case (CAN_80KBPS): // 80Kbps - cfg1 = MCP_8MHz_80kBPS_CFG1; - cfg2 = MCP_8MHz_80kBPS_CFG2; - cfg3 = MCP_8MHz_80kBPS_CFG3; - break; - case (CAN_100KBPS): // 100Kbps - cfg1 = MCP_8MHz_100kBPS_CFG1; - cfg2 = MCP_8MHz_100kBPS_CFG2; - cfg3 = MCP_8MHz_100kBPS_CFG3; - break; - case (CAN_125KBPS): // 125Kbps - cfg1 = MCP_8MHz_125kBPS_CFG1; - cfg2 = MCP_8MHz_125kBPS_CFG2; - cfg3 = MCP_8MHz_125kBPS_CFG3; - break; - case (CAN_200KBPS): // 200Kbps - cfg1 = MCP_8MHz_200kBPS_CFG1; - cfg2 = MCP_8MHz_200kBPS_CFG2; - cfg3 = MCP_8MHz_200kBPS_CFG3; - break; - case (CAN_250KBPS): // 250Kbps - cfg1 = MCP_8MHz_250kBPS_CFG1; - cfg2 = MCP_8MHz_250kBPS_CFG2; - cfg3 = MCP_8MHz_250kBPS_CFG3; - break; - case (CAN_500KBPS): // 500Kbps - cfg1 = MCP_8MHz_500kBPS_CFG1; - cfg2 = MCP_8MHz_500kBPS_CFG2; - cfg3 = MCP_8MHz_500kBPS_CFG3; - break; - case (CAN_1000KBPS): // 1Mbps - cfg1 = MCP_8MHz_1000kBPS_CFG1; - cfg2 = MCP_8MHz_1000kBPS_CFG2; - cfg3 = MCP_8MHz_1000kBPS_CFG3; - break; - default: - set = 0; - break; - } - break; - - case (MCP_16MHZ): - switch (canSpeed) - { - case (CAN_5KBPS): // 5Kbps - cfg1 = MCP_16MHz_5kBPS_CFG1; - cfg2 = MCP_16MHz_5kBPS_CFG2; - cfg3 = MCP_16MHz_5kBPS_CFG3; - break; - case (CAN_10KBPS): // 10Kbps - cfg1 = MCP_16MHz_10kBPS_CFG1; - cfg2 = MCP_16MHz_10kBPS_CFG2; - cfg3 = MCP_16MHz_10kBPS_CFG3; - break; - case (CAN_20KBPS): // 20Kbps - cfg1 = MCP_16MHz_20kBPS_CFG1; - cfg2 = MCP_16MHz_20kBPS_CFG2; - cfg3 = MCP_16MHz_20kBPS_CFG3; - break; - case (CAN_33KBPS): // 33.333Kbps - cfg1 = MCP_16MHz_33k3BPS_CFG1; - cfg2 = MCP_16MHz_33k3BPS_CFG2; - cfg3 = MCP_16MHz_33k3BPS_CFG3; - break; - case (CAN_40KBPS): // 40Kbps - cfg1 = MCP_16MHz_40kBPS_CFG1; - cfg2 = MCP_16MHz_40kBPS_CFG2; - cfg3 = MCP_16MHz_40kBPS_CFG3; - break; - case (CAN_50KBPS): // 50Kbps - cfg2 = MCP_16MHz_50kBPS_CFG2; - cfg3 = MCP_16MHz_50kBPS_CFG3; - break; - case (CAN_80KBPS): // 80Kbps - cfg1 = MCP_16MHz_80kBPS_CFG1; - cfg2 = MCP_16MHz_80kBPS_CFG2; - cfg3 = MCP_16MHz_80kBPS_CFG3; - break; - case (CAN_83K3BPS): // 83.333Kbps - cfg1 = MCP_16MHz_83k3BPS_CFG1; - cfg2 = MCP_16MHz_83k3BPS_CFG2; - cfg3 = MCP_16MHz_83k3BPS_CFG3; - break; - case (CAN_100KBPS): // 100Kbps - cfg1 = MCP_16MHz_100kBPS_CFG1; - cfg2 = MCP_16MHz_100kBPS_CFG2; - cfg3 = MCP_16MHz_100kBPS_CFG3; - break; - case (CAN_125KBPS): // 125Kbps - cfg1 = MCP_16MHz_125kBPS_CFG1; - cfg2 = MCP_16MHz_125kBPS_CFG2; - cfg3 = MCP_16MHz_125kBPS_CFG3; - break; - case (CAN_200KBPS): // 200Kbps - cfg1 = MCP_16MHz_200kBPS_CFG1; - cfg2 = MCP_16MHz_200kBPS_CFG2; - cfg3 = MCP_16MHz_200kBPS_CFG3; - break; - case (CAN_250KBPS): // 250Kbps - cfg1 = MCP_16MHz_250kBPS_CFG1; - cfg2 = MCP_16MHz_250kBPS_CFG2; - cfg3 = MCP_16MHz_250kBPS_CFG3; - break; - case (CAN_500KBPS): // 500Kbps - cfg1 = MCP_16MHz_500kBPS_CFG1; - cfg2 = MCP_16MHz_500kBPS_CFG2; - cfg3 = MCP_16MHz_500kBPS_CFG3; - break; - case (CAN_1000KBPS): // 1Mbps - cfg1 = MCP_16MHz_1000kBPS_CFG1; - cfg2 = MCP_16MHz_1000kBPS_CFG2; - cfg3 = MCP_16MHz_1000kBPS_CFG3; - break; - default: - set = 0; - break; - } - break; - - case (MCP_20MHZ): - switch (canSpeed) - { - case (CAN_33KBPS): // 33.333Kbps - cfg1 = MCP_20MHz_33k3BPS_CFG1; - cfg2 = MCP_20MHz_33k3BPS_CFG2; - cfg3 = MCP_20MHz_33k3BPS_CFG3; - break; - case (CAN_40KBPS): // 40Kbps - cfg1 = MCP_20MHz_40kBPS_CFG1; - cfg2 = MCP_20MHz_40kBPS_CFG2; - cfg3 = MCP_20MHz_40kBPS_CFG3; - break; - case (CAN_50KBPS): // 50Kbps - cfg1 = MCP_20MHz_50kBPS_CFG1; - cfg2 = MCP_20MHz_50kBPS_CFG2; - cfg3 = MCP_20MHz_50kBPS_CFG3; - break; - case (CAN_80KBPS): // 80Kbps - cfg1 = MCP_20MHz_80kBPS_CFG1; - cfg2 = MCP_20MHz_80kBPS_CFG2; - cfg3 = MCP_20MHz_80kBPS_CFG3; - break; - case (CAN_83K3BPS): // 83.333Kbps - cfg1 = MCP_20MHz_83k3BPS_CFG1; - cfg2 = MCP_20MHz_83k3BPS_CFG2; - cfg3 = MCP_20MHz_83k3BPS_CFG3; - break; - case (CAN_100KBPS): // 100Kbps - cfg1 = MCP_20MHz_100kBPS_CFG1; - cfg2 = MCP_20MHz_100kBPS_CFG2; - cfg3 = MCP_20MHz_100kBPS_CFG3; - break; - case (CAN_125KBPS): // 125Kbps - cfg1 = MCP_20MHz_125kBPS_CFG1; - cfg2 = MCP_20MHz_125kBPS_CFG2; - cfg3 = MCP_20MHz_125kBPS_CFG3; - break; - case (CAN_200KBPS): // 200Kbps - cfg1 = MCP_20MHz_200kBPS_CFG1; - cfg2 = MCP_20MHz_200kBPS_CFG2; - cfg3 = MCP_20MHz_200kBPS_CFG3; - break; - case (CAN_250KBPS): // 250Kbps - cfg1 = MCP_20MHz_250kBPS_CFG1; - cfg2 = MCP_20MHz_250kBPS_CFG2; - cfg3 = MCP_20MHz_250kBPS_CFG3; - break; - case (CAN_500KBPS): // 500Kbps - cfg1 = MCP_20MHz_500kBPS_CFG1; - cfg2 = MCP_20MHz_500kBPS_CFG2; - cfg3 = MCP_20MHz_500kBPS_CFG3; - break; - case (CAN_1000KBPS): // 1Mbps - cfg1 = MCP_20MHz_1000kBPS_CFG1; - cfg2 = MCP_20MHz_1000kBPS_CFG2; - cfg3 = MCP_20MHz_1000kBPS_CFG3; - break; - default: - set = 0; - break; - } - break; +MCP2515::ERROR MCP2515::set_bitrate_(const CAN_SPEED canSpeed, CAN_CLOCK canClock) { + ERROR error = set_config_mode_(); + if (error != ERROR_OK) { + return error; + } + uint8_t set, cfg1, cfg2, cfg3; + set = 1; + switch (canClock) { + case (MCP_8MHZ): + switch (canSpeed) { + case (CAN_5KBPS): // 5KBPS + cfg1 = MCP_8MHz_5kBPS_CFG1; + cfg2 = MCP_8MHz_5kBPS_CFG2; + cfg3 = MCP_8MHz_5kBPS_CFG3; + break; + case (CAN_10KBPS): // 10KBPS + cfg1 = MCP_8MHz_10kBPS_CFG1; + cfg2 = MCP_8MHz_10kBPS_CFG2; + cfg3 = MCP_8MHz_10kBPS_CFG3; + break; + case (CAN_20KBPS): // 20KBPS + cfg1 = MCP_8MHz_20kBPS_CFG1; + cfg2 = MCP_8MHz_20kBPS_CFG2; + cfg3 = MCP_8MHz_20kBPS_CFG3; + break; + case (CAN_31K25BPS): // 31.25KBPS + cfg1 = MCP_8MHz_31k25BPS_CFG1; + cfg2 = MCP_8MHz_31k25BPS_CFG2; + cfg3 = MCP_8MHz_31k25BPS_CFG3; + break; + case (CAN_33KBPS): // 33.333KBPS + cfg1 = MCP_8MHz_33k3BPS_CFG1; + cfg2 = MCP_8MHz_33k3BPS_CFG2; + cfg3 = MCP_8MHz_33k3BPS_CFG3; + break; + case (CAN_40KBPS): // 40Kbps + cfg1 = MCP_8MHz_40kBPS_CFG1; + cfg2 = MCP_8MHz_40kBPS_CFG2; + cfg3 = MCP_8MHz_40kBPS_CFG3; + break; + case (CAN_50KBPS): // 50Kbps + cfg1 = MCP_8MHz_50kBPS_CFG1; + cfg2 = MCP_8MHz_50kBPS_CFG2; + cfg3 = MCP_8MHz_50kBPS_CFG3; + break; + case (CAN_80KBPS): // 80Kbps + cfg1 = MCP_8MHz_80kBPS_CFG1; + cfg2 = MCP_8MHz_80kBPS_CFG2; + cfg3 = MCP_8MHz_80kBPS_CFG3; + break; + case (CAN_100KBPS): // 100Kbps + cfg1 = MCP_8MHz_100kBPS_CFG1; + cfg2 = MCP_8MHz_100kBPS_CFG2; + cfg3 = MCP_8MHz_100kBPS_CFG3; + break; + case (CAN_125KBPS): // 125Kbps + cfg1 = MCP_8MHz_125kBPS_CFG1; + cfg2 = MCP_8MHz_125kBPS_CFG2; + cfg3 = MCP_8MHz_125kBPS_CFG3; + break; + case (CAN_200KBPS): // 200Kbps + cfg1 = MCP_8MHz_200kBPS_CFG1; + cfg2 = MCP_8MHz_200kBPS_CFG2; + cfg3 = MCP_8MHz_200kBPS_CFG3; + break; + case (CAN_250KBPS): // 250Kbps + cfg1 = MCP_8MHz_250kBPS_CFG1; + cfg2 = MCP_8MHz_250kBPS_CFG2; + cfg3 = MCP_8MHz_250kBPS_CFG3; + break; + case (CAN_500KBPS): // 500Kbps + cfg1 = MCP_8MHz_500kBPS_CFG1; + cfg2 = MCP_8MHz_500kBPS_CFG2; + cfg3 = MCP_8MHz_500kBPS_CFG3; + break; + case (CAN_1000KBPS): // 1Mbps + cfg1 = MCP_8MHz_1000kBPS_CFG1; + cfg2 = MCP_8MHz_1000kBPS_CFG2; + cfg3 = MCP_8MHz_1000kBPS_CFG3; + break; default: - set = 0; - break; - } + set = 0; + break; + } + break; - if (set) { - set_register_(MCP_CNF1, cfg1); - set_register_(MCP_CNF2, cfg2); - set_register_(MCP_CNF3, cfg3); - return ERROR_OK; - } - else { - return ERROR_FAIL; - } + case (MCP_16MHZ): + switch (canSpeed) { + case (CAN_5KBPS): // 5Kbps + cfg1 = MCP_16MHz_5kBPS_CFG1; + cfg2 = MCP_16MHz_5kBPS_CFG2; + cfg3 = MCP_16MHz_5kBPS_CFG3; + break; + case (CAN_10KBPS): // 10Kbps + cfg1 = MCP_16MHz_10kBPS_CFG1; + cfg2 = MCP_16MHz_10kBPS_CFG2; + cfg3 = MCP_16MHz_10kBPS_CFG3; + break; + case (CAN_20KBPS): // 20Kbps + cfg1 = MCP_16MHz_20kBPS_CFG1; + cfg2 = MCP_16MHz_20kBPS_CFG2; + cfg3 = MCP_16MHz_20kBPS_CFG3; + break; + case (CAN_33KBPS): // 33.333Kbps + cfg1 = MCP_16MHz_33k3BPS_CFG1; + cfg2 = MCP_16MHz_33k3BPS_CFG2; + cfg3 = MCP_16MHz_33k3BPS_CFG3; + break; + case (CAN_40KBPS): // 40Kbps + cfg1 = MCP_16MHz_40kBPS_CFG1; + cfg2 = MCP_16MHz_40kBPS_CFG2; + cfg3 = MCP_16MHz_40kBPS_CFG3; + break; + case (CAN_50KBPS): // 50Kbps + cfg2 = MCP_16MHz_50kBPS_CFG2; + cfg3 = MCP_16MHz_50kBPS_CFG3; + break; + case (CAN_80KBPS): // 80Kbps + cfg1 = MCP_16MHz_80kBPS_CFG1; + cfg2 = MCP_16MHz_80kBPS_CFG2; + cfg3 = MCP_16MHz_80kBPS_CFG3; + break; + case (CAN_83K3BPS): // 83.333Kbps + cfg1 = MCP_16MHz_83k3BPS_CFG1; + cfg2 = MCP_16MHz_83k3BPS_CFG2; + cfg3 = MCP_16MHz_83k3BPS_CFG3; + break; + case (CAN_100KBPS): // 100Kbps + cfg1 = MCP_16MHz_100kBPS_CFG1; + cfg2 = MCP_16MHz_100kBPS_CFG2; + cfg3 = MCP_16MHz_100kBPS_CFG3; + break; + case (CAN_125KBPS): // 125Kbps + cfg1 = MCP_16MHz_125kBPS_CFG1; + cfg2 = MCP_16MHz_125kBPS_CFG2; + cfg3 = MCP_16MHz_125kBPS_CFG3; + break; + case (CAN_200KBPS): // 200Kbps + cfg1 = MCP_16MHz_200kBPS_CFG1; + cfg2 = MCP_16MHz_200kBPS_CFG2; + cfg3 = MCP_16MHz_200kBPS_CFG3; + break; + case (CAN_250KBPS): // 250Kbps + cfg1 = MCP_16MHz_250kBPS_CFG1; + cfg2 = MCP_16MHz_250kBPS_CFG2; + cfg3 = MCP_16MHz_250kBPS_CFG3; + break; + case (CAN_500KBPS): // 500Kbps + cfg1 = MCP_16MHz_500kBPS_CFG1; + cfg2 = MCP_16MHz_500kBPS_CFG2; + cfg3 = MCP_16MHz_500kBPS_CFG3; + break; + case (CAN_1000KBPS): // 1Mbps + cfg1 = MCP_16MHz_1000kBPS_CFG1; + cfg2 = MCP_16MHz_1000kBPS_CFG2; + cfg3 = MCP_16MHz_1000kBPS_CFG3; + break; + default: + set = 0; + break; + } + break; + + case (MCP_20MHZ): + switch (canSpeed) { + case (CAN_33KBPS): // 33.333Kbps + cfg1 = MCP_20MHz_33k3BPS_CFG1; + cfg2 = MCP_20MHz_33k3BPS_CFG2; + cfg3 = MCP_20MHz_33k3BPS_CFG3; + break; + case (CAN_40KBPS): // 40Kbps + cfg1 = MCP_20MHz_40kBPS_CFG1; + cfg2 = MCP_20MHz_40kBPS_CFG2; + cfg3 = MCP_20MHz_40kBPS_CFG3; + break; + case (CAN_50KBPS): // 50Kbps + cfg1 = MCP_20MHz_50kBPS_CFG1; + cfg2 = MCP_20MHz_50kBPS_CFG2; + cfg3 = MCP_20MHz_50kBPS_CFG3; + break; + case (CAN_80KBPS): // 80Kbps + cfg1 = MCP_20MHz_80kBPS_CFG1; + cfg2 = MCP_20MHz_80kBPS_CFG2; + cfg3 = MCP_20MHz_80kBPS_CFG3; + break; + case (CAN_83K3BPS): // 83.333Kbps + cfg1 = MCP_20MHz_83k3BPS_CFG1; + cfg2 = MCP_20MHz_83k3BPS_CFG2; + cfg3 = MCP_20MHz_83k3BPS_CFG3; + break; + case (CAN_100KBPS): // 100Kbps + cfg1 = MCP_20MHz_100kBPS_CFG1; + cfg2 = MCP_20MHz_100kBPS_CFG2; + cfg3 = MCP_20MHz_100kBPS_CFG3; + break; + case (CAN_125KBPS): // 125Kbps + cfg1 = MCP_20MHz_125kBPS_CFG1; + cfg2 = MCP_20MHz_125kBPS_CFG2; + cfg3 = MCP_20MHz_125kBPS_CFG3; + break; + case (CAN_200KBPS): // 200Kbps + cfg1 = MCP_20MHz_200kBPS_CFG1; + cfg2 = MCP_20MHz_200kBPS_CFG2; + cfg3 = MCP_20MHz_200kBPS_CFG3; + break; + case (CAN_250KBPS): // 250Kbps + cfg1 = MCP_20MHz_250kBPS_CFG1; + cfg2 = MCP_20MHz_250kBPS_CFG2; + cfg3 = MCP_20MHz_250kBPS_CFG3; + break; + case (CAN_500KBPS): // 500Kbps + cfg1 = MCP_20MHz_500kBPS_CFG1; + cfg2 = MCP_20MHz_500kBPS_CFG2; + cfg3 = MCP_20MHz_500kBPS_CFG3; + break; + case (CAN_1000KBPS): // 1Mbps + cfg1 = MCP_20MHz_1000kBPS_CFG1; + cfg2 = MCP_20MHz_1000kBPS_CFG2; + cfg3 = MCP_20MHz_1000kBPS_CFG3; + break; + default: + set = 0; + break; + } + break; + + default: + set = 0; + break; + } + + if (set) { + set_register_(MCP_CNF1, cfg1); + set_register_(MCP_CNF2, cfg2); + set_register_(MCP_CNF3, cfg3); + return ERROR_OK; + } else { + return ERROR_FAIL; + } } -} // namespace mcp2515 -} // namespace esphome +} // namespace mcp2515 +} // namespace esphome diff --git a/esphome/components/mcp2515/mcp2515.h b/esphome/components/mcp2515/mcp2515.h index 212a5d5cc8..162632971d 100644 --- a/esphome/components/mcp2515/mcp2515.h +++ b/esphome/components/mcp2515/mcp2515.h @@ -9,54 +9,62 @@ namespace esphome { namespace mcp2515 { class MCP2515 : public canbus::Canbus, - public spi::SPIDevice { -public: + public spi::SPIDevice { + public: MCP2515(){}; - - void set_cs_pin(GPIOPin *cs_pin) { cs_pin_ = cs_pin; } - static const uint32_t SPI_CLOCK = 10000000; // 10MHz - /* 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_RTR_FLAG = - 0x40000000UL; /* remote transmission request */ - static const uint32_t CAN_ERR_FLAG = 0x20000000UL; /* error message frame */ - - /* 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_EFF_MASK = - 0x1FFFFFFFUL; /* extended frame format (EFF) */ - static const uint32_t CAN_ERR_MASK = - 0x1FFFFFFFUL; /* omit EFF, RTR, ERR flags */ + static const uint32_t SPI_CLOCK = 10000000; // 10MHz static const int N_TXBUFFERS = 3; static const int N_RXBUFFERS = 2; -/* - * Controller Area Network Identifier structure - * - * bit 0-28 : CAN identifier (11/29 bit) - * bit 29 : error message frame flag (0 = data frame, 1 = error message) - * 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; + enum CAN_CLOCK { MCP_20MHZ, MCP_16MHZ, MCP_8MHZ }; + enum MASK { MASK0, MASK1 }; -/* 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 RXF { RXF0 = 0, RXF1 = 1, RXF2 = 2, RXF3 = 3, RXF4 = 4, RXF5 = 5 }; + enum RXBn { RXB0 = 0, RXB1 = 1 }; -struct can_frame { + 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))); -}; + 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; @@ -71,47 +79,48 @@ struct can_frame { 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: - GPIOPin *cs_pin_; + protected: bool send_internal_(int can_id, uint8_t *data) override; bool setup_internal_() override; - ERROR set_mode_(const CANCTRL_REQOP_MODE mode); + ERROR set_mode_(const CANCTRL_REQOP_MODE mode); - uint8_t read_register_(const REGISTER reg); - void read_registers_(const REGISTER reg, uint8_t values[], const uint8_t n); - void set_register_(const REGISTER reg, const uint8_t value); - void set_registers_(const REGISTER reg, uint8_t values[], const uint8_t n); - void modify_register_(const REGISTER reg, const uint8_t mask, const uint8_t data); + uint8_t read_register_(const REGISTER reg); + void read_registers_(const REGISTER reg, uint8_t values[], const uint8_t n); + void set_register_(const REGISTER reg, const uint8_t value); + void set_registers_(const REGISTER reg, uint8_t values[], const uint8_t n); + void modify_register_(const REGISTER reg, const uint8_t mask, const uint8_t data); - void prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id); - ERROR reset_(void); - ERROR set_config_mode_(); - ERROR set_listen_only_(); - ERROR set_sleep_mode_(); - 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_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 readMessage(const RXBn rxbn, struct can_frame *frame); - ERROR readMessage(struct can_frame *frame); - bool check_receive_(void); - bool check_error_(void); - uint8_t get_error_flags_(void); - void clearRXnOVRFlags(void); - uint8_t getInterrupts(void); - uint8_t getInterruptMask(void); - void clearInterrupts(void); - void clearTXInterrupts(void); - uint8_t get_status_(void); - void clearRXnOVR(void); - void clearMERR(); - void clearERRIF(); + void prepare_id_(uint8_t *buffer, const bool ext, const uint32_t id); + ERROR reset_(void); + ERROR set_config_mode_(); + ERROR set_listen_only_(); + ERROR set_sleep_mode_(); + 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_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); + bool check_receive_(void); + bool check_error_(void); + uint8_t get_error_flags_(void); + void clearRXnOVRFlags(void); + uint8_t getInterrupts(void); + uint8_t getInterruptMask(void); + void clearInterrupts(void); + void clearTXInterrupts(void); + uint8_t get_status_(void); + void clearRXnOVR(void); + void clearMERR(); + void clearERRIF(); }; -} // namespace mcp2515 -} // namespace esphome \ No newline at end of file +} // namespace mcp2515 +} // namespace esphome \ No newline at end of file diff --git a/esphome/components/mcp2515/mcp2515_defs.h b/esphome/components/mcp2515/mcp2515_defs.h index c6b0711077..e54e193040 100644 --- a/esphome/components/mcp2515/mcp2515_defs.h +++ b/esphome/components/mcp2515/mcp2515_defs.h @@ -3,386 +3,315 @@ namespace esphome { namespace mcp2515 { -enum CAN_CLOCK { - MCP_20MHZ, - MCP_16MHZ, - MCP_8MHZ +static const uint8_t CANCTRL_REQOP = 0xE0; +static const uint8_t CANCTRL_ABAT = 0x10; +static const uint8_t CANCTRL_OSM = 0x08; +static const uint8_t CANCTRL_CLKEN = 0x04; +static const uint8_t CANCTRL_CLKPRE = 0x03; + +enum /*class*/ CANCTRL_REQOP_MODE : uint8_t { + CANCTRL_REQOP_NORMAL = 0x00, + CANCTRL_REQOP_SLEEP = 0x20, + CANCTRL_REQOP_LOOPBACK = 0x40, + CANCTRL_REQOP_LISTENONLY = 0x60, + CANCTRL_REQOP_CONFIG = 0x80, + CANCTRL_REQOP_POWERUP = 0xE0 }; - enum MASK { - MASK0, - MASK1 - }; - enum RXF { - RXF0 = 0, - RXF1 = 1, - RXF2 = 2, - RXF3 = 3, - RXF4 = 4, - RXF5 = 5 - }; +enum /*class*/ TXBnCTRL : uint8_t { + TXB_ABTF = 0x40, + TXB_MLOA = 0x20, + TXB_TXERR = 0x10, + TXB_TXREQ = 0x08, + TXB_TXIE = 0x04, + TXB_TXP = 0x03 +}; - enum RXBn { - RXB0 = 0, - RXB1 = 1 - }; +enum /*class*/ INSTRUCTION : uint8_t { + INSTRUCTION_WRITE = 0x02, + INSTRUCTION_READ = 0x03, + INSTRUCTION_BITMOD = 0x05, + INSTRUCTION_LOAD_TX0 = 0x40, + INSTRUCTION_LOAD_TX1 = 0x42, + INSTRUCTION_LOAD_TX2 = 0x44, + INSTRUCTION_RTS_TX0 = 0x81, + INSTRUCTION_RTS_TX1 = 0x82, + INSTRUCTION_RTS_TX2 = 0x84, + INSTRUCTION_RTS_ALL = 0x87, + INSTRUCTION_READ_RX0 = 0x90, + INSTRUCTION_READ_RX1 = 0x94, + INSTRUCTION_READ_STATUS = 0xA0, + INSTRUCTION_RX_STATUS = 0xB0, + INSTRUCTION_RESET = 0xC0 +}; - enum TXBn { - TXB0 = 0, - TXB1 = 1, - TXB2 = 2 - }; +enum /*class*/ REGISTER : uint8_t { + MCP_RXF0SIDH = 0x00, + MCP_RXF0SIDL = 0x01, + MCP_RXF0EID8 = 0x02, + MCP_RXF0EID0 = 0x03, + MCP_RXF1SIDH = 0x04, + MCP_RXF1SIDL = 0x05, + MCP_RXF1EID8 = 0x06, + MCP_RXF1EID0 = 0x07, + MCP_RXF2SIDH = 0x08, + MCP_RXF2SIDL = 0x09, + MCP_RXF2EID8 = 0x0A, + MCP_RXF2EID0 = 0x0B, + MCP_CANSTAT = 0x0E, + MCP_CANCTRL = 0x0F, + MCP_RXF3SIDH = 0x10, + MCP_RXF3SIDL = 0x11, + MCP_RXF3EID8 = 0x12, + MCP_RXF3EID0 = 0x13, + MCP_RXF4SIDH = 0x14, + MCP_RXF4SIDL = 0x15, + MCP_RXF4EID8 = 0x16, + MCP_RXF4EID0 = 0x17, + MCP_RXF5SIDH = 0x18, + MCP_RXF5SIDL = 0x19, + MCP_RXF5EID8 = 0x1A, + MCP_RXF5EID0 = 0x1B, + MCP_TEC = 0x1C, + MCP_REC = 0x1D, + MCP_RXM0SIDH = 0x20, + MCP_RXM0SIDL = 0x21, + MCP_RXM0EID8 = 0x22, + MCP_RXM0EID0 = 0x23, + MCP_RXM1SIDH = 0x24, + MCP_RXM1SIDL = 0x25, + MCP_RXM1EID8 = 0x26, + MCP_RXM1EID0 = 0x27, + MCP_CNF3 = 0x28, + MCP_CNF2 = 0x29, + MCP_CNF1 = 0x2A, + MCP_CANINTE = 0x2B, + MCP_CANINTF = 0x2C, + MCP_EFLG = 0x2D, + MCP_TXB0CTRL = 0x30, + MCP_TXB0SIDH = 0x31, + MCP_TXB0SIDL = 0x32, + MCP_TXB0EID8 = 0x33, + MCP_TXB0EID0 = 0x34, + MCP_TXB0DLC = 0x35, + MCP_TXB0DATA = 0x36, + MCP_TXB1CTRL = 0x40, + MCP_TXB1SIDH = 0x41, + MCP_TXB1SIDL = 0x42, + MCP_TXB1EID8 = 0x43, + MCP_TXB1EID0 = 0x44, + MCP_TXB1DLC = 0x45, + MCP_TXB1DATA = 0x46, + MCP_TXB2CTRL = 0x50, + MCP_TXB2SIDH = 0x51, + MCP_TXB2SIDL = 0x52, + MCP_TXB2EID8 = 0x53, + MCP_TXB2EID0 = 0x54, + MCP_TXB2DLC = 0x55, + MCP_TXB2DATA = 0x56, + MCP_RXB0CTRL = 0x60, + MCP_RXB0SIDH = 0x61, + MCP_RXB0SIDL = 0x62, + MCP_RXB0EID8 = 0x63, + MCP_RXB0EID0 = 0x64, + MCP_RXB0DLC = 0x65, + MCP_RXB0DATA = 0x66, + MCP_RXB1CTRL = 0x70, + MCP_RXB1SIDH = 0x71, + MCP_RXB1SIDL = 0x72, + MCP_RXB1EID8 = 0x73, + MCP_RXB1EID0 = 0x74, + MCP_RXB1DLC = 0x75, + MCP_RXB1DATA = 0x76 +}; - enum CAN_CLKOUT { - CLKOUT_DISABLE = -1, - CLKOUT_DIV1 = 0x0, - CLKOUT_DIV2 = 0x1, - CLKOUT_DIV4 = 0x2, - CLKOUT_DIV8 = 0x3, - }; +static const uint8_t CANSTAT_OPMOD = 0xE0; +static const uint8_t CANSTAT_ICOD = 0x0E; - 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 - }; +static const uint8_t CNF3_SOF = 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) - }; +static const uint8_t TXB_EXIDE_MASK = 0x08; +static const uint8_t DLC_MASK = 0x0F; +static const uint8_t RTR_MASK = 0x40; - static const uint8_t CANCTRL_REQOP = 0xE0; - static const uint8_t CANCTRL_ABAT = 0x10; - static const uint8_t CANCTRL_OSM = 0x08; - static const uint8_t CANCTRL_CLKEN = 0x04; - static const uint8_t CANCTRL_CLKPRE = 0x03; - enum /*class*/ CANCTRL_REQOP_MODE : uint8_t { - CANCTRL_REQOP_NORMAL = 0x00, - CANCTRL_REQOP_SLEEP = 0x20, - CANCTRL_REQOP_LOOPBACK = 0x40, - CANCTRL_REQOP_LISTENONLY = 0x60, - CANCTRL_REQOP_CONFIG = 0x80, - CANCTRL_REQOP_POWERUP = 0xE0 - }; +static const uint8_t RXBnCTRL_RXM_STD = 0x20; +static const uint8_t RXBnCTRL_RXM_EXT = 0x40; +static const uint8_t RXBnCTRL_RXM_STDEXT = 0x00; +static const uint8_t RXBnCTRL_RXM_MASK = 0x60; +static const uint8_t RXBnCTRL_RTR = 0x08; +static const uint8_t RXB0CTRL_BUKT = 0x04; - enum /*class*/ STAT : uint8_t { - STAT_RX0IF = (1<<0), - STAT_RX1IF = (1<<1) - }; - - static const uint8_t STAT_RXIF_MASK = STAT_RX0IF | STAT_RX1IF; - - enum /*class*/ TXBnCTRL : uint8_t { - TXB_ABTF = 0x40, - TXB_MLOA = 0x20, - TXB_TXERR = 0x10, - TXB_TXREQ = 0x08, - TXB_TXIE = 0x04, - TXB_TXP = 0x03 - }; - - static const uint8_t EFLG_ERRORMASK = EFLG_RX1OVR - | EFLG_RX0OVR - | EFLG_TXBO - | EFLG_TXEP - | EFLG_RXEP; - - enum /*class*/ INSTRUCTION : uint8_t { - INSTRUCTION_WRITE = 0x02, - INSTRUCTION_READ = 0x03, - INSTRUCTION_BITMOD = 0x05, - INSTRUCTION_LOAD_TX0 = 0x40, - INSTRUCTION_LOAD_TX1 = 0x42, - INSTRUCTION_LOAD_TX2 = 0x44, - INSTRUCTION_RTS_TX0 = 0x81, - INSTRUCTION_RTS_TX1 = 0x82, - INSTRUCTION_RTS_TX2 = 0x84, - INSTRUCTION_RTS_ALL = 0x87, - INSTRUCTION_READ_RX0 = 0x90, - INSTRUCTION_READ_RX1 = 0x94, - INSTRUCTION_READ_STATUS = 0xA0, - INSTRUCTION_RX_STATUS = 0xB0, - INSTRUCTION_RESET = 0xC0 - }; - - enum /*class*/ REGISTER : uint8_t { - MCP_RXF0SIDH = 0x00, - MCP_RXF0SIDL = 0x01, - MCP_RXF0EID8 = 0x02, - MCP_RXF0EID0 = 0x03, - MCP_RXF1SIDH = 0x04, - MCP_RXF1SIDL = 0x05, - MCP_RXF1EID8 = 0x06, - MCP_RXF1EID0 = 0x07, - MCP_RXF2SIDH = 0x08, - MCP_RXF2SIDL = 0x09, - MCP_RXF2EID8 = 0x0A, - MCP_RXF2EID0 = 0x0B, - MCP_CANSTAT = 0x0E, - MCP_CANCTRL = 0x0F, - MCP_RXF3SIDH = 0x10, - MCP_RXF3SIDL = 0x11, - MCP_RXF3EID8 = 0x12, - MCP_RXF3EID0 = 0x13, - MCP_RXF4SIDH = 0x14, - MCP_RXF4SIDL = 0x15, - MCP_RXF4EID8 = 0x16, - MCP_RXF4EID0 = 0x17, - MCP_RXF5SIDH = 0x18, - MCP_RXF5SIDL = 0x19, - MCP_RXF5EID8 = 0x1A, - MCP_RXF5EID0 = 0x1B, - MCP_TEC = 0x1C, - MCP_REC = 0x1D, - MCP_RXM0SIDH = 0x20, - MCP_RXM0SIDL = 0x21, - MCP_RXM0EID8 = 0x22, - MCP_RXM0EID0 = 0x23, - MCP_RXM1SIDH = 0x24, - MCP_RXM1SIDL = 0x25, - MCP_RXM1EID8 = 0x26, - MCP_RXM1EID0 = 0x27, - MCP_CNF3 = 0x28, - MCP_CNF2 = 0x29, - MCP_CNF1 = 0x2A, - MCP_CANINTE = 0x2B, - MCP_CANINTF = 0x2C, - MCP_EFLG = 0x2D, - MCP_TXB0CTRL = 0x30, - MCP_TXB0SIDH = 0x31, - MCP_TXB0SIDL = 0x32, - MCP_TXB0EID8 = 0x33, - MCP_TXB0EID0 = 0x34, - MCP_TXB0DLC = 0x35, - MCP_TXB0DATA = 0x36, - MCP_TXB1CTRL = 0x40, - MCP_TXB1SIDH = 0x41, - MCP_TXB1SIDL = 0x42, - MCP_TXB1EID8 = 0x43, - MCP_TXB1EID0 = 0x44, - MCP_TXB1DLC = 0x45, - MCP_TXB1DATA = 0x46, - MCP_TXB2CTRL = 0x50, - MCP_TXB2SIDH = 0x51, - MCP_TXB2SIDL = 0x52, - MCP_TXB2EID8 = 0x53, - MCP_TXB2EID0 = 0x54, - MCP_TXB2DLC = 0x55, - MCP_TXB2DATA = 0x56, - MCP_RXB0CTRL = 0x60, - MCP_RXB0SIDH = 0x61, - MCP_RXB0SIDL = 0x62, - MCP_RXB0EID8 = 0x63, - MCP_RXB0EID0 = 0x64, - MCP_RXB0DLC = 0x65, - MCP_RXB0DATA = 0x66, - MCP_RXB1CTRL = 0x70, - MCP_RXB1SIDH = 0x71, - MCP_RXB1SIDL = 0x72, - MCP_RXB1EID8 = 0x73, - MCP_RXB1EID0 = 0x74, - MCP_RXB1DLC = 0x75, - MCP_RXB1DATA = 0x76 - }; - - static const uint8_t CANSTAT_OPMOD = 0xE0; - static const uint8_t CANSTAT_ICOD = 0x0E; - - static const uint8_t CNF3_SOF = 0x80; - - static const uint8_t TXB_EXIDE_MASK = 0x08; - static const uint8_t DLC_MASK = 0x0F; - static const uint8_t RTR_MASK = 0x40; - - static const uint8_t RXBnCTRL_RXM_STD = 0x20; - static const uint8_t RXBnCTRL_RXM_EXT = 0x40; - static const uint8_t RXBnCTRL_RXM_STDEXT = 0x00; - static const uint8_t RXBnCTRL_RXM_MASK = 0x60; - static const uint8_t RXBnCTRL_RTR = 0x08; - static const uint8_t RXB0CTRL_BUKT = 0x04; - - static const uint8_t MCP_SIDH = 0; - static const uint8_t MCP_SIDL = 1; - static const uint8_t MCP_EID8 = 2; - static const uint8_t MCP_EID0 = 3; - static const uint8_t MCP_DLC = 4; - static const uint8_t MCP_DATA = 5; +static const uint8_t MCP_SIDH = 0; +static const uint8_t MCP_SIDL = 1; +static const uint8_t MCP_EID8 = 2; +static const uint8_t MCP_EID0 = 3; +static const uint8_t MCP_DLC = 4; +static const uint8_t MCP_DATA = 5; /* * Speed 8M */ -static const uint8_t MCP_8MHz_1000kBPS_CFG1 =0x00; -static const uint8_t MCP_8MHz_1000kBPS_CFG2 =0x80; -static const uint8_t MCP_8MHz_1000kBPS_CFG3 =0x80; +static const uint8_t MCP_8MHz_1000kBPS_CFG1 = 0x00; +static const uint8_t MCP_8MHz_1000kBPS_CFG2 = 0x80; +static const uint8_t MCP_8MHz_1000kBPS_CFG3 = 0x80; -static const uint8_t MCP_8MHz_500kBPS_CFG1 =0x00; -static const uint8_t MCP_8MHz_500kBPS_CFG2 =0x90; -static const uint8_t MCP_8MHz_500kBPS_CFG3 =0x82; +static const uint8_t MCP_8MHz_500kBPS_CFG1 = 0x00; +static const uint8_t MCP_8MHz_500kBPS_CFG2 = 0x90; +static const uint8_t MCP_8MHz_500kBPS_CFG3 = 0x82; -static const uint8_t MCP_8MHz_250kBPS_CFG1 =0x00; -static const uint8_t MCP_8MHz_250kBPS_CFG2 =0xB1; -static const uint8_t MCP_8MHz_250kBPS_CFG3 =0x85; +static const uint8_t MCP_8MHz_250kBPS_CFG1 = 0x00; +static const uint8_t MCP_8MHz_250kBPS_CFG2 = 0xB1; +static const uint8_t MCP_8MHz_250kBPS_CFG3 = 0x85; -static const uint8_t MCP_8MHz_200kBPS_CFG1 =0x00; -static const uint8_t MCP_8MHz_200kBPS_CFG2 =0xB4; -static const uint8_t MCP_8MHz_200kBPS_CFG3 =0x86; +static const uint8_t MCP_8MHz_200kBPS_CFG1 = 0x00; +static const uint8_t MCP_8MHz_200kBPS_CFG2 = 0xB4; +static const uint8_t MCP_8MHz_200kBPS_CFG3 = 0x86; -static const uint8_t MCP_8MHz_125kBPS_CFG1 =0x01; -static const uint8_t MCP_8MHz_125kBPS_CFG2 =0xB1; -static const uint8_t MCP_8MHz_125kBPS_CFG3 =0x85; +static const uint8_t MCP_8MHz_125kBPS_CFG1 = 0x01; +static const uint8_t MCP_8MHz_125kBPS_CFG2 = 0xB1; +static const uint8_t MCP_8MHz_125kBPS_CFG3 = 0x85; -static const uint8_t MCP_8MHz_100kBPS_CFG1 =0x01; -static const uint8_t MCP_8MHz_100kBPS_CFG2 =0xB4; -static const uint8_t MCP_8MHz_100kBPS_CFG3 =0x86; +static const uint8_t MCP_8MHz_100kBPS_CFG1 = 0x01; +static const uint8_t MCP_8MHz_100kBPS_CFG2 = 0xB4; +static const uint8_t MCP_8MHz_100kBPS_CFG3 = 0x86; -static const uint8_t MCP_8MHz_80kBPS_CFG1 =0x01; -static const uint8_t MCP_8MHz_80kBPS_CFG2 =0xBF; -static const uint8_t MCP_8MHz_80kBPS_CFG3 =0x87; +static const uint8_t MCP_8MHz_80kBPS_CFG1 = 0x01; +static const uint8_t MCP_8MHz_80kBPS_CFG2 = 0xBF; +static const uint8_t MCP_8MHz_80kBPS_CFG3 = 0x87; -static const uint8_t MCP_8MHz_50kBPS_CFG1 =0x03; -static const uint8_t MCP_8MHz_50kBPS_CFG2 =0xB4; -static const uint8_t MCP_8MHz_50kBPS_CFG3 =0x86; +static const uint8_t MCP_8MHz_50kBPS_CFG1 = 0x03; +static const uint8_t MCP_8MHz_50kBPS_CFG2 = 0xB4; +static const uint8_t MCP_8MHz_50kBPS_CFG3 = 0x86; -static const uint8_t MCP_8MHz_40kBPS_CFG1 =0x03; -static const uint8_t MCP_8MHz_40kBPS_CFG2 =0xBF; -static const uint8_t MCP_8MHz_40kBPS_CFG3 =0x87; +static const uint8_t MCP_8MHz_40kBPS_CFG1 = 0x03; +static const uint8_t MCP_8MHz_40kBPS_CFG2 = 0xBF; +static const uint8_t MCP_8MHz_40kBPS_CFG3 = 0x87; -static const uint8_t MCP_8MHz_33k3BPS_CFG1 =0x47; -static const uint8_t MCP_8MHz_33k3BPS_CFG2 =0xE2; -static const uint8_t MCP_8MHz_33k3BPS_CFG3 =0x85; +static const uint8_t MCP_8MHz_33k3BPS_CFG1 = 0x47; +static const uint8_t MCP_8MHz_33k3BPS_CFG2 = 0xE2; +static const uint8_t MCP_8MHz_33k3BPS_CFG3 = 0x85; -static const uint8_t MCP_8MHz_31k25BPS_CFG1 =0x07; -static const uint8_t MCP_8MHz_31k25BPS_CFG2 =0xA4; -static const uint8_t MCP_8MHz_31k25BPS_CFG3 =0x84; +static const uint8_t MCP_8MHz_31k25BPS_CFG1 = 0x07; +static const uint8_t MCP_8MHz_31k25BPS_CFG2 = 0xA4; +static const uint8_t MCP_8MHz_31k25BPS_CFG3 = 0x84; -static const uint8_t MCP_8MHz_20kBPS_CFG1 =0x07; -static const uint8_t MCP_8MHz_20kBPS_CFG2 =0xBF; -static const uint8_t MCP_8MHz_20kBPS_CFG3 =0x87; +static const uint8_t MCP_8MHz_20kBPS_CFG1 = 0x07; +static const uint8_t MCP_8MHz_20kBPS_CFG2 = 0xBF; +static const uint8_t MCP_8MHz_20kBPS_CFG3 = 0x87; -static const uint8_t MCP_8MHz_10kBPS_CFG1 =0x0F; -static const uint8_t MCP_8MHz_10kBPS_CFG2 =0xBF; -static const uint8_t MCP_8MHz_10kBPS_CFG3 =0x87; +static const uint8_t MCP_8MHz_10kBPS_CFG1 = 0x0F; +static const uint8_t MCP_8MHz_10kBPS_CFG2 = 0xBF; +static const uint8_t MCP_8MHz_10kBPS_CFG3 = 0x87; -static const uint8_t MCP_8MHz_5kBPS_CFG1 =0x1F; -static const uint8_t MCP_8MHz_5kBPS_CFG2 =0xBF; -static const uint8_t MCP_8MHz_5kBPS_CFG3 =0x87; +static const uint8_t MCP_8MHz_5kBPS_CFG1 = 0x1F; +static const uint8_t MCP_8MHz_5kBPS_CFG2 = 0xBF; +static const uint8_t MCP_8MHz_5kBPS_CFG3 = 0x87; /* * speed 16M */ -static const uint8_t MCP_16MHz_1000kBPS_CFG1 =0x00; -static const uint8_t MCP_16MHz_1000kBPS_CFG2 =0xD0; -static const uint8_t MCP_16MHz_1000kBPS_CFG3 =0x82; +static const uint8_t MCP_16MHz_1000kBPS_CFG1 = 0x00; +static const uint8_t MCP_16MHz_1000kBPS_CFG2 = 0xD0; +static const uint8_t MCP_16MHz_1000kBPS_CFG3 = 0x82; -static const uint8_t MCP_16MHz_500kBPS_CFG1 =0x00; -static const uint8_t MCP_16MHz_500kBPS_CFG2 =0xF0; -static const uint8_t MCP_16MHz_500kBPS_CFG3 =0x86; +static const uint8_t MCP_16MHz_500kBPS_CFG1 = 0x00; +static const uint8_t MCP_16MHz_500kBPS_CFG2 = 0xF0; +static const uint8_t MCP_16MHz_500kBPS_CFG3 = 0x86; -static const uint8_t MCP_16MHz_250kBPS_CFG1 =0x41; -static const uint8_t MCP_16MHz_250kBPS_CFG2 =0xF1; -static const uint8_t MCP_16MHz_250kBPS_CFG3 =0x85; +static const uint8_t MCP_16MHz_250kBPS_CFG1 = 0x41; +static const uint8_t MCP_16MHz_250kBPS_CFG2 = 0xF1; +static const uint8_t MCP_16MHz_250kBPS_CFG3 = 0x85; -static const uint8_t MCP_16MHz_200kBPS_CFG1 =0x01; -static const uint8_t MCP_16MHz_200kBPS_CFG2 =0xFA; -static const uint8_t MCP_16MHz_200kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_200kBPS_CFG1 = 0x01; +static const uint8_t MCP_16MHz_200kBPS_CFG2 = 0xFA; +static const uint8_t MCP_16MHz_200kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_125kBPS_CFG1 =0x03; -static const uint8_t MCP_16MHz_125kBPS_CFG2 =0xF0; -static const uint8_t MCP_16MHz_125kBPS_CFG3 =0x86; +static const uint8_t MCP_16MHz_125kBPS_CFG1 = 0x03; +static const uint8_t MCP_16MHz_125kBPS_CFG2 = 0xF0; +static const uint8_t MCP_16MHz_125kBPS_CFG3 = 0x86; -static const uint8_t MCP_16MHz_100kBPS_CFG1 =0x03; -static const uint8_t MCP_16MHz_100kBPS_CFG2 =0xFA; -static const uint8_t MCP_16MHz_100kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_100kBPS_CFG1 = 0x03; +static const uint8_t MCP_16MHz_100kBPS_CFG2 = 0xFA; +static const uint8_t MCP_16MHz_100kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_80kBPS_CFG1 =0x03; -static const uint8_t MCP_16MHz_80kBPS_CFG2 =0xFF; -static const uint8_t MCP_16MHz_80kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_80kBPS_CFG1 = 0x03; +static const uint8_t MCP_16MHz_80kBPS_CFG2 = 0xFF; +static const uint8_t MCP_16MHz_80kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_83k3BPS_CFG1 =0x03; -static const uint8_t MCP_16MHz_83k3BPS_CFG2 =0xBE; -static const uint8_t MCP_16MHz_83k3BPS_CFG3 =0x07; +static const uint8_t MCP_16MHz_83k3BPS_CFG1 = 0x03; +static const uint8_t MCP_16MHz_83k3BPS_CFG2 = 0xBE; +static const uint8_t MCP_16MHz_83k3BPS_CFG3 = 0x07; -static const uint8_t MCP_16MHz_50kBPS_CFG1 =0x07; -static const uint8_t MCP_16MHz_50kBPS_CFG2 =0xFA; -static const uint8_t MCP_16MHz_50kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_50kBPS_CFG1 = 0x07; +static const uint8_t MCP_16MHz_50kBPS_CFG2 = 0xFA; +static const uint8_t MCP_16MHz_50kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_40kBPS_CFG1 =0x07; -static const uint8_t MCP_16MHz_40kBPS_CFG2 =0xFF; -static const uint8_t MCP_16MHz_40kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_40kBPS_CFG1 = 0x07; +static const uint8_t MCP_16MHz_40kBPS_CFG2 = 0xFF; +static const uint8_t MCP_16MHz_40kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_33k3BPS_CFG1 =0x4E; -static const uint8_t MCP_16MHz_33k3BPS_CFG2 =0xF1; -static const uint8_t MCP_16MHz_33k3BPS_CFG3 =0x85; +static const uint8_t MCP_16MHz_33k3BPS_CFG1 = 0x4E; +static const uint8_t MCP_16MHz_33k3BPS_CFG2 = 0xF1; +static const uint8_t MCP_16MHz_33k3BPS_CFG3 = 0x85; -static const uint8_t MCP_16MHz_20kBPS_CFG1 =0x0F; -static const uint8_t MCP_16MHz_20kBPS_CFG2 =0xFF; -static const uint8_t MCP_16MHz_20kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_20kBPS_CFG1 = 0x0F; +static const uint8_t MCP_16MHz_20kBPS_CFG2 = 0xFF; +static const uint8_t MCP_16MHz_20kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_10kBPS_CFG1 =0x1F; -static const uint8_t MCP_16MHz_10kBPS_CFG2 =0xFF; -static const uint8_t MCP_16MHz_10kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_10kBPS_CFG1 = 0x1F; +static const uint8_t MCP_16MHz_10kBPS_CFG2 = 0xFF; +static const uint8_t MCP_16MHz_10kBPS_CFG3 = 0x87; -static const uint8_t MCP_16MHz_5kBPS_CFG1 =0x3F; -static const uint8_t MCP_16MHz_5kBPS_CFG2 =0xFF; -static const uint8_t MCP_16MHz_5kBPS_CFG3 =0x87; +static const uint8_t MCP_16MHz_5kBPS_CFG1 = 0x3F; +static const uint8_t MCP_16MHz_5kBPS_CFG2 = 0xFF; +static const uint8_t MCP_16MHz_5kBPS_CFG3 = 0x87; /* * speed 20M */ -static const uint8_t MCP_20MHz_1000kBPS_CFG1 =0x00; -static const uint8_t MCP_20MHz_1000kBPS_CFG2 =0xD9; -static const uint8_t MCP_20MHz_1000kBPS_CFG3 =0x82; +static const uint8_t MCP_20MHz_1000kBPS_CFG1 = 0x00; +static const uint8_t MCP_20MHz_1000kBPS_CFG2 = 0xD9; +static const uint8_t MCP_20MHz_1000kBPS_CFG3 = 0x82; -static const uint8_t MCP_20MHz_500kBPS_CFG1 =0x00; -static const uint8_t MCP_20MHz_500kBPS_CFG2 =0xFA; -static const uint8_t MCP_20MHz_500kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_500kBPS_CFG1 = 0x00; +static const uint8_t MCP_20MHz_500kBPS_CFG2 = 0xFA; +static const uint8_t MCP_20MHz_500kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_250kBPS_CFG1 =0x41; -static const uint8_t MCP_20MHz_250kBPS_CFG2 =0xFB; -static const uint8_t MCP_20MHz_250kBPS_CFG3 =0x86; +static const uint8_t MCP_20MHz_250kBPS_CFG1 = 0x41; +static const uint8_t MCP_20MHz_250kBPS_CFG2 = 0xFB; +static const uint8_t MCP_20MHz_250kBPS_CFG3 = 0x86; -static const uint8_t MCP_20MHz_200kBPS_CFG1 =0x01; -static const uint8_t MCP_20MHz_200kBPS_CFG2 =0xFF; -static const uint8_t MCP_20MHz_200kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_200kBPS_CFG1 = 0x01; +static const uint8_t MCP_20MHz_200kBPS_CFG2 = 0xFF; +static const uint8_t MCP_20MHz_200kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_125kBPS_CFG1 =0x03; -static const uint8_t MCP_20MHz_125kBPS_CFG2 =0xFA; -static const uint8_t MCP_20MHz_125kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_125kBPS_CFG1 = 0x03; +static const uint8_t MCP_20MHz_125kBPS_CFG2 = 0xFA; +static const uint8_t MCP_20MHz_125kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_100kBPS_CFG1 =0x04; -static const uint8_t MCP_20MHz_100kBPS_CFG2 =0xFA; -static const uint8_t MCP_20MHz_100kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_100kBPS_CFG1 = 0x04; +static const uint8_t MCP_20MHz_100kBPS_CFG2 = 0xFA; +static const uint8_t MCP_20MHz_100kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_83k3BPS_CFG1 =0x04; -static const uint8_t MCP_20MHz_83k3BPS_CFG2 =0xFE; -static const uint8_t MCP_20MHz_83k3BPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_83k3BPS_CFG1 = 0x04; +static const uint8_t MCP_20MHz_83k3BPS_CFG2 = 0xFE; +static const uint8_t MCP_20MHz_83k3BPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_80kBPS_CFG1 =0x04; -static const uint8_t MCP_20MHz_80kBPS_CFG2 =0xFF; -static const uint8_t MCP_20MHz_80kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_80kBPS_CFG1 = 0x04; +static const uint8_t MCP_20MHz_80kBPS_CFG2 = 0xFF; +static const uint8_t MCP_20MHz_80kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_50kBPS_CFG1 =0x09; -static const uint8_t MCP_20MHz_50kBPS_CFG2 =0xFA; -static const uint8_t MCP_20MHz_50kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_50kBPS_CFG1 = 0x09; +static const uint8_t MCP_20MHz_50kBPS_CFG2 = 0xFA; +static const uint8_t MCP_20MHz_50kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_40kBPS_CFG1 =0x09; -static const uint8_t MCP_20MHz_40kBPS_CFG2 =0xFF; -static const uint8_t MCP_20MHz_40kBPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_40kBPS_CFG1 = 0x09; +static const uint8_t MCP_20MHz_40kBPS_CFG2 = 0xFF; +static const uint8_t MCP_20MHz_40kBPS_CFG3 = 0x87; -static const uint8_t MCP_20MHz_33k3BPS_CFG1 =0x0B; -static const uint8_t MCP_20MHz_33k3BPS_CFG2 =0xFF; -static const uint8_t MCP_20MHz_33k3BPS_CFG3 =0x87; +static const uint8_t MCP_20MHz_33k3BPS_CFG1 = 0x0B; +static const uint8_t MCP_20MHz_33k3BPS_CFG2 = 0xFF; +static const uint8_t MCP_20MHz_33k3BPS_CFG3 = 0x87; -}} \ No newline at end of file +} // namespace mcp2515 +} // namespace esphome \ No newline at end of file