From 7c5f4116d195a26794f1dd6d08a2f3200d7d51c0 Mon Sep 17 00:00:00 2001 From: Nathael Pajani Date: Wed, 9 Sep 2015 21:14:24 +0200 Subject: [PATCH] Add Max31855 thermocouple to digital converter support. --- extdrv/max31855_thermocouple.c | 126 +++++++++++++++++++++++++ include/extdrv/max31855_thermocouple.h | 66 +++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 extdrv/max31855_thermocouple.c create mode 100644 include/extdrv/max31855_thermocouple.h diff --git a/extdrv/max31855_thermocouple.c b/extdrv/max31855_thermocouple.c new file mode 100644 index 0000000..ef91e61 --- /dev/null +++ b/extdrv/max31855_thermocouple.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * extdrv/max31855_thermocouple.c + * + * + * Copyright 2015 Nathael Pajani + * + * + * 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 2 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 . + * + *************************************************************************** */ + +#include + +#include "core/lpc_regs_12xx.h" +#include "core/system.h" +#include "core/pio.h" +#include "drivers/gpio.h" +#include "drivers/ssp.h" +#include "extdrv/max31855_thermocouple.h" + +/* Debug */ +#include "lib/stdio.h" + + +/* Support for thermocouple temperature sensors using Maxim's MAX31855 themocouple + * to digital converter. + */ + + + +/* Convert raw temperature data (expressed as ....) + * into a centimal integer value of ten times the actual temperature. + * The value returned is thus in tenth of celcius degrees. + */ +int max31855_convert_to_centi_degrees(uint16_t raw) +{ + uint16_t val16 = ((raw >> 2) & 0x07FF); + int val = 0; + + if (raw & 0x2000) { + val16 = (~(val16) & 0x07FF);; + val = -val16; + val--; + } else { + val = val16; + } + val = val * 100; + + val += (25 * (raw & 0x03)); + return val; +} + +/* Temp Read + * Performs a non-blocking read of the temperature from the sensor. + * 'raw' and 'centi_degrees' : integer addresses for conversion result, may be NULL. + * Return value(s): + * Upon successfull completion, returns 0 and the temperature read is placed in the integers pointed to + * by 'raw' and 'centi_degrees' pointers. + * Return -EBUSY when unable to get SPI bus mutex or -ENODEV if the Fault bit is set in the temperature + * word. If -ENODEV is returned and 'raw' is not NULL then raw will be updated with the three bits + * indicating the error condition instead of the temparature. + */ +int max31855_sensor_read(const struct max31855_sensor_config* conf, uint16_t* raw, int* centi_degrees) +{ + int temp = 0; + uint32_t data = 0; + uint16_t raw_temp = 0; + + /* Get hold of the SPI bus */ + if (spi_get_mutex(conf->ssp_bus_num) != 1) { + return -EBUSY; + } + /* Read data */ + gpio_clear(conf->chip_select); + spi_transfer_multiple_frames(conf->ssp_bus_num, NULL, (uint8_t*)(&data), 4, 8); + gpio_set(conf->chip_select); + /* Release SPI bus */ + spi_release_mutex(conf->ssp_bus_num); + + /* Swap bytes ! */ + data = byte_swap_32(data); + + /* Check for fault info */ + if (data & MAX31855_TH_FAULT) { + if (raw != NULL) { + *raw = (data & MAX31855_TH_ERROR_BITS_MASK); + } + return -ENODEV; + } + + /* Convert result */ + raw_temp = MAX31855_TH_TEMP_DATA(data); + temp = max31855_convert_to_centi_degrees(raw_temp); + if (raw != NULL) { + *raw = raw_temp; + } + if (centi_degrees != NULL) { + *centi_degrees = temp; + } + + /* Debug */ + uprintf(0, "TC: data(0x%08x) - raw(0x%04x) - deg: %d,%d\r\n", data, raw_temp, (temp / 100), (temp % 100)); + + return 0; +} + + +/* Sensor config */ +void max31855_sensor_config(const struct max31855_sensor_config* conf) +{ + /* Configure slave select pin as GPIO and set initial level to 1 (not selected) */ + config_gpio(&(conf->chip_select), LPC_IO_MODE_PULL_UP, GPIO_DIR_OUT, 1); +} + + diff --git a/include/extdrv/max31855_thermocouple.h b/include/extdrv/max31855_thermocouple.h new file mode 100644 index 0000000..c1d01f8 --- /dev/null +++ b/include/extdrv/max31855_thermocouple.h @@ -0,0 +1,66 @@ +/**************************************************************************** + * extdrv/max31855_thermocouple.h + * + * + * Copyright 2012 Nathael Pajani + * + * + * 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 2 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 . + * + *************************************************************************** */ + +#ifndef EXTDRV_MAX31855_H +#define EXTDRV_MAX31855_H + +#include +#include "core/pio.h" + +/* Support for thermocouple temperature sensors using Maxim's MAX31855 themocouple + * to digital converter. + */ + +struct max31855_sensor_config { + uint8_t ssp_bus_num; + struct pio chip_select; +}; + +#define MAX31855_TH_TEMP_DATA(x) (((x) >> 18) & 0x3FFF) +#define MAX31855_TH_REF_DATA(x) (((x) >> 4) & 0x0FFF) +#define MAX31855_TH_FAULT (0x01 << 16) +#define MAX31855_TH_ERROR_BITS_MASK (0x07) +#define MAX31855_TH_ERR_SHORT_TO_VCC (0x01 << 2) +#define MAX31855_TH_ERR_SHORT_TO_GND (0x01 << 1) +#define MAX31855_TH_ERR_OPEN_CIRCUIT (0x01 << 0) + +/* Convert raw temperature data (expressed as ....) + * into a decimal integer value of ten times the actual temperature. + * The value returned is thus in tenth of celcius degrees. + */ +int max31855_convert_to_deci_degrees(uint16_t raw); + +/* Temp Read + * Performs a non-blocking read of the temperature from the sensor. + * 'raw' and 'deci_degrees' : integer addresses for conversion result, may be NULL. + * Return value(s): + * Upon successfull completion, returns 0 and the temperature read is placed in the + * integers pointed to by 'raw' and 'deci_degrees' pointers. + */ +int max31855_sensor_read(const struct max31855_sensor_config* conf, uint16_t* raw, int* deci_degrees); + +/* Sensor config */ +void max31855_sensor_config(const struct max31855_sensor_config* conf); + + +#endif /* EXTDRV_MAX31855_H */ + -- 2.43.0