Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drivers: add MAX31855 thermocouple-to-digital converter #20741

Merged
merged 2 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 <leandro.lanzieri@haw-hamburg.de>
*/

#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 */
Teufelchen1 marked this conversation as resolved.
Show resolved Hide resolved
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 <leandro.lanzieri@haw-hamburg.de>
*/

#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
Loading