Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions MAX31856/MAX31856MUD+Driver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <assert.h>
#include <MAX31856MUD+Driver.hpp>

#define SPI_DUMMY_BYTE 0x00

MAX31856Driver::MAX31856Driver() {}
MAX31856Driver::~MAX31856Driver() {}

//marks driver as initialized
void MAX31856Driver::Init(SPI_HandleTypeDef* hspi_, GPIO_TypeDef* cs_gpio_, uint16_t cs_pin_) {
hspi = hspi_;
initialized = true;

SetCSPin(cs_gpio_, cs_pin_);
CSHigh();

(void)GetRegister(MAX31856_REG::CR0);
}

uint8_t MAX31856Driver::GetRegister(MAX31856_REG::REG reg) {
assert(initialized);

uint8_t tx[2] = {
uint8_t(reg & 0x7F),
SPI_DUMMY_BYTE
};
uint8_t rx[2] = {0,0};

CSLow();
for(volatile int i = 0; i < 500; i++) { __NOP(); }

HAL_SPI_TransmitReceive(hspi, tx, rx, 2, 1000);

for(volatile int i = 0; i < 500; i++) { __NOP(); }
CSHigh();

return rx[1];
}

bool MAX31856Driver::SetRegister(MAX31856_REG::REG reg, uint8_t val) {
assert(initialized);

uint8_t tx[2] = {
uint8_t(reg | 0x80),
val
};
uint8_t dummy_rx[2] = {0, 0};

CSLow();
for(volatile int i = 0; i < 500; i++) { __NOP(); }

HAL_StatusTypeDef r = HAL_SPI_TransmitReceive(hspi, tx, dummy_rx, 2, 1000);

for(volatile int i = 0; i < 500; i++) { __NOP(); }
CSHigh();

return r == HAL_OK;
}

void MAX31856Driver::CSLow() {
assert(initialized);
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_RESET);
}

void MAX31856Driver::CSHigh() {
assert(initialized);
HAL_GPIO_WritePin(cs_gpio, cs_pin, GPIO_PIN_SET);
for(volatile int i = 0; i < 500; i++) { __NOP(); }
}

void MAX31856Driver::SetCSPin(GPIO_TypeDef* gpio, uint16_t pin) {
cs_gpio = gpio;
cs_pin = pin;
}

bool MAX31856Driver::SetMASK(uint8_t value) { return SetRegister(MAX31856_REG::MASK, value); }
uint8_t MAX31856Driver::GetMASK() { return GetRegister(MAX31856_REG::MASK); }
bool MAX31856Driver::SetCJHF(uint8_t value) { return SetRegister(MAX31856_REG::CJHF, value); }
uint8_t MAX31856Driver::GetCJHF() { return GetRegister(MAX31856_REG::CJHF); }
bool MAX31856Driver::SetCR0(uint8_t value) { return SetRegister(MAX31856_REG::CR0, value); }
uint8_t MAX31856Driver::GetCR0() { return GetRegister(MAX31856_REG::CR0); }
bool MAX31856Driver::SetCR1(uint8_t value) { return SetRegister(MAX31856_REG::CR1, value); }
uint8_t MAX31856Driver::GetCR1() { return GetRegister(MAX31856_REG::CR1); }
bool MAX31856Driver::SetCJLF(uint8_t value) { return SetRegister(MAX31856_REG::CJLF, value); }
uint8_t MAX31856Driver::GetCJLF() { return GetRegister(MAX31856_REG::CJLF); }
bool MAX31856Driver::SetLTHFTH(uint8_t value) { return SetRegister(MAX31856_REG::LTHFTH, value); }
uint8_t MAX31856Driver::GetLTHFTH() { return GetRegister(MAX31856_REG::LTHFTH); }
bool MAX31856Driver::SetLTHFTL(uint8_t value) { return SetRegister(MAX31856_REG::LTHFTL, value); }
uint8_t MAX31856Driver::GetLTHFTL() { return GetRegister(MAX31856_REG::LTHFTL); }
bool MAX31856Driver::SetLTLFTH(uint8_t value) { return SetRegister(MAX31856_REG::LTLFTH, value); }
uint8_t MAX31856Driver::GetLTLFTH() { return GetRegister(MAX31856_REG::LTLFTH); }
bool MAX31856Driver::SetCJTO(uint8_t value) { return SetRegister(MAX31856_REG::CJTO, value); }
uint8_t MAX31856Driver::GetCJTO() { return GetRegister(MAX31856_REG::CJTO); }
bool MAX31856Driver::SetCJTH(uint8_t value) { return SetRegister(MAX31856_REG::CJTH, value); }
uint8_t MAX31856Driver::GetCJTH() { return GetRegister(MAX31856_REG::CJTH); }
bool MAX31856Driver::SetCJTL(uint8_t value) { return SetRegister(MAX31856_REG::CJTL, value); }
uint8_t MAX31856Driver::GetCJTL() { return GetRegister(MAX31856_REG::CJTL); }
bool MAX31856Driver::SetLTLFTL(uint8_t value) { return SetRegister(MAX31856_REG::LTLFTL, value); }
uint8_t MAX31856Driver::GetLTLFTL() { return GetRegister(MAX31856_REG::LTLFTL); }

