Files @ 6cc8fa5ae0f6
Branch filter:

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

Ethan Zonca
Temp reading finally working!
//
// 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);
}