Browse Source

🐛 Fix dual MAX31865 initialization issues (#23496)

John Lagonikas 2 years ago
parent
commit
57cee04c89
No account linked to committer's email address
4 changed files with 217 additions and 153 deletions
  1. 13
    16
      Marlin/Configuration_adv.h
  2. 2
    0
      Marlin/src/HAL/shared/Delay.h
  3. 187
    130
      Marlin/src/libs/MAX31865.cpp
  4. 15
    7
      Marlin/src/libs/MAX31865.h

+ 13
- 16
Marlin/Configuration_adv.h View File

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

+ 2
- 0
Marlin/src/HAL/shared/Delay.h View File

166
   // Delay in microseconds
166
   // Delay in microseconds
167
   #define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL))
167
   #define DELAY_US(x) DELAY_CYCLES((x) * ((F_CPU) / 1000000UL))
168
 
168
 
169
+  #define DELAY_CYCLES_VAR DELAY_CYCLES
170
+
169
 #elif defined(ESP32) || defined(__PLAT_LINUX__) || defined(__PLAT_NATIVE_SIM__)
171
 #elif defined(ESP32) || defined(__PLAT_LINUX__) || defined(__PLAT_NATIVE_SIM__)
170
 
172
 
171
   // DELAY_CYCLES specified inside platform
173
   // DELAY_CYCLES specified inside platform

+ 187
- 130
Marlin/src/libs/MAX31865.cpp View File

50
   #define MAX31865_MIN_SAMPLING_TIME_MSEC 0
50
   #define MAX31865_MIN_SAMPLING_TIME_MSEC 0
51
 #endif
51
 #endif
52
 
52
 
53
-#ifdef TARGET_LPC1768
54
-  #include <SoftwareSPI.h>
55
-#endif
56
-
57
 #define DEBUG_OUT ENABLED(DEBUG_MAX31865)
53
 #define DEBUG_OUT ENABLED(DEBUG_MAX31865)
58
 #include "../core/debug_out.h"
54
 #include "../core/debug_out.h"
59
 
55
 
151
   digitalWrite(cselPin, HIGH);
147
   digitalWrite(cselPin, HIGH);
152
 
148
 
153
   if (sclkPin != TERN(LARGE_PINMAP, -1UL, 255))
149
   if (sclkPin != TERN(LARGE_PINMAP, -1UL, 255))
154
-    softSpiBegin(SPI_QUARTER_SPEED); // Define pin modes for Software SPI
150
+    softSpiInit(); // Define pin modes for Software SPI
155
   else {
151
   else {
156
-    DEBUG_ECHOLNPGM("Initializing MAX31865 Hardware SPI");
152
+    DEBUG_ECHOLNPGM("Init MAX31865 Hardware SPI");
157
     SPI.begin();    // Start and configure hardware SPI
153
     SPI.begin();    // Start and configure hardware SPI
158
   }
154
   }
159
 
155
 
160
   initFixedFlags(wires);
156
   initFixedFlags(wires);
161
 
157
 
162
-  clearFault(); // also initializes flags
158
+  DEBUG_ECHOLNPGM("MAX31865 Regs: CFG ", readRegister8(MAX31865_CONFIG_REG),
159
+    "|RTD ", readRegister16(MAX31865_RTDMSB_REG),
160
+    "|HTHRS ", readRegister16(MAX31865_HFAULTMSB_REG),
161
+    "|LTHRS ", readRegister16(MAX31865_LFAULTMSB_REG),
162
+    "|FLT  ", readRegister8(MAX31865_FAULTSTAT_REG));
163
+
164
+  // fault detection cycle seems to initialize the sensor better
165
+  runAutoFaultDetectionCycle(); // also initializes flags
166
+
167
+  if (lastFault)
168
+    SERIAL_ECHOLNPGM("MAX31865 init fault ", lastFault);
169
+
170
+  writeRegister16(MAX31865_HFAULTMSB_REG, 0xFFFF);
171
+  writeRegister16(MAX31865_LFAULTMSB_REG, 0);
172
+
173
+  #if ENABLED(MAX31865_USE_AUTO_MODE) // make a proper first read to initialize _lastRead
174
+
175
+   uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
176
+
177
+    #if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
178
+      rtd = fixFault(rtd);
179
+    #endif
180
+
181
+    if (rtd & 1) {
182
+      lastRead = 0xFFFF; // some invalid value
183
+      lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
184
+      clearFault(); // also clears the bias voltage flag, so no further action is required
185
+
186
+      DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
187
+    }
188
+    else {
189
+      DEBUG_ECHOLNPGM("RTD MSB:", (rtd >> 8), "  RTD LSB:", (rtd & 0x00FF));
190
+      lastRead = rtd;
191
+      TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
192
+    }
163
 
193
 
164
-  #if DISABLED(MAX31865_USE_AUTO_MODE) // make a proper first 1 shot read to initialize _lastRead
194
+  #else
165
 
195
 
166
     enableBias();
196
     enableBias();
167
-    DELAY_US(11500);
197
+    DELAY_US(2000); // according to the datasheet, 10.5τ+1msec (see below)
168
     oneShot();
198
     oneShot();
169
-    DELAY_US(65000);
199
+    DELAY_US(63000);
170
     uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
200
     uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
171
 
201
 
202
+    #if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
203
+      rtd = fixFault(rtd);
204
+    #endif
205
+
172
     if (rtd & 1) {
206
     if (rtd & 1) {
173
       lastRead = 0xFFFF; // some invalid value
207
       lastRead = 0xFFFF; // some invalid value
174
       lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
208
       lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
189
       TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = now);
223
       TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = now);
190
     }
