From 55f2ef26b88065f788ace39a6f55f7b4ffb8d455 Mon Sep 17 00:00:00 2001 From: Martin Turski Date: Thu, 20 Oct 2022 21:48:04 +0200 Subject: [PATCH] - fixed SPI bus sharing between TFT, SD, Touch, etc in combination with TMC by properly initializing and then terminating the SPI usage in the way that this library was previously written it was not easy to share the SPI bus between components because the SPI protocol was not properly terminated/cleaned-up across SPI sessions, causing conflicts for different SPI bus components. This library has been tested with Marlin 2.1.x bugfix on this repo: github.com/quiret/Marlin/ There is a Marlin pull request that would really appreciate this improvement: https://github.com/MarlinFirmware/Marlin/pull/24911 Please consider releasing another version of this library with the included fix so that the Marlin FW can be drastically improved! clobbering the global SPI object is not a good idea, especially on single-SPI boards... Martin Turski, company owner of EirDev (turningtides@outlook.de) --- src/TMCStepper.h | 40 ++++++++++++++--------------- src/source/TMC2130Stepper.cpp | 48 ++++++++++++++++++++++------------- src/source/TMC2160Stepper.cpp | 10 +++----- src/source/TMC2660Stepper.cpp | 47 ++++++++++++++++++++++++++-------- src/source/TMC5130Stepper.cpp | 10 +++----- src/source/TMC5160Stepper.cpp | 10 +++----- 6 files changed, 99 insertions(+), 66 deletions(-) diff --git a/src/TMCStepper.h b/src/TMCStepper.h index 6ea5661c..071e7d27 100644 --- a/src/TMCStepper.h +++ b/src/TMCStepper.h @@ -151,9 +151,8 @@ class TMCStepper { class TMC2130Stepper : public TMCStepper { public: - TMC2130Stepper(uint16_t pinCS, float RS = default_RS, int8_t link_index = -1); - TMC2130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); - TMC2130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); + TMC2130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); + TMC2130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); void begin(); void defaults(); void setSPISpeed(uint32_t speed); @@ -369,6 +368,9 @@ class TMC2130Stepper : public TMCStepper { static uint32_t spi_speed; // Default 2MHz const uint16_t _pinCS; + const uint16_t _pinMISO; + const uint16_t _pinMOSI; + const uint16_t _pinSCK; SW_SPIClass * TMC_SW_SPI = nullptr; static constexpr float default_RS = 0.11; @@ -378,9 +380,8 @@ class TMC2130Stepper : public TMCStepper { class TMC2160Stepper : public TMC2130Stepper { public: - TMC2160Stepper(uint16_t pinCS, float RS = default_RS, int8_t link_index = -1); - TMC2160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); - TMC2160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); + TMC2160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); + TMC2160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); void begin(); void defaults(); void push(); @@ -477,9 +478,8 @@ class TMC2160Stepper : public TMC2130Stepper { class TMC5130Stepper : public TMC2160Stepper { public: - TMC5130Stepper(uint16_t pinCS, float RS = default_RS, int8_t link_index = -1); - TMC5130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); - TMC5130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); + TMC5130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); + TMC5130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); void begin(); void defaults(); @@ -721,9 +721,8 @@ class TMC5130Stepper : public TMC2160Stepper { class TMC5160Stepper : public TMC5130Stepper { public: - TMC5160Stepper(uint16_t pinCS, float RS = default_RS, int8_t link_index = -1); - TMC5160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); - TMC5160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1); + TMC5160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); + TMC5160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false); void rms_current(uint16_t mA) { TMC2160Stepper::rms_current(mA); } void rms_current(uint16_t mA, float mult) { TMC2160Stepper::rms_current(mA, mult); } @@ -815,11 +814,10 @@ class TMC5160Stepper : public TMC5130Stepper { class TMC5161Stepper : public TMC5160Stepper { public: - TMC5161Stepper(uint16_t pinCS, float RS = default_RS, int8_t link_index = -1) : TMC5160Stepper(pinCS, RS, link_index) {} - TMC5161Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1) : - TMC5160Stepper(pinCS, pinMOSI, pinMISO, pinSCK, link_index) {} - TMC5161Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1) : - TMC5160Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link_index) {} + TMC5161Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false) : + TMC5160Stepper(pinCS, pinMOSI, pinMISO, pinSCK, link_index, softSPI) {} + TMC5161Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link_index = -1, bool softSPI = false) : + TMC5160Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link_index, softSPI) {} }; class TMC2208Stepper : public TMCStepper { @@ -1103,9 +1101,8 @@ class TMC2224Stepper : public TMC2208Stepper { class TMC2660Stepper { public: - TMC2660Stepper(uint16_t pinCS, float RS = default_RS); - TMC2660Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK); - TMC2660Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK); + TMC2660Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, bool softSPI = false); + TMC2660Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, bool softSPI = false); void write(uint8_t addressByte, uint32_t config); uint32_t read(); void switchCSpin(bool state); @@ -1255,6 +1252,9 @@ class TMC2660Stepper { INIT_REGISTER(READ_RDSEL10){{.sr=0}}; const uint16_t _pinCS; + const uint16_t _pinMISO; + const uint16_t _pinMOSI; + const uint16_t _pinSCK; const float Rsense; static constexpr float default_RS = 0.1; float holdMultiplier = 0.5; diff --git a/src/source/TMC2130Stepper.cpp b/src/source/TMC2130Stepper.cpp index 9d01c4fc..af11f377 100644 --- a/src/source/TMC2130Stepper.cpp +++ b/src/source/TMC2130Stepper.cpp @@ -4,37 +4,46 @@ int8_t TMC2130Stepper::chain_length = 0; uint32_t TMC2130Stepper::spi_speed = 16000000/8; -TMC2130Stepper::TMC2130Stepper(uint16_t pinCS, float RS, int8_t link) : - TMCStepper(RS), - _pinCS(pinCS), - link_index(link) - { - defaults(); - - if (link > chain_length) - chain_length = link; - } - -TMC2130Stepper::TMC2130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : +TMC2130Stepper::TMC2130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : TMCStepper(default_RS), _pinCS(pinCS), + _pinMISO(pinMISO), + _pinMOSI(pinMOSI), + _pinSCK(pinSCK), link_index(link) { - SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); - TMC_SW_SPI = SW_SPI_Obj; + if (softSPI) + { + SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); + TMC_SW_SPI = SW_SPI_Obj; + } + else + { + TMC_SW_SPI = nullptr; + } defaults(); if (link > chain_length) chain_length = link; } -TMC2130Stepper::TMC2130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : +TMC2130Stepper::TMC2130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : TMCStepper(RS), _pinCS(pinCS), + _pinMISO(pinMISO), + _pinMOSI(pinMOSI), + _pinSCK(pinSCK), link_index(link) { - SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); - TMC_SW_SPI = SW_SPI_Obj; + if (softSPI) + { + SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); + TMC_SW_SPI = SW_SPI_Obj; + } + else + { + TMC_SW_SPI = nullptr; + } defaults(); if (link > chain_length) @@ -67,6 +76,10 @@ void TMC2130Stepper::switchCSpin(bool state) { __attribute__((weak)) void TMC2130Stepper::beginTransaction() { if (TMC_SW_SPI == nullptr) { + SPI.setMISO(_pinMISO); + SPI.setMOSI(_pinMOSI); + SPI.setSCLK(_pinSCK); + SPI.begin(); SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3)); } } @@ -74,6 +87,7 @@ __attribute__((weak)) void TMC2130Stepper::endTransaction() { if (TMC_SW_SPI == nullptr) { SPI.endTransaction(); + SPI.end(); } } diff --git a/src/source/TMC2160Stepper.cpp b/src/source/TMC2160Stepper.cpp index f97487a9..eb3e9921 100644 --- a/src/source/TMC2160Stepper.cpp +++ b/src/source/TMC2160Stepper.cpp @@ -1,13 +1,11 @@ #include "TMCStepper.h" #include "TMC_MACROS.h" -TMC2160Stepper::TMC2160Stepper(uint16_t pinCS, float RS, int8_t link) : TMC2130Stepper(pinCS, RS, link) +TMC2160Stepper::TMC2160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : + TMC2130Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link, softSPI) { defaults(); } -TMC2160Stepper::TMC2160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : - TMC2130Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link) - { defaults(); } -TMC2160Stepper::TMC2160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : - TMC2130Stepper(pinCS, default_RS, pinMOSI, pinMISO, pinSCK, link) +TMC2160Stepper::TMC2160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : + TMC2130Stepper(pinCS, default_RS, pinMOSI, pinMISO, pinSCK, link, softSPI) { defaults(); } void TMC2160Stepper::begin() { diff --git a/src/source/TMC2660Stepper.cpp b/src/source/TMC2660Stepper.cpp index 316f7fa8..966add9f 100644 --- a/src/source/TMC2660Stepper.cpp +++ b/src/source/TMC2660Stepper.cpp @@ -1,25 +1,40 @@ #include "TMCStepper.h" #include "SW_SPI.h" -TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, float RS) : - _pinCS(pinCS), - Rsense(RS) - {} - -TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) : +TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, bool softSPI) : _pinCS(pinCS), + _pinMISO(pinMISO), + _pinMOSI(pinMOSI), + _pinSCK(pinSCK), Rsense(default_RS) { - SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); - TMC_SW_SPI = SW_SPI_Obj; + if (softSPI) + { + SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); + TMC_SW_SPI = SW_SPI_Obj; + } + else + { + TMC_SW_SPI = nullptr; + } } -TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) : +TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, bool softSPI) : _pinCS(pinCS), + _pinMISO(pinMISO), + _pinMOSI(pinMOSI), + _pinSCK(pinSCK), Rsense(RS) { - SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); - TMC_SW_SPI = SW_SPI_Obj; + if (softSPI) + { + SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK); + TMC_SW_SPI = SW_SPI_Obj; + } + else + { + TMC_SW_SPI = nullptr; + } } void TMC2660Stepper::switchCSpin(bool state) { @@ -38,6 +53,10 @@ uint32_t TMC2660Stepper::read() { response <<= 8; response |= TMC_SW_SPI->transfer(dummy & 0xFF); } else { + SPI.setMISO(_pinMISO); + SPI.setMOSI(_pinMOSI); + SPI.setSCLK(_pinSCK); + SPI.begin(); SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3)); switchCSpin(LOW); response |= SPI.transfer((dummy >> 16) & 0xFF); @@ -46,6 +65,7 @@ uint32_t TMC2660Stepper::read() { response <<= 8; response |= SPI.transfer(dummy & 0xFF); SPI.endTransaction(); + SPI.end(); } switchCSpin(HIGH); return response >> 4; @@ -59,12 +79,17 @@ void TMC2660Stepper::write(uint8_t addressByte, uint32_t config) { TMC_SW_SPI->transfer((data >> 8) & 0xFF); TMC_SW_SPI->transfer(data & 0xFF); } else { + SPI.setMISO(_pinMISO); + SPI.setMOSI(_pinMOSI); + SPI.setSCLK(_pinSCK); + SPI.begin(); SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3)); switchCSpin(LOW); SPI.transfer((data >> 16) & 0xFF); SPI.transfer((data >> 8) & 0xFF); SPI.transfer(data & 0xFF); SPI.endTransaction(); + SPI.end(); } switchCSpin(HIGH); } diff --git a/src/source/TMC5130Stepper.cpp b/src/source/TMC5130Stepper.cpp index efc95bef..45c023e8 100644 --- a/src/source/TMC5130Stepper.cpp +++ b/src/source/TMC5130Stepper.cpp @@ -1,13 +1,11 @@ #include "TMCStepper.h" #include "TMC_MACROS.h" -TMC5130Stepper::TMC5130Stepper(uint16_t pinCS, float RS, int8_t link) : TMC2160Stepper(pinCS, RS, link) +TMC5130Stepper::TMC5130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI): + TMC2160Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link, softSPI) { defaults(); } -TMC5130Stepper::TMC5130Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link): - TMC2160Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link) - { defaults(); } -TMC5130Stepper::TMC5130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : - TMC2160Stepper(pinCS, default_RS, pinMOSI, pinMISO, pinSCK, link) +TMC5130Stepper::TMC5130Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : + TMC2160Stepper(pinCS, default_RS, pinMOSI, pinMISO, pinSCK, link, softSPI) { defaults(); } void TMC5130Stepper::begin() { diff --git a/src/source/TMC5160Stepper.cpp b/src/source/TMC5160Stepper.cpp index d9b4221b..bc53f241 100644 --- a/src/source/TMC5160Stepper.cpp +++ b/src/source/TMC5160Stepper.cpp @@ -1,13 +1,11 @@ #include "TMCStepper.h" #include "TMC_MACROS.h" -TMC5160Stepper::TMC5160Stepper(uint16_t pinCS, float RS, int8_t link) : TMC5130Stepper(pinCS, RS, link) +TMC5160Stepper::TMC5160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : + TMC5130Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link, softSPI) { defaults(); } -TMC5160Stepper::TMC5160Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : - TMC5130Stepper(pinCS, RS, pinMOSI, pinMISO, pinSCK, link) - { defaults(); } -TMC5160Stepper::TMC5160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link) : - TMC5130Stepper(pinCS, default_RS, pinMOSI, pinMISO, pinSCK, link) +TMC5160Stepper::TMC5160Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK, int8_t link, bool softSPI) : + TMC5130Stepper(pinCS, default_RS, pinMOSI, pinMISO, pinSCK, link, softSPI) { defaults(); } void TMC5160Stepper::defaults() {