Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
TIMIQLib.cpp 19.46 KiB
//=============================================================================
// TIMIQLib.cpp
//=============================================================================
// abstraction.......TimIQ Application Programming Interface
// class.............TIMIQLib 
// original author...J. GOUNO - NEXEYA-FRANCE
//=============================================================================

// ============================================================================
// DEPENDENCIES
// ============================================================================

#include <timiq/TIMIQLib.h>
#include "TIMIQCurl.h"


namespace TIMIQLib_ns {

// ============================================================================
//- Check low level access to TIMIQ hardware pointer:
#define CHECK_TIMIQ_HW \
if (!m_timiq_hw) \
{ \
   throw Exception(static_cast<const char*>("INTERNAL_ERROR"), \
		static_cast<const char*>("Low level access to TIMIQ hardware pointer is null!"), \
		static_cast<const char*>("CHECK_TIMIQ_HW()")); \
}
// ============================================================================

// ============================================================================
// TIMIQLib::TIMIQLib
// ============================================================================
TIMIQLib::TIMIQLib ()
{
  m_timiq_hw = NULL;
  m_ipAddress = "";
  m_numPort = "";
  m_internal_timiq_state = Undefined;
  m_timiq_task = NULL;
}

// ============================================================================
// TIMIQLib::~TIMIQLib()
// ============================================================================
TIMIQLib::~TIMIQLib()
{
  if (m_timiq_hw)
  {
    delete m_timiq_hw;
    m_timiq_hw = NULL;
  }
		
  //- 	
  if (m_timiq_task)
  {
    m_timiq_task->exit();
    m_timiq_task = NULL;
  }
}

// ============================================================================
// TIMIQLib::init
// ============================================================================
void TIMIQLib::init(const std::string& ip_address, const short& num_port)
  throw (Exception)
{
  //- chek Ip Address/ num port
  if (ip_address.empty() || num_port == 0)
    throw Exception(static_cast<const char*>("INTERNAL_ERROR"),
                    static_cast<const char*>("Ip address or port number not properly defined!"), 
                    static_cast<const char*>("TIMIQLib::init")); 
		
  //- 
  m_ipAddress = ip_address;	
  char buffer[20];
  sprintf(buffer, "%d", num_port);
  m_numPort = buffer;
	
  // instantiate TIMIQCurl pointer
  m_timiq_hw = new TIMIQCurl(m_ipAddress, m_numPort);
	
  CHECK_TIMIQ_HW;		
}

// ============================================================================
// TIMIQLib::set_data
// ============================================================================		
void TIMIQLib::set_data(float data) 
  throw (Exception)
{	
  //- Threading configuration
  timIQConfig l_ti_cfg;
	
  //- set I value config 
  l_ti_cfg.id = TI_DATA;
  l_ti_cfg.value = data;
	
  this->ExecuteAction(l_ti_cfg);

/* Use direct call instead of thread (board cycle is about 30ms)
  if (m_internal_timiq_state != Busy)
  {
    //- force timiq state = Busy
    m_internal_timiq_state = Busy;
		
    m_timiq_task = new ThreadedAction(static_cast<yat::Thread::IOArg>(this), l_ti_cfg);
    if (m_timiq_task == NULL)
    {
      std::string msg_err = "Set data error -msg: " + m_timiq_hw->get_err_msg();
      throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                      static_cast<const char*>(msg_err.c_str()),
                      static_cast<const char*>("TIMIQLib::set_data"));
    }

    //- start the task to write data on TIMIQ equipment
    m_timiq_task->start_undetached();
  }
*/
}

// ============================================================================
// TIMIQLib::set_iValue
// ============================================================================		
void TIMIQLib::set_iValue(float iValue)
  throw (Exception)
{
  //std::cout << "TIMIQLib::set_iValue() entering... - iValue to set = " << iValue << std::endl;

  //- Threading configuration
  timIQConfig l_ti_cfg;
	
  //- set I value config 
  l_ti_cfg.id = TI_IVAL;
  l_ti_cfg.value = iValue;
  
  this->ExecuteAction(l_ti_cfg);

/* Use direct call instead of thread (board cycle is about 30ms)
  if (m_internal_timiq_state != Busy)
  {
    //- force timiq state = Busy
    m_internal_timiq_state = Busy;

    m_timiq_task = new ThreadedAction(static_cast<yat::Thread::IOArg>(this), l_ti_cfg);
    if (m_timiq_task == NULL)
    {
      std::string msg_err = " Can't instanciate set I value task";
      throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                      static_cast<const char*>(msg_err.c_str()),
                      static_cast<const char*>("TIMIQLib::set_iValue"));
    }

    //- start the task
    m_timiq_task->start_undetached();
  }
*/

}

// ============================================================================
// TIMIQLib::end_task
// ============================================================================		
void TIMIQLib::end_task()
  throw (Exception)
{
  //- Delete task 
  if (this->m_timiq_task)
  {	
    if (m_timiq_task->m_ti_cfg.ti_err != timiq_NO_ERROR)
    {	
      m_timiq_task->exit();
      m_timiq_task = NULL;
			
      std::string msg_err = "Threaded task error -msg: " + m_timiq_hw->get_err_msg();
      throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                      static_cast<const char*>(msg_err.c_str()),
                      static_cast<const char*>("TIMIQLib::end_task"));
    }

    //- destroy otherwise 
    yat::Thread::IOArg ioa;
    m_timiq_task->exit();
    m_timiq_task->join(&ioa);
    m_timiq_task = NULL;
  }	
}