224
     }
191
 
225
 
192
-  #endif // !MAX31865_USE_AUTO_MODE
226
+  #endif // MAX31865_USE_AUTO_MODE
193
 
227
 
194
   DEBUG_ECHOLNPGM(
228
   DEBUG_ECHOLNPGM(
195
     TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular")
229
     TERN(LARGE_PINMAP, "LARGE_PINMAP", "Regular")
198
     " sclkPin: ", sclkPin,
232
     " sclkPin: ", sclkPin,
199
     " mosiPin: ", mosiPin,
233
     " mosiPin: ", mosiPin,
200
     " config: ", readRegister8(MAX31865_CONFIG_REG)
234
     " config: ", readRegister8(MAX31865_CONFIG_REG)
201
-  );
235
+    );
202
 }
236
 }
203
 
237
 
204
 /**
238
 /**
240
   setConfig(MAX31865_CONFIG_1SHOT | MAX31865_CONFIG_BIAS, 1);
274
   setConfig(MAX31865_CONFIG_1SHOT | MAX31865_CONFIG_BIAS, 1);
241
 }
275
 }
242
 
276
 
277
+void MAX31865::runAutoFaultDetectionCycle() {
278
+  writeRegister8(MAX31865_CONFIG_REG, (stdFlags & 0x11) | 0x84 ); // cfg reg = 100X010Xb
279
+  DELAY_US(600);
280
+  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)
281
+  readFault();
282
+  clearFault();
283
+}
284
+
285
+/**
286
+ * Set a value in the configuration register.
287
+ *
288
+ * @param config  8-bit value for the config item
289
+ * @param enable  whether to enable or disable the value
290
+ */
291
+void MAX31865::setConfig(uint8_t config, bool enable) {
292
+  uint8_t t = stdFlags;
293
+  if (enable)
294
+    t |= config;
295
+  else
296
+    t &= ~config;
297
+  writeRegister8(MAX31865_CONFIG_REG, t);
298
+}
299
+
243
 /**
300
 /**
244
  * Initialize standard flags with flags that will not change during operation (Hz, polling mode and no. of wires)
301
  * Initialize standard flags with flags that will not change during operation (Hz, polling mode and no. of wires)
245
  *
302
  *
249
 
306
 
250
   // set config-defined flags (same for all sensors)
307
   // set config-defined flags (same for all sensors)
251
   stdFlags = TERN(MAX31865_50HZ_FILTER, MAX31865_CONFIG_FILT50HZ, MAX31865_CONFIG_FILT60HZ) |
308
   stdFlags = TERN(MAX31865_50HZ_FILTER, MAX31865_CONFIG_FILT50HZ, MAX31865_CONFIG_FILT60HZ) |
252
-              TERN(MAX31865_USE_AUTO_MODE, MAX31865_CONFIG_MODEAUTO | MAX31865_CONFIG_BIAS, MAX31865_CONFIG_MODEOFF);
309
+             TERN(MAX31865_USE_AUTO_MODE, MAX31865_CONFIG_MODEAUTO | MAX31865_CONFIG_BIAS, MAX31865_CONFIG_MODEOFF);
253
 
310
 
254
   if (wires == MAX31865_3WIRE)
311
   if (wires == MAX31865_3WIRE)
255
-    stdFlags |= MAX31865_CONFIG_3WIRE;
256
-  else  // 2 or 4 wire
257
-    stdFlags &= ~MAX31865_CONFIG_3WIRE;
312
+    stdFlags |= MAX31865_CONFIG_3WIRE;   // 3 wire
313
+  else
314
+    stdFlags &= ~MAX31865_CONFIG_3WIRE;  // 2 or 4 wire
315
+}
316
+
317
+#if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
318
+
319
+  inline uint16_t MAX31865::fixFault(uint16_t rtd) {
320
+    if (!ignore_faults || !(rtd & 1))
321
+      return rtd;
322
+
323
+    ignore_faults--;
324
+    clearFault();
325
+
326
+    DEBUG_ECHOLNPGM("MAX31865 ignoring fault ", (MAX31865_IGNORE_INITIAL_FAULTY_READS) - ignore_faults);
327
+
328
+    return rtd & ~1;  // 0xFFFE
329
+  }
330
+
331
+#endif
332
+
333
+inline uint16_t MAX31865::readRawImmediate() {
334
+  uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
335
+  DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
336
+
337
+  #if MAX31865_IGNORE_INITIAL_FAULTY_READS > 0
338
+    rtd = fixFault(rtd);
339
+  #endif
340
+
341
+  if (rtd & 1) {
342
+    lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
343
+    lastRead |= 1;
344
+    clearFault(); // also clears the bias voltage flag, so no further action is required
345
+    DEBUG_ECHOLNPGM("MAX31865 read fault: ", lastFault);
346
+  }
347
+  else {
348
+    TERN_(MAX31865_USE_READ_ERROR_DETECTION, const millis_t ms = millis());
349
+    if (TERN0(MAX31865_USE_READ_ERROR_DETECTION, ABS((int)(lastRead - rtd)) > 500 && PENDING(ms, lastReadStamp + 1000))) {
350
+      // If 2 readings within 1s differ too much (~20°C) it's a read error.
351
+      lastFault = 0x01;
352
+      lastRead |= 1;
353
+      DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
354
+    }
355
+    else {
356
+      lastRead = rtd;
357
+      TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = ms);
358
+    }
359
+  }
360
+
361
+  return rtd;
258
 }
362
 }
259
 
363
 
260
 /**
364
 /**
267
 
371
 
268
   #if ENABLED(MAX31865_USE_AUTO_MODE)
372
   #if ENABLED(MAX31865_USE_AUTO_MODE)
269
 
373
 
270
-    const uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
271
-    DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
272
-
273
-    if (rtd & 1) {
274
-      lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
275
-      lastRead |= 1;
276
-      clearFault(); // also clears the bias voltage flag, so no further action is required
277
-      DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
278
-    }
279
-    #if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
280
-      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.
281
-        lastFault = 0x01;
282
-        lastRead |= 1;
283
-        DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
284
-      }
285
-    #endif
286
-    else {
287
-      lastRead = rtd;
288
-      TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
289
-    }
374
+    readRawImmediate();
290
 
375
 
291
   #else
376
   #else
292
 
377
 
293
-    if (PENDING(millis(), nextEventStamp)) {
378
+    const millis_t ms = millis();
379
+
380
+    if (PENDING(ms, nextEventStamp)) {
294
       DEBUG_ECHOLNPGM("MAX31865 waiting for event ", nextEvent);
381
       DEBUG_ECHOLNPGM("MAX31865 waiting for event ", nextEvent);
295
       return lastRead;
382
       return lastRead;
296
     }
383
     }
298
     switch (nextEvent) {
385
     switch (nextEvent) {
299
       case SETUP_BIAS_VOLTAGE:
386
       case SETUP_BIAS_VOLTAGE:
300
         enableBias();
387
         enableBias();
301
-        nextEventStamp = millis() + 11; // wait at least 11msec before enabling 1shot
388
+        nextEventStamp = ms + 2; // wait at least 10.5*τ (τ = 100nF*430Ω max for PT100 / 10nF*4.3ΚΩ for PT1000 = 43μsec) + 1msec
302
         nextEvent = SETUP_1_SHOT_MODE;
389
         nextEvent = SETUP_1_SHOT_MODE;
303
         DEBUG_ECHOLNPGM("MAX31865 bias voltage enabled");
390
         DEBUG_ECHOLNPGM("MAX31865 bias voltage enabled");
304
         break;
391
         break;
305
 
392
 
306
       case SETUP_1_SHOT_MODE:
393
       case SETUP_1_SHOT_MODE:
307
         oneShot();
394
         oneShot();
308
-        nextEventStamp = millis() + 65; // wait at least 65msec before reading RTD register
395
+        nextEventStamp = ms + TERN(MAX31865_50HZ_FILTER, 63, 52); // wait at least 52msec for 60Hz (63msec for 50Hz) before reading RTD register
309
         nextEvent = READ_RTD_REG;
396
         nextEvent = READ_RTD_REG;
310
         DEBUG_ECHOLNPGM("MAX31865 1 shot mode enabled");
397
         DEBUG_ECHOLNPGM("MAX31865 1 shot mode enabled");
311
         break;
398
         break;
312
 
399
 
313
-      case READ_RTD_REG: {
314
-        const uint16_t rtd = readRegister16(MAX31865_RTDMSB_REG);
315
-        DEBUG_ECHOLNPGM("MAX31865 RTD MSB:", (rtd >> 8), " LSB:", (rtd & 0x00FF));
316
-
317
-        if (rtd & 1) {
318
-          lastFault = readRegister8(MAX31865_FAULTSTAT_REG);
319
-          lastRead |= 1;
320
-          clearFault(); // also clears the bias voltage flag, so no further action is required
321
-          DEBUG_ECHOLNPGM("MAX31865 read fault: ", rtd);
322
-        }
323
-        #if ENABLED(MAX31865_USE_READ_ERROR_DETECTION)
324
-          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.
325
-            lastFault = 0x01;
326
-            lastRead |= 1;
327
-            DEBUG_ECHOLNPGM("MAX31865 read error: ", rtd);
328
-          }
329
-        #endif
330
-        else {
331
-          lastRead = rtd;
332
-          TERN_(MAX31865_USE_READ_ERROR_DETECTION, lastReadStamp = millis());
333
-        }
334
-
335
-        if (!(rtd & 1))   // if clearFault() was not invoked, need to clear the bias voltage and 1-shot flags
400
+      case READ_RTD_REG:
401
+
402
+        if (!(readRawImmediate() & 1))   // if clearFault() was not invoked, need to clear the bias voltage and 1-shot flags
336
           resetFlags();
403
           resetFlags();
337
 
404
 
338
         nextEvent = SETUP_BIAS_VOLTAGE;
405
         nextEvent = SETUP_BIAS_VOLTAGE;
339
-        nextEventStamp = millis() + MAX31865_MIN_SAMPLING_TIME_MSEC; // next step should not occur within less than MAX31865_MIN_SAMPLING_TIME_MSEC from the last one
340
-      } break;
406
+        nextEventStamp = ms + (MAX31865_MIN_SAMPLING_TIME_MSEC); // next step should not occur within less than MAX31865_MIN_SAMPLING_TIME_MSEC from the last one
407
+        break;
341
     }
408
     }
342
 
409
 
343
   #endif
410
   #endif
411
   return temp;
478
   return temp;
412
 }
479
 }
413
 
480
 
414
-//
415
-// private:
416
-//
417
-
418
 /**
481
 /**
419
- * Set a value in the configuration register.
420
- *
421
- * @param config  8-bit value for the config item
422
- * @param enable  whether to enable or disable the value
482
+ * MAX31865 SPI Timing constants
483
+ * See MAX31865 datasheet (https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf)
484
+ * All timings in nsec, minimum values.
423
  */
