2021-07-07 02:36:41 +02:00
/**
* Marlin 3 D Printer Firmware
* Copyright ( c ) 2021 MarlinFirmware [ https : //github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl .
* Copyright ( c ) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*
*/
/**
* Based on Based on Adafruit MAX31865 library :
*
* This is a library for the Adafruit PT100 / P1000 RTD Sensor w / MAX31865
* Designed specifically to work with the Adafruit RTD Sensor
* https : //www.adafruit.com/products/3328
*
* This sensor uses SPI to communicate , 4 pins are required to interface .
*
* Adafruit invests time and resources providing this open source code ,
* please support Adafruit and open - source hardware by purchasing
* products from Adafruit !
*
* Written by Limor Fried / Ladyada for Adafruit Industries .
*
* Modifications by JoAnn Manges ( @ GadgetAngel )
* Copyright ( c ) 2020 , JoAnn Manges
* All rights reserved .
*/
# include "../inc/MarlinConfig.h"
2021-08-31 05:40:49 +02:00
# if HAS_MAX31865 && !USE_ADAFRUIT_MAX31865
2021-07-07 02:36:41 +02:00
# include "MAX31865.h"
2021-12-08 19:55:09 +01:00
# ifndef MAX31865_MIN_SAMPLING_TIME_MSEC
# define MAX31865_MIN_SAMPLING_TIME_MSEC 0
# endif
2021-11-07 04:53:36 +01:00
# ifdef TARGET_LPC1768
# include <SoftwareSPI.h>
# endif
2021-12-08 19:55:09 +01:00
# define DEBUG_OUT ENABLED(DEBUG_MAX31865)
# include "../core/debug_out.h"
2021-07-07 02:36:41 +02:00
// The maximum speed the MAX31865 can do is 5 MHz
SPISettings MAX31865 : : spiConfig = SPISettings (
2021-11-07 04:53:36 +01:00
TERN ( TARGET_LPC1768 , SPI_QUARTER_SPEED , TERN ( ARDUINO_ARCH_STM32 , SPI_CLOCK_DIV4 , 500000 ) ) ,
MSBFIRST ,
SPI_MODE1 // CPOL0 CPHA1
2021-07-07 02:36:41 +02:00
) ;
2021-12-08 19:55:09 +01:00
# if DISABLED(LARGE_PINMAP)
2021-07-07 02:36:41 +02:00
/**
* Create the interface object using software ( bitbang ) SPI for PIN values
* less than or equal to 127.
*
* @ param spi_cs the SPI CS pin to use
* @ param spi_mosi the SPI MOSI pin to use
* @ param spi_miso the SPI MISO pin to use
* @ param spi_clk the SPI clock pin to use
*/
MAX31865 : : MAX31865 ( int8_t spi_cs , int8_t spi_mosi , int8_t spi_miso , int8_t spi_clk ) {
2021-12-08 19:40:23 +01:00
cselPin = spi_cs ;
mosiPin = spi_mosi ;
misoPin = spi_miso ;
sclkPin = spi_clk ;
2021-07-07 02:36:41 +02:00
}
/**
* Create the interface object using hardware SPI for PIN for PIN values less
* than or equal to 127.
*
* @ param spi_cs the SPI CS pin to use along with the default SPI device
*/
MAX31865 : : MAX31865 ( int8_t spi_cs ) {
2021-12-08 19:40:23 +01:00
cselPin = spi_cs ;
sclkPin = misoPin = mosiPin = - 1 ;
2021-07-07 02:36:41 +02:00
}
2021-11-07 04:53:36 +01:00
# else // LARGE_PINMAP
2021-07-07 02:36:41 +02:00
/**
* Create the interface object using software ( bitbang ) SPI for PIN values
* which are larger than 127. If you have PIN values less than or equal to
* 127 use the other call for SW SPI .
*
* @ param spi_cs the SPI CS pin to use
* @ param spi_mosi the SPI MOSI pin to use
* @ param spi_miso the SPI MISO pin to use
* @ param spi_clk the SPI clock pin to use
* @ param pin_mapping set to 1 for positive pin values
*/
2021-11-07 04:53:36 +01:00
MAX31865 : : MAX31865 ( uint32_t spi_cs , uint32_t spi_mosi , uint32_t spi_miso , uint32_t spi_clk , uint8_t pin_mapping ) {
2021-12-08 19:40:23 +01:00
cselPin = spi_cs ;
mosiPin = spi_mosi ;
misoPin = spi_miso ;
sclkPin = spi_clk ;
2021-07-07 02:36:41 +02:00
}
/**
* Create the interface object using hardware SPI for PIN values which are
* larger than 127. If you have PIN values less than or equal to 127 use
* the other call for HW SPI .
*
* @ param spi_cs the SPI CS pin to use along with the default SPI device
* @ param pin_mapping set to 1 for positive pin values
*/
MAX31865 : : MAX31865 ( uint32_t spi_cs , uint8_t pin_mapping ) {
2021-12-08 19:40:23 +01:00
cselPin = spi_cs ;
sclkPin = misoPin = mosiPin = - 1UL ; //-1UL or 0xFFFFFFFF or 4294967295
2021-07-07 02:36:41 +02:00
}
# endif // LARGE_PINMAP
/**
*
* Instance & Class methods
*
*/
/**
* Initialize the SPI interface and set the number of RTD wires used
*
* @ param wires The number of wires in enum format . Can be MAX31865_2WIRE , MAX31865_3WIRE , or MAX31865_4WIRE .
* @ param zero The resistance of the RTD at 0 degC , in ohms .
* @ param ref The resistance of the reference resistor , in ohms .
2021-12-08 19:55:09 +01:00
* @ param wire The resistance of the wire connecting the sensor to the RTD , in ohms .
2021-07-07 02:36:41 +02:00
*/
2021-12-08 19:55:09 +01:00
void MAX31865 : : begin ( max31865_numwires_t wires , float zero_res , float ref_res , float wire_res ) {
zeroRes = zero_res ;
refRes = ref_res ;
wireRes = wire_res ;
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
pinMode ( cselPin , OUTPUT ) ;
digitalWrite ( cselPin , HIGH ) ;
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
if ( sclkPin ! = TERN ( LARGE_PINMAP , - 1UL , 255 ) )
2021-11-07 04:53:36 +01:00
softSpiBegin ( SPI_QUARTER_SPEED ) ; // Define pin modes for Software SPI
2021-08-31 05:40:49 +02:00
else {
2021-12-08 19:55:09 +01:00
DEBUG_ECHOLNPGM ( " Initializing MAX31865 Hardware SPI " ) ;
2021-11-07 04:53:36 +01:00
SPI . begin ( ) ; // Start and configure hardware SPI
2021-07-07 02:36:41 +02:00
}
2021-12-08 19:55:09 +01:00
initFixedFlags ( wires ) ;
clearFault ( ) ; // also initializes flags
# if DISABLED(MAX31865_USE_AUTO_MODE) // make a proper first 1 shot read to initialize _lastRead
enableBias ( ) ;
DELAY_US ( 11500 ) ;
oneShot ( ) ;
DELAY_US ( 65000 ) ;
uint16_t rtd = readRegister16 ( MAX31865_RTDMSB_REG ) ;
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 ) ) ;
resetFlags ( ) ;
lastRead = rtd ;
nextEvent = SETUP_BIAS_VOLTAGE ;
millis_t now = millis ( ) ;
nextEventStamp = now + MAX31865_MIN_SAMPLING_TIME_MSEC ;
TERN_ ( MAX31865_USE_READ_ERROR_DETECTION , lastReadStamp = now ) ;
}
# endif // !MAX31865_USE_AUTO_MODE
DEBUG_ECHOLNPGM (
TERN ( LARGE_PINMAP , " LARGE_PINMAP " , " Regular " )
" begin call with cselPin: " , cselPin ,
" misoPin: " , misoPin ,
" sclkPin: " , sclkPin ,
" mosiPin: " , mosiPin ,
" config: " , readRegister8 ( MAX31865_CONFIG_REG )
) ;
2021-07-07 02:36:41 +02:00
}
/**
2021-12-08 19:55:09 +01:00
* Return and clear the last fault value
2021-07-07 02:36:41 +02:00
*
2021-12-08 19:55:09 +01:00
* @ return The raw unsigned 8 - bit FAULT status register or spike fault
2021-07-07 02:36:41 +02:00
*/
uint8_t MAX31865 : : readFault ( ) {
2021-12-08 19:55:09 +01:00
uint8_t r = lastFault ;
lastFault = 0 ;
return r ;
2021-07-07 02:36:41 +02:00
}
/**
2021-12-08 19:55:09 +01:00
* Clear last fault
2021-07-07 02:36:41 +02:00
*/
void MAX31865 : : clearFault ( ) {
2021-12-07 03:18:50 +01:00
setConfig ( MAX31865_CONFIG_FAULTSTAT , 1 ) ;
2021-07-07 02:36:41 +02:00
}
/**
2021-12-08 19:55:09 +01:00
* Reset flags
2021-07-07 02:36:41 +02:00
*/
2021-12-08 19:55:09 +01:00
void MAX31865 : : resetFlags ( ) {
writeRegister8 ( MAX31865_CONFIG_REG , stdFlags ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Enable the bias voltage on the RTD sensor
*/
2021-12-08 19:55:09 +01:00
void MAX31865 : : enableBias ( ) {
setConfig ( MAX31865_CONFIG_BIAS , 1 ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Start a one - shot temperature reading .
*/
void MAX31865 : : oneShot ( ) {
2021-12-08 19:55:09 +01:00
setConfig ( MAX31865_CONFIG_1SHOT | MAX31865_CONFIG_BIAS , 1 ) ;
2021-07-07 02:36:41 +02:00
}
/**
2021-12-08 19:55:09 +01:00
* Initialize standard flags with flags that will not change during operation ( Hz , polling mode and no . of wires )
2021-07-07 02:36:41 +02:00
*
* @ param wires The number of wires in enum format
*/
2021-12-08 19:55:09 +01:00
void MAX31865 : : initFixedFlags ( max31865_numwires_t wires ) {
// set config-defined flags (same for all sensors)
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 ) ;
2021-07-07 02:36:41 +02:00
if ( wires = = MAX31865_3WIRE )
2021-12-08 19:55:09 +01:00
stdFlags | = MAX31865_CONFIG_3WIRE ;
else // 2 or 4 wire
stdFlags & = ~ MAX31865_CONFIG_3WIRE ;
2021-07-07 02:36:41 +02:00
}
/**
* Read the raw 16 - bit value from the RTD_REG in one shot mode . This will include
* the fault bit , D0 .
*
* @ return The raw unsigned 16 - bit register value with ERROR bit attached , NOT temperature !
*/
uint16_t MAX31865 : : readRaw ( ) {
2021-12-08 19:55:09 +01:00
# if ENABLED(MAX31865_USE_AUTO_MODE)
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
const uint16_t rtd = readRegister16 ( MAX31865_RTDMSB_REG ) ;
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 ( ) ) ;
}
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
# else
if ( PENDING ( millis ( ) , nextEventStamp ) ) {
DEBUG_ECHOLNPGM ( " MAX31865 waiting for event " , nextEvent ) ;
return lastRead ;
}
switch ( nextEvent ) {
case SETUP_BIAS_VOLTAGE :
enableBias ( ) ;
nextEventStamp = millis ( ) + 11 ; // wait at least 11msec before enabling 1shot
nextEvent = SETUP_1_SHOT_MODE ;
DEBUG_ECHOLN ( " MAX31865 bias voltage enabled " ) ;
break ;
case SETUP_1_SHOT_MODE :
oneShot ( ) ;
nextEventStamp = millis ( ) + 65 ; // wait at least 65msec before reading RTD register
nextEvent = READ_RTD_REG ;
DEBUG_ECHOLN ( " MAX31865 1 shot mode enabled " ) ;
break ;
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 ) {
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 ( ) ;
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
} break ;
}
# endif
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
return lastRead ;
2021-07-07 02:36:41 +02:00
}
/**
2021-08-04 02:02:34 +02:00
* Calculate and return the resistance value of the connected RTD .
2021-07-07 02:36:41 +02:00
*
* @ return The raw RTD resistance value , NOT temperature !
*/
float MAX31865 : : readResistance ( ) {
// Strip the error bit (D0) and convert to a float ratio.
2021-12-08 19:40:23 +01:00
// less precise method: (readRaw() * refRes) >> 16
2021-12-08 19:55:09 +01:00
return ( ( readRaw ( ) * RECIPROCAL ( 65536.0f ) ) * refRes - wireRes ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Read the RTD and pass it to temperature ( float ) for calculation .
*
* @ return Temperature in C
*/
float MAX31865 : : temperature ( ) {
return temperature ( readResistance ( ) ) ;
}
/**
* Given the 15 - bit ADC value , calculate the resistance and pass it to temperature ( float ) for calculation .
*
* @ return Temperature in C
*/
2021-12-08 19:40:23 +01:00
float MAX31865 : : temperature ( uint16_t adc_val ) {
2021-12-08 19:55:09 +01:00
return temperature ( ( ( adc_val ) * RECIPROCAL ( 32768.0f ) ) * refRes - wireRes ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Calculate the temperature in C from the RTD resistance .
* Uses the technique outlined in this PDF :
* http : //www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf
*
2021-12-08 19:40:23 +01:00
* @ param rtd_res the resistance value in ohms
* @ return the temperature in degC
2021-07-07 02:36:41 +02:00
*/
2021-12-08 19:40:23 +01:00
float MAX31865 : : temperature ( float rtd_res ) {
float temp = ( RTD_Z1 + sqrt ( RTD_Z2 + ( RTD_Z3 * rtd_res ) ) ) * RECIPROCAL ( RTD_Z4 ) ;
2021-07-07 02:36:41 +02:00
// From the PDF...
//
// The previous equation is valid only for temperatures of 0°C and above.
// The equation for RRTD(t) that defines negative temperature behavior is a
// fourth-order polynomial (after expanding the third term) and is quite
// impractical to solve for a single expression of temperature as a function
// of resistance.
//
if ( temp < 0 ) {
2021-12-08 19:40:23 +01:00
rtd_res = ( rtd_res / zeroRes ) * 100 ; // normalize to 100 ohm
float rpoly = rtd_res ;
2021-07-07 02:36:41 +02:00
temp = - 242.02 + ( 2.2228 * rpoly ) ;
2021-12-08 19:40:23 +01:00
rpoly * = rtd_res ; // square
2021-07-07 02:36:41 +02:00
temp + = 2.5859e-3 * rpoly ;
2021-12-08 19:40:23 +01:00
rpoly * = rtd_res ; // ^3
2021-07-07 02:36:41 +02:00
temp - = 4.8260e-6 * rpoly ;
2021-12-08 19:40:23 +01:00
rpoly * = rtd_res ; // ^4
2021-07-07 02:36:41 +02:00
temp - = 2.8183e-8 * rpoly ;
2021-12-08 19:40:23 +01:00
rpoly * = rtd_res ; // ^5
2021-07-07 02:36:41 +02:00
temp + = 1.5243e-10 * rpoly ;
}
return temp ;
}
//
// private:
//
/**
* 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 ) {
2021-12-08 19:55:09 +01:00
uint8_t t = stdFlags ;
if ( enable ) t | = config ; else t & = ~ config ;
2021-12-07 03:18:50 +01:00
writeRegister8 ( MAX31865_CONFIG_REG , t ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Read a single byte from the specified register address .
*
* @ param addr the register address
* @ return the register contents
*/
uint8_t MAX31865 : : readRegister8 ( uint8_t addr ) {
uint8_t ret = 0 ;
readRegisterN ( addr , & ret , 1 ) ;
return ret ;
}
/**
* Read two bytes : 1 from the specified register address , and 1 from the next address .
*
* @ param addr the first register address
* @ return both register contents as a single 16 - bit int
*/
uint16_t MAX31865 : : readRegister16 ( uint8_t addr ) {
2021-12-08 19:55:09 +01:00
uint8_t buffer [ 2 ] = { 0 } ;
2021-07-07 02:36:41 +02:00
readRegisterN ( addr , buffer , 2 ) ;
2021-12-08 19:55:09 +01:00
return uint16_t ( buffer [ 0 ] ) < < 8 | buffer [ 1 ] ;
2021-07-07 02:36:41 +02:00
}
/**
* Read + n + bytes from a specified address into + buffer + . Set D7 to 0 to specify a read .
*
* @ param addr the first register address
* @ param buffer storage for the read bytes
* @ param n the number of bytes to read
*/
void MAX31865 : : readRegisterN ( uint8_t addr , uint8_t buffer [ ] , uint8_t n ) {
addr & = 0x7F ; // make sure top bit is not set
2021-12-08 19:55:09 +01:00
if ( sclkPin = = TERN ( LARGE_PINMAP , - 1UL , 255 ) )
2021-07-07 02:36:41 +02:00
SPI . beginTransaction ( spiConfig ) ;
else
2021-12-08 19:55:09 +01:00
digitalWrite ( sclkPin , LOW ) ;
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
digitalWrite ( cselPin , LOW ) ;
2021-11-07 04:53:36 +01:00
# ifdef TARGET_LPC1768
2021-12-08 19:40:23 +01:00
DELAY_CYCLES ( spiSpeed ) ;
2021-11-07 04:53:36 +01:00
# endif
spiTransfer ( addr ) ;
2021-07-07 02:36:41 +02:00
while ( n - - ) {
2021-11-07 04:53:36 +01:00
buffer [ 0 ] = spiTransfer ( 0xFF ) ;
2021-07-07 02:36:41 +02:00
buffer + + ;
}
2021-12-08 19:55:09 +01:00
if ( sclkPin = = TERN ( LARGE_PINMAP , - 1UL , 255 ) )
2021-07-07 02:36:41 +02:00
SPI . endTransaction ( ) ;
2021-12-08 19:55:09 +01:00
digitalWrite ( cselPin , HIGH ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Write an 8 - bit value to a register . Set D7 to 1 to specify a write .
*
* @ param addr the address to write to
* @ param data the data to write
*/
void MAX31865 : : writeRegister8 ( uint8_t addr , uint8_t data ) {
2021-12-08 19:55:09 +01:00
if ( sclkPin = = TERN ( LARGE_PINMAP , - 1UL , 255 ) )
2021-07-07 02:36:41 +02:00
SPI . beginTransaction ( spiConfig ) ;
else
2021-12-08 19:55:09 +01:00
digitalWrite ( sclkPin , LOW ) ;
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
digitalWrite ( cselPin , LOW ) ;
2021-07-07 02:36:41 +02:00
2021-11-07 04:53:36 +01:00
# ifdef TARGET_LPC1768
2021-12-08 19:40:23 +01:00
DELAY_CYCLES ( spiSpeed ) ;
2021-11-07 04:53:36 +01:00
# endif
spiTransfer ( addr | 0x80 ) ; // make sure top bit is set
spiTransfer ( data ) ;
2021-07-07 02:36:41 +02:00
2021-12-08 19:55:09 +01:00
if ( sclkPin = = TERN ( LARGE_PINMAP , - 1UL , 255 ) )
2021-07-07 02:36:41 +02:00
SPI . endTransaction ( ) ;
2021-12-08 19:55:09 +01:00
digitalWrite ( cselPin , HIGH ) ;
2021-07-07 02:36:41 +02:00
}
/**
* Transfer SPI data + x + and read the response . From the datasheet . . .
* Input data ( SDI ) is latched on the internal strobe edge and output data ( SDO ) is
* shifted out on the shift edge . There is one clock for each bit transferred .
* Address and data bits are transferred in groups of eight , MSB first .
*
* @ param x an 8 - bit chunk of data to write
* @ return the 8 - bit response
*/
2021-11-07 04:53:36 +01:00
uint8_t MAX31865 : : spiTransfer ( uint8_t x ) {
2021-12-08 19:55:09 +01:00
if ( sclkPin = = TERN ( LARGE_PINMAP , - 1UL , 255 ) )
2021-07-07 02:36:41 +02:00
return SPI . transfer ( x ) ;
2021-11-07 04:53:36 +01:00
# ifdef TARGET_LPC1768
2021-12-08 19:55:09 +01:00
2021-12-08 19:40:23 +01:00
return swSpiTransfer ( x , spiSpeed , sclkPin , misoPin , mosiPin ) ;
2021-12-08 19:55:09 +01:00
2021-11-07 04:53:36 +01:00
# else
2021-12-08 19:55:09 +01:00
2021-11-07 04:53:36 +01:00
uint8_t reply = 0 ;
for ( int i = 7 ; i > = 0 ; i - - ) {
2021-12-08 19:55:09 +01:00
digitalWrite ( sclkPin , HIGH ) ; DELAY_NS_VAR ( spiDelay ) ;
2021-11-07 04:53:36 +01:00
reply < < = 1 ;
2021-12-08 19:55:09 +01:00
digitalWrite ( mosiPin , x & _BV ( i ) ) ; DELAY_NS_VAR ( spiDelay ) ;
if ( digitalRead ( misoPin ) ) reply | = 1 ;
digitalWrite ( sclkPin , LOW ) ; DELAY_NS_VAR ( spiDelay ) ;
2021-11-07 04:53:36 +01:00
}
return reply ;
2021-12-08 19:55:09 +01:00
2021-11-07 04:53:36 +01:00
# endif
}
2021-08-31 05:40:49 +02:00
2021-11-07 04:53:36 +01:00
void MAX31865 : : softSpiBegin ( const uint8_t spi_speed ) {
2021-12-08 19:55:09 +01:00
DEBUG_ECHOLNPGM ( " Initializing MAX31865 Software SPI " ) ;
2021-11-07 04:53:36 +01:00
# ifdef TARGET_LPC1768
2021-12-08 19:40:23 +01:00
swSpiBegin ( sclkPin , misoPin , mosiPin ) ;
spiSpeed = swSpiInit ( spi_speed , sclkPin , mosiPin ) ;
2021-11-07 04:53:36 +01:00
# else
2021-12-08 19:40:23 +01:00
spiDelay = ( 100UL < < spi_speed ) / 3 ; // Calculate delay in ns. Top speed is ~10MHz, or 100ns delay between bits.
2021-12-08 19:55:09 +01:00
pinMode ( sclkPin , OUTPUT ) ;
digitalWrite ( sclkPin , LOW ) ;
pinMode ( mosiPin , OUTPUT ) ;
pinMode ( misoPin , INPUT ) ;
2021-11-07 04:53:36 +01:00
# endif
2021-07-07 02:36:41 +02:00
}
2021-08-31 05:40:49 +02:00
# endif // HAS_MAX31865 && !USE_ADAFRUIT_MAX31865