void MAX31856Driver::GetMultipleRegisters(MAX31856_REG::REG startreg, int numBytes, uint8_t* out) {
assert(initialized);

if (numBytes > 7) numBytes = 7;
uint8_t tx[8] = {0};
uint8_t rx[8] = {0};

tx[0] = startreg & 0x7F;
for(int i = 1; i <= numBytes; i++) tx[i] = SPI_DUMMY_BYTE;

CSLow();
for(volatile int i = 0; i < 500; i++) { __NOP(); }

HAL_SPI_TransmitReceive(hspi, tx, rx, numBytes + 1, 1000);

for(volatile int i = 0; i < 500; i++) { __NOP(); }
CSHigh();

for(int i = 0; i < numBytes; i++)
out[i] = rx[i+1];
}


float MAX31856Driver::ReadThermocoupleTempC() {
uint8_t buf[3];



GetMultipleRegisters(MAX31856_REG::LTCBH, 3, buf);

// Convert 24-bit
int32_t raw = ((uint32_t)buf[0] << 16) | ((uint32_t)buf[1] << 8) | buf[2];

// Sign extend
if(raw & 0x800000)
raw |= 0xFF000000;

return raw / 4096.0f;
}

uint8_t MAX31856Driver::GetFaultStatus() {
return GetRegister(MAX31856_REG::SR);
}
58 changes: 58 additions & 0 deletions MAX31856/MAX31856MUD+Driver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef MAX31856_DRIVER_HPP_
#define MAX31856_DRIVER_HPP_

#include "stm32h7xx_hal.h"
#include "MAX31856_regs.hpp"
#include <stdint.h>

class MAX31856Driver {
public:
MAX31856Driver();
~MAX31856Driver();

void Init(SPI_HandleTypeDef *hspi, GPIO_TypeDef *gpio, uint16_t pin);

bool SetRegister(MAX31856_REG::REG reg, uint8_t val);
uint8_t GetRegister(MAX31856_REG::REG reg);
void GetMultipleRegisters(MAX31856_REG::REG startreg, int numBytes, uint8_t *out);

float ReadThermocoupleTempC();
uint8_t GetFaultStatus();

bool SetMASK(uint8_t value);
uint8_t GetMASK();
bool SetCJHF(uint8_t value);
uint8_t GetCJHF();
bool SetCR0(uint8_t value);
uint8_t GetCR0();
bool SetCR1(uint8_t value);
uint8_t GetCR1();
bool SetCJLF(uint8_t value);
uint8_t GetCJLF();
bool SetLTHFTH(uint8_t value);
uint8_t GetLTHFTH();
bool SetLTHFTL(uint8_t value);
uint8_t GetLTHFTL();
bool SetLTLFTH(uint8_t value);
uint8_t GetLTLFTH();
bool SetCJTO(uint8_t value);
uint8_t GetCJTO();
bool SetCJTH(uint8_t value);
uint8_t GetCJTH();
bool SetCJTL(uint8_t value);
uint8_t GetCJTL();
bool SetLTLFTL(uint8_t value);
uint8_t GetLTLFTL();

private:
SPI_HandleTypeDef *hspi = nullptr;
GPIO_TypeDef *cs_gpio = nullptr;
uint16_t cs_pin = 0;
bool initialized = false;

void CSLow();
void CSHigh();
void SetCSPin(GPIO_TypeDef *gpio, uint16_t pin);
};

