/*---------------------------------------------------------------------------- A N S T O H M A histogramming memory driver for the ANSTO histogrammer. This version assumes the histogrammer is a TANGO device server and uses the TANGO api to communicate with the histogrammer. It has to be compiled with the C++ compiler and the SICServer has to be linked with C++. Andy Gotz, February 2004 Copyright: ANSTO Lucas Heights New South Wales AUSTRALIA The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. ----------------------------------------------------------------------------*/ #include #include #include #include extern "C" { #include "fortify.h" #include "sics.h" #include "countdriv.h" #include "counter.h" #include "stringdict.h" #include "HistMem.h" #include "HistDriv.i" #include "anstohm.h" } #include /* #define TESTVAL 128 define TESTVAL to set the simulated histogram to a fixed value for testing */ static int iSet = 0; static HistInt iSetVal = 0; static HistMode eHistMode; /* * histogrammer proxy and data globals * * NOTE: defining this as globals means ONLY one histogrammer can be * interfaces from SICS. If we need more we need to manage multiple * histogram devices e.g. by adding them to the pHistDriver structure */ static char *hm_device = "localhost:30001/hifar/mrpd/hm#dbase=no"; static Tango::DeviceProxy *hm_proxy=NULL; static vector hm_data; /*--------------------------------------------------------------------------*/ static int AnstoHMConfig(pHistDriver self, SConnection *pCon, pStringDict pOption, SicsInterp *pSics) { int i, iLength = 1, status; char pData[132]; if(eHistMode == eHTOF) { for(i = 0; i < self->data->rank; i++) { iLength *= self->data->iDim[i]; } iLength *= self->data->nTimeChan; } /* * set count mode */ if (hm_proxy != NULL) { try { string count_mode; if (self->eCount == ePreset) { count_mode = "monitor"; } else { count_mode = "time"; } Tango::DeviceAttribute attr_write((const char*)"count_mode",count_mode); hm_proxy->write_attribute(attr_write); } catch(Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram Count Mode failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } } /* * send preset to histogrammer */ if (hm_proxy != NULL) { try { /* * QUESTION: what are the time units of fCountPreset ? Might have to scale it * should iExponent be taken into account here ? */ long preset = (long)self->fCountPreset; Tango::DeviceAttribute attr_write((const char*)"preset",preset); hm_proxy->write_attribute(attr_write); } catch(Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram Preset failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } } return 1; } /*-------------------------------------------------------------------------*/ static int AnstoHMStart(pHistDriver self, SConnection *pCon) { if (hm_proxy != NULL) { try { hm_proxy->command_inout("Start"); } catch (Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: TANGO Histogram Start failed",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } } return 1; } /*-------------------------------------------------------------------------*/ static int AnstoHMPause(pHistDriver self, SConnection *pCon) { if (hm_proxy != NULL) { try { hm_proxy->command_inout("Pause"); } catch (Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram Pause failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } } return 1; } /*------------------------------------------------------------------------*/ static int AnstoHMContinue(pHistDriver self, SConnection *pCon) { if (hm_proxy != NULL) { try { hm_proxy->command_inout("Continue"); } catch (Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram Continue failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } } return 1; } /*-------------------------------------------------------------------------*/ static int AnstoHMHalt(pHistDriver self) { if (hm_proxy != NULL) { try { hm_proxy->command_inout("Halt"); } catch (Tango::DevFailed &exception) { /* SCWrite(pCon,"ERROR: Histogram Halt failed",eError); SCWrite(pCon,exception.errors[0].desc,eError); */ return 0; } } return 1; } /*-------------------------------------------------------------------------*/ static int AnstoHMGetCountStatus(pHistDriver self, SConnection *pCon) { if (hm_proxy != NULL) { try { Tango::DevState state; state = hm_proxy->state(); switch (state) { case Tango::OFF : return HWIdle; case Tango::RUNNING : return HWBusy; case Tango::STANDBY : return HWPause; case Tango::FAULT : return HWFault; default : return HWFault; } } catch(Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram state() failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } } } /*-------------------------------------------------------------------------*/ static int AnstoHMGetError(pHistDriver self, int *iCode, char *pError, int iLen) { return 0; } /*-------------------------------------------------------------------------*/ static int AnstoHMTryAndFixIt(pHistDriver self, int iCode) { if (hm_proxy != NULL) { try { hm_proxy->command_inout("Reset"); } catch (Tango::DevFailed &exception) { /* SCWrite(pCon,"ERROR: Histogram Reset failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); */ return 0; } } return 1; } /*--------------------------------------------------------------------------*/ static int AnstoHMGetData(pHistDriver self, SConnection *pCon) { try { Tango::DeviceAttribute attr_read = hm_proxy->read_attribute("data"); // return data in global hm_data variable attr_read >> hm_data; } catch(Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram GetData failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } return 1; } /*--------------------------------------------------------------------------*/ static int AnstoHMGetHistogram(pHistDriver self, SConnection *pCon, int i, int iStart, int iEnd, HistInt *lData) { int ii; if(i < 0) { SCWrite(pCon,"ERROR: histogram out of range",eError); return 0; } #ifdef TESTVAL for(ii = iStart; ii < iEnd; ii++) { lData[ii] = TESTVAL; } #else AnstoHMGetData(self, pCon); for(ii = iStart; ii < iEnd; ii++) { if (ii < hm_data.size()) lData[ii-iStart] = hm_data[ii]; } #endif return 1; } /*------------------------------------------------------------------------*/ static int AnstoHMSetHistogram(pHistDriver self, SConnection *pCon, int i, int iStart, int iEnd, HistInt *lData) { iSet = 1; iSetVal = lData[0]; return 1; } /*-------------------------------------------------------------------------*/ static int AnstoHMPreset(pHistDriver self, SConnection *pCon, HistInt iVal) { iSet = 1; iSetVal = iVal; return 1; } /*------------------------------------------------------------------------*/ static int AnstoHMFreePrivate(pHistDriver self) { return 1; } /*------------------------------------------------------------------------*/ static long AnstoHMGetMonitor(pHistDriver self, int i, SConnection *pCon) { long hm_monitor; try { Tango::DeviceAttribute attr_read = hm_proxy->read_attribute("monitor"); // return data in global hm_data variable attr_read >> hm_monitor; } catch(Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram GetData failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } return hm_monitor; } /*------------------------------------------------------------------------*/ static float AnstoHMGetTime(pHistDriver self, SConnection *pCon) { double hm_time; try { Tango::DeviceAttribute attr_read = hm_proxy->read_attribute("time"); // return data in global hm_data variable attr_read >> hm_time; } catch(Tango::DevFailed &exception) { SCWrite(pCon,"ERROR: Histogram GetData failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); return 0; } return (float)hm_time; } /*-------------------------------------------------------------------------*/ pHistDriver CreateAnstoHM(pStringDict pOpt) { pHistDriver pNew = NULL; /* create the general driver */ pNew = CreateHistDriver(pOpt); if(!pNew) { return NULL; } /* not using private data currently */ pNew->pPriv = NULL; /* configure all those functions */ pNew->Configure = AnstoHMConfig; pNew->Start = AnstoHMStart; pNew->Halt = AnstoHMHalt; pNew->GetCountStatus = AnstoHMGetCountStatus; pNew->GetError = AnstoHMGetError; pNew->TryAndFixIt = AnstoHMTryAndFixIt; pNew->GetData = AnstoHMGetData; pNew->GetHistogram = AnstoHMGetHistogram; pNew->SetHistogram = AnstoHMSetHistogram; pNew->GetMonitor = AnstoHMGetMonitor; pNew->GetTime = AnstoHMGetTime; pNew->Preset = AnstoHMPreset; pNew->FreePrivate = AnstoHMFreePrivate; pNew->Pause = AnstoHMPause; pNew->Continue = AnstoHMContinue; pNew->fCountPreset = 1; StringDictAddPair(pOpt,"device",hm_device); try { hm_proxy = new Tango::DeviceProxy(hm_device); } catch(Tango::DevFailed &exception) { printf("ERROR: New Tango DeviceProxy failed\n"); /* SCWrite(pCon,"ERROR: New Tango DeviceProxy failed",eError); SCWrite(pCon,"Tango error :",eError); SCWrite(pCon,exception.errors[0].desc,eError); */ return 0; } hm_data.resize(10); return pNew; }