Files @ b61e1f4d75c5
Branch filter:

Location: therm-ng/lib/max31856/max31856.c

Ethan Zonca
Fix indentation/formatting
//
// 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;

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_AUTOCONVERT); //  MAX31856_CR0_OCFAULT0

    // 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
float max31856_process(void)
{
    uint8_t tempbuf[3];
    __read_reg(MAX31856_LTCBH_REG, tempbuf, 3);


    volatile int32_t temp24 = tempbuf[0] << 16 | tempbuf[1] << 8 | tempbuf[2];
    if (temp24 & 0x800000) {
        temp24 |= 0xFF000000;  // fix sign
    }

    temp24 >>= 5;  // bottom 5 bits are unused

    float tempfloat = temp24;
    tempfloat *= 0.0078125;

    temp_latest = tempfloat;
    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};
    uint8_t dummyrx[2];

    // Assert the bus
    __cs_assert();


    // Write data
    volatile HAL_StatusTypeDef res = HAL_SPI_TransmitReceive(spiport, outarr, dummyrx, 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];
    regarr[0] = reg;

    uint8_t dummyrx[12] = {0};
    uint8_t dummytx[12] = {0};

    // Assert the bus
    __cs_assert();

    // Send address
    HAL_SPI_TransmitReceive(spiport, regarr, dummyrx, 1, 100);

    // Receive data
    HAL_SPI_TransmitReceive(spiport, dummytx, 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);
}