// ============================================================================
// TIMIQLib::set_qValue
// ============================================================================		
void TIMIQLib::set_qValue(float qValue)
  throw (Exception)
{
  //std::cout << "TIMIQLib::set_qValue() entering... - qValue to set = " << qValue << std::endl;

  //- Threading configuration
  timIQConfig l_ti_cfg;
	
  //- set Q value config 
  l_ti_cfg.id = TI_QVAL;
  l_ti_cfg.value = qValue;
	
  this->ExecuteAction(l_ti_cfg);

/* Use direct call instead of thread (board cycle is about 30ms)
  if (m_internal_timiq_state != Busy)
  {
    //- force timiq state = Busy
    m_internal_timiq_state = Busy;
		
    m_timiq_task = new ThreadedAction(static_cast<yat::Thread::IOArg>(this), l_ti_cfg);
    if (m_timiq_task == NULL)
    {
      std::string msg_err = "Set Q value error -msg: " + m_timiq_hw->get_err_msg();
      throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                      static_cast<const char*>(msg_err.c_str()),
                      static_cast<const char*>("TIMIQLib::set_qValue"));
    }

    //- start the task to write "Q" tension value on TIMIQ equipment
    m_timiq_task->start_undetached();
  }
*/
}	

// ============================================================================
// TIMIQLib::set_boardTemperature
// ============================================================================		
void TIMIQLib::set_boardTemperature(float boardTemperature) 
	throw (Exception)
{
  //- Threading configuration
  timIQConfig l_ti_cfg;
	
  //- set board temperature value config 
  l_ti_cfg.id = TI_BTEMP;
  l_ti_cfg.value = boardTemperature;
	
  this->ExecuteAction(l_ti_cfg);

/* Use direct call instead of thread (board cycle is about 30ms)
  if (m_internal_timiq_state != Busy)
  {
    //- force timiq state = Busy
    m_internal_timiq_state = Busy;
		
    m_timiq_task = new ThreadedAction(static_cast<yat::Thread::IOArg>(this), l_ti_cfg);
    if (m_timiq_task == NULL)
    {
      std::string msg_err = "Set board Temperature error -msg: " + m_timiq_hw->get_err_msg();
      throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                      static_cast<const char*>(msg_err.c_str()),
                      static_cast<const char*>("TIMIQLib::set_boardTemperature"));
    }

    //- start the task to set board temperature on TIMIQ equipment
    m_timiq_task->start_undetached();
  }
*/		
}

