From 8c75166c79f90d5d103484aeb0fb91e1cff849a5 Mon Sep 17 00:00:00 2001 From: CarlosHdezM <64612604+CarlosHdezM@users.noreply.github.com> Date: Sat, 8 Oct 2022 12:11:57 -0500 Subject: [PATCH] MCP2515 constructor now has an optional SPIClass pointer as its last parameter to allow selecting a different SPI peripheral. Fully backward compatible. All the code that works so far will continue to work correctly without any changes. - If no argument is passed during construction (defaults to nullptr), the Arduino default "SPI" will be used and initialized with begin(). - If a SPIClass to use is specified, then it is the library user responsibility to initialize that SPI ( other_spi.begin()) with the proper settings outside of the library (I.E. in void setup()). In this way one can use different SPI pins in boards that support it (ESP32, some STM32). Thanks to @morcibacsi and @FStefanni for the suggestions. Tested on ESP32 HSPI and VSPI with default and custom pins. It should also work with all boards featuring multiple SPI peripherals (SPI1, SPI2, etc.). --- mcp2515.cpp | 52 +++++++++++++++++++++++++++++----------------------- mcp2515.h | 3 ++- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/mcp2515.cpp b/mcp2515.cpp index 271a37c..6f5464b 100644 --- a/mcp2515.cpp +++ b/mcp2515.cpp @@ -12,9 +12,15 @@ const struct MCP2515::RXBn_REGS MCP2515::RXB[N_RXBUFFERS] = { {MCP_RXB1CTRL, MCP_RXB1SIDH, MCP_RXB1DATA, CANINTF_RX1IF} }; -MCP2515::MCP2515(const uint8_t _CS, const uint32_t _SPI_CLOCK) +MCP2515::MCP2515(const uint8_t _CS, const uint32_t _SPI_CLOCK, SPIClass * _SPI) { - SPI.begin(); + if (_SPI != nullptr) { + SPIn = _SPI; + } + else { + SPIn = &SPI; + SPIn->begin(); + } SPICS = _CS; SPI_CLOCK = _SPI_CLOCK; @@ -23,19 +29,19 @@ MCP2515::MCP2515(const uint8_t _CS, const uint32_t _SPI_CLOCK) } void MCP2515::startSPI() { - SPI.beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0)); + SPIn->beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0)); digitalWrite(SPICS, LOW); } void MCP2515::endSPI() { digitalWrite(SPICS, HIGH); - SPI.endTransaction(); + SPIn->endTransaction(); } MCP2515::ERROR MCP2515::reset(void) { startSPI(); - SPI.transfer(INSTRUCTION_RESET); + SPIn->transfer(INSTRUCTION_RESET); endSPI(); delay(10); @@ -86,9 +92,9 @@ MCP2515::ERROR MCP2515::reset(void) uint8_t MCP2515::readRegister(const REGISTER reg) { startSPI(); - SPI.transfer(INSTRUCTION_READ); - SPI.transfer(reg); - uint8_t ret = SPI.transfer(0x00); + SPIn->transfer(INSTRUCTION_READ); + SPIn->transfer(reg); + uint8_t ret = SPIn->transfer(0x00); endSPI(); return ret; @@ -97,11 +103,11 @@ uint8_t MCP2515::readRegister(const REGISTER reg) void MCP2515::readRegisters(const REGISTER reg, uint8_t values[], const uint8_t n) { startSPI(); - SPI.transfer(INSTRUCTION_READ); - SPI.transfer(reg); + SPIn->transfer(INSTRUCTION_READ); + SPIn->transfer(reg); // mcp2515 has auto-increment of address-pointer for (uint8_t i=0; itransfer(0x00); } endSPI(); } @@ -109,19 +115,19 @@ void MCP2515::readRegisters(const REGISTER reg, uint8_t values[], const uint8_t void MCP2515::setRegister(const REGISTER reg, const uint8_t value) { startSPI(); - SPI.transfer(INSTRUCTION_WRITE); - SPI.transfer(reg); - SPI.transfer(value); + SPIn->transfer(INSTRUCTION_WRITE); + SPIn->transfer(reg); + SPIn->transfer(value); endSPI(); } void MCP2515::setRegisters(const REGISTER reg, const uint8_t values[], const uint8_t n) { startSPI(); - SPI.transfer(INSTRUCTION_WRITE); - SPI.transfer(reg); + SPIn->transfer(INSTRUCTION_WRITE); + SPIn->transfer(reg); for (uint8_t i=0; itransfer(values[i]); } endSPI(); } @@ -129,18 +135,18 @@ void MCP2515::setRegisters(const REGISTER reg, const uint8_t values[], const uin void MCP2515::modifyRegister(const REGISTER reg, const uint8_t mask, const uint8_t data) { startSPI(); - SPI.transfer(INSTRUCTION_BITMOD); - SPI.transfer(reg); - SPI.transfer(mask); - SPI.transfer(data); + SPIn->transfer(INSTRUCTION_BITMOD); + SPIn->transfer(reg); + SPIn->transfer(mask); + SPIn->transfer(data); endSPI(); } uint8_t MCP2515::getStatus(void) { startSPI(); - SPI.transfer(INSTRUCTION_READ_STATUS); - uint8_t i = SPI.transfer(0x00); + SPIn->transfer(INSTRUCTION_READ_STATUS); + uint8_t i = SPIn->transfer(0x00); endSPI(); return i; diff --git a/mcp2515.h b/mcp2515.h index 73a3524..1dd51e2 100644 --- a/mcp2515.h +++ b/mcp2515.h @@ -444,6 +444,7 @@ class MCP2515 uint8_t SPICS; uint32_t SPI_CLOCK; + SPIClass * SPIn; private: @@ -461,7 +462,7 @@ class MCP2515 void prepareId(uint8_t *buffer, const bool ext, const uint32_t id); public: - MCP2515(const uint8_t _CS, const uint32_t _SPI_CLOCK = DEFAULT_SPI_CLOCK); + MCP2515(const uint8_t _CS, const uint32_t _SPI_CLOCK = DEFAULT_SPI_CLOCK, SPIClass * _SPI = nullptr); ERROR reset(void); ERROR setConfigMode(); ERROR setListenOnlyMode();