From 4667e991d4134424ff5612a11d8cd545c01755db Mon Sep 17 00:00:00 2001 From: rusefillc <48498823+rusefillc@users.noreply.github.com> Date: Mon, 29 May 2023 18:16:28 -0400 Subject: [PATCH] max3185x: support also max31856 (#253) (cherry picked from commit 703985dc709afad2df0ff69d929751894da51b34) Co-authored-by: Andrey Gusakov --- firmware/Makefile | 2 +- firmware/auxout.cpp | 2 +- firmware/livedata.cpp | 2 +- firmware/main.cpp | 2 +- firmware/max31855.cpp | 163 ----------------- firmware/max3185x.cpp | 266 ++++++++++++++++++++++++++++ firmware/{max31855.h => max3185x.h} | 45 +++-- firmware/uart.cpp | 2 +- 8 files changed, 299 insertions(+), 185 deletions(-) delete mode 100644 firmware/max31855.cpp create mode 100644 firmware/max3185x.cpp rename firmware/{max31855.h => max3185x.h} (50%) diff --git a/firmware/Makefile b/firmware/Makefile index 3feb258..65d5a42 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -151,7 +151,7 @@ CPPSRC = $(ALLCPPSRC) \ heater_control.cpp \ pid.cpp \ pump_control.cpp \ - max31855.cpp \ + max3185x.cpp \ uart.cpp \ auxout.cpp \ livedata.cpp \ diff --git a/firmware/auxout.cpp b/firmware/auxout.cpp index b6e29d8..527f145 100644 --- a/firmware/auxout.cpp +++ b/firmware/auxout.cpp @@ -6,7 +6,7 @@ #include "wideband_config.h" -#include "max31855.h" +#include "max3185x.h" #include "hal.h" diff --git a/firmware/livedata.cpp b/firmware/livedata.cpp index d00f919..ac05023 100644 --- a/firmware/livedata.cpp +++ b/firmware/livedata.cpp @@ -5,7 +5,7 @@ #include "sampling.h" #include "pump_dac.h" #include "heater_control.h" -#include "max31855.h" +#include "max3185x.h" #include "fault.h" #include diff --git a/firmware/main.cpp b/firmware/main.cpp index dbd7a4d..59b21aa 100644 --- a/firmware/main.cpp +++ b/firmware/main.cpp @@ -10,7 +10,7 @@ #include "uart.h" #include "io_pins.h" #include "auxout.h" -#include "max31855.h" +#include "max3185x.h" #include "port.h" #include "tunerstudio.h" #include "indication.h" diff --git a/firmware/max31855.cpp b/firmware/max31855.cpp deleted file mode 100644 index 4c9c72c..0000000 --- a/firmware/max31855.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include - -#include "io_pins.h" -#include "wideband_config.h" -#include "bit.h" -#include "livedata.h" - -#include "max31855.h" - -#if (EGT_CHANNELS > 0) - -static SPIConfig spi_config[2] = -{ - { - .circular = false, - .end_cb = NULL, - .ssport = EGT_CS0_PORT, - .sspad = EGT_CS0_PIN, - .cr1 = - /* SPI_CR1_LSBFIRST | */ - ((3 << SPI_CR1_BR_Pos) & SPI_CR1_BR) | /* div = 16 */ - /* SPI_CR1_CPOL | */ // = 0 - SPI_CR1_CPHA | // = 1 - 0, - .cr2 = 0 - }, - { - .circular = false, - .end_cb = NULL, - .ssport = EGT_CS1_PORT, - .sspad = EGT_CS1_PIN, - .cr1 = - /* SPI_CR1_LSBFIRST | */ - ((3 << SPI_CR1_BR_Pos) & SPI_CR1_BR) | /* div = 16 */ - /* SPI_CR1_CPOL | */ // = 0 - SPI_CR1_CPHA | // = 1 - 0, - .cr2 = 0 - } -}; - -static Max31855 instances[] = {&spi_config[0], &spi_config[1]}; - -static Max31855Thread EgtThread(instances); - -int Max31855::spi_rx(uint32_t *data) -{ - uint8_t rx[4]; - - /* Acquire ownership of the bus. */ - spiAcquireBus(EGT_SPI_DRIVER); - /* Setup transfer parameters. */ - spiStart(EGT_SPI_DRIVER, spi); - /* Slave Select assertion. */ - spiSelect(EGT_SPI_DRIVER); - //spiExchange(spi, 4, tx, rx); - spiReceive(EGT_SPI_DRIVER, 4, rx); - /* Slave Select de-assertion. */ - spiUnselect(EGT_SPI_DRIVER); - /* Ownership release. */ - spiReleaseBus(EGT_SPI_DRIVER); - - if (data) { - *data = (rx[0] << 24) | - (rx[1] << 16) | - (rx[2] << 8) | - (rx[3] << 0); - } - - /* no errors for now */ - return 0; -} - -int Max31855::readPacket() -{ - uint32_t data; - - int ret = spi_rx(&data); - - /* TODO: also check for 0x00000000? */ - if ((ret) || (data == 0xffffffff)) { - livedata.state = MAX31855_NO_REPLY; - - ret = -1; - } else if (data & BIT(16)) { - if (data & BIT(0)) { - livedata.state = MAX31855_OPEN_CIRCUIT; - } else if (data & BIT(1)) { - livedata.state = MAX31855_SHORT_TO_GND; - } else if (data & BIT(2)) { - livedata.state = MAX31855_SHORT_TO_VCC; - } - - ret = -1; - } else { - livedata.state = MAX31855_OK; - - /* D[15:4] */ - int16_t tmp = (data >> 4) & 0xfff; - /* extend sign */ - tmp = tmp << 4; - tmp = tmp >> 4; /* shifting right signed is not a good idea */ - coldJunctionTemperature = (float)tmp * 0.0625; - - /* D[31:18] */ - tmp = (data >> 18) & 0x3fff; - /* extend sign */ - tmp = tmp << 2; - tmp = tmp >> 2; /* shifting right signed is not a good idea */ - temperature = (float) tmp * 0.25; - } - - if (ret) { - coldJunctionTemperature = NAN; - livedata.coldJunctionTemperature = 0; - temperature = NAN; - livedata.temperature = 0; - } else { - /* update livedata: float to int */ - livedata.coldJunctionTemperature = coldJunctionTemperature; - livedata.temperature = temperature; - } - - return ret; -} - -void Max31855Thread::ThreadTask() { - - while (true) { - for (int ch = 0; ch < EGT_CHANNELS; ch++) { - Max31855 ¤t = max31855[ch]; - current.readPacket(); - } - - chThdSleepMilliseconds(500); - } -} - -void StartEgt() { - EgtThread.Start(); -} - -Max31855* getEgtDrivers() { - return instances; -} - -template<> -const livedata_egt_s* getLiveData(size_t ch) -{ - if (ch < EGT_CHANNELS) - return &getEgtDrivers()[ch].livedata; - return NULL; -} - -#else - -template<> -const livedata_egt_s* getLiveData(size_t) -{ - return nullptr; -} - -#endif /* EGT_CHANNELS > 0 */ diff --git a/firmware/max3185x.cpp b/firmware/max3185x.cpp new file mode 100644 index 0000000..cf8cc7d --- /dev/null +++ b/firmware/max3185x.cpp @@ -0,0 +1,266 @@ +#include + +#include "io_pins.h" +#include "wideband_config.h" +#include "bit.h" +#include "livedata.h" + +#include "max3185x.h" + +#if (EGT_CHANNELS > 0) + +static SPIConfig spi_config[2] = +{ + { + .circular = false, + .end_cb = NULL, + .ssport = EGT_CS0_PORT, + .sspad = EGT_CS0_PIN, + .cr1 = + /* SPI_CR1_LSBFIRST | */ + ((3 << SPI_CR1_BR_Pos) & SPI_CR1_BR) | /* div = 16 */ + /* SPI_CR1_CPOL | */ // = 0 + SPI_CR1_CPHA | // = 1 + 0, + .cr2 = 0 + }, + { + .circular = false, + .end_cb = NULL, + .ssport = EGT_CS1_PORT, + .sspad = EGT_CS1_PIN, + .cr1 = + /* SPI_CR1_LSBFIRST | */ + ((3 << SPI_CR1_BR_Pos) & SPI_CR1_BR) | /* div = 16 */ + /* SPI_CR1_CPOL | */ // = 0 + SPI_CR1_CPHA | // = 1 + 0, + .cr2 = 0 + } +}; + +static Max3185x instances[] = {&spi_config[0], &spi_config[1]}; + +static Max3185xThread EgtThread(instances); + +int Max3185x::spi_txrx(uint8_t tx[], uint8_t rx[], size_t n) +{ + /* Acquire ownership of the bus. */ + spiAcquireBus(EGT_SPI_DRIVER); + /* Setup transfer parameters. */ + spiStart(EGT_SPI_DRIVER, spi); + /* Slave Select assertion. */ + spiSelect(EGT_SPI_DRIVER); + spiExchange(EGT_SPI_DRIVER, n, tx, rx); + /* Slave Select de-assertion. */ + spiUnselect(EGT_SPI_DRIVER); + /* Ownership release. */ + spiReleaseBus(EGT_SPI_DRIVER); + + /* no errors for now */ + return 0; +} + +int Max3185x::spi_rx32(uint32_t *data) +{ + int ret; + /* dummy */ + uint8_t tx[4] = {0}; + uint8_t rx[4]; + + ret = spi_txrx(tx, rx, 4); + if (ret) { + return ret; + } + if (data) { + *data = (rx[0] << 24) | + (rx[1] << 16) | + (rx[2] << 8) | + (rx[3] << 0); + } + return 0; +} + +int Max3185x::detect() +{ + uint8_t rx[4]; + /* read MASK, CJHF, CJLF */ + uint8_t tx[4] = {0x02, 0x00, 0x00, 0x00}; + uint32_t data; + + int ret = spi_txrx(tx, rx, 4); + data = (rx[0] << 24) | + (rx[1] << 16) | + (rx[2] << 8) | + (rx[3] << 0); + /* MASK, CJHF, CJLF defaults: 0xff, 0x7f, 0xc0 */ + if ((data & 0x00ffffff) == 0x00ff7fc0) { + /* configure */ + /* CR0: 50 Hz mode + * Change the notch frequency only while in the "Normally Off" mode - not in the Automatic + * Conversion mode.*/ + tx[0] = 0x80; + tx[1] = 0x01; + spi_txrx(tx, rx, 2); + /* CR0: Automatic Conversion mode, OCFAULT = 2, 50Hz mode */ + tx[1] = BIT(7) | BIT(0) | 2 << 4; + /* CR1: 4 samples average, K type */ + tx[2] = (2 << 4) | (3 << 0); + spi_txrx(tx, rx, 3); + type = MAX31856_TYPE; + return 0; + } + if (data != 0xffffffff) { + type = MAX31855_TYPE; + return 0; + } + + livedata.state = MAX3185X_NO_REPLY; + type = UNKNOWN_TYPE; + return -1; +} + +int Max3185x::readPacket31855() +{ + uint32_t data; + + int ret = spi_rx32(&data); + + /* TODO: also check for 0x00000000? */ + if ((ret) || (data == 0xffffffff)) { + livedata.state = MAX3185X_NO_REPLY; + + ret = -1; + } else if (data & BIT(16)) { + if (data & BIT(0)) { + livedata.state = MAX3185X_OPEN_CIRCUIT; + } else if (data & BIT(1)) { + livedata.state = MAX3185X_SHORT_TO_GND; + } else if (data & BIT(2)) { + livedata.state = MAX3185X_SHORT_TO_VCC; + } + + ret = -1; + } + + if (ret) { + coldJunctionTemperature = NAN; + livedata.coldJunctionTemperature = 0; + temperature = NAN; + livedata.temperature = 0; + } else { + /* D[15:4] */ + int16_t tmp = (data >> 4) & 0xfff; + /* extend sign */ + tmp = tmp << 4; + tmp = tmp >> 4; /* shifting right signed is not a good idea */ + coldJunctionTemperature = (float)tmp * 0.0625; + + /* D[31:18] */ + tmp = (data >> 18) & 0x3fff; + /* extend sign */ + tmp = tmp << 2; + tmp = tmp >> 2; /* shifting right signed is not a good idea */ + temperature = (float) tmp * 0.25; + + /* update livedata: float to int */ + livedata.coldJunctionTemperature = coldJunctionTemperature; + livedata.temperature = temperature; + + livedata.state = MAX3185X_OK; + } + + return ret; +} + +int Max3185x::readPacket31856() +{ + uint8_t rx[7]; + /* read Cold-Junction temperature MSB, LSB, Linearized TC temperature 3 bytes and Fault Status */ + uint8_t tx[7] = {0x0a}; + + int ret = spi_txrx(tx, rx, 7); + + if (rx[6] & BIT(0)) { + livedata.state = MAX3185X_OPEN_CIRCUIT; + ret = -1; + } else if (rx[6] & BIT(1)) { + livedata.state = MAX3185X_SHORT_TO_VCC; + ret = -1; + } + + if (ret) { + coldJunctionTemperature = NAN; + livedata.coldJunctionTemperature = 0; + temperature = NAN; + livedata.temperature = 0; + } else { + /* update livedata: float to int */ + coldJunctionTemperature = (float)(rx[1] << 8 | rx[2]) / 256.0; + temperature = (float)((rx[3] << 11) | (rx[4] << 3) | (rx[5] >> 5)) / 128.0; + livedata.coldJunctionTemperature = coldJunctionTemperature; + livedata.temperature = temperature; + + livedata.state = MAX3185X_OK; + } + + return ret; +} + +int Max3185x::readPacket() +{ + int ret; + + if (type == UNKNOWN_TYPE) { + ret = detect(); + if (ret < 0) { + return ret; + } + } + + if (type == MAX31855_TYPE) { + return readPacket31855(); + } else if (type == MAX31856_TYPE) { + return readPacket31856(); + } + + return -1; +} + +void Max3185xThread::ThreadTask() { + + while (true) { + for (int ch = 0; ch < EGT_CHANNELS; ch++) { + Max3185x ¤t = max3185x[ch]; + current.readPacket(); + } + + chThdSleepMilliseconds(500); + } +} + +void StartEgt() { + EgtThread.Start(); +} + +Max3185x* getEgtDrivers() { + return instances; +} + +template<> +const livedata_egt_s* getLiveData(size_t ch) +{ + if (ch < EGT_CHANNELS) + return &getEgtDrivers()[ch].livedata; + return NULL; +} + +#else + +template<> +const livedata_egt_s* getLiveData(size_t) +{ + return nullptr; +} + +#endif /* EGT_CHANNELS > 0 */ diff --git a/firmware/max31855.h b/firmware/max3185x.h similarity index 50% rename from firmware/max31855.h rename to firmware/max3185x.h index d6ff353..433eba5 100644 --- a/firmware/max31855.h +++ b/firmware/max3185x.h @@ -6,12 +6,18 @@ #include "thread_controller.h" typedef enum { - MAX31855_OK = 0, - MAX31855_OPEN_CIRCUIT = 1, - MAX31855_SHORT_TO_GND = 2, - MAX31855_SHORT_TO_VCC = 3, - MAX31855_NO_REPLY = 4, -} Max31855State; + UNKNOWN_TYPE = 0, + MAX31855_TYPE = 1, + MAX31856_TYPE = 2, +} Max3185xType; + +typedef enum { + MAX3185X_OK = 0, + MAX3185X_OPEN_CIRCUIT = 1, + MAX3185X_SHORT_TO_GND = 2, + MAX3185X_SHORT_TO_VCC = 3, + MAX3185X_NO_REPLY = 4, +} Max3185xState; /* livedata: +96/112 offset, size = 16 */ struct livedata_egt_s { @@ -30,38 +36,43 @@ const struct livedata_egt_s * getEgtLiveDataStructAddr(const int ch); #if (EGT_CHANNELS > 0) -#define MAX31855_THREAD_STACK (512) -#define MAX31855_THREAD_PRIO (NORMALPRIO + 1) +#define MAX3185X_THREAD_STACK (512) +#define MAX3185X_THREAD_PRIO (NORMALPRIO + 1) -class Max31855 { +class Max3185x { public: - Max31855(SPIConfig *spi) { + Max3185x(SPIConfig *spi) { this->spi = spi; } livedata_egt_s livedata; /* do we need float temperatures? */ float coldJunctionTemperature; float temperature; + Max3185xType type; int readPacket(); private: SPIConfig *spi; - int spi_rx(uint32_t *data); + int detect(); + int readPacket31855(); + int readPacket31856(); + int spi_rx32(uint32_t *data); + int spi_txrx(uint8_t tx[], uint8_t rx[], size_t n); }; -class Max31855Thread : public ThreadController { +class Max3185xThread : public ThreadController { public: - Max31855Thread(Max31855 max31855[EGT_CHANNELS]) - : ThreadController("egt", MAX31855_THREAD_PRIO) + Max3185xThread(Max3185x max3185x[EGT_CHANNELS]) + : ThreadController("egt", MAX3185X_THREAD_PRIO) { - this->max31855 = max31855; + this->max3185x = max3185x; } void ThreadTask() override; private: - Max31855 *max31855; + Max3185x *max3185x; }; void StartEgt(); -Max31855* getEgtDrivers(); +Max3185x* getEgtDrivers(); #endif // (EGT_CHANNELS > 0) diff --git a/firmware/uart.cpp b/firmware/uart.cpp index e2d9744..c453acc 100644 --- a/firmware/uart.cpp +++ b/firmware/uart.cpp @@ -5,7 +5,7 @@ #include "lambda_conversion.h" #include "sampling.h" #include "heater_control.h" -#include "max31855.h" +#include "max3185x.h" #include "fault.h" #include "uart.h"