// ============================================================================
// TIMIQLib::set_command
// ============================================================================		
void TIMIQLib::set_command(E_timiq_cmd_t& cmd) 
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- write command on TIMIQ equipment

/* Use direct call instead of thread (board cycle is about 30ms)
  // thread PLL calibration command:
  if (cmd == RECALIBRATE_PLL)
  {
    if (m_internal_timiq_state != Busy)
    {
      timIQConfig l_ti_cfg;
      l_ti_cfg.id = TI_CALIB;
		
      //- force timiq state = Busy
      m_internal_timiq_state = Busy;
		
      m_timiq_task = new ThreadedAction(static_cast<yat::Thread::IOArg>(this), l_ti_cfg);
      if (m_timiq_task == NULL)
      {
        std::string msg_err = "Set Q value error -msg: " + m_timiq_hw->get_err_msg();
        throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                        static_cast<const char*>(msg_err.c_str()),
                        static_cast<const char*>("TIMIQLib::set_command"));
      }

      //- start the task to do the pll calibration
      m_timiq_task->start_undetached();
    }
  }
  else
*/
  {
    err = m_timiq_hw->write_command(cmd, false); // use standard curl reference
    if (err != timiq_NO_ERROR)
    {
      std::string msg_err = "Set command error -msg: " + m_timiq_hw->get_err_msg();
      throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                      static_cast<const char*>(msg_err.c_str()),
                      static_cast<const char*>("TIMIQLib::set_command()"));
    }
	
    //- update state of TIMIQ equipment
    m_internal_timiq_state = OK;
  }
}		

// ============================================================================
// TIMIQLib::get_data
// ============================================================================		
void TIMIQLib::get_data(float &data)
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read data from TIMIQ equipment
  err = m_timiq_hw->read_data(data);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get data error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_data()"));
  }
}

// ============================================================================
// TIMIQLib::get_iValue
// ============================================================================		
void TIMIQLib::get_iValue(float& iValue)
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read "I" tension value from TIMIQ equipment
  err = m_timiq_hw->read_iValue(iValue);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get I value error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_iValue()"));
  }
}

// ============================================================================
// TIMIQLib::get_qValue
// ============================================================================		
void TIMIQLib::get_qValue(float& qValue)
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read "Q" tension value from TIMIQ equipment
  err = m_timiq_hw->read_qValue(qValue);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get Q value error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_qValue()"));
  }
}

// ============================================================================
// TIMIQLib::get_mixerCosOutput
// ============================================================================		
void TIMIQLib::get_mixerCosOutput(float& mixerCosOutput)
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read mixer cos output value from TIMIQ equipment
  err = m_timiq_hw->read_mixerCosOutput(mixerCosOutput);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get mixer cosinus output value error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_mixerCosOutput()"));
  }
}

// ============================================================================
// TIMIQLib::get_mixerSinOutput
// ============================================================================		
void TIMIQLib::get_mixerSinOutput(float& mixerSinOutput)
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read mixer sin output value from TIMIQ equipment
  err = m_timiq_hw->read_mixerSinOutput(mixerSinOutput);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get mixer sinus output value error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_mixerSinOutput()"));
  }	
}
	
// ============================================================================
// TIMIQLib::get_boardTemperature
// ============================================================================		
void TIMIQLib::get_boardTemperature(float& boardTemperature)
  throw (Exception)
{
  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read board temperature value from TIMIQ equipment
  err = m_timiq_hw->read_boardTemperature(boardTemperature);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get board temperature value error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_boardTemperature()"));
  }
}

// ============================================================================
// TIMIQLib::get_state
// ============================================================================		
E_timiq_code_t TIMIQLib::get_state(std::string& status)
  throw (Exception)
{
  E_timiq_errno_t err;
  E_timiq_code_t retCode;
	
  CHECK_TIMIQ_HW;
	
  //- get internal timiq state
  //- read status of TIMIQ equipment
  err = m_timiq_hw->read_state_and_status(status, m_internal_timiq_state);

//std::cout << "m_internal_timiq_state in read state and status = " << m_internal_timiq_state << std::endl;

  if (err != timiq_NO_ERROR)
  {
    m_internal_timiq_state = Undefined;
    std::string msg_err = "Get status error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_status()"));
  }
	
  return m_internal_timiq_state;
}

