Commit 230e6cbc authored by elaazzouzi's avatar elaazzouzi

Add Caen Easydriver power supply driver

parent 470b69a3
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CAENEASYDRIVERDEF_H
#define CAENEASYDRIVERDEF_H
namespace caen_easydriver {
/*
* Commands
*/
static const char VERSION_COMMAND[] = "MVER";
static const char ON_COMMAND[] = "MON";
static const char OFF_COMMAND[] = "MOFF";
static const char READ_CURRENT_COMMAND[] = "MRI";
static const char READ_VOLTAGE_COMMAND[] = "MRV";
static const char WRITE_CURRENT_COMMAND[] = "MWI";
static const char WRITE_VOLTAGE_COMMAND[] = "MWV";
static const char READ_STATUS_COMMAND[] = "MST";
static const char RESET_STATUS_COMMAND[] = "MRESET";
static const char HASH[] = "#";
static const char SEPARATOR[] = ":";
static const char NAK[] = "NAK";
static const char AK[] = "AK";
/*
* Status
*/
static const int32 NO_STATUS = 0x00;
static const int32 CHANGING = 0x100;
static const int32 IN_TOLERANCE = 0x200;
/*
* CaenEasydriver Error code
*/
static const int32 MODULE_ON = 1; // Module on
static const int32 FAULT = 2; // Fault
static const int32 DC_LINK_UNDERVOLTAGE = 4; // DC link under voltage
static const int32 MOSFET_TEMPERATURE = 8; // Mosfet temperature
static const int32 SHUNT_TEMPERATURE = 16; // Shunt temperature
static const int32 EXTERNAL_INTERLOCK_FLAG = 32; // External interlock flag
}
#endif //CAENEASYDRIVERDEF_H
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "CaenEasydriverDriver.h"
#include "CaenEasydriverDef.h"
#include "RealCaenEasydriverDriver.h"
#include "PerfectCaenEasydriverDriver.h"
#include "SimulatedCaenEasydriverDriver.h"
namespace caen_easydriver {
const std::string CaenEasydriverDriver::TYPE = "CaenEasydriver";
/*
* Constructor
*/
CaenEasydriverDriver::CaenEasydriverDriver(const std::string& name) :
current::CurrentCommon(name) {
driver::SocketTcp::init(name);
registerStates(new RealCaenEasydriverDriver(this), new PerfectCaenEasydriverDriver(this),
new SimulatedCaenEasydriverDriver(this));
// Init functions
registerFunction(NONE_FUNCTION);
deviceType = LEAF_DEVICE_TYPE_DEVICE_CONTAINER;
/*
* Register the Spy and Observer commands necessary to do the updates.
*/
registerSpyCommand(driver::READ_COMMAND, 4);
registerSpyCommand(driver::STATUS_COMMAND, 4);
registerObserverCommand(driver::READ_COMMAND, 25);
registerObserverCommand(driver::STATUS_COMMAND, 25);
}
/*
* Destructor
*/
CaenEasydriverDriver::~CaenEasydriverDriver() {
}
/*
* execute
*/
void CaenEasydriverDriver::execute(const std::string& aCommand) {
if ((aCommand != COMMAND_STOP_DEVICE_CONTAINER) && (aCommand != driver::STATUS_COMMAND)
&& (aCommand != driver::READ_COMMAND)) {
commandProgression = PROGRESSION_UNKNOWNSTATE_DEVICE_CONTAINER;
}
CaenEasydriverState* currentState = dynamic_cast<CaenEasydriverState *>(getCurrentState());
// Check command
if (aCommand == driver::READ_INFOS_COMMAND) {
// Info command
currentState->readInfos();
} else if (aCommand == driver::START_COMMAND) {
startActivated = true;
m_startedCurrent = actualCurrent();
currentState->start();
} else if (aCommand == COMMAND_SWITCH_ON) {
currentState->on();
} else if (aCommand == COMMAND_SWITCH_OFF) {
currentState->off();
} else if (aCommand == driver::INIT_COMMAND) {
currentState->init();
} else if (aCommand == driver::READ_COMMAND) {
currentState->read();
} else if (aCommand == driver::STOP_COMMAND) {
startActivated = false;
currentState->stop();
} else if (aCommand == driver::STATUS_COMMAND) {
currentState->readStatus();
}
}
/*
* computeCurrentStatus
*/
void CaenEasydriverDriver::computeCurrentStatus(int32 value) {
if ((value & caen_easydriver::FAULT) || (value & caen_easydriver::DC_LINK_UNDERVOLTAGE)
|| (value & caen_easydriver::MOSFET_TEMPERATURE) || (value & caen_easydriver::SHUNT_TEMPERATURE)
|| (value & caen_easydriver::EXTERNAL_INTERLOCK_FLAG)) {
commandStatus.setError();
} else if (value & caen_easydriver::CHANGING) {
commandStatus.setRunning();
} else if (value & caen_easydriver::IN_TOLERANCE) {
commandStatus.setIdle();
}
status = value;
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CAENEASYDRIVERDRIVER_H
#define CAENEASYDRIVERDRIVER_H
#include "controllers/common/current/CurrentCommon.h"
#include "drivers/global/sockettcp/SocketTcp.h"
namespace caen_easydriver {
/*!
* Global implementation of the Caen Fast Ps
*/
class CaenEasydriverDriver: public current::CurrentCommon, public driver::SocketTcp {
friend class RealCaenEasydriverDriver;
friend class PerfectCaenEasydriverDriver;
friend class SimulatedCaenEasydriverDriver;
public:
//! Driver type value
static const std::string TYPE;
/*!
* \brief Constructor
* \param[in] name the name of the device driver
*/
CaenEasydriverDriver(const std::string& name);
/*!
* \brief Destructor
*/
virtual ~CaenEasydriverDriver();
/*!
* \brief Method called for executing a command
*
* \param[in] command the command to apply on the controller
*/
virtual void execute(const std::string& aCommand);
private:
/*!
* \brief compute global axis status
* \param[in] value the driver status
*/
virtual void computeCurrentStatus(int32 value);
};
}
#endif //CAENEASYDRIVERDRIVER_H
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef CAENEASYDRIVERSTATE_H
#define CAENEASYDRIVERSTATE_H
#include <Driver.h>
#include "CaenEasydriverDriver.h"
namespace caen_easydriver {
/*!
* \class CaenEasydriverState
* \brief Virtual class for implement State pattern
*
* Define all methods that perfect, simulated and real classes have to implement
*/
class CaenEasydriverState: public DriverState<CaenEasydriverDriver> {
public:
/*!
* \brief Constructor
* \param[in] owner The device driver main class link
*/
CaenEasydriverState(CaenEasydriverDriver* owner) :
DriverState<CaenEasydriverDriver>(owner) {
}
/*!
* \brief Destructor
*/
virtual ~CaenEasydriverState() {
}
/*!
* \brief Start command implementation
*/
virtual void start() = 0;
/*!
* \brief Read command implementation
*/
virtual void read() = 0;
/*!
* \brief On command implementation
*/
virtual void on() = 0;
/*!
* \brief Off command implementation
*/
virtual void off() = 0;
/*!
* \brief Stop command implementation
*/
virtual void stop() = 0;
/*!
* \brief Read status command implementation
*/
virtual void readStatus() = 0;
/*!
* \brief Read Infos command implementation
*/
virtual void readInfos() = 0;
};
}
#endif //CaenEasydriverSTATE_H
<module name="caen_easydriver">
<driver class="caen_easydriver::CaenEasydriverDriver"/>
</module>
\ No newline at end of file
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "PerfectCaenEasydriverDriver.h"
#include "CaenEasydriverDriver.h"
#include "CaenEasydriverDef.h"
namespace caen_easydriver {
/*
* Constructor
*/
PerfectCaenEasydriverDriver::PerfectCaenEasydriverDriver(CaenEasydriverDriver* owner) :
CaenEasydriverState(owner) {
/* Empty */
}
/*
* Destructor
*/
PerfectCaenEasydriverDriver::~PerfectCaenEasydriverDriver() {
/* Empty */
}
/*
* init
*/
void PerfectCaenEasydriverDriver::init() {
}
/*
* readStatus
*/
void PerfectCaenEasydriverDriver::readStatus() {
owner()->startActivated = false;
owner()->commandProgression = PROGRESSION_END_DEVICE_CONTAINER;
owner()->computeCurrentStatus(caen_easydriver::IN_TOLERANCE);
}
/*
* stop
*/
void PerfectCaenEasydriverDriver::stop() {
owner()->commandProgression = PROGRESSION_END_DEVICE_CONTAINER;
}
/*
* readInfos
*/
void PerfectCaenEasydriverDriver::readInfos() {
}
/*
* read
*/
void PerfectCaenEasydriverDriver::read() {
}
/*
* on
*/
void PerfectCaenEasydriverDriver::on() {
}
/*
* off
*/
void PerfectCaenEasydriverDriver::off() {
}
/*
* start
*/
void PerfectCaenEasydriverDriver::start() {
owner()->actualCurrent = owner()->wantedCurrent();
owner()->actualVoltage = owner()->wantedVoltage();
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef PERFECTCAENEASYDRIVERDRIVER_H
#define PERFECTCAENEASYDRIVERDRIVER_H
#include "CaenEasydriverState.h"
namespace caen_easydriver {
class CaenEasydriverDriver;
/*!
* \class PerfectCaenEasydriverDriver
* \brief Perfect implementation class for the generic rs232 device driver
*
* On start command, all actual values become target's ones.
*/
class PerfectCaenEasydriverDriver: public CaenEasydriverState {
public:
/*!
* \brief Constructor
* \param[in] owner The device driver main class link
*/
PerfectCaenEasydriverDriver(CaenEasydriverDriver* owner);
/*!
* \brief Destructor
*/
virtual ~PerfectCaenEasydriverDriver();
/*!
* \brief init command implementation
*/
virtual void init();
/*!
* \brief Start command implementation
*/
virtual void start();
/*!
* \brief Read command implementation
*/
virtual void read();
/*!
* \brief On command implementation
*/
virtual void on();
/*!
* \brief Off command implementation
*/
virtual void off();
/*!
* \brief Stop command implementation
*/
virtual void stop();
/*!
* \brief Read status command implementation
*/
virtual void readStatus();
/*!
* \brief Read Infos command implementation
*/
virtual void readInfos();
};
}
#endif //PERFECTCAENEASYDRIVERDRIVER_H
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "RealCaenEasydriverDriver.h"
#include "CaenEasydriverDriver.h"
#include "CaenEasydriverDef.h"
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
using namespace boost;
using namespace std;
namespace caen_easydriver {
/*
* Constructor
*/
RealCaenEasydriverDriver::RealCaenEasydriverDriver(CaenEasydriverDriver* owner) :
CaenEasydriverState(owner) {
m_Errors[MODULE_ON] = "Module is Enabled and Correctly Regulating Output Current";
m_Errors[FAULT] = "Fault";
m_Errors[DC_LINK_UNDERVOLTAGE] = "DC Link Undervoltage";
m_Errors[MOSFET_TEMPERATURE] = "Mosfet Over Temperature";
m_Errors[SHUNT_TEMPERATURE] = "Shunt Over Temperature";
m_Errors[EXTERNAL_INTERLOCK_FLAG] = "External Interlock Trips";
}
/*
* Destructor
*/
RealCaenEasydriverDriver::~RealCaenEasydriverDriver() {
/* Empty */
}
/*
* init
*/
void RealCaenEasydriverDriver::init() {
owner()->connect();
readInfos();
read();
readStatus();
}
/*
* readStatus
*/
void RealCaenEasydriverDriver::readStatus() {
try {
vector<string> answer = writeCaenEasydriver(READ_STATUS_COMMAND);
if (answer.size() > 1) {
int32 status = NO_STATUS;
std::stringstream ss;
ss << std::hex << answer[1];
ss >> status;
status &= 0x3FFFFFFF;
// Test tolerance
if ((status & MODULE_ON) == 0) {
float64 delta = owner()->wantedCurrent() - owner()->actualCurrent();
if (fabs(delta) <= owner()->currentTolerance()) {
status |= IN_TOLERANCE;
}
} else {
float64 delta = owner()->wantedVoltage() - owner()->actualVoltage();
if (fabs(delta) <= owner()->voltageTolerance()) {
status |= IN_TOLERANCE;
}
}
if (owner()->startActivated() == true) {
// Start activated , wait for the current
if (status & IN_TOLERANCE) {
// Finished
owner()->startActivated = false;
owner()->commandProgression = PROGRESSION_END_DEVICE_CONTAINER;
} else {
owner()->calculateProgression();
}
} else {
owner()->commandProgression = PROGRESSION_END_DEVICE_CONTAINER;
}
if (owner()->startActivated() == true) {
status |= CHANGING;
}
owner()->computeCurrentStatus(status);
}
} catch (CaenError& e) {
throw Exceptions(e.code, getStringError(e.code));
}
}
/*
* read
*/
void RealCaenEasydriverDriver::read() {
try {
vector<string> answer = writeCaenEasydriver(READ_CURRENT_COMMAND);
if (answer.size() > 1) {
owner()->actualCurrent.update(lexical_cast<float64>(answer[1]));
}
answer = writeCaenEasydriver(READ_VOLTAGE_COMMAND);
if (answer.size() > 1) {
owner()->actualVoltage.update(lexical_cast<float64>(answer[1]));
}
} catch (CaenError& e) {
throw Exceptions(e.code, getStringError(e.code));
}
}
/*
* readInfos
*/
void RealCaenEasydriverDriver::readInfos() {
try {
vector<string> answer = writeCaenEasydriver(VERSION_COMMAND);
string tmp;
for(int32 i = 1; i < answer.size(); i++) {
tmp.append(answer[i]);
tmp.append(" ");
}
owner()->version.update(tmp);
} catch (CaenError& e) {
throw Exceptions(e.code, getStringError(e.code));
}
}
/*
* start
*/
void RealCaenEasydriverDriver::start() {
try {
// writeCaenEasydriver(RESET_STATUS_COMMAND);
// ostringstream buf1;
// buf1 << LOOP_COMMAND << SEPARATOR;
if (owner()->mode() == current::CurrentCommon::CC_MODE) {
// buf1 << CURRENT_LOOP_COMMAND;
// writeCaenEasydriver(buf1.str());
ostringstream buf2;
buf2 << WRITE_CURRENT_COMMAND << SEPARATOR << owner()->wantedCurrent();
writeCaenEasydriver(buf2.str());
} else if (owner()->mode() == current::CurrentCommon::CV_MODE) {
// buf1 << VOLTAGE_LOOP_COMMAND;
// writeCaenEasydriver(buf1.str());
ostringstream buf2;
buf2 << WRITE_VOLTAGE_COMMAND << SEPARATOR << owner()->wantedVoltage();
writeCaenEasydriver(buf2.str());
}
// Force on to activate power supply
on();
} catch (CaenError& e) {
throw Exceptions(e.code, getStringError(e.code));
}
}
/*
* on
*/
void RealCaenEasydriverDriver::on() {
if ((owner()->status() & MODULE_ON) == 0) {
try {
writeCaenEasydriver(ON_COMMAND);
} catch (CaenError& e) {
throw Exceptions(e.code, getStringError(e.code));
}
}
}