//-----------------------------------------------------------------------------
///
/// \brief  QT GUI for showing TMP117 sensor values
///
///         https://www.ti.com/lit/ds/symlink/tmp117.pdf
///
/// \date   20220502
/// \author Maximilian Seesslen <development@seesslen.net>
///
//-----------------------------------------------------------------------------


//---Include------------------------------------------------------------------


#include <biwak/tmp117.hpp>
#include <arpa/inet.h>
#include <lepto/log.h>

#define SINGLE_SHOT

//---Implementation-----------------------------------------------------------

constexpr uint8_t CTmp117::regTemperature;
constexpr uint8_t CTmp117::regConfig;

#define     AVG_00      0b00
#define     CONV_00     0b00
#define     MODE_OS     0b11
// Single-Shot-Config: 0x0E20; 0x0C00

CTmp117::CTmp117( CI2c &i2cBus, int address /* = 0x48 */ )
   :CI2cSlave( i2cBus, address /*m_slaveAddress*/)
{
   int sta;
   uint16_t id=0;

   m_config=( AVG_00 << 5 ) | ( CONV_00 << 7) | ( MODE_OS << 10 );

   sta=i2cReadData(0xF, &id, sizeof(id));
   id=ntohs(id);
   if( sta || (id!=0x117))
   {
      if(sta)
      {
         lCaution( LDS("DSBL TMP117. s=%d", "Disabling tmp117. sta=%d"), sta);
      }
      else
      {
         lCaution( LDS("DSBL TMP117. id=0x%X", "Disabling tmp117. id=0x%X"), id);
      }
      return;
   }
   
   #if IS_ENABLED( CONFIG_BIWAK_I2C_NODE_ABSENT )
      setPresent(true);
   #endif

   #if defined(SINGLE_SHOT)
      writeConfig( m_config );
   #else
      writeConfig(0x0220);
   #endif

   //lInfo( LDS("Tmp Ofs:%d", "Temperature offset: %d"), readRaw(0x07) );
}

uint16_t CTmp117::readRaw(uint8_t reg)
{
   int sta;
   uint16_t raw;

   sta=i2cReadData(reg, &raw, sizeof(raw));

   if( sta != 0 )
   {
      lCritical( LDS("CNRD Reg: 0x%X", "Could not read register: 0x%X"), sta);
      raw=0;
   }

   raw=ntohs(raw);
   return(raw);
}

// centi-celsius; 1 = 0,01°C
int CTmp117::convertTemperature(int16_t raw)
{
   // one LSB is 7.8125 m°C; deg = raw * 0.0078125
   return( ( (int)raw * 78125 ) / 100000 );
}

float CTmp117::convertTemperature_f(int16_t raw)
{
   // one LSB is 7.8125 m°C; deg = raw * 0.0078125
   return( raw * 0.0078125 );
}

uint16_t CTmp117::getRawTemperature()
{
   uint16_t reg;

   #if defined(SINGLE_SHOT)
      while ( ! ( ( reg=readRaw( regConfig )) & 0x2000 ) )
      {
         lCritical( LDS("CNRD Temp: 0x%X: 0x%X", "Failed to read temperatur: 0x%X: 0x%X"), getSlaveAddress(), reg );
         break;
      }
   #endif

   uint16_t tempRaw=readRaw( regTemperature );

   #if defined(SINGLE_SHOT)
      writeConfig(m_config);
   #endif

   return( tempRaw );
}

int CTmp117::getTemperature()
{
   return(convertTemperature( getRawTemperature() ));
}

float CTmp117::getTemperature_f()
{
   return(convertTemperature_f( getRawTemperature() ));
}

void CTmp117::writeConfig(uint16_t conf)
{
   int sta;
   uint16_t _conf;

   _conf=htons(conf);

   if ( ( sta = i2cWriteData(regConfig, &_conf, sizeof(_conf) ) ) )
   {
      lCritical( LDS("CNWR CNF: %d", "Failed writing config: %d"), sta);
   }

   return;
}


//---fin----------------------------------------------------------------------
