Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAX31865 enhancements #22682

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions Marlin/src/HAL/shared/Delay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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))
2 changes: 1 addition & 1 deletion Marlin/src/HAL/shared/Marduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
125 changes: 62 additions & 63 deletions Marlin/src/libs/MAX31865.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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
*
Expand All @@ -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
thinkyhead marked this conversation as resolved.
Show resolved Hide resolved
}
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);
Expand All @@ -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
}

/**
Expand Down Expand Up @@ -371,7 +345,6 @@ float MAX31865::temperature(float Rrtd) {
// private:
//


/**
* Set a value in the configuration register.
*
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand All @@ -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.
thinkyhead marked this conversation as resolved.
Show resolved Hide resolved
OUT_WRITE(_sclk, LOW);
SET_OUTPUT(_mosi);
SET_INPUT(_miso);
#endif
}

#endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865
11 changes: 10 additions & 1 deletion Marlin/src/libs/MAX31865.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ class MAX31865 {
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);
Expand All @@ -99,7 +106,9 @@ class MAX31865 {
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
Expand Down
3 changes: 2 additions & 1 deletion buildroot/tests/LPC1769
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
5 changes: 3 additions & 2 deletions buildroot/tests/teensy41
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down