Skip to content
Snippets Groups Projects
MAX31856.cpp 5.37 KiB
Newer Older
fxk8y's avatar
fxk8y committed
#include "MAX31856.hpp"

// C++ system level
// #include <functional>

// ESP32 specific
#include "esp_log.h"
#include "esp_err.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

// project specific
#include <SpiderLib.hpp>

// qthing stuff
// #include <qthing>

// misc
// #include ""




static const char* TAG = "MAX31856";


namespace MAX31856 {


  SoftSPI::SoftSPI(u8 miso, u8 mosi, u8 sclk, u8 cs) : miso(miso), mosi(mosi), sclk(sclk), cs(cs) {

    // gpio init
    mutex.run ([&]() {

      gpio_config_t cfg;
      u8 init_ios[] = {mosi, sclk, cs};

      cfg.pin_bit_mask = 0;
      for (u8 i = 0; i < 3; i++)
        cfg.pin_bit_mask |= 1ULL << init_ios[i];

      cfg.mode         = GPIO_MODE_OUTPUT;
      cfg.intr_type    = GPIO_INTR_DISABLE;
      cfg.pull_up_en   = GPIO_PULLUP_DISABLE;
      cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;

      gpio_config(&cfg);

      setCS(1);
      setMOSI(0);
      setSCLK(0);

    });
  }


  void SoftSPI::writeU8(u8 addr, u8 value) {
    mutex.run ([&]() {

      addr     = (addr & 0x0F) | 0x80;
      u16 data = (addr << 8) | value;

      setCS(0);

      for (i8 n = 15; n >= 0; n--) {
        setSCLK(1);
        setMOSI((data >> n) & 1);
        setSCLK(0);
      }

      //setSCLK(0);
      setMOSI(0);
      setCS(1);
    });
  }


  u8 SoftSPI::readU8(u8 addr) {
    return mutex.runReturn<u8> ([&]() {

      addr &= 0x0F;  // mask out write adresses
      u8 value = 0x00;

      setCS(0);

      for (i8 n = 7; n >= 0; n--) {
        setSCLK(1);
        setMOSI((addr >> n) & 1);
        setSCLK(0);
      }

      setMOSI(0);

      for (i8 n = 7; n >= 0; n--) {
        setSCLK(1);
        value |= getMISO() << n;
        setSCLK(0);
      }

      //setSCLK(0);
      setCS(1);

      return value;
    });
  }

  void SoftSPI::setMOSI(bool value) {
    gpio_set_level((gpio_num_t)mosi, value);
  }

  void SoftSPI::setSCLK(bool value) {
    gpio_set_level((gpio_num_t)sclk, value);
  }

  void SoftSPI::setCS(bool value) {
    gpio_set_level((gpio_num_t)cs, value);
  }

  bool SoftSPI::getMISO() {
    return gpio_get_level((gpio_num_t)miso);
  }



  MAX31856::MAX31856(u8 miso, u8 mosi, u8 sclk, u8 cs) : miso(miso), mosi(mosi), sclk(sclk), cs(cs) {

    spi = new SoftSPI(miso, mosi, sclk, cs);

    setPwrLnRjFrq(F50Hz);

    //return;

    for (u8 addr = 0; addr < (0x0F+1); addr++) {

      u8 data = spi->readU8(addr);

      ESP_LOGI(TAG, "Addr[ 0x%02X ] ~~> Data[ 0x%02X ]", addr, data);
    }

    setPwrLnRjFrq(F60Hz);
    ESP_LOGI(TAG, "----");


    for (u8 addr = 0; addr < (0x0F+1); addr++) {

      u8 data = spi->readU8(addr);

      ESP_LOGI(TAG, "Addr[ 0x%02X ] ~~> Data[ 0x%02X ]", addr, data);
    }

  }




  void MAX31856::setThermocoupleType(ThermocoupleType tc) {
    return mutex.run ([&]() {

      CR1 reg;
      reg.value = spi->readU8(CR1::addr);

fxk8y's avatar
fxk8y committed
      reg.TCTYPE = tc;
fxk8y's avatar
fxk8y committed

      spi->writeU8(CR1::addr, reg.value);
    });
  }

  ThermocoupleType MAX31856::getThermocoupleType() {
    return mutex.runReturn<ThermocoupleType> ([&]() {

      CR1 reg;
      reg.value = spi->readU8(CR1::addr);

fxk8y's avatar
fxk8y committed
      return (ThermocoupleType)reg.TCTYPE;
fxk8y's avatar
fxk8y committed
    });
  }

fxk8y's avatar
fxk8y committed
  bool MAX31856::isTCOpenCircuit() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.OPEN;
    });
  }

  bool MAX31856::isTCOVUV() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.OVUV;
    });
  }

  bool MAX31856::isTCLOW() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.TCLOW;
    });
  }

  bool MAX31856::isTCHIGH() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.TCHIGH;
    });
  }

  bool MAX31856::isCJLOW() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.CJLOW;
    });
  }

  bool MAX31856::isCJHIGH() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.CJHIGH;
    });
  }

  bool MAX31856::isCJRANGE() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.CJRANGE;
    });
  }

  bool MAX31856::isTCRANGE() {
    return mutex.runReturn<bool> ([&]() {

      SR reg;
      reg.value = spi->readU8(SR::addr);

      return reg.TCRANGE;
    });
  }

fxk8y's avatar
fxk8y committed







  void MAX31856::setPwrLnRjFrq(PowerlineFrequencyRejection pfr) {
    return mutex.run ([&]() {

      CR0 reg;
      reg.value = spi->readU8(CR0::addr);

      reg.PWRLNRJ = pfr;


      //if (pfr == F60Hz) reg.PWRLNRJ = 0;
      //else              reg.PWRLNRJ = 1;

      spi->writeU8(CR0::addr, reg.value);
    });
  }

  PowerlineFrequencyRejection MAX31856::getPwrLnRjFrq() {
    return mutex.runReturn<PowerlineFrequencyRejection> ([&]() {

      CR0 reg;
      reg.value = spi->readU8(CR0::addr);

      // TODO: Can this be done by casting?
      //if (reg.PWRLNRJ == 0) return F60Hz;
      //else                  return F50Hz;
      return (PowerlineFrequencyRejection)reg.PWRLNRJ;
    });
  }






















  void MAX31856::mainLoop() {
    while (true) {





      ESP_LOGI(TAG, "LoL");

      vTaskDelay(100 / portTICK_PERIOD_MS);
    }
  }


  // bool MAX31856::getIRQState() {
  //   return gpio_get_level((gpio_num_t)ioIRQ);
  // }

}