Skip to content

Commit

Permalink
Merge pull request #20741 from leandrolanzieri/pr/driver/max31855
Browse files Browse the repository at this point in the history
Drivers: add MAX31855 thermocouple-to-digital converter
  • Loading branch information
leandrolanzieri authored Jun 13, 2024
2 parents 4aefcd2 + b092f95 commit 755f931
Show file tree
Hide file tree
Showing 13 changed files with 795 additions and 0 deletions.
135 changes: 135 additions & 0 deletions drivers/include/max31855.h
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 */
/** @} */
1 change: 1 addition & 0 deletions drivers/max31855/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
1 change: 1 addition & 0 deletions drivers/max31855/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FEATURES_REQUIRED += periph_spi
2 changes: 2 additions & 0 deletions drivers/max31855/Makefile.include
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)
173 changes: 173 additions & 0 deletions drivers/max31855/include/max31855_constants.h
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)

Check warning on line 59 in drivers/max31855/include/max31855_constants.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

/**
* @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)

Check warning on line 69 in drivers/max31855/include/max31855_constants.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

/**
* @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)

Check warning on line 109 in drivers/max31855/include/max31855_constants.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

/**
* @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)

Check warning on line 129 in drivers/max31855/include/max31855_constants.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters

/**
* @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 */
/** @} */
Loading

0 comments on commit 755f931

Please sign in to comment.