// // 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); }