/***************************************************************************** * CTRV custom event source * ***************************************************************************** * Modified: 2009-01-06 HBr * ****************************************************************************/ // // FESA framework October 2004. // // You may update this C++ code. #include "CTRVSource.h" #include #include using namespace SIS3350; CTRVSource::CTRVSource():AbstractEventSource("CTRVSource") { cout << "CTRVSource Ctor" << endl; // Initialize low level timing interface to recieve events from any timing device TimLibError err= TimLibInitialize(TimLibDevice_ANY); if (err != TimLibErrorSUCCESS) { cout << "TimLibInitialize fails: " << TimLibErrorToString(err) << endl; } } CTRVSource::~CTRVSource(){} void CTRVSource::connect(const string& eventName) { cout <<"Now connecting event " << eventName << endl; // connect to direct hardware, module 1 and counter 1+2 interrupts TimLibError err = TimLibConnect(TimLibClassHARDWARE,TimLibHardwareCOUNTER_1|TimLibHardwareCOUNTER_2,1); if (err != TimLibErrorSUCCESS) { string s("TimingEventSource::connect() TimLibConnect error when trying to connect event "); s.append(": "); s.append(TimLibErrorToString(err)); throw FesaBadConfig("Fesa_FWK",err,s.c_str()); } } RTEvent *CTRVSource::wait() { // This custom event-source may fire any of the following events: static char *eventName[] = { "CTRVEvent1", "CTRVEvent2" }; // Rely on POSIX nanosleep which is protected against signals // struct timespec delay, time_left_before_wakeup ; // delay.tv_sec = 5 ; // wake-up every 5 seconds // delay.tv_nsec = 0 ; // nanosleep( &delay, &time_left_before_wakeup ); // RTEventPayload * payload = new RTEventPayload("this is the payload"); // RTEvent* rtEvt = new RTEvent(eventName[0], this, payload ); // any valid eventName[i] // RTEvent* rtEvt = new RTEvent(eventName[0], this, 0 ); // the payload is optional // return rtEvt; // Rely on POSIX nanosleep which is protected against signals struct timespec time_left_before_wakeup; struct timespec delay; delay.tv_sec = 1; // wake-up every 1 seconds delay.tv_nsec = 0; TimLibError err; TimLibClass t_class; /* Class of interrupt */ unsigned long equip; /* PTIM CTIM or hardware mask */ unsigned long plnum; /* Ptim line number 1..n or 0 */ TimLibHardware source; /* Hardware source of interrupt: NOTE this is the counter number (1,2,3,...) and NOT the mask */ TimLibTime onzero; /* Time of interrupt/output */ TimLibTime trigger; /* Time of counters load */ TimLibTime start; /* Time of counters start */ unsigned long ctim; /* CTIM trigger equipment ID */ unsigned long payload = 0; /* Payload of trigger event */ unsigned long module = 0; /* Module that interrupted */ unsigned long missed = 0; /* Number of missed interrupts */ unsigned long qsize = 0; /* Remaining interrupts on queue */ TgmMachine tgmMachine; // This loop is necessary in case of error on TimLib call. For errors other // than TimLibTIMEOUT we have to insert our own delay to avoid to loop // in TimLibCall very fast consuming all CPU time. for(;;) { err = TimLibWait(&t_class, &equip, &plnum, &source, &onzero, &trigger, &start, &ctim, &payload, &module, &missed, &qsize, &tgmMachine); if (err != TimLibErrorSUCCESS) { cout << "TimLibWait: " << err << " - " << TimLibErrorToString(err) << endl; if (err != TimLibErrorTIMEOUT) // Severe error: wait to avoid hogging all CPU time { nanosleep(&delay,&time_left_before_wakeup); } continue; // try again } cout << "TimLibWait: source=" << source << " (" << equip << ")" << endl; //Empty timingContext no cycleStamp TimingContext* tc = new TimingContext(); int event = 0; if ((equip & TimLibHardwareCOUNTER_2) != 0) event = 1; RTEvent* theEvent = new RTEvent(eventName[event],tc,this); return theEvent; } return NULL; } void CTRVSource::consume(RTEvent *evt) { if(evt->getPayload()) delete evt->getPayload(); if(evt->getMultiplexingContext()) delete evt->getMultiplexingContext(); delete evt; }