🐛 Fix dual MAX31865 initialization issues (#23496)

This commit is contained in:
John Lagonikas 2022-02-05 03:10:59 +02:00 committed by Scott Lahteine
parent a23ecf0d2f
commit cdcf31453b
4 changed files with 216 additions and 152 deletions

View file

@ -138,24 +138,21 @@
#endif #endif
/** /**
* Configuration options for MAX Thermocouples (-2, -3, -5). * Thermocouple Options for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5).
* FORCE_HW_SPI: Ignore SCK/MOSI/MISO pins and just use the CS pin & default SPI bus.
* MAX31865_WIRES: Set the number of wires for the probe connected to a MAX31865 board, 2-4. Default: 2
* MAX31865_50HZ: Enable 50Hz filter instead of the default 60Hz.
* MAX31865_USE_READ_ERROR_DETECTION: Detects random read errors from value spikes (a 20°C difference in less than 1sec)
* MAX31865_USE_AUTO_MODE: Faster and more frequent reads than 1-shot, but bias voltage always on, slightly affecting RTD temperature.
* MAX31865_MIN_SAMPLING_TIME_MSEC: in 1-shot mode, the minimum time between subsequent reads. This reduces the effect of bias voltage by leaving the sensor unpowered for longer intervals.
* MAX31865_WIRE_OHMS: In 2-wire configurations, manually set the wire resistance for more accurate readings
*/ */
//#define TEMP_SENSOR_FORCE_HW_SPI //#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus.
//#define MAX31865_SENSOR_WIRES_0 2 //#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board.
//#define MAX31865_SENSOR_WIRES_1 2 //#define MAX31865_SENSOR_WIRES_1 2
//#define MAX31865_50HZ_FILTER
//#define MAX31865_USE_READ_ERROR_DETECTION //#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz.
//#define MAX31865_USE_AUTO_MODE //#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors.
//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100
//#define MAX31865_WIRE_OHMS_0 0.0f //#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature.
//#define MAX31865_WIRE_OHMS_1 0.0f //#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals.
//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439).
//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings.
//#define MAX31865_WIRE_OHMS_1 0.0f
/** /**
* Hephestos 2 24V heated bed upgrade kit. * Hephestos 2 24V heated bed upgrade kit.

View file

@ -166,6 +166,8 @@ void calibrate_delay_loop();
// Delay in microseconds // Delay in microseconds
#define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL)) #define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL))
#define DELAY_CYCLES_VAR DELAY_CYCLES
#elif defined(ESP32) || defined(__PLAT_LINUX__) || defined(__PLAT_NATIVE_SIM__) #elif defined(ESP32) || defined(__PLAT_LINUX__) || defined(__PLAT_NATIVE_SIM__)
// DELAY_CYCLES specified inside platform // DELAY_CYCLES specified inside platform

View file

@ -50,10 +50,6 @@
#define MAX31865_MIN_SAMPLING_TIME_MSEC 0 #define MAX31865_MIN_SAMPLING_TIME_MSEC 0
#endif #endif
#ifdef TARGET_LPC1768
#include <SoftwareSPI.h>
#endif
#define DEBUG_OUT ENABLED(DEBUG_MAX31865) #define DEBUG_OUT ENABLED(DEBUG_MAX31865)
#include "../core/debug_out.h" #include "../core/debug_out.h"
@ -151,24 +147,62 @@ void MAX31865::begin(max31865_numwires_t wires, float zero_res, float ref_res, f
digitalWrite(cselPin, HIGH); digitalWrite(cselPin, HIGH);
if (sclkPin != TERN(LARGE_PINMAP, -1UL, 255)) if (sclkPin != TERN(LARGE_PINMAP, -1UL, 255))
softSpiBegin(SPI_QUARTER_SPEED); // Define pin modes for Software SPI softSpiInit(); // Define pin modes for Software SPI
else { else {
DEBUG_ECHOLNPGM("Initializing MAX31865 Hardware SPI"); DEBUG_ECHOLNPGM("Init MAX31865 Hardware SPI");
SPI.begin(); // Start and configure hardware SPI SPI.begin(); // Start and configure hardware SPI
} }
initFixedFlags(wires); initFixedFlags(wires);
clearFault(); // also initializes flags DEBUG_ECHOLNPGM("MAX31865 Regs: CFG ", readRegister8(MAX31865_CONFIG_REG),
"|RTD ", readRegister16(MAX31865_RTDMSB_REG),
"|HTHRS ", readRegister16(MAX31865_HFAULTMSB_REG),
"|LTHRS ", readRegister16(MAX31865_LFAULTMSB_REG),
"|FLT ", readRegister8(MAX31865_FAULTSTAT_REG));
#if DISABLED(MAX31865_USE_AUTO_MODE) // make a proper first 1 shot read to initialize _lastRead // fault detection cycle seems to initialize the sensor better
runAutoFaultDetectionCycle(); // also initializes flags
if (lastFault)
SERIAL_ECHOLNPGM("MAX31865 init fault ", lastFault);
writeRegister16(MAX31865_HFAULTMSB_REG, 0xFFFF);
writeRegister16(MAX31865_LFAULTMSB_REG, 0);
#if ENABLED(MAX31865_USE_AUTO_MODE) // make a proper first read to initialize _lastRead
uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
#if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
rtd = fixFault(rtd);
#endif
if (rtd & 1) {
lastRead = 0xFFFF; // some invalid value
lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
clearFault(); // also clears the bias voltage flag, so no further action is required
DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
}
else {
DEBUG_ECHOLNPGM("RTD MSB:", (rtd >> 8), " RTD LSB:", (rtd & 0x00FF));
lastRead = rtd;
TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
}
#else
enableBias(); enableBias();
DELAY_US(11500); DELAY_US(2000); // according to the datasheet, 10.5τ+1msec (see below)
oneShot(); oneShot();
DELAY_US(65000); DELAY_US(63000);
uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG); uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
#if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
rtd = fixFault(rtd);
#endif
if (rtd & 1) { if (rtd & 1) {
lastRead = 0xFFFF; // some invalid value lastRead = 0xFFFF; // some invalid value
lastFault = readRegister8(MAX31865_FAULTSTAT_REG); lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
@ -189,7 +223,7 @@ void MAX31865::begin(max31865_numwires_t wires, float zero_res, float ref_res, f
TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = now); TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = now);
} }
#endif // !MAX31865_USE_AUTO_MODE #endif // MAX31865_USE_AUTO_MODE
DEBUG_ECHOLNPGM( DEBUG_ECHOLNPGM(
TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular") TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular")
@ -198,7 +232,7 @@ void MAX31865::begin(max31865_numwires_t wires, float zero_res, float ref_res, f
" sclkPin: ", sclkPin, " sclkPin: ", sclkPin,
" mosiPin: ", mosiPin, " mosiPin: ", mosiPin,
" config: ", readRegister8(MAX31865_CONFIG_REG) " config: ", readRegister8(MAX31865_CONFIG_REG)
); );
} }
/** /**
@ -240,6 +274,29 @@ void MAX31865::oneShot() {
setConfig(MAX31865_CONFIG_1SHOT | MAX31865_CONFIG_BIAS, 1); setConfig(MAX31865_CONFIG_1SHOT | MAX31865_CONFIG_BIAS, 1);
} }
void MAX31865::runAutoFaultDetectionCycle() {
writeRegister8(MAX31865_CONFIG_REG, (stdFlags & 0x11) | 0x84 ); // cfg reg = 100X010Xb
DELAY_US(600);
for (int i = 0; i < 10 && (readRegister8(MAX31865_CONFIG_REG) & 0xC) > 0; i++) DELAY_US(100); // Fault det completes when bits 2 and 3 are zero (or after 10 tries)
readFault();
clearFault();
}
/**
* Set a value in the configuration register.
*
* @param config 8-bit value for the config item
* @param enable whether to enable or disable the value
*/
void MAX31865::setConfig(uint8_t config, bool enable) {
uint8_t t = stdFlags;
if (enable)
t |= config;
else
t &= ~config;
writeRegister8(MAX31865_CONFIG_REG, t);
}
/** /**
* Initialize standard flags with flags that will not change during operation (Hz, polling mode and no. of wires) * Initialize standard flags with flags that will not change during operation (Hz, polling mode and no. of wires)
* *
@ -249,12 +306,59 @@ void MAX31865::initFixedFlags(max31865_numwires_t wires) {
// set config-defined flags (same for all sensors) // set config-defined flags (same for all sensors)
stdFlags = TERN(MAX31865_50HZ_FILTER, MAX31865_CONFIG_FILT50HZ, MAX31865_CONFIG_FILT60HZ) | stdFlags = TERN(MAX31865_50HZ_FILTER, MAX31865_CONFIG_FILT50HZ, MAX31865_CONFIG_FILT60HZ) |
TERN(MAX31865_USE_AUTO_MODE, MAX31865_CONFIG_MODEAUTO | MAX31865_CONFIG_BIAS, MAX31865_CONFIG_MODEOFF); TERN(MAX31865_USE_AUTO_MODE, MAX31865_CONFIG_MODEAUTO | MAX31865_CONFIG_BIAS, MAX31865_CONFIG_MODEOFF);
if (wires == MAX31865_3WIRE) if (wires == MAX31865_3WIRE)
stdFlags |= MAX31865_CONFIG_3WIRE; stdFlags |= MAX31865_CONFIG_3WIRE; // 3 wire
else // 2 or 4 wire else
stdFlags &= ~MAX31865_CONFIG_3WIRE; stdFlags &= ~MAX31865_CONFIG_3WIRE; // 2 or 4 wire
}
#if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
inline uint16_t MAX31865::fixFault(uint16_t rtd) {
if (!ignore_faults || !(rtd & 1))
return rtd;
ignore_faults--;
clearFault();
DEBUG_ECHOLNPGM("MAX31865 ignoring fault ", (MAX31865_IGNORE_INITIAL_FAULTY_READS) - ignore_faults);
return rtd & ~1; // 0xFFFE
}
#endif
inline uint16_t MAX31865::readRawImmediate() {
uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
#if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
rtd = fixFault(rtd);
#endif
if (rtd & 1) {
lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
lastRead |= 1;
clearFault(); // also clears the bias voltage flag, so no further action is required
DEBUG_ECHOLNPGM("MAX31865 read fault: ", lastFault);
}
else {
TERN_(MAX31865_USE_READ_ERROR_DETECTION, const millis_t ms = millis());
if (TERN0(MAX31865_USE_READ_ERROR_DETECTION, ABS((int)(lastRead - rtd)) > 500 && PENDING(ms, lastReadStamp + 1000))) {
// If 2 readings within 1s differ too much (~20°C) it's a read error.
lastFault = 0x01;
lastRead |= 1;
DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
}
else {
lastRead = rtd;
TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = ms);
}
}
return rtd;
} }
/** /**
@ -267,30 +371,13 @@ uint16_t MAX31865::readRaw() {
#if ENABLED(MAX31865_USE_AUTO_MODE) #if ENABLED(MAX31865_USE_AUTO_MODE)
const uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG); readRawImmediate();
DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
if (rtd & 1) {
lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
lastRead |= 1;
clearFault(); // also clears the bias voltage flag, so no further action is required
DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
}
#if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
else if (ABS(lastRead - rtd) > 500 && PENDING(millis(), lastReadStamp + 1000)) { // if two readings within a second differ too much (~20°C), consider it a read error.
lastFault = 0x01;
lastRead |= 1;
DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
}
#endif
else {
lastRead = rtd;
TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
}
#else #else
if (PENDING(millis(), nextEventStamp)) { const millis_t ms = millis();
if (PENDING(ms, nextEventStamp)) {
DEBUG_ECHOLNPGM("MAX31865 waiting for event ", nextEvent); DEBUG_ECHOLNPGM("MAX31865 waiting for event ", nextEvent);
return lastRead; return lastRead;
} }
@ -298,46 +385,26 @@ uint16_t MAX31865::readRaw() {
switch (nextEvent) { switch (nextEvent) {
case SETUP_BIAS_VOLTAGE: case SETUP_BIAS_VOLTAGE:
enableBias(); enableBias();
nextEventStamp = millis() + 11; // wait at least 11msec before enabling 1shot nextEventStamp = ms + 2; // wait at least 10.5*τ (τ = 100nF*430Ω max for PT100 / 10nF*4.3ΚΩ for PT1000 = 43μsec) + 1msec
nextEvent = SETUP_1_SHOT_MODE; nextEvent = SETUP_1_SHOT_MODE;
DEBUG_ECHOLNPGM("MAX31865 bias voltage enabled"); DEBUG_ECHOLNPGM("MAX31865 bias voltage enabled");
break; break;
case SETUP_1_SHOT_MODE: case SETUP_1_SHOT_MODE:
oneShot(); oneShot();
nextEventStamp = millis() + 65; // wait at least 65msec before reading RTD register nextEventStamp = ms + TERN(MAX31865_50HZ_FILTER, 63, 52); // wait at least 52msec for 60Hz (63msec for 50Hz) before reading RTD register
nextEvent = READ_RTD_REG; nextEvent = READ_RTD_REG;
DEBUG_ECHOLNPGM("MAX31865 1 shot mode enabled"); DEBUG_ECHOLNPGM("MAX31865 1 shot mode enabled");
break; break;
case READ_RTD_REG: { case READ_RTD_REG:
const uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
if (rtd & 1) { if (!(readRawImmediate() & 1)) // if clearFault() was not invoked, need to clear the bias voltage and 1-shot flags
lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
lastRead |= 1;
clearFault(); // also clears the bias voltage flag, so no further action is required
DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
}
#if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
else if (ABS(lastRead - rtd) > 500 && PENDING(millis(), lastReadStamp + 1000)) { // if two readings within a second differ too much (~20°C), consider it a read error.
lastFault = 0x01;
lastRead |= 1;
DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
}
#endif
else {
lastRead = rtd;
TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
}
if (!(rtd & 1)) // if clearFault() was not invoked, need to clear the bias voltage and 1-shot flags
resetFlags(); resetFlags();
nextEvent = SETUP_BIAS_VOLTAGE; nextEvent = SETUP_BIAS_VOLTAGE;
nextEventStamp = millis() + MAX31865_MIN_SAMPLING_TIME_MSEC; // next step should not occur within less than MAX31865_MIN_SAMPLING_TIME_MSEC from the last one nextEventStamp = ms + (MAX31865_MIN_SAMPLING_TIME_MSEC); // next step should not occur within less than MAX31865_MIN_SAMPLING_TIME_MSEC from the last one
} break; break;
} }
#endif #endif
@ -411,21 +478,17 @@ float MAX31865::temperature(float rtd_res) {
return temp; return temp;
} }
//
// private:
//
/** /**
* Set a value in the configuration register. * MAX31865 SPI Timing constants
* * See MAX31865 datasheet (https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf)
* @param config 8-bit value for the config item * All timings in nsec, minimum values.
* @param enable whether to enable or disable the value
*/ */
void MAX31865::setConfig(uint8_t config, bool enable) {
uint8_t t = stdFlags; #define MAX31865_SPI_TIMING_TCC 400 // CS to SCLK setup
if (enable) t |= config; else t &= ~config; #define MAX31865_SPI_TIMING_TDC 35 // Data to SCLK setup
writeRegister8(MAX31865_CONFIG_REG, t); #define MAX31865_SPI_TIMING_TCL 100 // SCK half period
} #define MAX31865_SPI_TIMING_TCCH 100 // SCK to CS hold
#define MAX31865_SPI_TIMING_TCWH 400 // CS inactive time (min)
/** /**
* Read a single byte from the specified register address. * Read a single byte from the specified register address.
@ -459,18 +522,10 @@ uint16_t MAX31865::readRegister16(uint8_t addr) {
* @param n the number of bytes to read * @param n the number of bytes to read
*/ */
void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) { void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
addr &= 0x7F; // make sure top bit is not set addr &= 0x7F; // make sure top bit is not set
if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
SPI.beginTransaction(spiConfig);
else
digitalWrite(sclkPin, LOW);
digitalWrite(cselPin, LOW);
#ifdef TARGET_LPC1768
DELAY_CYCLES(spiSpeed);
#endif
spiBeginTransaction();
spiTransfer(addr); spiTransfer(addr);
while (n--) { while (n--) {
@ -478,10 +533,15 @@ void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
buffer++; buffer++;
} }
if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255)) spiEndTransaction();
SPI.endTransaction(); }
digitalWrite(cselPin, HIGH); void MAX31865::writeRegister16(uint8_t addr, uint16_t data) {
spiBeginTransaction();
spiTransfer(addr | 0x80); // make sure top bit is set
spiTransfer(data >> 8);
spiTransfer(data & 0xFF);
spiEndTransaction();
} }
/** /**
@ -491,22 +551,31 @@ void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
* @param data the data to write * @param data the data to write
*/ */
void MAX31865::writeRegister8(uint8_t addr, uint8_t data) { void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
spiBeginTransaction();
spiTransfer(addr | 0x80); // make sure top bit is set
spiTransfer(data);
spiEndTransaction();
}
void MAX31865::spiBeginTransaction() {
digitalWrite(sclkPin, LOW); // ensure CPOL0
DELAY_NS_VAR(MAX31865_SPI_TIMING_TCWH); // ensure minimum time of CS inactivity after previous operation
digitalWrite(cselPin, LOW);
DELAY_NS_VAR(MAX31865_SPI_TIMING_TCC);
if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255)) if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
SPI.beginTransaction(spiConfig); SPI.beginTransaction(spiConfig);
else else
digitalWrite(sclkPin, LOW); digitalWrite(sclkPin, HIGH);
}
digitalWrite(cselPin, LOW);
#ifdef TARGET_LPC1768
DELAY_CYCLES(spiSpeed);
#endif
spiTransfer(addr | 0x80); // make sure top bit is set
spiTransfer(data);
void MAX31865::spiEndTransaction() {
if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255)) if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
SPI.endTransaction(); SPI.endTransaction();
else
digitalWrite(sclkPin, LOW);
DELAY_NS_VAR(MAX31865_SPI_TIMING_TCCH);
digitalWrite(cselPin, HIGH); digitalWrite(cselPin, HIGH);
} }
@ -521,42 +590,30 @@ void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
* @return the 8-bit response * @return the 8-bit response
*/ */
uint8_t MAX31865::spiTransfer(uint8_t x) { uint8_t MAX31865::spiTransfer(uint8_t x) {
if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255)) if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
return SPI.transfer(x); return SPI.transfer(x);
#ifdef TARGET_LPC1768 uint8_t reply = 0;
for (int i = 7; i >= 0; i--) {
return swSpiTransfer(x, spiSpeed, sclkPin, misoPin, mosiPin); digitalWrite(mosiPin, x & _BV(i));
DELAY_NS_VAR(MAX31865_SPI_TIMING_TDC);
#else digitalWrite(sclkPin, LOW);
DELAY_NS_VAR(MAX31865_SPI_TIMING_TCL - MAX31865_SPI_TIMING_TDC);
uint8_t reply = 0; reply <<= 1;
for (int i = 7; i >= 0; i--) { if (digitalRead(misoPin)) reply |= 1;
digitalWrite(sclkPin, HIGH); DELAY_NS_VAR(spiDelay); DELAY_NS_VAR(MAX31865_SPI_TIMING_TDC);
reply <<= 1; digitalWrite(sclkPin, HIGH);
digitalWrite(mosiPin, x & _BV(i)); DELAY_NS_VAR(spiDelay); DELAY_NS_VAR(MAX31865_SPI_TIMING_TCL - MAX31865_SPI_TIMING_TDC);
if (digitalRead(misoPin)) reply |= 1; }
digitalWrite(sclkPin, LOW); DELAY_NS_VAR(spiDelay); return reply;
}
return reply;
#endif
} }
void MAX31865::softSpiBegin(const uint8_t spi_speed) { void MAX31865::softSpiInit() {
DEBUG_ECHOLNPGM("Initializing MAX31865 Software SPI"); DEBUG_ECHOLNPGM("Initializing MAX31865 Software SPI");
pinMode(sclkPin, OUTPUT);
#ifdef TARGET_LPC1768 digitalWrite(sclkPin, LOW);
swSpiBegin(sclkPin, misoPin, mosiPin); pinMode(mosiPin, OUTPUT);
spiSpeed = swSpiInit(spi_speed, sclkPin, mosiPin); pinMode(misoPin, INPUT);
#else
spiDelay = (100UL << spi_speed) / 3; // Calculate delay in ns. Top speed is ~10MHz, or 100ns delay between bits.
pinMode(sclkPin, OUTPUT);
digitalWrite(sclkPin, LOW);
pinMode(mosiPin, OUTPUT);
pinMode(misoPin, INPUT);
#endif
} }
#endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865 #endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865