485
  */
424
-void MAX31865::setConfig(uint8_t config, bool enable) {
425
-  uint8_t t = stdFlags;
426
-  if (enable) t |= config; else t &= ~config;
427
-  writeRegister8(MAX31865_CONFIG_REG, t);
428
-}
486
+
487
+#define MAX31865_SPI_TIMING_TCC    400    // CS to SCLK setup
488
+#define MAX31865_SPI_TIMING_TDC     35    // Data to SCLK setup
489
+#define MAX31865_SPI_TIMING_TCL    100    // SCK half period
490
+#define MAX31865_SPI_TIMING_TCCH   100    // SCK to CS hold
491
+#define MAX31865_SPI_TIMING_TCWH   400    // CS inactive time (min)
429
 
492
 
430
 /**
493
 /**
431
  * Read a single byte from the specified register address.
494
  * Read a single byte from the specified register address.
459
  * @param n       the number of bytes to read
522
  * @param n       the number of bytes to read
460
  */
523
  */
461
 void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
524
 void MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) {
462
-  addr &= 0x7F; // make sure top bit is not set
463
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
464
-    SPI.beginTransaction(spiConfig);
465
-  else
466
-    digitalWrite(sclkPin, LOW);
467
 
525
 
468
-  digitalWrite(cselPin, LOW);
469
-
470
-  #ifdef TARGET_LPC1768
471
-    DELAY_CYCLES(spiSpeed);
472
-  #endif
526
+  addr &= 0x7F; // make sure top bit is not set
473
 
527
 
528
+  spiBeginTransaction();
474
   spiTransfer(addr);
529
   spiTransfer(addr);
475
 
530
 
476
   while (n--) {
531
   while (n--) {
478
     buffer++;
533
     buffer++;
479
   }
534
   }
480
 
535
 
481
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
482
-    SPI.endTransaction();
536
+  spiEndTransaction();
537
+}
483
 
