-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20741 from leandrolanzieri/pr/driver/max31855
Drivers: add MAX31855 thermocouple-to-digital converter
- Loading branch information
Showing
13 changed files
with
795 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright (C) 2024 HAW Hamburg | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @defgroup drivers_max31855 MAX31855 Thermocouple-to-Digital Converter driver | ||
* @ingroup drivers_sensors | ||
* @brief Driver for the SPI Thermocouple-to-Digital Converter MAX31855. | ||
* | ||
* The MAX31855 performs cold-junction compensation and digitizes | ||
* the signal from a K-, J-, N-, T-, S-, R-, or E-type | ||
* thermocouple. The data is output in a signed 14-bit, | ||
* SPI-compatible, read-only format. This converter resolves | ||
* temperatures to 0.25°C, allows readings as high as +1800°C and | ||
* as low as -270°C, and exhibits thermocouple accuracy of ±2°C | ||
* for temperatures ranging from -200°C to +700°C for K-type | ||
* thermocouples. | ||
* | ||
* @note See the datasheet for more information: | ||
* https://www.analog.com/media/en/technical-documentation/data-sheets/MAX31855.pdf | ||
* | ||
* @note This driver doesn't require a MOSI line, as the MAX31855 is a read-only. | ||
* | ||
* @{ | ||
* | ||
* @file | ||
* | ||
* @author Leandro Lanzieri <[email protected]> | ||
*/ | ||
|
||
#ifndef MAX31855_H | ||
#define MAX31855_H | ||
|
||
/* Add header includes here */ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include "periph/spi.h" | ||
|
||
/* Declare the API of the driver */ | ||
|
||
/** | ||
* @brief Device initialization parameters | ||
*/ | ||
typedef struct { | ||
spi_t spi; /**< SPI device */ | ||
spi_cs_t cs_pin; /**< Chip select pin */ | ||
} max31855_params_t; | ||
|
||
/** | ||
* @brief Device descriptor for the driver | ||
*/ | ||
typedef struct { | ||
const max31855_params_t *params; /**< device configuration */ | ||
} max31855_t; | ||
|
||
/** | ||
* @brief Fault status of the MAX31855 | ||
*/ | ||
typedef enum { | ||
MAX31855_FAULT_VCC_SHORT = 0, /**< VCC short-circuit */ | ||
MAX31855_FAULT_GND_SHORT = 1, /**< GND short-circuit */ | ||
MAX31855_FAULT_OPEN_CIRCUIT = 2, /**< Open circuit */ | ||
MAX31855_FAULT_NO_FAULT = 3 /**< No fault */ | ||
} max31855_fault_t; | ||
|
||
/** | ||
* @brief Data structure for the MAX31855 | ||
*/ | ||
typedef struct { | ||
int32_t thermocouple_temperature; /**< Thermocouple temperature in centi degrees C */ | ||
int32_t internal_temperature; /**< Internal temperature in centi degrees C */ | ||
max31855_fault_t fault; /**< Fault status */ | ||
} max31855_data_t; | ||
|
||
/** | ||
* @brief Initialize the given device | ||
* | ||
* @param[inout] dev Device descriptor of the driver | ||
* @param[in] params Initialization parameters | ||
* | ||
* @retval 0 on success | ||
* @retval -ENXIO invalid SPI device | ||
* @retval -EINVAL invalid SPI CS pin/line | ||
*/ | ||
int max31855_init(max31855_t *dev, const max31855_params_t *params); | ||
|
||
/** | ||
* @brief Parse the raw data from the MAX31855 to the data structure | ||
* | ||
* @param[in] raw_data Raw data from the MAX31855 | ||
* @param[out] data Pointer to the data structure. | ||
* | ||
* @pre @p data must not be NULL | ||
*/ | ||
void max31855_raw_to_data(uint32_t raw_data, max31855_data_t *data); | ||
|
||
/** | ||
* @brief Read data from the MAX31855. This is a shortcut to read raw data | ||
* and parse it to the data structure. | ||
* | ||
* @param[in] dev Device descriptor of the driver | ||
* @param[out] data Pointer to the data structure. | ||
* | ||
* @pre @p dev and @p data must not be NULL | ||
* | ||
* @retval 0 on success | ||
* @retval -EIO if there is an error detected by the MAX31855. For a detailed | ||
* error description, check the fault field of the data structure. On this | ||
* case, temperature fields are not valid. | ||
*/ | ||
int max31855_read(max31855_t *dev, max31855_data_t *data); | ||
|
||
/** | ||
* @brief Read raw data from the MAX31855 | ||
* | ||
* @param[in] dev Device descriptor of the driver | ||
* @param[out] data Pointer where to store the raw data. | ||
* | ||
* @pre @p dev and @p data must not be NULL | ||
*/ | ||
void max31855_read_raw(max31855_t *dev, uint32_t *data); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* MAX31855_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
FEATURES_REQUIRED += periph_spi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
USEMODULE_INCLUDES_max31855 := $(LAST_MAKEFILEDIR)/include | ||
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_max31855) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright (C) 2024 HAW Hamburg | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup drivers_max31855 | ||
* @{ | ||
* | ||
* @file | ||
* @brief Internal addresses, registers and constants | ||
* | ||
* @author Leandro Lanzieri <[email protected]> | ||
*/ | ||
|
||
#ifndef MAX31855_CONSTANTS_H | ||
#define MAX31855_CONSTANTS_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Size of the data read from the MAX31855 in bytes. | ||
*/ | ||
#define MAX31855_DATA_SIZE (4) | ||
|
||
/** | ||
* @brief Shift value for the thermocouple sign bit. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_SIGN_SHIFT (31) | ||
|
||
/** | ||
@brief Mask value for the thermocouple sign bit. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_SIGN_MASK (1UL << MAX31855_THERMOCOUPLE_SIGN_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the thermocouple integer bits. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_INTEGER_SHIFT (20) | ||
|
||
/** | ||
* @brief Mask value for the thermocouple integer bits. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_INTEGER_MASK (0x7FFUL << MAX31855_THERMOCOUPLE_INTEGER_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the thermocouple fractional half degree bit. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_FRACTIONAL_HALF_SHIFT (19) | ||
|
||
/** | ||
* @brief Mask value for the thermocouple fractional half degree bit. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_FRACTIONAL_HALF_MASK (1UL << MAX31855_THERMOCOUPLE_FRACTIONAL_HALF_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the thermocouple fractional quarter degree bit. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_FRACTIONAL_QUARTER_SHIFT (18) | ||
|
||
/** | ||
* @brief Mask value for the thermocouple fractional quarter degree bit. | ||
*/ | ||
#define MAX31855_THERMOCOUPLE_FRACTIONAL_QUARTER_MASK (1UL << MAX31855_THERMOCOUPLE_FRACTIONAL_QUARTER_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the internal sign bit. | ||
*/ | ||
#define MAX31855_INTERNAL_SIGN_SHIFT (15) | ||
|
||
/** | ||
@brief Mask value for the internal sign bit. | ||
*/ | ||
#define MAX31855_INTERNAL_SIGN_MASK (1UL << MAX31855_INTERNAL_SIGN_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the internal integer bits. | ||
*/ | ||
#define MAX31855_INTERNAL_INTEGER_SHIFT (8) | ||
|
||
/** | ||
* @brief Mask value for the internal integer bits. | ||
*/ | ||
#define MAX31855_INTERNAL_INTEGER_MASK (0x7FUL << MAX31855_INTERNAL_INTEGER_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the internal fractional half degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_HALF_SHIFT (7) | ||
|
||
/** | ||
* @brief Mask value for the internal fractional half degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_HALF_MASK (1UL << MAX31855_INTERNAL_FRACTIONAL_HALF_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the internal fractional quarter degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_QUARTER_SHIFT (6) | ||
|
||
/** | ||
* @brief Mask value for the internal fractional quarter degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_QUARTER_MASK (1UL << MAX31855_INTERNAL_FRACTIONAL_QUARTER_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the internal fractional eighth degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_EIGHTH_SHIFT (5) | ||
|
||
/** | ||
* @brief Shift value for the internal fractional eighth degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_EIGHTH_MASK (1UL << MAX31855_INTERNAL_FRACTIONAL_EIGHTH_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the internal fractional sixteenth degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_SIXTEENTH_SHIFT (4) | ||
|
||
/** | ||
* @brief Shift value for the internal fractional sixteenth degree bit. | ||
*/ | ||
#define MAX31855_INTERNAL_FRACTIONAL_SIXTEENTH_MASK (1UL << MAX31855_INTERNAL_FRACTIONAL_SIXTEENTH_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the fault bit indicating a VCC short. | ||
*/ | ||
#define MAX31855_FAULT_VCC_SHORT_SHIFT (2) | ||
|
||
/** | ||
* @brief Mask value for the fault bit indicating a VCC short. | ||
*/ | ||
#define MAX31855_FAULT_VCC_SHORT_MASK (1UL << MAX31855_FAULT_VCC_SHORT_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the fault bit indicating a GND short. | ||
*/ | ||
#define MAX31855_FAULT_GND_SHORT_SHIFT (1) | ||
|
||
/** | ||
* @brief Mask value for the fault bit indicating a GND short. | ||
*/ | ||
#define MAX31855_FAULT_GND_SHORT_MASK (1UL << MAX31855_FAULT_GND_SHORT_SHIFT) | ||
|
||
/** | ||
* @brief Shift value for the fault bit indicating an open circuit. | ||
*/ | ||
#define MAX31855_FAULT_OPEN_CIRCUIT_SHIFT (0) | ||
|
||
/** | ||
* @brief Mask value for the fault bit indicating an open circuit. | ||
*/ | ||
#define MAX31855_FAULT_OPEN_CIRCUIT_MASK (1UL << MAX31855_FAULT_OPEN_CIRCUIT_SHIFT) | ||
|
||
/** | ||
* @brief Mask value for the fault bits. | ||
*/ | ||
#define MAX31855_FAULT_MASK (MAX31855_FAULT_VCC_SHORT_MASK | \ | ||
MAX31855_FAULT_GND_SHORT_MASK | \ | ||
MAX31855_FAULT_OPEN_CIRCUIT_MASK) | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* MAX31855_CONSTANTS_H */ | ||
/** @} */ |
Oops, something went wrong.