/*------------------------------------------------------------ * USBPixDcx.cxx * Version: 0.1.USBsystem * Created: 23 February 2009 * Author: Joern Grosse-Knetter * * Functional interface to the USB system for communication * with the ADCs on the USB system *------------------------------------------------------------*/ #include #include "PixDcs/USB_PixDcs.h" #include "Config/Config.h" #include "Config/ConfGroup.h" #include "PixController/USBPixController.h" #include "PixConfDBInterface/PixConfDBInterface.h" #include #define UDCS_DEB false using namespace PixLib; USBPixDcsChan::USBPixDcsChan(PixDcs *parent, DBInquire *dbInquire) : PixDcsChan(parent, dbInquire){ configInit(); m_conf->read(dbInquire); // get last part of decorated name which describes this object std::string myDecName = dbInquire->getMyDecName(); int pos = (int)myDecName.find_last_of("/"); pos--; pos = (int)myDecName.find_last_of("/", pos); myDecName.erase(0,pos+1); // set config name to DBInquire's decorated name to allow automatc saving m_conf->m_confName = myDecName; m_chanIsOn = false; } USBPixDcsChan::USBPixDcsChan(USBPixDcsChan &chan_in) : PixDcsChan(chan_in.m_parent, 0){ configInit(); *m_conf = *(chan_in.m_conf); m_chanIsOn = false; } USBPixDcsChan::~USBPixDcsChan(){ //delete m_conf; // taken care of by PixDcs's config } void USBPixDcsChan::configInit(){ // Create the Config object m_conf = new Config("USBPixDcsChan"); Config &conf = *m_conf; // Group general conf.addGroup("general"); conf["general"].addString("ChannelName", m_name, "unknown", "name of PixDcs channel", true); if(m_parent->getDevType()==PixDcs::SUPPLY){ std::map configMap; configMap["VDDA1"] = VDDA1; configMap["VDDA2"] = VDDA2; configMap["VDDD1"] = VDDD1; configMap["VDDD2"] = VDDD2; conf["general"].addList("ChannelDescr", m_channelDescr, VDDA1, configMap, "USB-ADC-Type of channel", true); conf.addGroup("settings"); conf["settings"].addFloat("NomVolts", m_nomVolts, 0.0, "Nominal voltage (in V) on this channel", true); } else{ std::map configMap; configMap["Temp"] = PixDcsChan::TEMP; conf["general"].addList("ChannelDescr", m_channelDescr, 0, configMap, "USB-ADC-Type of channel", true); } conf.reset(); } double USBPixDcsChan::ReadParam(std::string measType) { if(UDCS_DEB) cout << "USBPixDcsChan::ReadParam" << endl; Config &conf = *m_conf; USBPixDcs *parent = dynamic_cast(m_parent); if(parent->m_USBADC==0) throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since not yet initialised"); if(parent->m_USBPC->getUsbHandle()==0){ throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since USB link not available"); } parent->m_USBADC->UpdateMeasurements(); if(measType=="voltage"){ if(m_parent->getDevType()==PixDcs::SUPPLY && m_channelDescrm_USBADC->PSU[m_channelDescr]; double retval = sc->GetVoltage(); return retval; } else{ throw PixDcsExc(PixDcsExc::WARNING, "unknown channel or measurement type requested: "+ ((ConfList&)conf["general"]["ChannelDescr"]).sValue()+ ", " + measType); } }else if(measType=="current"){ if(m_parent->getDevType()==PixDcs::SUPPLY && m_channelDescrm_USBADC->PSU[m_channelDescr]; double retval = sc->GetCurrent(); return retval; } else{ throw PixDcsExc(PixDcsExc::WARNING, "unknown channel or measurement type requested: "+ ((ConfList&)conf["general"]["ChannelDescr"]).sValue()+ ", " + measType); } }else if(measType=="temperature"){ if(m_parent->getDevType()==PixDcs::ADCMETER && m_channelDescr==PixDcsChan::TEMP){ double retval = parent->m_USBADC->GetNTCTemperature(); return retval; } else{ throw PixDcsExc(PixDcsExc::WARNING, "unknown measurement type requested: "+ ((ConfList&)conf["general"]["ChannelDescr"]).sValue()+ ", " + measType); } }else { throw PixDcsExc(PixDcsExc::WARNING, "unknown measurement type requested: "+ ((ConfList&)conf["general"]["ChannelDescr"]).sValue()+ ", " + measType); } } void USBPixDcsChan::SetParam(string varType) { // Set resource with string id to default value. if(varType=="voltage") SetParam(varType, (double)m_nomVolts); else throw PixDcsExc(PixDcsExc::ERROR, "request for neither voltage setting nor current limit: "+varType); } void USBPixDcsChan::SetParam(string varType, double value) { if(UDCS_DEB) cout << "USBPixDcsChan::SetParam" << endl; // Set resource with string id to a double value. Config &conf = *m_conf; USBPixDcs *parent = dynamic_cast(m_parent); if(parent->m_USBADC==0) throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since not yet initialised"); if(parent->m_USBPC->getUsbHandle()==0){ throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since USB link not available"); } if(varType=="voltage"){ if(m_channelDescrm_USBADC->PSU[m_channelDescr]; sc->SetVoltage(value); }else{ throw PixDcsExc(PixDcsExc::WARNING, "unknown channel type requested: "+ ((ConfList&)conf["general"]["ChannelDescr"]).sValue()); } }else{ throw PixDcsExc(PixDcsExc::ERROR, "can only process request for voltage setting: "+varType); } } std::string USBPixDcsChan::ReadState(std::string){ if(UDCS_DEB) cout << "USBPixDcsChan::ReadState" << endl; USBPixDcs *parent = dynamic_cast(m_parent); if(parent->m_USBADC==0){ throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since not yet initialised"); return "unknown"; } if(parent->m_USBPC->getUsbHandle()==0) return "unknown"; if(parent->m_devType!=PixDcs::SUPPLY) return "unknown"; else return m_chanIsOn?"ON":"OFF"; } void USBPixDcsChan::SetState(std::string new_state){ if(UDCS_DEB) cout << "USBPixDcsChan::SetState" << endl; Config &conf = *m_conf; USBPixDcs *parent = dynamic_cast(m_parent); if(parent->m_USBADC==0) throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since not yet initialised"); if(parent->m_USBPC->getUsbHandle()==0){ throw PixDcsExc(PixDcsExc::WARNING, "can't read from device since USB link not available"); } if(parent->m_devType!=PixDcs::SUPPLY) return; if(m_channelDescrm_USBADC->PSU[m_channelDescr]; // sc->Enable(m_chanIsOn); -- not implemented, use register access instead parent->m_USBPC->getUsbHandle(); //ConfigRegister *reg = parent->m_USBPC->getRegister(); if(m_chanIsOn) SetParam("voltage", m_nomVolts); USBpix *reg = parent->m_USBPC->getUSBpix(); //M.B.: Is this correct? reg->EnablePowerChannel(m_chanIsOn, m_channelDescr); }else{ throw PixDcsExc(PixDcsExc::WARNING, "unknown channel type requested: "+ ((ConfList&)conf["general"]["ChannelDescr"]).sValue());} } USBPixDcs::USBPixDcs(DBInquire *dbInquire, void *interface) : PixDcs(dbInquire, interface){ m_USBPC = (USBPixController*)interface; //dynamic_cast(interface); if(m_USBPC==0) throw PixDcsExc(PixDcsExc::FATAL, "interface provided to PixDcs::make is either NULL or not USB although USB was requested"); configInit(); m_conf->read(dbInquire); m_problemInit = false; // if(m_devType!=ADCMETER) // throw PixDcsExc(PixDcsExc::FATAL, "USBPixDcs can at the moment only be used as type meter, different type requested though"); for(recordIterator it = dbInquire->recordBegin(); it != dbInquire->recordEnd(); it++){ // Look for DCS channel inquire if((*it)->getName() == "PixDcsChan") { USBPixDcsChan *uch = new USBPixDcsChan(this, *it); m_channels.push_back(uch); m_conf->addConfig(uch->m_conf); // set default name and channel ID if none given yet int chID = (int)m_channels.size()-1; std::stringstream a; a << chID; if(uch->m_name=="unknown"){ uch->m_name = m_name+"_Ch"+a.str(); uch->m_channelDescr = VDDA1; } } } m_USBADC = 0; } USBPixDcs::~USBPixDcs(){ delete m_conf; for(vector::iterator it = m_channels.begin(); it!=m_channels.end(); it++){ PixDcsChan *pdc = *it; delete pdc; } m_channels.clear(); delete m_USBADC; } std::string USBPixDcs::ReadState(std::string req) { if(UDCS_DEB) cout << "USBPixDcs::ReadState" << endl; // Read a string value from DDC, returning a string. std::string ret="uninit."; // check if hadle of USBPixController is still valid, otherwise go into uninit state if(m_USBPC->getUsbHandle()==0){ delete m_USBADC; m_USBADC=0; } if(m_USBADC!=0){ if(m_devType==SUPPLY){ // have on/off-states controller per channel int n_On=0; for(vector::iterator IT=chanBegin(); IT!=chanEnd(); IT++){ USBPixDcsChan *ch = dynamic_cast(*IT); if(ch->ReadState(req)=="ON") n_On++; } if(n_On==nchan()) ret = "ALL ON"; else if(n_On==0) ret = "ALL OFF"; else ret = "CHAN"; } else ret = "OK"; } else if(m_problemInit) ret = "ERROR"; return ret; } void USBPixDcs::SetState(std::string new_state){ if(UDCS_DEB) cout << "USBPixDcs::SetState" << endl; if(new_state!="OFF" && new_state!="ON") throw PixDcsExc(PixDcsExc::ERROR, "unknown request for change in state (should be ON or OFF): "+new_state); if(m_USBADC==0) return; // can't set anything without init. hardware if(m_devType!=SUPPLY) return; // can only set this for supplies if(new_state=="ON"){ // turn on in order 0,1,2,... for(vector::iterator IT=chanBegin(); IT!=chanEnd(); IT++){ USBPixDcsChan *ch = dynamic_cast(*IT); ch->SetState(new_state); } } else { // turn off in reverse order for(int i = ((int)m_channels.size())-1; i>=0; i--){ USBPixDcsChan *ch = dynamic_cast(m_channels[i]); ch->SetState(new_state); } } } void USBPixDcs::configInit(){ // Create the Config object m_conf = new Config("USBPixDcs"); Config &conf = *m_conf; // Group general conf.addGroup("general"); conf["general"].addString("DeviceName", m_name, "unknown", "name of PixDcs device", true); conf["general"].addList("DeviceType", (int &)m_devType, ADCMETER, m_typeMap, "Type of device", false); conf["general"].addInt("Index", m_index, -1, "Index - order in which device is used amongst other DCS devices", true); conf.reset(); } void USBPixDcs::initHW(){ if(m_USBADC!=0) delete m_USBADC; m_USBADC=0; if(UDCS_DEB) cout << "Retrieving board handle from controller " << m_USBPC->getModGroup().getName() << endl; SiUSBDevice *handle = m_USBPC->getUsbHandle(); if(handle!=0){ m_USBADC = new USBPixDCS(handle); m_USBADC->Init(); m_problemInit = false; SetState("OFF"); // init. state should be off stringstream c; c << m_USBADC->GetId(); if(UDCS_DEB) cout << "DCS device " << m_name << " has USB board ID " << handle->GetId() << " and interface board ID " << c.str() << endl; }else{ m_problemInit = true; throw PixDcsExc(PixDcsExc::ERROR, "USB interface must be initialised before DCS object can be set up"); } }