// ============================================================================
// TIMIQLib::ExecuteAction
// ============================================================================
void TIMIQLib::ExecuteAction(timIQConfig & cfg)
  throw (Exception)
{
  E_timiq_errno_t err;
  E_timiq_cmd_t cmd;
	
  CHECK_TIMIQ_HW;
	
  // Actions to be threaded
  switch(cfg.id)
  {
    //- write "I" value
    case TI_IVAL:	
      cfg.ti_err = m_timiq_hw->write_iValue(cfg.value);
      this->end_task();
    break;
			
    //- write "Q" value
    case TI_QVAL:
      cfg.ti_err = m_timiq_hw->write_qValue(cfg.value);
      this->end_task();
    break;		
			
    //- write "DATA" value
    case TI_DATA:
      cfg.ti_err = m_timiq_hw->write_data(cfg.value);	
      this->end_task();
    break;

    //- write "BOARD Temperature" value
    case TI_BTEMP:
      cfg.ti_err = m_timiq_hw->write_data(cfg.value);	
      this->end_task();
    break;

    //- PLL calibration
    case TI_CALIB:
      cmd = RECALIBRATE_PLL;
      cfg.ti_err = m_timiq_hw->write_command(cmd);
      this->end_task();
    break;
    			
    default:
    break;
  }
}

// ============================================================================
// TIMIQLib::get_boardData
// ============================================================================
void TIMIQLib::get_boardData(timIQval_t& val)
  throw (Exception)
{
  val.temperature = yat::IEEE_NAN;
  val.iVal = yat::IEEE_NAN;
  val.qVal = yat::IEEE_NAN;
  val.mixerSin = yat::IEEE_NAN;
  val.mixerCos = yat::IEEE_NAN;

  E_timiq_errno_t  err;
	
  CHECK_TIMIQ_HW;
	
  //- read all values from TIMIQ equipment
  err = m_timiq_hw->read_all(val);
  if (err != timiq_NO_ERROR)
  {
    std::string msg_err = "Get all data error -msg: " + m_timiq_hw->get_err_msg();
    throw Exception(static_cast<const char*>("SOFTWARE_FAILURE"),
                    static_cast<const char*>(msg_err.c_str()),
                    static_cast<const char*>("TIMIQLib::get_boardData()"));
  }
}

//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
// Threaded actions for TimIQ equipment
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
// ============================================================================
// ThreadedAction::ThreadedAction
// ============================================================================
ThreadedAction::ThreadedAction(yat::Thread::IOArg ioa, timIQConfig& cfg)
:yat::Thread(ioa), 
 m_goOn(true),
 m_isActionDone(false),
 m_ti_cfg(cfg)
{
  //- noop ctor
}

// ============================================================================
// ThreadedAction::~ThreadedAction
// ============================================================================
ThreadedAction::~ThreadedAction()
{
  //- noop dtor
}

// ============================================================================
// ThreadedAction::run_undetached
// ============================================================================
yat::Thread::IOArg ThreadedAction::run_undetached (yat::Thread::IOArg ioa)
{
  //DEBUG_STREAM << "ThreadedAction::run_undetached() entering... " << std::endl; 
  m_isActionDone = false;
	
  //- get the reference to parent task
  TIMIQLib * l_task = reinterpret_cast<TIMIQLib *>(ioa);
  l_task->ExecuteAction(m_ti_cfg);
	
  //- Action is done  
  m_isActionDone = true;

  return 0;
}

// ============================================================================
// ThreadedAction::exit
// ============================================================================
void ThreadedAction::exit()
{
  this->m_goOn = false;
}

} // namespace timiqlib