diff --git a/mcp2515.cpp b/mcp2515.cpp index e6f14c5..cc6e29e 100644 --- a/mcp2515.cpp +++ b/mcp2515.cpp @@ -226,7 +226,7 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) cfg3 = MCP_8MHz_31k25BPS_CFG3; break; - case (CAN_33KBPS): // 33.33KBPS + case (CAN_33KBPS): // 33.333KBPS cfg1 = MCP_8MHz_33k3BPS_CFG1; cfg2 = MCP_8MHz_33k3BPS_CFG2; cfg3 = MCP_8MHz_33k3BPS_CFG3; @@ -313,7 +313,7 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) cfg3 = MCP_16MHz_20kBPS_CFG3; break; - case (CAN_33KBPS): // 20Kbps + case (CAN_33KBPS): // 33.333Kbps cfg1 = MCP_16MHz_33k3BPS_CFG1; cfg2 = MCP_16MHz_33k3BPS_CFG2; cfg3 = MCP_16MHz_33k3BPS_CFG3; @@ -336,7 +336,7 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) cfg3 = MCP_16MHz_80kBPS_CFG3; break; - case (CAN_83K3BPS): // 83.3333Kbps + case (CAN_83K3BPS): // 83.333Kbps cfg1 = MCP_16MHz_83k3BPS_CFG1; cfg2 = MCP_16MHz_83k3BPS_CFG2; cfg3 = MCP_16MHz_83k3BPS_CFG3; @@ -387,6 +387,12 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) 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; @@ -405,6 +411,12 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) 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; @@ -452,7 +464,6 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) break; } - if (set) { setRegister(MCP_CNF1, cfg1); setRegister(MCP_CNF2, cfg2); @@ -464,6 +475,31 @@ MCP2515::ERROR MCP2515::setBitrate(const CAN_SPEED canSpeed, CAN_CLOCK canClock) } } +MCP2515::ERROR MCP2515::setClkOut(const CAN_CLKOUT divisor) +{ + ERROR res; + uint8_t cfg3; + + if (divisor == CLKOUT_DISABLE) { + /* Turn off CLKEN */ + modifyRegister(MCP_CANCTRL, CANCTRL_CLKEN, 0x00); + + /* Turn on CLKOUT for SOF */ + modifyRegister(MCP_CNF3, CNF3_SOF, CNF3_SOF); + return ERROR_OK; + } + + /* Set the prescaler (CLKPRE) */ + modifyRegister(MCP_CANCTRL, CANCTRL_CLKPRE, divisor); + + /* Turn on CLKEN */ + modifyRegister(MCP_CANCTRL, CANCTRL_CLKEN, CANCTRL_CLKEN); + + /* Turn off CLKOUT for SOF */ + modifyRegister(MCP_CNF3, CNF3_SOF, 0x00); + return ERROR_OK; +} + void MCP2515::prepareId(uint8_t *buffer, const bool ext, const uint32_t id) { uint16_t canid = (uint16_t)(id & 0x0FFFF); diff --git a/mcp2515.h b/mcp2515.h index 32b9263..7e38d18 100644 --- a/mcp2515.h +++ b/mcp2515.h @@ -149,6 +149,10 @@ #define MCP_20MHz_100kBPS_CFG2 (0xFA) #define MCP_20MHz_100kBPS_CFG3 (0x87) +#define MCP_20MHz_83k3BPS_CFG1 (0x04) +#define MCP_20MHz_83k3BPS_CFG2 (0xFE) +#define MCP_20MHz_83k3BPS_CFG3 (0x87) + #define MCP_20MHz_80kBPS_CFG1 (0x04) #define MCP_20MHz_80kBPS_CFG2 (0xFF) #define MCP_20MHz_80kBPS_CFG3 (0x87) @@ -161,6 +165,10 @@ #define MCP_20MHz_40kBPS_CFG2 (0xFF) #define MCP_20MHz_40kBPS_CFG3 (0x87) +#define MCP_20MHz_33k3BPS_CFG1 (0x0B) +#define MCP_20MHz_33k3BPS_CFG2 (0xFF) +#define MCP_20MHz_33k3BPS_CFG3 (0x87) + enum CAN_CLOCK { MCP_20MHZ, MCP_16MHZ, @@ -186,6 +194,14 @@ enum CAN_SPEED { CAN_1000KBPS }; +enum CAN_CLKOUT { + CLKOUT_DISABLE = -1, + CLKOUT_DIV1 = 0x0, + CLKOUT_DIV2 = 0x1, + CLKOUT_DIV4 = 0x2, + CLKOUT_DIV8 = 0x3, +}; + class MCP2515 { public: @@ -264,6 +280,8 @@ class MCP2515 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; @@ -298,7 +316,6 @@ class MCP2515 TXB_TXP = 0x03 }; - static const uint8_t EFLG_ERRORMASK = EFLG_RX1OVR | EFLG_RX0OVR | EFLG_TXBO @@ -446,6 +463,7 @@ class MCP2515 ERROR setSleepMode(); ERROR setLoopbackMode(); ERROR setNormalMode(); + ERROR setClkOut(const CAN_CLKOUT divisor); ERROR setBitrate(const CAN_SPEED canSpeed); ERROR setBitrate(const CAN_SPEED canSpeed, const CAN_CLOCK canClock); ERROR setFilterMask(const MASK num, const bool ext, const uint32_t ulData);