View file

@ -101,11 +101,7 @@ private:
TERN(LARGE_PINMAP, uint32_t, uint8_t) sclkPin, misoPin, mosiPin, cselPin; TERN(LARGE_PINMAP, uint32_t, uint8_t) sclkPin, misoPin, mosiPin, cselPin;
#ifdef TARGET_LPC1768 uint16_t spiDelay;
uint8_t spiSpeed;
#else
uint16_t spiDelay;
#endif
float zeroRes, refRes, wireRes; float zeroRes, refRes, wireRes;
@ -121,6 +117,11 @@ private:
one_shot_event_t nextEvent; one_shot_event_t nextEvent;
#endif #endif
#ifdef MAX31865_IGNORE_INITIAL_FAULTY_READS
uint8_t ignore_faults = MAX31865_IGNORE_INITIAL_FAULTY_READS;
uint16_t fixFault(uint16_t rtd);
#endif
uint8_t stdFlags = 0; uint8_t stdFlags = 0;
void setConfig(uint8_t config, bool enable); void setConfig(uint8_t config, bool enable);
@ -130,9 +131,12 @@ private:
uint16_t readRegister16(uint8_t addr); uint16_t readRegister16(uint8_t addr);
void writeRegister8(uint8_t addr, uint8_t reg); void writeRegister8(uint8_t addr, uint8_t reg);
uint8_t spiTransfer(uint8_t addr); void writeRegister16(uint8_t addr, uint16_t reg);
void softSpiBegin(const uint8_t spi_speed); void softSpiInit();
void spiBeginTransaction();
uint8_t spiTransfer(uint8_t addr);
void spiEndTransaction();
void initFixedFlags(max31865_numwires_t wires); void initFixedFlags(max31865_numwires_t wires);
@ -141,6 +145,10 @@ private:
void oneShot(); void oneShot();
void resetFlags(); void resetFlags();
uint16_t readRawImmediate();
void runAutoFaultDetectionCycle();
public: public:
#if ENABLED(LARGE_PINMAP) #if ENABLED(LARGE_PINMAP)
MAX31865(uint32_t spi_cs, uint8_t pin_mapping); MAX31865(uint32_t spi_cs, uint8_t pin_mapping);