538
 
484
-  digitalWrite(cselPin, HIGH);
539
+void MAX31865::writeRegister16(uint8_t addr, uint16_t data) {
540
+  spiBeginTransaction();
541
+  spiTransfer(addr | 0x80); // make sure top bit is set
542
+  spiTransfer(data >> 8);
543
+  spiTransfer(data & 0xFF);
544
+  spiEndTransaction();
485
 }
545
 }
486
 
546
 
487
 /**
547
 /**
491
  * @param data  the data to write
551
  * @param data  the data to write
492
  */
552
  */
493
 void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
553
 void MAX31865::writeRegister8(uint8_t addr, uint8_t data) {
494
-  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
495
-    SPI.beginTransaction(spiConfig);
496
-  else
497
-    digitalWrite(sclkPin, LOW);
554
+  spiBeginTransaction();
555
+  spiTransfer(addr | 0x80); // make sure top bit is set
556
+  spiTransfer(data);
557
+  spiEndTransaction();
558
+}
498
 
559
 
560
+void MAX31865::spiBeginTransaction() {
561
+  digitalWrite(sclkPin, LOW); // ensure CPOL0
562
+  DELAY_NS_VAR(MAX31865_SPI_TIMING_TCWH); // ensure minimum time of CS inactivity after previous operation
499
   digitalWrite(cselPin, LOW);
563
   digitalWrite(cselPin, LOW);
564
+  DELAY_NS_VAR(MAX31865_SPI_TIMING_TCC);
500
 
565
 
501
-  #ifdef TARGET_LPC1768
502
-    DELAY_CYCLES(spiSpeed);
503
-  #endif
504
-
505
-  spiTransfer(addr | 0x80); // make sure top bit is set
506
-  spiTransfer(data);
566
+  if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
567
+    SPI.beginTransaction(spiConfig);
568
+  else
569
+    digitalWrite(sclkPin, HIGH);
570
+}
507
 
