diff --git a/inc/tempsense.h b/inc/tempsense.h --- a/inc/tempsense.h +++ b/inc/tempsense.h @@ -2,6 +2,10 @@ #define TEMPSENSE_H +#define TEMPSENSE_MAX_CS_PIN GPIO_PIN_15 +#define TEMPSENSE_MAX_CS_PORT GPIOA + + void tempsense_init(void); float tempsense_readtemp(void); diff --git a/lib/max31856/max31856.c b/lib/max31856/max31856.c --- a/lib/max31856/max31856.c +++ b/lib/max31856/max31856.c @@ -4,17 +4,31 @@ #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; @@ -31,14 +45,40 @@ void max31856_init(SPI_HandleTypeDef* sp // - 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 - uint8_t data[] = {0,0,0,0}; - HAL_SPI_Transmit(spiport, data, 1, 100); + + // 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); @@ -52,8 +92,57 @@ 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); +} diff --git a/lib/max31856/max31856.h b/lib/max31856/max31856.h --- a/lib/max31856/max31856.h +++ b/lib/max31856/max31856.h @@ -3,5 +3,62 @@ #include "stm32f3xx_hal.h" +void max31856_init(SPI_HandleTypeDef* spi_port, GPIO_TypeDef* cs_port, uint32_t cs_pin, uint32_t sensor_type); +void max31856_process(void); +float max31856_latest_temp(void); +float max31856_avg_temp(void); + +// Thanks to Adafruit: +#define MAX31856_CR0_REG 0x00 +#define MAX31856_CR0_AUTOCONVERT 0x80 +#define MAX31856_CR0_1SHOT 0x40 +#define MAX31856_CR0_OCFAULT1 0x20 +#define MAX31856_CR0_OCFAULT0 0x10 +#define MAX31856_CR0_CJ 0x08 +#define MAX31856_CR0_FAULT 0x04 +#define MAX31856_CR0_FAULTCLR 0x02 + +#define MAX31856_CR1_REG 0x01 +#define MAX31856_MASK_REG 0x02 +#define MAX31856_CJHF_REG 0x03 +#define MAX31856_CJLF_REG 0x04 +#define MAX31856_LTHFTH_REG 0x05 +#define MAX31856_LTHFTL_REG 0x06 +#define MAX31856_LTLFTH_REG 0x07 +#define MAX31856_LTLFTL_REG 0x08 +#define MAX31856_CJTO_REG 0x09 +#define MAX31856_CJTH_REG 0x0A +#define MAX31856_CJTL_REG 0x0B +#define MAX31856_LTCBH_REG 0x0C +#define MAX31856_LTCBM_REG 0x0D +#define MAX31856_LTCBL_REG 0x0E +#define MAX31856_SR_REG 0x0F + +#define MAX31856_FAULT_CJRANGE 0x80 +#define MAX31856_FAULT_TCRANGE 0x40 +#define MAX31856_FAULT_CJHIGH 0x20 +#define MAX31856_FAULT_CJLOW 0x10 +#define MAX31856_FAULT_TCHIGH 0x08 +#define MAX31856_FAULT_TCLOW 0x04 +#define MAX31856_FAULT_OVUV 0x02 +#define MAX31856_FAULT_OPEN 0x01 + + +#define MAX31856_WRITE_BIT 0x80 + +typedef enum +{ + MAX31856_TCTYPE_B = 0b0000, + MAX31856_TCTYPE_E = 0b0001, + MAX31856_TCTYPE_J = 0b0010, + MAX31856_TCTYPE_K = 0b0011, + MAX31856_TCTYPE_N = 0b0100, + MAX31856_TCTYPE_R = 0b0101, + MAX31856_TCTYPE_S = 0b0110, + MAX31856_TCTYPE_T = 0b0111, + MAX31856_VMODE_G8 = 0b1000, + MAX31856_VMODE_G32 = 0b1100, +} max31856_thermocoupletype_t; + #endif diff --git a/lib/ssd1306/ssd1306.h b/lib/ssd1306/ssd1306.h --- a/lib/ssd1306/ssd1306.h +++ b/lib/ssd1306/ssd1306.h @@ -31,6 +31,8 @@ //#define SPI_SendByte(data) SPI_I2S_SendData(SPI1,data) //#define SPI_Wait() while(!(SPI1->SR&SPI_FLAG_TXE));while(SPI1->SR&SPI_FLAG_BSY); +SPI_HandleTypeDef* spi_get(); + void ssd1306_init(void); void ssd1306_drawchar(char ascii, unsigned char row, unsigned char xPos); void ssd1306_drawcharbig(char ascii, unsigned char row, unsigned char xPos); diff --git a/src/tempsense.c b/src/tempsense.c --- a/src/tempsense.c +++ b/src/tempsense.c @@ -4,10 +4,16 @@ #include "tempsense.h" #include "flash.h" +#include "ssd1306/ssd1306.h" +#include "max31856/max31856.h" void tempsense_init(void) { + // TODO: Rework SPI stuff... init the port in a sharedlib then pass ref to display and tempsense + + max31856_init(spi_get(), TEMPSENSE_MAX_CS_PORT, TEMPSENSE_MAX_CS_PIN, 0); + // Maybe don't perform temp sensor setup in here, but in readtemp? // what happens if the user changes the tempsense type while running? // we need to re-init...