|
|
|
@ -44,30 +44,44 @@
|
|
|
|
|
#include "../lcd/extui/ui_api.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if MAX6675_IS_MAX31865
|
|
|
|
|
#if MAX6675_0_IS_MAX31865 || MAX6675_1_IS_MAX31865
|
|
|
|
|
#include <Adafruit_MAX31865.h>
|
|
|
|
|
#ifndef MAX31865_CS_PIN
|
|
|
|
|
#define MAX31865_CS_PIN MAX6675_SS_PIN // HW:49 SW:65 for example
|
|
|
|
|
#if MAX6675_0_IS_MAX31865 && !defined(MAX31865_CS_PIN) && PIN_EXISTS(MAX6675_SS)
|
|
|
|
|
#define MAX31865_CS_PIN MAX6675_SS_PIN
|
|
|
|
|
#endif
|
|
|
|
|
#if MAX6675_1_IS_MAX31865 && !defined(MAX31865_CS2_PIN) && PIN_EXISTS(MAX6675_SS2)
|
|
|
|
|
#define MAX31865_CS2_PIN MAX6675_SS2_PIN
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef MAX31865_MOSI_PIN
|
|
|
|
|
#define MAX31865_MOSI_PIN MOSI_PIN // 63
|
|
|
|
|
#define MAX31865_MOSI_PIN MOSI_PIN
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef MAX31865_MISO_PIN
|
|
|
|
|
#define MAX31865_MISO_PIN MAX6675_DO_PIN // 42
|
|
|
|
|
#define MAX31865_MISO_PIN MAX6675_DO_PIN
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef MAX31865_SCK_PIN
|
|
|
|
|
#define MAX31865_SCK_PIN MAX6675_SCK_PIN // 40
|
|
|
|
|
#define MAX31865_SCK_PIN MAX6675_SCK_PIN
|
|
|
|
|
#endif
|
|
|
|
|
#if MAX6675_0_IS_MAX31865 && PIN_EXISTS(MAX31865_CS)
|
|
|
|
|
#define HAS_MAX31865 1
|
|
|
|
|
Adafruit_MAX31865 max31865_0 = Adafruit_MAX31865(MAX31865_CS_PIN
|
|
|
|
|
#if MAX31865_CS_PIN != MAX6675_SS_PIN
|
|
|
|
|
, MAX31865_MOSI_PIN, MAX31865_MISO_PIN, MAX31865_SCK_PIN // For software SPI also set MOSI/MISO/SCK
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
#endif
|
|
|
|
|
#if MAX6675_1_IS_MAX31865 && PIN_EXISTS(MAX31865_CS2)
|
|
|
|
|
#define HAS_MAX31865 1
|
|
|
|
|
Adafruit_MAX31865 max31865_1 = Adafruit_MAX31865(MAX31865_CS2_PIN
|
|
|
|
|
#if MAX31865_CS2_PIN != MAX6675_SS2_PIN
|
|
|
|
|
, MAX31865_MOSI_PIN, MAX31865_MISO_PIN, MAX31865_SCK_PIN // For software SPI also set MOSI/MISO/SCK
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
#endif
|
|
|
|
|
Adafruit_MAX31865 max31865 = Adafruit_MAX31865(MAX31865_CS_PIN
|
|
|
|
|
#if MAX31865_CS_PIN != MAX6675_SS_PIN
|
|
|
|
|
, MAX31865_MOSI_PIN // For software SPI also set MOSI/MISO/SCK
|
|
|
|
|
, MAX31865_MISO_PIN
|
|
|
|
|
, MAX31865_SCK_PIN
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define MAX6675_SEPARATE_SPI (EITHER(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675) && PINS_EXIST(MAX6675_SCK, MAX6675_DO))
|
|
|
|
|
#if EITHER(HEATER_0_USES_MAX6675, HEATER_1_USES_MAX6675) && PINS_EXIST(MAX6675_SCK, MAX6675_DO)
|
|
|
|
|
#define MAX6675_SEPARATE_SPI 1
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if MAX6675_SEPARATE_SPI
|
|
|
|
|
#include "../libs/private_spi.h"
|
|
|
|
@ -1471,13 +1485,7 @@ void Temperature::manage_heater() {
|
|
|
|
|
#if HEATER_0_USER_THERMISTOR
|
|
|
|
|
return user_thermistor_to_deg_c(CTI_HOTEND_0, raw);
|
|
|
|
|
#elif HEATER_0_USES_MAX6675
|
|
|
|
|
return (
|
|
|
|
|
#if MAX6675_IS_MAX31865
|
|
|
|
|
max31865.temperature(MAX31865_SENSOR_OHMS, MAX31865_CALIBRATION_OHMS)
|
|
|
|
|
#else
|
|
|
|
|
raw * 0.25
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
return TERN(MAX6675_0_IS_MAX31865, max31865_0.temperature(MAX31865_SENSOR_OHMS_0, MAX31865_CALIBRATION_OHMS_0), raw * 0.25);
|
|
|
|
|
#elif HEATER_0_USES_AD595
|
|
|
|
|
return TEMP_AD595(raw);
|
|
|
|
|
#elif HEATER_0_USES_AD8495
|
|
|
|
@ -1489,7 +1497,7 @@ void Temperature::manage_heater() {
|
|
|
|
|
#if HEATER_1_USER_THERMISTOR
|
|
|
|
|
return user_thermistor_to_deg_c(CTI_HOTEND_1, raw);
|
|
|
|
|
#elif HEATER_1_USES_MAX6675
|
|
|
|
|
return raw * 0.25;
|
|
|
|
|
return TERN(MAX6675_1_IS_MAX31865, max31865_1.temperature(MAX31865_SENSOR_OHMS_1, MAX31865_CALIBRATION_OHMS_1), raw * 0.25);
|
|
|
|
|
#elif HEATER_1_USES_AD595
|
|
|
|
|
return TEMP_AD595(raw);
|
|
|
|
|
#elif HEATER_1_USES_AD8495
|
|
|
|
@ -1691,7 +1699,8 @@ void Temperature::updateTemperaturesFromRawValues() {
|
|
|
|
|
*/
|
|
|
|
|
void Temperature::init() {
|
|
|
|
|
|
|
|
|
|
TERN_(MAX6675_IS_MAX31865, max31865.begin(MAX31865_2WIRE)); // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE
|
|
|
|
|
TERN_(MAX6675_0_IS_MAX31865, max31865_0.begin(MAX31865_2WIRE)); // MAX31865_2WIRE, MAX31865_3WIRE, MAX31865_4WIRE
|
|
|
|
|
TERN_(MAX6675_1_IS_MAX31865, max31865_1.begin(MAX31865_2WIRE));
|
|
|
|
|
|
|
|
|
|
#if EARLY_WATCHDOG
|
|
|
|
|
// Flag that the thermalManager should be running
|
|
|
|
@ -2200,50 +2209,64 @@ void Temperature::disable_all_heaters() {
|
|
|
|
|
#define THERMOCOUPLE_MAX_ERRORS 15
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int Temperature::read_max6675(
|
|
|
|
|
#if COUNT_6675 > 1
|
|
|
|
|
const uint8_t hindex
|
|
|
|
|
#endif
|
|
|
|
|
) {
|
|
|
|
|
#if COUNT_6675 == 1
|
|
|
|
|
constexpr uint8_t hindex = 0;
|
|
|
|
|
#else
|
|
|
|
|
// Needed to return the correct temp when this is called too soon
|
|
|
|
|
static uint16_t max6675_temp_previous[COUNT_6675] = { 0 };
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static uint8_t max6675_errors[COUNT_6675] = { 0 };
|
|
|
|
|
|
|
|
|
|
int Temperature::read_max6675(TERN_(HAS_MULTI_6675, const uint8_t hindex/*=0*/)) {
|
|
|
|
|
#define MAX6675_HEAT_INTERVAL 250UL
|
|
|
|
|
|
|
|
|
|
#if MAX6675_IS_MAX31855
|
|
|
|
|
#if MAX6675_0_IS_MAX31855 || MAX6675_1_IS_MAX31855
|
|
|
|
|
static uint32_t max6675_temp = 2000;
|
|
|
|
|
#define MAX6675_ERROR_MASK 7
|
|
|
|
|
#define MAX6675_DISCARD_BITS 18
|
|
|
|
|
#define MAX6675_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64
|
|
|
|
|
#define MAX6675_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64
|
|
|
|
|
#elif HAS_MAX31865
|
|
|
|
|
static uint16_t max6675_temp = 2000; // From datasheet 16 bits D15-D0
|
|
|
|
|
#define MAX6675_ERROR_MASK 1 // D0 Bit not used
|
|
|
|
|
#define MAX6675_DISCARD_BITS 1 // Data is in D15-D1
|
|
|
|
|
#define MAX6675_SPEED_BITS 3 // (_BV(SPR1)) // clock ÷ 64
|
|
|
|
|
#else
|
|
|
|
|
static uint16_t max6675_temp = 2000;
|
|
|
|
|
#define MAX6675_ERROR_MASK 4
|
|
|
|
|
#define MAX6675_DISCARD_BITS 3
|
|
|
|
|
#define MAX6675_SPEED_BITS 2 // (_BV(SPR0)) // clock ÷ 16
|
|
|
|
|
#define MAX6675_SPEED_BITS 2 // (_BV(SPR0)) // clock ÷ 16
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if HAS_MULTI_6675
|
|
|
|
|
// Needed to return the correct temp when this is called between readings
|
|
|
|
|
static uint16_t max6675_temp_previous[COUNT_6675] = { 0 };
|
|
|
|
|
#define MAX6675_TEMP(I) max6675_temp_previous[I]
|
|
|
|
|
#define MAX6675_SEL(A,B) (hindex ? (B) : (A))
|
|
|
|
|
#define MAX6675_WRITE(V) do{ switch (hindex) { case 1: WRITE(MAX6675_SS2_PIN, V); break; default: WRITE(MAX6675_SS_PIN, V); } }while(0)
|
|
|
|
|
#define MAX6675_SET_OUTPUT() do{ switch (hindex) { case 1: SET_OUTPUT(MAX6675_SS2_PIN); break; default: SET_OUTPUT(MAX6675_SS_PIN); } }while(0)
|
|
|
|
|
#else
|
|
|
|
|
constexpr uint8_t hindex = 0;
|
|
|
|
|
#define MAX6675_TEMP(I) max6675_temp
|
|
|
|
|
#if MAX6675_1_IS_MAX31865
|
|
|
|
|
#define MAX6675_SEL(A,B) B
|
|
|
|
|
#else
|
|
|
|
|
#define MAX6675_SEL(A,B) A
|
|
|
|
|
#endif
|
|
|
|
|
#if HEATER_0_USES_MAX6675
|
|
|
|
|
#define MAX6675_WRITE(V) WRITE(MAX6675_SS_PIN, V)
|
|
|
|
|
#define MAX6675_SET_OUTPUT() SET_OUTPUT(MAX6675_SS_PIN)
|
|
|
|
|
#else
|
|
|
|
|
#define MAX6675_WRITE(V) WRITE(MAX6675_SS2_PIN, V)
|
|
|
|
|
#define MAX6675_SET_OUTPUT() SET_OUTPUT(MAX6675_SS2_PIN)
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static uint8_t max6675_errors[COUNT_6675] = { 0 };
|
|
|
|
|
|
|
|
|
|
// Return last-read value between readings
|
|
|
|
|
static millis_t next_max6675_ms[COUNT_6675] = { 0 };
|
|
|
|
|
millis_t ms = millis();
|
|
|
|
|
if (PENDING(ms, next_max6675_ms[hindex]))
|
|
|
|
|
return int(
|
|
|
|
|
#if COUNT_6675 == 1
|
|
|
|
|
max6675_temp
|
|
|
|
|
#else
|
|
|
|
|
max6675_temp_previous[hindex] // Need to return the correct previous value
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (PENDING(ms, next_max6675_ms[hindex])) return int(MAX6675_TEMP(hindex));
|
|
|
|
|
next_max6675_ms[hindex] = ms + MAX6675_HEAT_INTERVAL;
|
|
|
|
|
|
|
|
|
|
#if MAX6675_IS_MAX31865
|
|
|
|
|
max6675_temp = int(max31865.temperature(MAX31865_SENSOR_OHMS, MAX31865_CALIBRATION_OHMS));
|
|
|
|
|
#if HAS_MAX31865
|
|
|
|
|
Adafruit_MAX31865 &maxref = MAX6675_SEL(max31865_0, max31865_1);
|
|
|
|
|
max6675_temp = int(maxref.temperature(
|
|
|
|
|
MAX6675_SEL(MAX31865_SENSOR_OHMS_0, MAX31865_SENSOR_OHMS_1),
|
|
|
|
|
MAX6675_SEL(MAX31865_CALIBRATION_OHMS_0, MAX31865_CALIBRATION_OHMS_1)
|
|
|
|
|
));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
@ -2254,39 +2277,24 @@ void Temperature::disable_all_heaters() {
|
|
|
|
|
spiInit(MAX6675_SPEED_BITS);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if COUNT_6675 > 1
|
|
|
|
|
#define WRITE_MAX6675(V) do{ switch (hindex) { case 1: WRITE(MAX6675_SS2_PIN, V); break; default: WRITE(MAX6675_SS_PIN, V); } }while(0)
|
|
|
|
|
#define SET_OUTPUT_MAX6675() do{ switch (hindex) { case 1: SET_OUTPUT(MAX6675_SS2_PIN); break; default: SET_OUTPUT(MAX6675_SS_PIN); } }while(0)
|
|
|
|
|
#elif HEATER_1_USES_MAX6675
|
|
|
|
|
#define WRITE_MAX6675(V) WRITE(MAX6675_SS2_PIN, V)
|
|
|
|
|
#define SET_OUTPUT_MAX6675() SET_OUTPUT(MAX6675_SS2_PIN)
|
|
|
|
|
#else
|
|
|
|
|
#define WRITE_MAX6675(V) WRITE(MAX6675_SS_PIN, V)
|
|
|
|
|
#define SET_OUTPUT_MAX6675() SET_OUTPUT(MAX6675_SS_PIN)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
SET_OUTPUT_MAX6675();
|
|
|
|
|
WRITE_MAX6675(LOW); // enable TT_MAX6675
|
|
|
|
|
MAX6675_SET_OUTPUT();
|
|
|
|
|
MAX6675_WRITE(LOW); // enable TT_MAX6675
|
|
|
|
|
|
|
|
|
|
DELAY_NS(100); // Ensure 100ns delay
|
|
|
|
|
|
|
|
|
|
// Read a big-endian temperature value
|
|
|
|
|
max6675_temp = 0;
|
|
|
|
|
for (uint8_t i = sizeof(max6675_temp); i--;) {
|
|
|
|
|
max6675_temp |= (
|
|
|
|
|
#if MAX6675_SEPARATE_SPI
|
|
|
|
|
max6675_spi.receive()
|
|
|
|
|
#else
|
|
|
|
|
spiRec()
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
max6675_temp |= TERN(MAX6675_SEPARATE_SPI, max6675_spi.receive(), spiRec());
|
|
|
|
|
if (i > 0) max6675_temp <<= 8; // shift left if not the last byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WRITE_MAX6675(HIGH); // disable TT_MAX6675
|
|
|
|
|
MAX6675_WRITE(HIGH); // disable TT_MAX6675
|
|
|
|
|
|
|
|
|
|
if (DISABLED(IGNORE_THERMOCOUPLE_ERRORS) && (max6675_temp & MAX6675_ERROR_MASK)) {
|
|
|
|
|
max6675_errors[hindex] += 1;
|
|
|
|
|
const uint8_t fault_31865 = TERN1(HAS_MAX31865, maxref.readFault());
|
|
|
|
|
|
|
|
|
|
if (DISABLED(IGNORE_THERMOCOUPLE_ERRORS) && (max6675_temp & MAX6675_ERROR_MASK) && fault_31865) {
|
|
|
|
|
max6675_errors[hindex]++;
|
|
|
|
|
if (max6675_errors[hindex] > THERMOCOUPLE_MAX_ERRORS) {
|
|
|
|
|
SERIAL_ERROR_START();
|
|
|
|
|
SERIAL_ECHOPGM("Temp measurement error! ");
|
|
|
|
@ -2298,18 +2306,29 @@ void Temperature::disable_all_heaters() {
|
|
|
|
|
SERIAL_ECHOLNPGM("Short to GND");
|
|
|
|
|
else if (max6675_temp & 4)
|
|
|
|
|
SERIAL_ECHOLNPGM("Short to VCC");
|
|
|
|
|
#elif HAS_MAX31865
|
|
|
|
|
if (fault_31865) {
|
|
|
|
|
maxref.clearFault();
|
|
|
|
|
SERIAL_ECHOPAIR("MAX31865 Fault :(", fault_31865, ") >>");
|
|
|
|
|
if (fault_31865 & MAX31865_FAULT_HIGHTHRESH)
|
|
|
|
|
SERIAL_ECHOLNPGM("RTD High Threshold");
|
|
|
|
|
else if (fault_31865 & MAX31865_FAULT_LOWTHRESH)
|
|
|
|
|
SERIAL_ECHOLNPGM("RTD Low Threshold");
|
|
|
|
|
else if (fault_31865 & MAX31865_FAULT_REFINLOW)
|
|
|
|
|
SERIAL_ECHOLNPGM("REFIN- > 0.85 x Bias");
|
|
|
|
|
else if (fault_31865 & MAX31865_FAULT_REFINHIGH)
|
|
|
|
|
SERIAL_ECHOLNPGM("REFIN- < 0.85 x Bias - FORCE- open");
|
|
|
|
|
else if (fault_31865 & MAX31865_FAULT_RTDINLOW)
|
|
|
|
|
SERIAL_ECHOLNPGM("REFIN- < 0.85 x Bias - FORCE- open");
|
|
|
|
|
else if (fault_31865 & MAX31865_FAULT_OVUV)
|
|
|
|
|
SERIAL_ECHOLNPGM("Under/Over voltage");
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
SERIAL_ECHOLNPGM("MAX6675");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Thermocouple open
|
|
|
|
|
max6675_temp = 4 * (
|
|
|
|
|
#if COUNT_6675 > 1
|
|
|
|
|
hindex ? HEATER_1_MAX6675_TMAX : HEATER_0_MAX6675_TMAX
|
|
|
|
|
#else
|
|
|
|
|
TERN(HEATER_1_USES_MAX6675, HEATER_1_MAX6675_TMAX, HEATER_0_MAX6675_TMAX)
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
max6675_temp = 4 * MAX6675_SEL(HEATER_0_MAX6675_TMAX, HEATER_1_MAX6675_TMAX);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
max6675_temp >>= MAX6675_DISCARD_BITS;
|
|
|
|
@ -2319,13 +2338,11 @@ void Temperature::disable_all_heaters() {
|
|
|
|
|
max6675_errors[hindex] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if ENABLED(MAX6675_IS_MAX31855)
|
|
|
|
|
#if MAX6675_0_IS_MAX31855 || MAX6675_1_IS_MAX31855
|
|
|
|
|
if (max6675_temp & 0x00002000) max6675_temp |= 0xFFFFC000; // Support negative temperature
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if COUNT_6675 > 1
|
|
|
|
|
max6675_temp_previous[hindex] = max6675_temp;
|
|
|
|
|
#endif
|
|
|
|
|
MAX6675_TEMP(hindex) = max6675_temp;
|
|
|
|
|
|
|
|
|
|
return int(max6675_temp);
|
|
|
|
|
}
|
|
|
|
|