571
 
572
+void MAX31865::spiEndTransaction() {
508
   if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
573
   if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
509
     SPI.endTransaction();
574
     SPI.endTransaction();
575
+  else
576
+    digitalWrite(sclkPin, LOW);
577
+
578
+  DELAY_NS_VAR(MAX31865_SPI_TIMING_TCCH);
510
 
579
 
511
   digitalWrite(cselPin, HIGH);
580
   digitalWrite(cselPin, HIGH);
512
 }
581
 }
521
  * @return    the 8-bit response
590
  * @return    the 8-bit response
522
  */
591
  */
523
 uint8_t MAX31865::spiTransfer(uint8_t x) {
592
 uint8_t MAX31865::spiTransfer(uint8_t x) {
524
-
525
   if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
593
   if (sclkPin == TERN(LARGE_PINMAP, -1UL, 255))
526
     return SPI.transfer(x);
594
     return SPI.transfer(x);
527
 
595
 
528
-  #ifdef TARGET_LPC1768
529
-
530
-    return swSpiTransfer(x, spiSpeed, sclkPin, misoPin, mosiPin);
531
-
532
-  #else
533
-
534
-    uint8_t reply = 0;
535
-    for (int i = 7; i >= 0; i--) {
536
-      digitalWrite(sclkPin, HIGH);       DELAY_NS_VAR(spiDelay);
537
-      reply <<= 1;
538
-      digitalWrite(mosiPin, x & _BV(i)); DELAY_NS_VAR(spiDelay);
539
-      if (digitalRead(misoPin)) reply |= 1;
540
-      digitalWrite(sclkPin, LOW);        DELAY_NS_VAR(spiDelay);
541
-    }
542
-    return reply;
543
-
544
-  #endif
596
+  uint8_t reply = 0;
597
+  for (int i = 7; i >= 0; i--) {
598
+    digitalWrite(mosiPin, x & _BV(i));
599
+    DELAY_NS_VAR(MAX31865_SPI_TIMING_TDC);
600
+    digitalWrite(sclkPin, LOW);
601
+    DELAY_NS_VAR(MAX31865_SPI_TIMING_TCL - MAX31865_SPI_TIMING_TDC);
602
+    reply <<= 1;
603
+    if (digitalRead(misoPin)) reply |= 1;
604
+    DELAY_NS_VAR(MAX31865_SPI_TIMING_TDC);
605
+    digitalWrite(sclkPin, HIGH);
606
+    DELAY_NS_VAR(MAX31865_SPI_TIMING_TCL - MAX31865_SPI_TIMING_TDC);
607
+  }
608
+  return reply;
545
 }
609
 }
