-
Sonia Minolli authoredSonia Minolli authored
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