File power_testbench.cpp
File List > midas_fe > power > power_testbench.cpp
Go to the documentation of this file
/********************************************************************\
Name: power.cpp
Created by: Frederik Wauters
Contents: frontend to control to main Genesys power supplies
lab supplies are also be added
One daisy chain of Genesys supplies is one "equipment" as it has a single IP address
and "channels" to select A single HAMEG is one equipment to follow the same structure This Midas
frontend instantiates custum C++ drivers which also take care of the ODB The type of driver is
derived from the equipment name
$Id$
\********************************************************************/
#include <stdio.h>
#include <iostream>
#include <thread>
#include <chrono>
#include <future>
#include "midas.h"
#include "mfe.h"
#include "mscb.h"
#include "history.h"
#include "odbxx.h"
#include "class/multi.h"
#include "class/generic.h"
#include "device/mscbdev.h"
#include "device/mscbhvr.h"
#include "GenesysDriver.h"
#include "HMP4040Driver.h"
#include "Keithley2611BDriver.h"
#include "Keithley2612ADriver.h"
#include "Keithley2450Driver.h"
#include "Keithley2400Driver.h"
#include "Keithley6487Driver.h"
#include "mstrlcpy.h"
using midas::odb;
/*-- Globals -------------------------------------------------------*/
/* The frontend name (client name) as seen by other MIDAS clients */
const char* frontend_name = "Power Frontend TestBench";
/* The frontend file name, don't change it */
const char* frontend_file_name = __FILE__;
/* frontend_loop is called periodically if this variable is TRUE */
BOOL frontend_call_loop = FALSE;
/* Overwrite equipment struct in ODB from values in code*/
BOOL equipment_common_overwrite = TRUE;
/* a frontend status page is displayed with this frequency in ms */
INT display_period = 1000;
/* maximum event size produced by this frontend */
INT max_event_size = 10000;
/* maximum event size for fragmented events (EQ_FRAGMENTED) */
INT max_event_size_frag = 5 * 1024 * 1024;
/* buffer size to hold events */
INT event_buffer_size = 10 * 10000;
std::vector<PowerDriver*> drivers;
/*-- Function declarations -----------------------------------------*/
INT frontend_init();
INT frontend_exit();
INT begin_of_run(INT run_number, char* error);
INT end_of_run(INT run_number, char* error);
INT pause_run(INT run_number, char* error);
INT resume_run(INT run_number, char* error);
INT frontend_loop();
/*
INT read_genesys_power(char *pevent, INT off);*/
INT read_hameg_power(char* pevent, INT off, std::string eq_name, std::string lvh_num);
INT read_keithley_power0(char* pevent, INT off);
INT read_keithley_power1(char* pevent, INT off);
INT read_hameg_power0(char* pevent, INT off);
INT read_hameg_power1(char* pevent, INT off);
INT read_hameg_power2(char* pevent, INT off);
/*
INT read_hameg_power3(char *pevent, INT off);
INT read_hameg_power4(char *pevent, INT off);
INT read_hameg_power5(char *pevent, INT off);
INT read_hameg_power6(char *pevent, INT off);
INT read_hameg_power7(char *pevent, INT off);
INT read_hameg_power8(char *pevent, INT off);
*/
INT read_power(float* pdata, const std::string& eqn);
void setup_history();
/*-- Equipment list ------------------------------------------------*/
/* device driver list */
DEVICE_DRIVER mscb_driver[] = {{"Output", mscbdev, 0, nullptr, DF_OUTPUT | DF_MULTITHREAD},
{"Input", mscbdev, 0, nullptr, DF_INPUT | DF_MULTITHREAD},
{""}};
EQUIPMENT equipment[] = {
// {"HVSUPPLY0", /* equipment name */
// {121, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 1000, /* read every 0.2 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_keithley_power0,
// },
// {"HVSUPPLY1", /* equipment name */
// {122, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 1000, /* read every 0.2 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_keithley_power0,
// },
// {"HVSUPPLY1", /* equipment name */
// {122, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 1000, /* read every 0.2 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_keithley_power1,
// },
{
"LVSUPPLY0", /* equipment name */
{120, 0, /* event ID, trigger mask */
"SYSTEM", /* event buffer */
EQ_PERIODIC, /* equipment type */
0, /* event source */
"MIDAS", /* format */
TRUE, /* enabled */
RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
1000, /* read every 1 sec */
0, /* stop run after this event limit */
0, /* number of sub events */
1, /* log history every event */
"", "", ""}, /* device driver list */
read_hameg_power0,
},
{
"LVSUPPLY1", /* equipment name */
{121, 0, /* event ID, trigger mask */
"SYSTEM", /* event buffer */
EQ_PERIODIC, /* equipment type */
0, /* event source */
"MIDAS", /* format */
TRUE, /* enabled */
RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
1000, /* read every 10 sec */
0, /* stop run after this event limit */
0, /* number of sub events */
1, /* log history every event */
"", "", ""}, /* device driver list */
read_hameg_power1,
},
// {"LVSUPPLY2", /* equipment name */
// {122, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 10000, /* read every 10 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_hameg_power2,
// },
// {"HAMEG3", /* equipment name */
// {123, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 10000, /* read every 10 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_hameg_power3,
// },
// {"HAMEG4", /* equipment name */
// {124, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 10000, /* read every 10 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_hameg_power4,
// },
// {"HAMEG5", /* equipment name */
// {125, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 10000, /* read every 10 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_hameg_power5,
// },
//{"HAMEG6", /* equipment name */
// {126, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 10000, /* read every 10 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_hameg_power6,
//},
// {"HAMEG7", /* equipment name */
// {127, 0, /* event ID, trigger mask */
// "SYSTEM", /* event buffer */
// EQ_PERIODIC, /* equipment type */
// 0, /* event source */
// "MIDAS", /* format */
// TRUE, /* enabled */
// RO_STOPPED | RO_RUNNING | RO_PAUSE, /* all, but not write to odb */
// 10000, /* read every 10 sec */
// 0, /* stop run after this event limit */
// 0, /* number of sub events */
// 1, /* log history every event */
// "", "", ""} , /* device driver list */
// read_hameg_power7,
// },
{""} // why is there actually this empty one here? FW
};
/*-- Function to define MSCB variables in a convenient way ---------*/
void mscb_define(std::string eq, std::string devname, DEVICE_DRIVER* driver, std::string submaster,
int address, unsigned char var_index, std::string name, double threshold,
double factor, double offset) {
midas::odb::set_debug(false);
midas::odb dev = {{"Device", std::string(255, '\0')},
{"Pwd", std::string(31, '\0')},
{"MSCB Address", 0},
{"MSCB Index", (UINT8)0}};
dev.connect("/Equipment/" + eq + "/Settings/Devices/" + devname);
if (!submaster.empty()) {
if (dev["Device"] == std::string(""))
dev["Device"] = submaster;
else if (dev["Device"] != submaster) {
cm_msg(MERROR, "mscb_define", "Device \"%s\" defined with different submasters",
devname.c_str());
return;
}
} else if (dev["Device"] == std::string("")) {
cm_msg(MERROR, "mscb_define", "Device \"%s\" defined without submaster name",
devname.c_str());
return;
}
// find device in device driver
int dev_index;
for (dev_index = 0; driver[dev_index].name[0]; dev_index++)
if (equal_ustring(driver[dev_index].name, devname.c_str()))
break;
if (!driver[dev_index].name[0]) {
cm_msg(MERROR, "mscb_define", "Device \"%s\" not present in device driver list",
devname.c_str());
return;
}
int chn_index = driver[dev_index].channels;
dev.set_auto_enlarge_array(true);
dev["MSCB Address"][chn_index] = address;
dev["MSCB Index"][chn_index] = var_index;
midas::odb settings;
settings.connect("/Equipment/" + eq + "/Settings");
settings.set_auto_enlarge_array(true);
settings.set_preserve_string_size(true);
if (driver[dev_index].flags & DF_INPUT) {
if (chn_index == 0)
settings["Update Threshold"] = (float)threshold;
else
settings["Update Threshold"][chn_index] = (float)threshold;
}
std::string fn(devname + " Factor");
std::string on(devname + " Offset");
if (chn_index == 0) {
settings[fn] = (float)factor;
settings[on] = (float)offset;
} else {
settings[fn][chn_index] = (float)factor;
settings[on][chn_index] = (float)offset;
}
if (!name.empty()) {
std::string sk = "Names " + devname;
if (chn_index == 0) {
settings[sk] = std::string(31, ' ');
settings[sk] = name;
} else
settings[sk][chn_index] = &name;
}
// increment number of channels for this driver
driver[dev_index].channels++;
// setup custom page
odb custom("/Custom");
custom["Pixel Test"] = "transfer/main.html";
}
/*-- Error dispatcher causing communication alarm -------------------*/
void scfe_error(const char* error) {
char str[256];
mstrlcpy(str, error, sizeof(str));
cm_msg(MERROR, "scfe_error", "%s", str);
al_trigger_alarm("MSCB", str, "MSCB Alarm", "Communication Problem", AT_INTERNAL);
}
/*-- Frontend Init -------------------------------------------------*/
INT frontend_init() {
// distribution control with SCS3000
/* set error dispatcher for alarm functionality */
mfe_set_error(scfe_error);
/* set maximal retry count */
mscb_set_max_retry(100);
/*---- set correct ODB device addresses ----*/
/*mscb_define("PowerDistribution", "Output", mscb_driver, "mscb401.psi.ch", 65535, 26, "Enable
channel 1", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Output", mscb_driver,
"mscb401.psi.ch", 65535, 27, "Enable channel 2", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Output", mscb_driver, "mscb401.psi.ch", 65535, 28, "Enable
channel 3", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Output", mscb_driver,
"mscb401.psi.ch", 65535, 30, "Enable channel 4", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Output", mscb_driver, "mscb401.psi.ch", 65535, 34, "Enable
channel 5", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Output", mscb_driver,
"mscb401.psi.ch", 65535, 35, "Enable channel 6", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Output", mscb_driver, "mscb401.psi.ch", 65535, 36, "Enable
channel 7", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Output", mscb_driver,
"mscb401.psi.ch", 65535, 37, "Enable channel 8", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Output", mscb_driver, "mscb401.psi.ch", 65535, 25, "Reset
ch1-4", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Output", mscb_driver,
"mscb401.psi.ch", 65535, 33, "Reset ch5-8", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535, 1, "OC ch1",
0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535,
2, "OC ch2", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver,
"mscb401.psi.ch", 65535, 3, "OC ch3", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Input",
mscb_driver, "mscb401.psi.ch", 65535, 4, "OC ch4", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535, 9, "OC ch5",
0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535,
10, "OC ch6", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver,
"mscb401.psi.ch", 65535, 11, "OC ch7", 0.1, 1.0, 0.0); mscb_define("PowerDistribution", "Input",
mscb_driver, "mscb401.psi.ch", 65535, 12, "OC ch8", 0.1, 1.0, 0.0);
mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535, 17, "Current
ch1", 0.01, 5.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch",
65535, 18, "Current ch2", 0.01, 5.0, 0.0); mscb_define("PowerDistribution", "Input",
mscb_driver, "mscb401.psi.ch", 65535, 19, "Current ch3", 0.01, 5.0, 0.0);
mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535, 20, "Current
ch4", 0.01, 5.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch",
65535, 42, "Current ch5", 0.01, 5.0, 0.0); mscb_define("PowerDistribution", "Input",
mscb_driver, "mscb401.psi.ch", 65535, 43, "Current ch6", 0.01, 5.0, 0.0);
mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch", 65535, 44, "Current
ch7", 0.01, 5.0, 0.0); mscb_define("PowerDistribution", "Input", mscb_driver, "mscb401.psi.ch",
65535, 45, "Current ch8", 0.01, 5.0, 0.0);*/
// Get N equipments
unsigned int nEq = sizeof(equipment) / sizeof(equipment[0]);
if (nEq < 2) {
cm_msg(MINFO, "power_fe", "No Equipment defined");
return FE_ERR_DISABLED;
}
for (unsigned int i = 0; i < nEq - 1; i++)
cm_msg(MINFO, "power_fe", "Init 'Equipment' nr %d name = %s, event ID = %d", i,
equipment[i].name, equipment[i].info.event_id);
// allow equipment name starts to recognize supply type
std::vector<std::string> genysis_names = {"Gen", "gen", "tdk", "TDK"};
std::vector<std::string> hameg_names = {"HMP", "hmp", "ham", "HAM", "Lab", "lab", "LVS"};
std::vector<std::string> keithley_names = {"Kei", "kei", "KEI", "HVS"};
for (unsigned int eqID = 0; eqID < nEq - 1; eqID++) {
std::cout << "start init Equipment id " << eqID << std::endl;
std::string name(equipment[eqID].name);
std::string shortname = name.substr(0, 3);
midas::odb driver_settings;
driver_settings.connect("/Equipment/" + name + "/Settings");
std::string driver_name = driver_settings["DriverName"];
// identify type and instatiate driver
if (std::find(genysis_names.begin(), genysis_names.end(), shortname) !=
genysis_names.end()) {
drivers.emplace_back(new GenesysDriver(equipment[eqID].name, &equipment[eqID].info));
} else if (std::find(hameg_names.begin(), hameg_names.end(), shortname) !=
hameg_names.end()) {
if (driver_name == "HMP4040")
drivers.emplace_back(
new HMP4040Driver(equipment[eqID].name, &equipment[eqID].info));
else {
std::cout << "Driver name " << driver_settings["DriverName"]
<< " not recognized. Set to default = HMP4040\n";
drivers.emplace_back(
new HMP4040Driver(equipment[eqID].name, &equipment[eqID].info));
}
} else if (std::find(keithley_names.begin(), keithley_names.end(), shortname) !=
keithley_names.end()) {
if (driver_name == "Keithley2450")
drivers.emplace_back(
new Keithley2450Driver(equipment[eqID].name, &equipment[eqID].info));
else if (driver_name == "Keithley2400")
drivers.emplace_back(
new Keithley2400Driver(equipment[eqID].name, &equipment[eqID].info));
else if (driver_name == "Keithley2611B")
drivers.emplace_back(
new Keithley2611BDriver(equipment[eqID].name, &equipment[eqID].info));
else if (driver_name == "Keithley6487")
drivers.emplace_back(
new Keithley6487Driver(equipment[eqID].name, &equipment[eqID].info));
else {
std::cout << "Driver name " << driver_settings["DriverName"]
<< " not recognized. Set to default = Keithley2611B\n";
drivers.emplace_back(
new Keithley2611BDriver(equipment[eqID].name, &equipment[eqID].info));
}
} else if (name == std::string("PowerDistribution")) {
// do nothing, also no warning
continue;
} else {
cm_msg(MINFO, "power_fe", "Init 'Equipment' nr %d name = %s not recognized", eqID,
equipment[eqID].name);
continue;
}
// initialize
std::cout << "initialize equipment " << equipment[eqID].name << std::endl;
set_equipment_status(equipment[eqID].name, "Initializing...", "yellowLight");
equipment[eqID].status = drivers.at(eqID)->ConnectODB();
}
for (unsigned int eqID = 0; eqID < nEq - 1; eqID++) {
std::string name(equipment[eqID].name);
if (equipment[eqID].status == FE_ERR_ODB) {
set_equipment_status(equipment[eqID].name, "ODB Error", "redLight");
cm_msg(MERROR, "initialize_equipment", "Equipment %s disabled because of %s",
equipment[eqID].name, "ODB ERROR");
continue;
}
if (!drivers.at(eqID)->Enabled()) // cross check before doing something
{
set_equipment_status(equipment[eqID].name, "Disabled", "redLight");
continue;
}
equipment[eqID].status = drivers.at(eqID)->Connect();
if (equipment[eqID].status != FE_SUCCESS) {
set_equipment_status(equipment[eqID].name, "Connection Error", "redLight");
cm_msg(MERROR, "initialize_equipment", "Equipment %s disabled because of %s",
equipment[eqID].name, "CONNECTION ERROR");
continue;
}
equipment[eqID].status = drivers.at(eqID)->Init();
if (equipment[eqID].status != FE_SUCCESS) {
set_equipment_status(equipment[eqID].name, "DRIVER Error", "redLight");
cm_msg(MERROR, "initialize_equipment", "Equipment %s disabled because of %s",
equipment[eqID].name, "DRIVER ERROR");
continue;
} else {
drivers.at(eqID)->SetInitialized();
drivers.at(eqID)->Print();
std::cout << " read setting " << equipment[eqID].info.read_on << std::endl;
set_equipment_status(equipment[eqID].name, "Ok", "greenLight");
}
// And start the threaded reading
drivers.at(eqID)->StartReading();
}
setup_history();
ss_sleep(5000);
// Equipment ready
return CM_SUCCESS;
}
/*-- Frontend Exit -------------------------------------------------*/
INT frontend_exit() {
for (auto& d : drivers) {
delete d;
}
// gendriver->Print();
ss_sleep(1000);
return CM_SUCCESS;
}
INT read_power(float* pdata, const std::string& eq_name) {
INT error = CM_SUCCESS;
for (const auto& d : drivers) {
if (!d->Initialized())
continue;
if (d->GetName() != eq_name)
continue;
error = d->GetReadStatus();
if (error == FE_SUCCESS) {
std::vector<float> voltage = d->GetVoltage();
std::vector<float> current = d->GetCurrent();
if (voltage.size() != current.size()) {
continue;
cm_msg(MERROR, "read_power", "Number of channel reads not consistent");
}
for (unsigned int iChannel = 0; iChannel < voltage.size(); iChannel++) {
*pdata++ = voltage.at(iChannel);
*pdata++ = current.at(iChannel);
}
// And start the next read
d->StartReading();
d->ResetNReadFaults();
} else {
cm_msg(MERROR, "power read", "Error in read: %d", error);
d->AddReadFault();
// And start the next read
d->StartReading();
return 0;
}
if (d->GetNReadFaults() >= 3) {
d->UnsetInitialized();
set_equipment_status(d->GetName().c_str(), "Read Error", "redLight");
}
}
return error;
}
INT read_hameg_power(char* pevent, INT off [[maybe_unused]], std::string eq_name,
std::string lvh_num) {
/* init bank structure */
bk_init32a(pevent);
float* pdata;
std::string LVH_str = "LVH";
LVH_str.append(lvh_num);
bk_create(pevent, LVH_str.c_str(), TID_FLOAT, (void**)&pdata);
read_power(pdata, eq_name);
// printf("creating bank %s\n",LVH_str.c_str());
bk_close(pevent, pdata);
return bk_size(pevent);
}
INT read_hameg_power0(char* pevent, INT off) {
return read_hameg_power(pevent, off, "LVSUPPLY0", "0");
}
INT read_hameg_power1(char* pevent, INT off) {
return read_hameg_power(pevent, off, "LVSUPPLY1", "1");
}
INT read_hameg_power2(char* pevent, INT off) {
return read_hameg_power(pevent, off, "HAMEG2", "2");
}
/*
INT read_hameg_power3(char *pevent, INT off)
{
return read_hameg_power(pevent, off, "HAMEG3", "3");
}
INT read_hameg_power4(char *pevent, INT off)
{
return read_hameg_power(pevent, off, "HAMEG4", "4");
}
INT read_hameg_power5(char *pevent, INT off)
{
return read_hameg_power(pevent, off, "HAMEG5", "5");
}
INT read_hameg_power6(char *pevent, INT off)
{
return read_hameg_power(pevent, off, "HAMEG6", "6");
}
INT read_hameg_power7(char *pevent, INT off)
{
return read_hameg_power(pevent, off, "HAMEG7", "7");
}
INT read_hameg_power8(char *pevent, INT off)
{
return read_hameg_power(pevent, off, "HAMEG8", "8");
}
*/
INT read_keithley_power0(char* pevent, INT off) {
return read_hameg_power(pevent, off, "HVSUPPLY0", "0");
}
INT read_keithley_power1(char* pevent, INT off) {
return read_hameg_power(pevent, off, "HVSUPPLY1", "1");
}
INT frontend_loop() { return SUCCESS; }
//*************** Not used ******************//
/*-- Dummy routines ------------------------------------------------*/
INT poll_event(INT source [[maybe_unused]], INT count [[maybe_unused]],
BOOL test [[maybe_unused]]) {
return 1;
}
INT interrupt_configure(INT cmd [[maybe_unused]], INT source [[maybe_unused]],
POINTER_T adr [[maybe_unused]]) {
return 1;
}
/*-- Frontend Loop -------------------------------------------------*/
/*-- Begin of Run --------------------------------------------------*/
INT begin_of_run(INT run_number [[maybe_unused]], char* error [[maybe_unused]]) {
return CM_SUCCESS;
}
/*-- End of Run ----------------------------------------------------*/
INT end_of_run(INT run_number [[maybe_unused]], char* error [[maybe_unused]]) { return CM_SUCCESS; }
/*-- Pause Run -----------------------------------------------------*/
INT pause_run(INT run_number [[maybe_unused]], char* error [[maybe_unused]]) { return CM_SUCCESS; }
/*-- Resume Run ----------------------------------------------------*/
INT resume_run(INT run_number [[maybe_unused]], char* error [[maybe_unused]]) { return CM_SUCCESS; }
/*-- Set up history panels-----------------------------------------------*/
void setup_history() {
for (const auto& d : drivers) {
if (!d->Initialized())
continue;
std::string name = d->GetName();
size_t nchannels = d->GetVoltage().size();
std::vector<std::string> cnames;
std::vector<std::string> vnames;
for (unsigned int i = 0; i < nchannels; i++) {
cnames.push_back(std::string(name + std::string(":Current[") + std::to_string(i) +
std::string("]")));
vnames.push_back(std::string(name + std::string(":Voltage[") + std::to_string(i) +
std::string("]")));
}
hs_define_panel("Power", std::string(name + std::string(" Currents")).c_str(), cnames);
hs_define_panel("Power", std::string(name + std::string(" Voltages")).c_str(), vnames);
}
}