Skip to content

Commit

Permalink
fixup! drivers: add max31855
Browse files Browse the repository at this point in the history
  • Loading branch information
leandrolanzieri committed Jun 12, 2024
1 parent d180651 commit e42b736
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 38 deletions.
9 changes: 7 additions & 2 deletions drivers/include/max31855.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ int max31855_init(max31855_t *dev, const max31855_params_t *params);
*
* @pre @p data must not be NULL
*/
void max31855_raw_to_data(const uint32_t raw_data, max31855_data_t *data);
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
Expand All @@ -109,8 +109,13 @@ void max31855_raw_to_data(const uint32_t raw_data, max31855_data_t *data);
* @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.
*/
void max31855_read(max31855_t *dev, max31855_data_t *data);
int max31855_read(max31855_t *dev, max31855_data_t *data);

/**
* @brief Read raw data from the MAX31855
Expand Down
65 changes: 61 additions & 4 deletions drivers/max31855/include/max31855_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
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.
*/
Expand All @@ -31,7 +36,7 @@ extern "C" {
/**
@brief Mask value for the thermocouple sign bit.
*/
#define MAX31855_THERMOCOUPLE_SIGN_MASK (0x01)
#define MAX31855_THERMOCOUPLE_SIGN_MASK (1 << MAX31855_THERMOCOUPLE_SIGN_SHIFT)

/**
* @brief Shift value for the thermocouple integer bits.
Expand All @@ -41,18 +46,28 @@ extern "C" {
/**
* @brief Mask value for the thermocouple integer bits.
*/
#define MAX31855_THERMOCOUPLE_INTEGER_MASK (0x7FF)
#define MAX31855_THERMOCOUPLE_INTEGER_MASK (0x7FF << 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 (1 << 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 (1 << 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.
*/
Expand All @@ -61,7 +76,7 @@ extern "C" {
/**
@brief Mask value for the internal sign bit.
*/
#define MAX31855_INTERNAL_SIGN_MASK (0x01)
#define MAX31855_INTERNAL_SIGN_MASK (1 << MAX31855_INTERNAL_SIGN_SHIFT)

/**
* @brief Shift value for the internal integer bits.
Expand All @@ -71,43 +86,85 @@ extern "C" {
/**
* @brief Mask value for the internal integer bits.
*/
#define MAX31855_INTERNAL_INTEGER_MASK (0x7F)
#define MAX31855_INTERNAL_INTEGER_MASK (0x7F << 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 (1 << 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 (1 << 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 (1 << 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 (1 << 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 (1 << 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 (1 << 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 (1 << 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
Expand Down
75 changes: 43 additions & 32 deletions drivers/max31855/max31855.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <assert.h>
#include <errno.h>
#include <stdio.h>

#include "byteorder.h"
#include "log.h"

#include "max31855.h"
Expand All @@ -32,22 +34,21 @@ void _raw_data_to_thermocouple_temperature(uint32_t raw_data, int32_t *temperatu
{
assert(temperature);

int32_t is_negative = (raw_data >> MAX31855_THERMOCOUPLE_SIGN_SHIFT) &
MAX31855_THERMOCOUPLE_SIGN_MASK;
int32_t is_negative = raw_data & MAX31855_THERMOCOUPLE_SIGN_MASK;

if (is_negative) {
raw_data = ~raw_data + 1;
}

*temperature = (raw_data >>
MAX31855_THERMOCOUPLE_INTEGER_SHIFT) & MAX31855_THERMOCOUPLE_INTEGER_MASK;
*temperature = (raw_data & MAX31855_THERMOCOUPLE_INTEGER_MASK) >>
MAX31855_THERMOCOUPLE_INTEGER_SHIFT;

/* convert to centi degC */
*temperature = *temperature * 100;

/* add fractional parts */
*temperature += (raw_data & (1 << MAX31855_THERMOCOUPLE_FRACTIONAL_HALF_SHIFT)) ? 50 : 0;
*temperature += (raw_data & (1 << MAX31855_THERMOCOUPLE_FRACTIONAL_QUARTER_SHIFT)) ? 25 : 0;
*temperature += (raw_data & MAX31855_THERMOCOUPLE_FRACTIONAL_HALF_MASK) ? 50 : 0;
*temperature += (raw_data & MAX31855_THERMOCOUPLE_FRACTIONAL_QUARTER_MASK) ? 25 : 0;

if (is_negative) {
*temperature *= -1;
Expand All @@ -58,42 +59,45 @@ void _raw_data_to_internal_temperature(uint32_t raw_data, int32_t *temperature)
{
assert(temperature);

int32_t sign = (raw_data >> MAX31855_INTERNAL_SIGN_SHIFT) &
MAX31855_INTERNAL_SIGN_MASK ? -1 : 1;
int32_t is_negative = raw_data & MAX31855_INTERNAL_SIGN_MASK;

if (sign == -1) {
if (is_negative) {
raw_data = ~raw_data + 1;
}

*temperature = (raw_data >> MAX31855_INTERNAL_INTEGER_SHIFT) & MAX31855_INTERNAL_INTEGER_MASK;
*temperature = (raw_data & MAX31855_INTERNAL_INTEGER_MASK) >> MAX31855_INTERNAL_INTEGER_SHIFT;

/* convert to centi degC */
*temperature = *temperature * 100;

/* add fractional parts */
*temperature += (raw_data & (1 << MAX31855_INTERNAL_FRACTIONAL_HALF_SHIFT)) ? 50 : 0;
*temperature += (raw_data & (1 << MAX31855_INTERNAL_FRACTIONAL_QUARTER_SHIFT)) ? 25 : 0;
*temperature += (raw_data & (1 << MAX31855_INTERNAL_FRACTIONAL_EIGHTH_SHIFT)) ? 12 : 0;
*temperature += (raw_data & (1 << MAX31855_INTERNAL_FRACTIONAL_SIXTEENTH_SHIFT)) ? 6 : 0;
*temperature += (raw_data & MAX31855_INTERNAL_FRACTIONAL_HALF_MASK) ? 50 : 0;
*temperature += (raw_data & MAX31855_INTERNAL_FRACTIONAL_QUARTER_MASK) ? 25 : 0;
*temperature += (raw_data & MAX31855_INTERNAL_FRACTIONAL_EIGHTH_MASK) ? 12 : 0;
*temperature += (raw_data & MAX31855_INTERNAL_FRACTIONAL_SIXTEENTH_MASK) ? 6 : 0;

*temperature *= sign;
if (is_negative) {
*temperature *= -1;
}
}

void _raw_data_to_fault(const uint32_t raw_data, max31855_fault_t *fault)
void _raw_data_to_fault(uint32_t raw_data, max31855_fault_t *fault)
{
assert(fault);

if (raw_data & (1 << MAX31855_FAULT_VCC_SHORT_SHIFT)) {
*fault = MAX31855_FAULT_VCC_SHORT;
}
else if (raw_data & (1 << MAX31855_FAULT_GND_SHORT_SHIFT)) {
*fault = MAX31855_FAULT_GND_SHORT;
}
else if (raw_data & (1 << MAX31855_FAULT_OPEN_CIRCUIT_SHIFT)) {
*fault = MAX31855_FAULT_OPEN_CIRCUIT;
}
else {
*fault = MAX31855_FAULT_NO_FAULT;
switch (raw_data & MAX31855_FAULT_MASK) {
case MAX31855_FAULT_VCC_SHORT_MASK:
*fault = MAX31855_FAULT_VCC_SHORT;
break;
case MAX31855_FAULT_GND_SHORT_MASK:
*fault = MAX31855_FAULT_GND_SHORT;
break;
case MAX31855_FAULT_OPEN_CIRCUIT_MASK:
*fault = MAX31855_FAULT_OPEN_CIRCUIT;
break;
default:
*fault = MAX31855_FAULT_NO_FAULT;
break;
}
}

Expand All @@ -118,15 +122,15 @@ void max31855_read_raw(max31855_t *dev, uint32_t *data)
assert(dev);
assert(data);

uint8_t buffer[4] = { 0 };
uint8_t buffer[MAX31855_DATA_SIZE] = { 0 };
spi_acquire(dev->params->spi, dev->params->cs_pin, SPI_MODE_0, SPI_CLK_5MHZ);
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, NULL, buffer, 4);
spi_transfer_bytes(dev->params->spi, dev->params->cs_pin, false, NULL, buffer, sizeof(buffer));
spi_release(dev->params->spi);

*data = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
*data = byteorder_bebuftohl(buffer);
}

void max31855_raw_to_data(const uint32_t raw_data, max31855_data_t *data)
void max31855_raw_to_data(uint32_t raw_data, max31855_data_t *data)
{
assert(data);

Expand All @@ -135,11 +139,18 @@ void max31855_raw_to_data(const uint32_t raw_data, max31855_data_t *data)
_raw_data_to_fault(raw_data, &data->fault);
}

void max31855_read(max31855_t *dev, max31855_data_t *data)
int max31855_read(max31855_t *dev, max31855_data_t *data)
{
assert(dev && data);

uint32_t raw_data;
max31855_read_raw(dev, &raw_data);
max31855_raw_to_data(raw_data, data);

if (data->fault != MAX31855_FAULT_NO_FAULT) {
LOG_ERROR("MAX31855 fault: %d\n", data->fault);
return -EIO;
}

return 0;
}

0 comments on commit e42b736

Please sign in to comment.