diff --git a/lib/max31856/max31856.c b/lib/max31856/max31856.c new file mode 100644 --- /dev/null +++ b/lib/max31856/max31856.c @@ -0,0 +1,148 @@ +// +// MAX31856: Driver to configure and read temperature from the MAX31856 thermoouple-to-Digital IC +// + +#include "max31856.h" +#include "states.h" +#include "error.h" + +// Private variables +static float temp_latest = 0.0; +static float temp_avg = 0.0; + +static SPI_HandleTypeDef* spiport; +static GPIO_TypeDef* csport; +static uint32_t cspin; + + +// Private prototypes +static void __cs_assert(void); +static void __cs_deassert(void); +static void __write_reg(uint8_t reg, uint8_t data); +static void __read_reg(uint8_t reg, uint8_t* rxbuf, uint8_t len); + + +// Initialize the MAX31856 driver +void max31856_init(SPI_HandleTypeDef* spi_port, GPIO_TypeDef* cs_port, uint32_t cs_pin, uint32_t sensor_type) +{ + // Set CS pin references + csport = cs_port; + cspin = cs_pin; + + // Set SPI port reference + spiport = spi_port; + + // Configure the CS pin for output + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Pin = cs_pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(cs_port, &GPIO_InitStruct); + + // MAX31856 + // - set to continuous conversion mode + // - probably no filtering, we'll do that on this side of things + // - set up to read the typical open/short faults but not the high/low alarms + + + // TODO: Enable open/short detection + // Enables auto conv + __write_reg(MAX31856_CR0_REG, MAX31856_CR0_OCFAULT0 | MAX31856_CR0_AUTOCONVERT); + + // Averaging set to 1 sample, TC type set to K + __write_reg(MAX31856_CR1_REG, MAX31856_TCTYPE_K); + + // sensor type - could we just mask bits off? maybe optimize the enum for this +} + + +// Pull reading from the MAX31856 IC +void max31856_process(void) +{ + uint8_t tempbuf[4]; + __read_reg(MAX31856_LTCBH_REG, tempbuf, 3); + + + int32_t temp24 = tempbuf[0] << 16 | tempbuf[1] << 8 | tempbuf[0]; + if (temp24 & 0x800000) { + temp24 |= 0xFF000000; // fix sign + } + + temp24 >>= 5; // bottom 5 bits are unused + + float tempfloat = temp24; + tempfloat *= 0.0078125; + + return tempfloat; + + + + + // Read temperature from the MAX31856 (approx 10hz optimally) + uint8_t data[] = {0,0,0,0}; + HAL_SPI_Transmit(spiport, data, 1, 100); + +} + + +// Return latest temperature reading (unaveraged, deg C) +float max31856_latest_temp(void) +{ + return temp_latest; +} + + +// Return average temperature reading (deg C) +float max31856_avg_temp(void) +{ + return temp_latest; +} + + +static void __write_reg(uint8_t reg, uint8_t data) +{ + // Set write bit + reg |= MAX31856_WRITE_BIT; + + uint8_t outarr[2] = {reg, data}; + + // Assert the bus + __cs_assert(); + + // Write data + HAL_SPI_Transmit(spiport, outarr, 2, 100); + + // Release the bus + __cs_deassert(); +} + +static void __read_reg(uint8_t reg, uint8_t* rxbuf, uint8_t len) +{ + // Transmit buffer only uses first item for reg addr + uint8_t regarr[1] = {reg}; + + + // Assert the bus + __cs_assert(); + + // Send address + HAL_SPI_Transmit(spiport, regarr, 1, 100); + + // Receive data + HAL_SPI_Receive(spiport, rxbuf, len, 100); + + // Release bus + __cs_deassert(); + +} + +static void __cs_assert(void) +{ + HAL_GPIO_WritePin(csport, cspin, 0); +} + +static void __cs_deassert(void) +{ + HAL_GPIO_WritePin(csport, cspin, 1); +}