🍻 Preliminary fix for Max31865 SPI (#22682)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
		| @@ -92,6 +92,12 @@ void calibrate_delay_loop(); | ||||
|  | ||||
|   #define DELAY_CYCLES(X) do { SmartDelay<IS_CONSTEXPR(X), IS_CONSTEXPR(X) ? X : 0> _smrtdly_X(X); } while(0) | ||||
|  | ||||
|   #if GCC_VERSION <= 70000 | ||||
|     #define DELAY_CYCLES_VAR(X) DelayCycleFnc(X) | ||||
|   #else | ||||
|     #define DELAY_CYCLES_VAR DELAY_CYCLES | ||||
|   #endif | ||||
|  | ||||
|   // For delay in microseconds, no smart delay selection is required, directly call the delay function | ||||
|   // Teensy compiler is too old and does not accept smart delay compile-time / run-time selection correctly | ||||
|   #define DELAY_US(x) DelayCycleFnc((x) * ((F_CPU) / 1000000UL)) | ||||
| @@ -200,9 +206,12 @@ void calibrate_delay_loop(); | ||||
| #endif | ||||
|  | ||||
| #if ENABLED(DELAY_NS_ROUND_DOWN) | ||||
|   #define DELAY_NS(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL) / 1000UL)          // floor | ||||
|   #define _NS_TO_CYCLES(x) ( (x) * ((F_CPU) / 1000000UL)        / 1000UL) // floor | ||||
| #elif ENABLED(DELAY_NS_ROUND_CLOSEST) | ||||
|   #define DELAY_NS(x) DELAY_CYCLES(((x) * ((F_CPU) / 1000000UL) + 500) / 1000UL)  // round | ||||
|   #define _NS_TO_CYCLES(x) (((x) * ((F_CPU) / 1000000UL) + 500) / 1000UL) // round | ||||
| #else | ||||
|   #define DELAY_NS(x) DELAY_CYCLES(((x) * ((F_CPU) / 1000000UL) + 999) / 1000UL)  // "ceil" | ||||
|   #define _NS_TO_CYCLES(x) (((x) * ((F_CPU) / 1000000UL) + 999) / 1000UL) // "ceil" | ||||
| #endif | ||||
|  | ||||
| #define DELAY_NS(x)         DELAY_CYCLES(_NS_TO_CYCLES(x)) | ||||
| #define DELAY_NS_VAR(x) DELAY_CYCLES_VAR(_NS_TO_CYCLES(x)) | ||||
|   | ||||
| @@ -39,7 +39,7 @@ | ||||
| #define DISABLED(V...) DO(DIS,&&,V) | ||||
|  | ||||
| #undef _BV | ||||
| #define _BV(b) (1UL << (b)) | ||||
| #define _BV(b) (1 << (b)) | ||||
| #ifndef SBI | ||||
|   #define SBI(A,B) (A |= _BV(B)) | ||||
| #endif | ||||
|   | ||||
| @@ -48,20 +48,17 @@ | ||||
|  | ||||
| #if HAS_MAX31865 && !USE_ADAFRUIT_MAX31865 | ||||
|  | ||||
| //#include <SoftwareSPI.h> // TODO: switch to SPIclass/SoftSPI | ||||
| #include "MAX31865.h" | ||||
|  | ||||
| #ifdef TARGET_LPC1768 | ||||
|   #include <SoftwareSPI.h> | ||||
| #endif | ||||
|  | ||||
| // The maximum speed the MAX31865 can do is 5 MHz | ||||
| SPISettings MAX31865::spiConfig = SPISettings( | ||||
|   #if defined(TARGET_LPC1768) | ||||
|     SPI_QUARTER_SPEED | ||||
|   #elif defined(ARDUINO_ARCH_STM32) | ||||
|     SPI_CLOCK_DIV4 | ||||
|   #else | ||||
|     500000 | ||||
|   #endif | ||||
|   , MSBFIRST | ||||
|   , SPI_MODE_1 // CPOL0 CPHA1 | ||||
|   TERN(TARGET_LPC1768, SPI_QUARTER_SPEED, TERN(ARDUINO_ARCH_STM32, SPI_CLOCK_DIV4, 500000)), | ||||
|   MSBFIRST, | ||||
|   SPI_MODE1 // CPOL0 CPHA1 | ||||
| ); | ||||
|  | ||||
| #ifndef LARGE_PINMAP | ||||
| @@ -93,7 +90,7 @@ SPISettings MAX31865::spiConfig = SPISettings( | ||||
|     _sclk = _miso = _mosi = -1; | ||||
|   } | ||||
|  | ||||
| #else | ||||
| #else // LARGE_PINMAP | ||||
|  | ||||
|   /** | ||||
|    * Create the interface object using software (bitbang) SPI for PIN values | ||||
| @@ -106,9 +103,7 @@ SPISettings MAX31865::spiConfig = SPISettings( | ||||
|    * @param spi_clk      the SPI clock pin to use | ||||
|    * @param pin_mapping  set to 1 for positive pin values | ||||
|    */ | ||||
|   MAX31865::MAX31865(uint32_t spi_cs, uint32_t spi_mosi, | ||||
|                      uint32_t spi_miso, uint32_t spi_clk, | ||||
|                      uint8_t pin_mapping) { | ||||
|   MAX31865::MAX31865(uint32_t spi_cs, uint32_t spi_mosi, uint32_t spi_miso, uint32_t spi_clk, uint8_t pin_mapping) { | ||||
|     _cs = spi_cs; | ||||
|     _mosi = spi_mosi; | ||||
|     _miso = spi_miso; | ||||
| @@ -130,14 +125,12 @@ SPISettings MAX31865::spiConfig = SPISettings( | ||||
|  | ||||
| #endif // LARGE_PINMAP | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Instance & Class methods | ||||
|  * | ||||
|  */ | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Initialize the SPI interface and set the number of RTD wires used | ||||
|  * | ||||
| @@ -152,22 +145,13 @@ void MAX31865::begin(max31865_numwires_t wires, float zero, float ref) { | ||||
|   OUT_WRITE(_cs, HIGH); | ||||
|  | ||||
|   if (_sclk != TERN(LARGE_PINMAP, -1UL, -1)) { | ||||
|     // Define pin modes for Software SPI | ||||
|     #ifdef MAX31865_DEBUG | ||||
|       SERIAL_ECHOLN("Initializing MAX31865 Software SPI"); | ||||
|     #endif | ||||
|  | ||||
|     OUT_WRITE(_sclk, LOW); | ||||
|     SET_OUTPUT(_mosi); | ||||
|     SET_INPUT(_miso); | ||||
|     softSpiBegin(SPI_QUARTER_SPEED); // Define pin modes for Software SPI | ||||
|   } | ||||
|   else { | ||||
|     // Start and configure hardware SPI | ||||
|     #ifdef MAX31865_DEBUG | ||||
|       SERIAL_ECHOLN("Initializing MAX31865 Hardware SPI"); | ||||
|       SERIAL_ECHOLNPGM("Initializing MAX31865 Hardware SPI"); | ||||
|     #endif | ||||
|  | ||||
|     SPI.begin(); | ||||
|     SPI.begin();    // Start and configure hardware SPI | ||||
|   } | ||||
|  | ||||
|   setWires(wires); | ||||
| @@ -176,25 +160,15 @@ void MAX31865::begin(max31865_numwires_t wires, float zero, float ref) { | ||||
|   clearFault(); | ||||
|  | ||||
|   #ifdef MAX31865_DEBUG_SPI | ||||
|     #ifndef LARGE_PINMAP | ||||
|       SERIAL_ECHOLNPGM( | ||||
|         "Regular begin call with _cs: ", _cs, | ||||
|         " _miso: ", _miso, | ||||
|         " _sclk: ", _sclk, | ||||
|         " _mosi: ", _mosi | ||||
|       ); | ||||
|     #else | ||||
|       SERIAL_ECHOLNPGM( | ||||
|         "LARGE_PINMAP begin call with _cs: ", _cs, | ||||
|         " _miso: ", _miso, | ||||
|         " _sclk: ", _sclk, | ||||
|         " _mosi: ", _mosi | ||||
|       ); | ||||
|     #endif // LARGE_PINMAP | ||||
|  | ||||
|     SERIAL_ECHOLNPGM("config: ", readRegister8(MAX31856_CONFIG_REG)); | ||||
|     SERIAL_EOL(); | ||||
|   #endif // MAX31865_DEBUG_SPI | ||||
|     SERIAL_ECHOLNPGM( | ||||
|       TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular") | ||||
|       " begin call with _cs: ", _cs, | ||||
|       " _miso: ", _miso, | ||||
|       " _sclk: ", _sclk, | ||||
|       " _mosi: ", _mosi, | ||||
|       " config: ", readRegister8(MAX31856_CONFIG_REG) | ||||
|     ); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -371,7 +345,6 @@ float MAX31865::temperature(float Rrtd) { | ||||
| // private: | ||||
| // | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Set a value in the configuration register. | ||||
|  * | ||||
| @@ -432,10 +405,15 @@ void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) { | ||||
|     WRITE(_sclk, LOW); | ||||
|  | ||||
|   WRITE(_cs, LOW); | ||||
|   spixfer(addr); | ||||
|  | ||||
|   #ifdef TARGET_LPC1768 | ||||
|     DELAY_CYCLES(_spi_speed); | ||||
|   #endif | ||||
|  | ||||
|   spiTransfer(addr); | ||||
|  | ||||
|   while (n--) { | ||||
|     buffer[0] = spixfer(0xFF); | ||||
|     buffer[0] = spiTransfer(0xFF); | ||||
|     #ifdef MAX31865_DEBUG_SPI | ||||
|       SERIAL_ECHOLNPGM("buffer read ", n, " data: ", buffer[0]); | ||||
|     #endif | ||||
| @@ -462,8 +440,12 @@ void MAX31865::writeRegister8(uint8_t addr, uint8_t data) { | ||||
|  | ||||
|   WRITE(_cs, LOW); | ||||
|  | ||||
|   spixfer(addr | 0x80); // make sure top bit is set | ||||
|   spixfer(data); | ||||
|   #ifdef TARGET_LPC1768 | ||||
|     DELAY_CYCLES(_spi_speed); | ||||
|   #endif | ||||
|  | ||||
|   spiTransfer(addr | 0x80); // make sure top bit is set | ||||
|   spiTransfer(data); | ||||
|  | ||||
|   if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) | ||||
|     SPI.endTransaction(); | ||||
| @@ -480,21 +462,38 @@ void MAX31865::writeRegister8(uint8_t addr, uint8_t data) { | ||||
|  * @param  x  an 8-bit chunk of data to write | ||||
|  * @return    the 8-bit response | ||||
|  */ | ||||
| uint8_t MAX31865::spixfer(uint8_t x) { | ||||
| uint8_t MAX31865::spiTransfer(uint8_t x) { | ||||
|   if (_sclk == TERN(LARGE_PINMAP, -1UL, -1)) | ||||
|     return SPI.transfer(x); | ||||
|  | ||||
|   uint8_t reply = 0; | ||||
|   for (int i = 7; i >= 0; i--) { | ||||
|     reply <<= 1; | ||||
|     WRITE(_sclk, HIGH); | ||||
|     WRITE(_mosi, x & (1 << i)); | ||||
|     WRITE(_sclk, LOW); | ||||
|     if (READ(_miso)) | ||||
|       reply |= 1; | ||||
|   } | ||||
|   #ifdef TARGET_LPC1768 | ||||
|     return swSpiTransfer(x, _spi_speed, _sclk, _miso, _mosi); | ||||
|   #else | ||||
|     uint8_t reply = 0; | ||||
|     for (int i = 7; i >= 0; i--) { | ||||
|       WRITE(_sclk, HIGH);           DELAY_NS_VAR(_spi_delay); | ||||
|       reply <<= 1; | ||||
|       WRITE(_mosi, x & _BV(i));     DELAY_NS_VAR(_spi_delay); | ||||
|       if (READ(_miso)) reply |= 1; | ||||
|       WRITE(_sclk, LOW);            DELAY_NS_VAR(_spi_delay); | ||||
|     } | ||||
|     return reply; | ||||
|   #endif | ||||
| } | ||||
|  | ||||
|   return reply; | ||||
| void MAX31865::softSpiBegin(const uint8_t spi_speed) { | ||||
|   #ifdef MAX31865_DEBUG | ||||
|     SERIAL_ECHOLNPGM("Initializing MAX31865 Software SPI"); | ||||
|   #endif | ||||
|   #ifdef TARGET_LPC1768 | ||||
|     swSpiBegin(_sclk, _miso, _mosi); | ||||
|     _spi_speed = swSpiInit(spi_speed, _sclk, _mosi); | ||||
|   #else | ||||
|     _spi_delay = (100UL << spi_speed) / 3; // Calculate delay in ns. Top speed is ~10MHz, or 100ns delay between bits. | ||||
|     OUT_WRITE(_sclk, LOW); | ||||
|     SET_OUTPUT(_mosi); | ||||
|     SET_INPUT(_miso); | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865 | ||||
|   | ||||
| @@ -90,6 +90,13 @@ private: | ||||
|   static SPISettings spiConfig; | ||||
|  | ||||
|   TERN(LARGE_PINMAP, uint32_t, uint8_t) _sclk, _miso, _mosi, _cs; | ||||
|  | ||||
|   #ifdef TARGET_LPC1768 | ||||
|     uint8_t _spi_speed; | ||||
|   #else | ||||
|     uint16_t _spi_delay; | ||||
|   #endif | ||||
|  | ||||
|   float Rzero, Rref; | ||||
|  | ||||
|   void setConfig(uint8_t config, bool enable); | ||||
| @@ -99,7 +106,9 @@ private: | ||||
|   uint16_t readRegister16(uint8_t addr); | ||||
|  | ||||
|   void writeRegister8(uint8_t addr, uint8_t reg); | ||||
|   uint8_t spixfer(uint8_t addr); | ||||
|   uint8_t spiTransfer(uint8_t addr); | ||||
|  | ||||
|   void softSpiBegin(const uint8_t spi_speed); | ||||
|  | ||||
| public: | ||||
|   #ifdef LARGE_PINMAP | ||||
|   | ||||
| @@ -14,11 +14,12 @@ exec_test $1 $2 "Azteeg X5GT Example Configuration" "$3" | ||||
|  | ||||
| restore_configs | ||||
| opt_set MOTHERBOARD BOARD_SMOOTHIEBOARD \ | ||||
|         EXTRUDERS 2 TEMP_SENSOR_1 -1 TEMP_SENSOR_BED 5 \ | ||||
|         EXTRUDERS 2 TEMP_SENSOR_0 -5 TEMP_SENSOR_1 -1 TEMP_SENSOR_BED 5 TEMP_0_CS_PIN P1_29 \ | ||||
|         GRID_MAX_POINTS_X 16 \ | ||||
|         NOZZLE_CLEAN_START_POINT "{ {  10, 10, 3 }, {  10, 10, 3 } }" \ | ||||
|         NOZZLE_CLEAN_END_POINT "{ {  10, 20, 3 }, {  10, 20, 3 } }" | ||||
| opt_enable TFTGLCD_PANEL_SPI SDSUPPORT ADAPTIVE_FAN_SLOWING NO_FAN_SLOWING_IN_PID_TUNING \ | ||||
|            MAX31865_SENSOR_OHMS_0 MAX31865_CALIBRATION_OHMS_0 \ | ||||
|            FIX_MOUNTED_PROBE AUTO_BED_LEVELING_BILINEAR G29_RETRY_AND_RECOVER Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE \ | ||||
|            BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET LEVEL_CORNERS_USE_PROBE LEVEL_CORNERS_VERIFY_RAISED \ | ||||
|            PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE SLOW_PWM_HEATERS PIDTEMPBED EEPROM_SETTINGS INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT \ | ||||
|   | ||||
| @@ -15,12 +15,13 @@ exec_test $1 $2 "Teensy4.1 with default config" "$3" | ||||
| # | ||||
| restore_configs | ||||
| opt_set MOTHERBOARD BOARD_TEENSY41 \ | ||||
|         EXTRUDERS 2 TEMP_SENSOR_0 1 TEMP_SENSOR_1 5 TEMP_SENSOR_BED 1 \ | ||||
|         EXTRUDERS 2 TEMP_SENSOR_0 -5 TEMP_SENSOR_1 5 TEMP_SENSOR_BED 1 TEMP_0_CS_PIN 23 \ | ||||
|         I2C_SLAVE_ADDRESS 63 \ | ||||
|         GRID_MAX_POINTS_X 16 \ | ||||
|         NOZZLE_CLEAN_START_POINT "{ {  10, 10, 3 }, {  10, 10, 3 } }" \ | ||||
|         NOZZLE_CLEAN_END_POINT "{ {  10, 20, 3 }, {  10, 20, 3 } }" | ||||
| opt_enable EXTENSIBLE_UI LCD_INFO_MENU SDSUPPORT SDCARD_SORT_ALPHA \ | ||||
| opt_enable MAX31865_SENSOR_OHMS_0 MAX31865_CALIBRATION_OHMS_0 \ | ||||
|            EXTENSIBLE_UI LCD_INFO_MENU SDSUPPORT SDCARD_SORT_ALPHA \ | ||||
|            FILAMENT_LCD_DISPLAY CALIBRATION_GCODE BAUD_RATE_GCODE \ | ||||
|            FIX_MOUNTED_PROBE Z_SAFE_HOMING AUTO_BED_LEVELING_BILINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE \ | ||||
|            BABYSTEPPING BABYSTEP_XY BABYSTEP_ZPROBE_OFFSET \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user