#endif
83 changes: 83 additions & 0 deletions MAX31856/MAX31856_regs.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
******************************************************************************
* @file MAX31856_regs.hpp
* @brief Register map and bit definitions for MAX31856.
******************************************************************************
*/

#ifndef MAX31856_REGS_HPP_
#define MAX31856_REGS_HPP_

#include <stdint.h>

namespace MAX31856_REG {

// Register addresses.
enum REG : uint8_t {
CR0 = 0x00,
CR1 = 0x01,
MASK = 0x02,
CJHF = 0x03,
CJLF = 0x04,
LTHFTH = 0x05,
LTHFTL = 0x06,
LTLFTH = 0x07,
LTLFTL = 0x08,
CJTO = 0x09,
CJTH = 0x0A,
CJTL = 0x0B,
LTCBH = 0x0C,
LTCBM = 0x0D,
LTCBL = 0x0E,
SR = 0x0F
};

// CR0 bit masks.
constexpr uint8_t CR0_CONV_MODE = 0x80; // 1 = automatic, 0 = normally off
constexpr uint8_t CR0_1SHOT = 0x40; // 1 = trigger one-shot conversion
constexpr uint8_t CR0_OCFAULT = 0x30; // Fault mode bits [5:4]
constexpr uint8_t CR0_CJ = 0x08; // 1 = enable cold-junction sensor
constexpr uint8_t CR0_FAULT = 0x04; // 1 = fault detection enable
constexpr uint8_t CR0_FAULTCLR = 0x02; // 1 = clear fault status
constexpr uint8_t CR0_50HZ = 0x01; // 1 = 50Hz, 0 = 60Hz

// CR1 bit masks and field values.
constexpr uint8_t CR1_AVG_MASK = 0x70; // Averaging [6:4]
constexpr uint8_t CR1_TYPE_MASK = 0x0F; // Thermocouple type [3:0]

constexpr uint8_t CR1_AVG_1 = 0x00;
constexpr uint8_t CR1_AVG_2 = 0x10;
constexpr uint8_t CR1_AVG_4 = 0x20;
constexpr uint8_t CR1_AVG_8 = 0x30;
constexpr uint8_t CR1_AVG_16 = 0x40;

constexpr uint8_t CR1_TYPE_B = 0x00;
constexpr uint8_t CR1_TYPE_E = 0x01;
constexpr uint8_t CR1_TYPE_J = 0x02;
constexpr uint8_t CR1_TYPE_K = 0x03;
constexpr uint8_t CR1_TYPE_N = 0x04;
constexpr uint8_t CR1_TYPE_R = 0x05;
constexpr uint8_t CR1_TYPE_S = 0x06;
constexpr uint8_t CR1_TYPE_T = 0x07;

// MASK register bits (1 = mask fault).
constexpr uint8_t MASK_CJHF = 0x01; // Cold-junction high
constexpr uint8_t MASK_CJLF = 0x02; // Cold-junction low
constexpr uint8_t MASK_TCHF = 0x04; // Thermocouple high
constexpr uint8_t MASK_TCLF = 0x08; // Thermocouple low
constexpr uint8_t MASK_OVUV = 0x10; // Over/under voltage
constexpr uint8_t MASK_OPEN = 0x20; // Open-circuit

// SR (fault status) bits.
constexpr uint8_t SR_CJHF = 0x01;
constexpr uint8_t SR_CJLF = 0x02;
constexpr uint8_t SR_TCHF = 0x04;
constexpr uint8_t SR_TCLF = 0x08;
constexpr uint8_t SR_OVUV = 0x10;
constexpr uint8_t SR_OPEN = 0x20;
constexpr uint8_t SR_RANGE = 0x40; // Linearized temperature out of range
constexpr uint8_t SR_CJ_RANGE = 0x80; // Cold-junction temperature out of range

} // namespace MAX31856_REG

#endif // MAX31856_REGS_HPP_