#ifndef _MAX31855_H_
#define _MAX31855_H_
//----------------------------------------------------------------------------
///
/// \brief  MAX31855
///
///         See implementation files for further information.
///         https://cdn-reichelt.de/documents/datenblatt/A300/MAX31855.pdf
/// 
///         Max 5Mhz serial clock
///
/// \date   20200313
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


//---Own------------------------------

#include <biwak/spi_slave.h>
#include <lepto/log.h>


//---Declaration--------------------------------------------------------------

//#define GPIO_CS_REF

class CMax31855
      :public CSpiSlave
{
private:
   
   int m_temperature;
   int m_refTemperature;
   int m_status;
   
   #if defined BIWAK_MAX3185_CALIBRATION
   int m_calibration;
   #endif

public:
    
   static constexpr int INVALID_TEMP= -237 * 100;
    
   #if defined(GPIO_CS_REF)
   CMax31855(CSpi &spi, COutput &outputCs)
   #else
   CMax31855(CSpi &spi, EGpioPeripheral eGpioPeripheralCS, EGpioPin eGpioPinCS)
   #endif
   #if defined(GPIO_CS_REF)
      :CSpiSlave(spi, outputCs)
   #else
      :CSpiSlave(spi, eGpioPeripheralCS, eGpioPinCS)
   #endif
      ,m_status(2)
   #if defined BIWAK_MAX3185_CALIBRATION
      ,m_calibration(0)
   #endif
   {
      // According to datasheet the clock maximum is 5Mhz
      lDebugAssert( spi.isSlowerOrEqual( eSpiMode3Mhz ) );
   }
   ~CMax31855()
   {

   }

   int32_t acquireTemperature()
   {
      int rawValue, mTemp;
      bool fault;
      
      getSpi().setDataSize(8);
      
      chipSelect();
      rawValue=getSpi().readData( 4 );
      // Biwak takes care about endianess; rawValue=__REV(rawValue);
      chipDeselect();
      
      //lInfo("RAW: 0x%x", rawValue);
      fault=(rawValue >> 16) & 1;
      mTemp=(rawValue >> 18);
      // LSB=2^-2; 0.25°C
      mTemp=( ( mTemp * 100 ) / ( 1 << 2 ) );
      m_temperature=mTemp;

      //Reference Junction Temperature
      mTemp=(rawValue >> 4) & 0xFFF;
      // LSB=2^-4; 0.0625°C
      mTemp=( ( mTemp * 100 ) / ( 1 << 4 ) );
      m_refTemperature=mTemp;

      m_status=fault ? 1 : 0;
      
      #if defined BIWAK_MAX3185_CALIBRATION
      m_temperature+=m_calibration;
      #endif

      if( m_status )
         m_temperature = CMax31855::INVALID_TEMP;

      return(m_temperature);
   }
   int32_t getTemperature()
   {
      acquireTemperature();
      
      return( m_temperature );
   }

   int32_t getReferenceTemperature()
   {
      return( m_refTemperature );
   }
   
   #if defined BIWAK_MAX3185_CALIBRATION
   void setCalibration(int calibration)
   {
       m_calibration=calibration;
   }
   #endif

   int getStatus()
   {
      return(m_status);
   }
};


//---fin----------------------------------------------------------------------
#endif // ? ! _MAX31855_H_