546
 
610
 
547
-void MAX31865::softSpiBegin(const uint8_t spi_speed) {
611
+void MAX31865::softSpiInit() {
548
   DEBUG_ECHOLNPGM("Initializing MAX31865 Software SPI");
612
   DEBUG_ECHOLNPGM("Initializing MAX31865 Software SPI");
549
-
550
-  #ifdef TARGET_LPC1768
551
-    swSpiBegin(sclkPin, misoPin, mosiPin);
552
-    spiSpeed = swSpiInit(spi_speed, sclkPin, mosiPin);
553
-  #else
554
-    spiDelay = (100UL << spi_speed) / 3; // Calculate delay in ns. Top speed is ~10MHz, or 100ns delay between bits.
555
-    pinMode(sclkPin, OUTPUT);
556
-    digitalWrite(sclkPin, LOW);
557
-    pinMode(mosiPin, OUTPUT);
558
-    pinMode(misoPin, INPUT);
559
-  #endif
613
+  pinMode(sclkPin, OUTPUT);
614
+  digitalWrite(sclkPin, LOW);
615
+  pinMode(mosiPin, OUTPUT);
616
+  pinMode(misoPin, INPUT);
560
 }
617
 }
561
 
618
 
562
 #endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865
619
 #endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865

+ 15
- 7
Marlin/src/libs/MAX31865.h View File

101
 
101
 
102
   TERN(LARGE_PINMAP, uint32_t, uint8_t) sclkPin, misoPin, mosiPin, cselPin;
102
   TERN(LARGE_PINMAP, uint32_t, uint8_t) sclkPin, misoPin, mosiPin, cselPin;
103
 
103
 
104
-  #ifdef TARGET_LPC1768
105
-    uint8_t spiSpeed;
106
-  #else
107
-    uint16_t spiDelay;
108
-  #endif
104
+  uint16_t spiDelay;
109
 
105
 
110
   float zeroRes, refRes, wireRes;
106
   float zeroRes, refRes, wireRes;
111
 
107
 
121
     one_shot_event_t nextEvent;
117
     one_shot_event_t nextEvent;
122
   #endif
118
   #endif
123
 
119
 
120
+  #ifdef MAX31865_IGNORE_INITIAL_FAULTY_READS
121
+    uint8_t ignore_faults = MAX31865_IGNORE_INITIAL_FAULTY_READS;
122
+    uint16_t fixFault(uint16_t rtd);
123
+  #endif
124
+
124
   uint8_t stdFlags = 0;
125
   uint8_t stdFlags = 0;
125
 
126
 
126
   void setConfig(uint8_t config, bool enable);
127
   void setConfig(uint8_t config, bool enable);
130
   uint16_t readRegister16(uint8_t addr);
131
   uint16_t readRegister16(uint8_t addr);
131
 
132
 
132
   void writeRegister8(uint8_t addr, uint8_t reg);
133
   void writeRegister8(uint8_t addr, uint8_t reg);
133
-  uint8_t spiTransfer(uint8_t addr);
134
+  void writeRegister16(uint8_t addr, uint16_t reg);
134
 
135
 
135
-  void softSpiBegin(const uint8_t spi_speed);
136
+  void softSpiInit();
137
+  void spiBeginTransaction();
138
+  uint8_t spiTransfer(uint8_t addr);
139
+  void spiEndTransaction();
136
 
140
 
137
   void initFixedFlags(max31865_numwires_t wires);
141
   void initFixedFlags(max31865_numwires_t wires);
138
 
142
 
141
   void oneShot();
145
   void oneShot();
142
   void resetFlags();
146
   void resetFlags();
143
 
147
 
148
+  uint16_t readRawImmediate();
149
+
150
+  void runAutoFaultDetectionCycle();
151
+
144
 public:
152
 public:
145
   #if ENABLED(LARGE_PINMAP)
153
   #if ENABLED(LARGE_PINMAP)
146
     MAX31865(uint32_t spi_cs, uint8_t pin_mapping);
154
     MAX31865(uint32_t spi_cs, uint8_t pin_mapping);

Loading…
Cancel
Save