//****************************************************************************** // MARTe Library // $Log: ATCAadcDrv.cpp,v $ // Revision 1.48 2010/02/09 14:50:59 ppcc_dev // Significantly increased the PollSleepTimeWakeBeforeUs in order to disallow any // sleeping in online... // // Revision 1.47 2010/01/22 09:29:07 aneto // pollSleepTimeWakeBeforeUs was only being converted to us if not specified // // Revision 1.46 2009/12/15 12:16:51 aneto // Code cleaning // // Revision 1.45 2009/12/03 14:52:13 ppcc_dev // Sleeps, if time is available, before start busy polling. // The time to sleep is given by the remaining time until the start of // the next pulse minus the worst jitter from a sleep and minus the // desired time, before the beginning of the next pulse, that we want to start // busy polling. // The worst jitter decays to zero in order to try to maintain a good performance // // Revision 1.44 2009/09/23 12:21:20 aneto // Cast the header to unsigned int 32 in order to avoid rollover problems // when it changes the bit sign // // Revision 1.43 2009/08/07 09:31:47 aneto // Allow the autoSoftwareTrigger to work even if the softwareTrigger flag // is set to false // // Revision 1.42 2009/06/23 13:44:19 aneto // In Linux wait sometime between header synchronisation // // Revision 1.41 2009/06/09 09:55:28 ppcc_dev // Time is read directly from the board header // // Revision 1.40 2009/05/21 15:18:34 ppcc_dev // DigIO does not have outputMap // // Revision 1.39 2009/04/21 08:48:42 aneto // Channel statistics variable weren't being initialised // // Revision 1.38 2009/04/14 09:06:10 aneto // Allow the system to auto-trigger after a specified amount of time // // Revision 1.37 2009/04/03 10:02:03 aneto // lastCycleUsecTime now is true 64 bits. // This uses the information from the headers to increment an internal counter // // Revision 1.36 2009/04/01 15:10:36 aneto // Bug in the way the modulus was being calculated for the usec time. The bug was in converting from 64 to 32 bits of lastCycleUsecTime // // Revision 1.35 2009/03/31 08:11:37 aneto // Support for multiple input // // Revision 1.34 2009/03/26 15:13:21 aneto // Automatic offset compensation // // Revision 1.33 2009/03/16 11:42:16 aneto // Corrected the polling mode in order to allow different acquisition frequencies // // Revision 1.32 2009/03/11 12:31:54 aneto // Support an html output with information about the driver // // Revision 1.31 2009/01/26 17:26:20 ppcc_dev // Small bugs solved // // Revision 1.30 2009/01/26 09:23:51 aneto // Removed printfs // // Revision 1.29 2009/01/26 09:20:38 aneto // linux support // // Revision 1.28 2009/01/22 13:59:18 aneto // Miror clean up // // Revision 1.27 2008/11/28 12:03:13 aneto // Added bufferNumber // // Revision 1.26 2008/11/21 14:16:42 ppcc_dev // This version works with the new firmware: jet clock+trigger // // Revision 1.24 2008/09/30 11:24:49 rvitelli // Added non-synchronous operating mode. // // Revision 1.23 2008/09/30 10:36:03 ppcc_dev // Minor modifications to both driver and low level module // // Revision 1.22 2008/09/16 13:06:57 fpiccolo // Modified SleepMsec to SleepNoMore to remove jitter on cycle time // // Revision 1.21 2008/09/15 16:51:45 ppcc_dev // Solved few bugs // // Revision 1.20 2008/09/09 11:10:36 fpiccolo // Patch to make it work only with two modules and old firmware // // Revision 1.19 2008/09/09 09:29:15 fpiccolo // Modified driver structure. // Added SingleATCAModule class // Added Writing facilities // // Revision 1.18 2008/09/04 11:48:52 ppcc_dev // Minor modifications to the GETData function. // Removed DisableAcquisition call from the ObjectLoadSetup function // since was causing a crash. // // Revision 1.17 2008/08/19 12:43:29 ppcc_dev // Corrected memory addresses in memcpy, added simulation code for SoftTrigger // // Revision 1.16 2008/08/15 10:41:35 fpiccolo // Minor stylish modifications. // Added TimeModule Interface // // Revision 1.15 2008/08/01 14:09:26 rvitelli // First working version // // Revision 1.14 2008/07/28 13:50:05 aneto // Added support for multiple boards. // //****************************************************************************** #include "ATCAadcDrv.h" #include "ConfigurationDataBase.h" #include "CDBExtended.h" #include "HRT.h" #include "Sleep.h" #include "Console.h" int32 SingleATCAModule::currentDMABufferIndex = 0; int32 SingleATCAModule::currentMasterHeader = 0; #ifdef _LINUX int32 ATCAadcDrv::pageSize = 0; int32 ATCAadcDrv::fileDescriptor = 0; #endif SingleATCAModule::SingleATCAModule(){ moduleIdentifier = 0; numberOfAnalogueInputChannels = 0; numberOfDigitalInputChannels = 0; numberOfAnalogueOutputChannels = 0; numberOfDigitalOutputChannels = 0; int i = 0; for(i = 0; i < 8; i++)outputMap[i] = 0; // Input Section // isMaster = False; for(i = 0; i < 4; i++)dmaBuffers[i] = NULL; nextExpectedAcquisitionCPUTicks = 0; boardInternalCycleTicks = 0; datagramArrivalFastMonitorSecSleep = 0.0; boardInternalCycleTime = 0; lastCycleUsecTime = 0; packetCounter = 0; synchronizing = False; channelStatistics = NULL; allowPollSleeping = True; worstPollSleepJitter = 0; worstPollSleepJitterDecayRate = (1 - 5e-6); pollSleepTime = 0; pollSleepTimeWakeBeforeUs = 20; } bool SingleATCAModule::ObjectLoadSetup(ConfigurationDataBase &info,StreamInterface *err){ CDBExtended cdb(info); FString moduleName; cdb->NodeName(moduleName); if(!cdb.ReadInt32(moduleIdentifier, "ModuleIdentifier")){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: ModuleIdentifier has not been specified."); return False; } int32 master = 0; cdb.ReadInt32(master, "IsMaster",0); isMaster = (master != 0); if(isMaster){ CStaticAssertErrorCondition(Information,"SingleATCAModule::ObjectLoadSetup: Module with identifier %d has been specified as master.", moduleIdentifier); } synchronizing = False; if (isMaster) { FString syncMethod; if(!cdb.ReadFString(syncMethod, "SynchronizationMethod")){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: SynchronizationMethod has not been specified."); return False; } if (syncMethod == "GetLatest") { synchronizing = False; CStaticAssertErrorCondition(Information,"SingleATCAModule::ObjectLoadSetup: synchronization method: GetLatest"); } else { synchronizing = True; CStaticAssertErrorCondition(Information,"SingleATCAModule::ObjectLoadSetup: synchronization method: Synchronous on input"); } } if(!cdb.ReadInt32(numberOfAnalogueInputChannels, "NumberOfAnalogueInput")){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfAnalogueInput has not been specified."); return False; } if(!cdb.ReadInt32(numberOfDigitalInputChannels, "NumberOfDigitalInput")){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfDigitalInput has not been specified."); return False; } if(!cdb.ReadInt32(numberOfAnalogueOutputChannels, "NumberOfAnalogueOutput")){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfAnalogueOutput has not been specified."); return False; } if(!cdb.ReadInt32(numberOfDigitalOutputChannels, "NumberOfDigitalOutput")){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfDigitalOutput has not been specified."); return False; } int32 detectedNumberOfInputAnalogChannels = 0; #ifdef _RTAI detectedNumberOfInputAnalogChannels = GetNumberOfInputAnalogChannels(moduleIdentifier); #elif defined(_LINUX) int32 temp = moduleIdentifier; int32 ret = ioctl(ATCAadcDrv::fileDescriptor, PCIE_ATCA_ADC_IOCT_N_IN_ANA_CHANNELS, &temp); if(ret != 0){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: Could not query number of analog input channels. ioctl returned : %d", ret); return False; } detectedNumberOfInputAnalogChannels = temp; #endif if(numberOfAnalogueInputChannels > detectedNumberOfInputAnalogChannels){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfAnalogueInputs is at most %d. Specified %d.", detectedNumberOfInputAnalogChannels, numberOfAnalogueInputChannels); return False; } int32 detectedNumberOfInputDigitalChannels = 0; #ifdef _RTAI detectedNumberOfInputDigitalChannels = GetNumberOfInputDigitalChannels(moduleIdentifier); #elif defined(_LINUX) temp = moduleIdentifier; ret = ioctl(ATCAadcDrv::fileDescriptor, PCIE_ATCA_ADC_IOCT_N_IN_DIG_CHANNELS, &temp); if(ret != 0){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: Could not query number of digital input channels. ioctl returned : %d", ret); return False; } detectedNumberOfInputDigitalChannels = temp; #endif if(numberOfDigitalInputChannels > detectedNumberOfInputDigitalChannels){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfDigitalInputs is at most %d. Specified %d.", detectedNumberOfInputDigitalChannels, numberOfDigitalInputChannels); return False; } int32 detectedNumberOfOutputAnalogChannels = 0; #ifdef _RTAI detectedNumberOfOutputAnalogChannels = GetNumberOfAnalogueOutputChannels(moduleIdentifier); #elif defined(_LINUX) temp = moduleIdentifier; ret = ioctl(ATCAadcDrv::fileDescriptor, PCIE_ATCA_ADC_IOCT_N_OUT_ANA_CHANNELS, &temp); if(ret != 0){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: Could not query number of analog output channels. ioctl returned : %d", ret); return False; } detectedNumberOfOutputAnalogChannels = temp; #endif if(numberOfAnalogueOutputChannels > detectedNumberOfOutputAnalogChannels){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfAnalogueOutputs is at most %d. Specified %d.", detectedNumberOfOutputAnalogChannels, numberOfAnalogueOutputChannels); return False; } int32 detectedNumberOfDigitalOutputChannels = 0; #ifdef _RTAI detectedNumberOfDigitalOutputChannels = GetNumberOfDigitalOutputChannels(moduleIdentifier); #elif defined(_LINUX) temp = moduleIdentifier; ret = ioctl(ATCAadcDrv::fileDescriptor, PCIE_ATCA_ADC_IOCT_N_OUT_DIG_CHANNELS, &temp); if(ret != 0){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: Could not query number of digital output channels. ioctl returned : %d", ret); return False; } detectedNumberOfDigitalOutputChannels = temp; #endif if(numberOfDigitalOutputChannels > detectedNumberOfDigitalOutputChannels){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: NumberOfAnalogueOutputs is at most %d. Specified %d.", detectedNumberOfDigitalOutputChannels, numberOfAnalogueOutputChannels); return False; } if(numberOfAnalogueOutputChannels > 0){ bool hasRTM = False; #ifdef _RTAI hasRTM = IsRTMPresent(moduleIdentifier); #elif defined(_LINUX) int rtm = moduleIdentifier; ret = ioctl(ATCAadcDrv::fileDescriptor, PCIE_ATCA_ADC_IOCT_IS_RTM_PRESENT, &rtm); if(ret != 0){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: Could not query IsRTMPresent. ioctl returned : %d", ret); return False; } hasRTM = (rtm == 1); #endif if(!hasRTM){ CStaticAssertErrorCondition(Warning,"SingleATCAModule::ObjectLoadSetup: Module %d specifies %d outputs but does not have RTM module", moduleIdentifier, numberOfAnalogueOutputChannels); return False; } int dims = 1; int size[2] = {numberOfAnalogueOutputChannels,1}; if(!cdb.ReadInt32Array(outputMap, size, dims, "OutputMap")){ CStaticAssertErrorCondition(Warning,"SingleATCAModule::ObjectLoadSetup: OutputMap not specified. Assuming sequential order."); for(int i = 0; i < numberOfAnalogueOutputChannels; i++) outputMap[i] = i+1; } // output order starts from 0 for convenience. for(int i = 0; i < numberOfAnalogueOutputChannels; i++) outputMap[i]--; } if(channelStatistics != NULL){ delete[] channelStatistics; channelStatistics = NULL; } channelStatistics = new StatSignalInfo[NumberOfInputChannels()]; if(channelStatistics == NULL){ CStaticAssertErrorCondition(InitialisationError,"SingleATCAModule::ObjectLoadSetup: Could not create ChannelStatistics for %d channels", NumberOfInputChannels()); return False; } for(int i=0; i *latestBufferHeader)) { latestBufferHeader = header; latestBufferIndex = dmaIndex; } } return latestBufferIndex; } int32 SingleATCAModule::CurrentBufferIndex(){ uint32 *oldestBufferHeader = (uint32 *)dmaBuffers[0]; uint32 oldestBufferIndex = 0; int64 stopAcquisition = HRT::HRTCounter() + dataAcquisitionUsecTimeOut; // check which one is the oldest buffer int dmaIndex = 0; for (dmaIndex = 1; dmaIndex < DMA_BUFFS; dmaIndex++) { // Pointer to the header uint32 *header = (uint32 *)dmaBuffers[dmaIndex]; if (*header < *oldestBufferHeader) { oldestBufferHeader = header; oldestBufferIndex = dmaIndex; } } uint32 *oldestBufferFooter = oldestBufferHeader + NumberOfInputChannels() + HEADER_LENGTH; uint32 oldestTimeMark = *oldestBufferFooter; // If the data transfer is not in progress it means that the new data will // be stored in the oldest buffer. int64 actualTime = HRT::HRTCounter(); while (oldestTimeMark == *oldestBufferFooter) { if(actualTime > stopAcquisition) { return -1; } actualTime = HRT::HRTCounter(); } if(*oldestBufferHeader == *oldestBufferFooter) return oldestBufferIndex; return -2; } bool SingleATCAModule::WriteData(const int32 *&buffer){ for(int i = 0; i < numberOfAnalogueOutputChannels; i++){ #ifdef _LINUX int32 toWrite[4]; toWrite[0] = moduleIdentifier; toWrite[1] = outputMap[i]; toWrite[2] = *buffer++; toWrite[3] = 0; write(ATCAadcDrv::fileDescriptor, toWrite, 4 * sizeof(int32)); #else WriteToDAC(moduleIdentifier, outputMap[i], *buffer++); #endif } for(int i = 0; i < numberOfDigitalOutputChannels; i++){ #ifdef _LINUX int32 toWrite[4]; toWrite[0] = moduleIdentifier; toWrite[1] = 0; toWrite[2] = *buffer++; toWrite[3] = 1; if(write(ATCAadcDrv::fileDescriptor, toWrite, 4 * sizeof(int32)) < 0){ CStaticAssertErrorCondition(FatalError,"SingleATCAModule::WriteData: Could not write the value : %d to module %d", toWrite[2], toWrite[0]); return False; } #else WriteToDIO(moduleIdentifier, 0, *buffer++); #endif } return True; } bool SingleATCAModule::Poll(){ #ifdef _LINUX static int firstTime = 1; if(firstTime == 1){ SleepSec(1e-3); firstTime = 0; } #endif if(isMaster){ if (synchronizing) { if(allowPollSleeping) { //Allow the worstPollSleepJitter to decay -> 0 worstPollSleepJitter *= worstPollSleepJitterDecayRate; int64 tStart = HRT::HRTCounter(); pollSleepTime = (nextExpectedAcquisitionCPUTicks - tStart) * HRT::HRTPeriod() - pollSleepTimeWakeBeforeUs - worstPollSleepJitter; if(pollSleepTime > 0){ SleepNoMore(pollSleepTime); float jitter = ((HRT::HRTCounter() - tStart) * HRT::HRTPeriod()) - pollSleepTime; if(jitter < 0) jitter = -jitter; if(jitter > worstPollSleepJitter){ worstPollSleepJitter = jitter; } } } int32 previousAcquisitionIndex = currentDMABufferIndex; int32 currentDMA = CurrentBufferIndex(); if(currentDMA < 0){ CStaticAssertErrorCondition(Warning,"SingleATCAModule::GetData: Returned -1"); return False; } currentDMABufferIndex = currentDMA; // Update NextExecTime with a guess nextExpectedAcquisitionCPUTicks = HRT::HRTCounter() + boardInternalCycleTicks; int deltaBuffer = *dmaBuffers[currentDMABufferIndex] - *dmaBuffers[previousAcquisitionIndex]; int nOfLostPackets = deltaBuffer - boardInternalCycleTime; if( *dmaBuffers[currentDMABufferIndex] == 0){ printf("dmaBuffers[currentDMABufferIndex]: %d, *dmaBuffers[previousAcquisitionIndex = %d\n", *dmaBuffers[currentDMABufferIndex], *dmaBuffers[previousAcquisitionIndex]); } if (( nOfLostPackets > 0)){ CStaticAssertErrorCondition(Warning,"SingleATCAModule::GetData: Lost %d Packets", nOfLostPackets / boardInternalCycleTime); CStaticAssertErrorCondition(Warning,"SingleATCAModule::GetData: boardInternalCycleTime %d, deltaBuffer: %d", boardInternalCycleTime, deltaBuffer); } currentMasterHeader = *(dmaBuffers[currentDMABufferIndex]); lastCycleUsecTime = (uint32)currentMasterHeader; } return True; } return False; } bool SingleATCAModule::GetData(int32 *&buffer){ /** Perform synchronisation */ if(isMaster){ if (synchronizing) { buffer[0] = *dmaBuffers[currentDMABufferIndex]; buffer[1] = buffer[0]; // Skip the packet sample number and sample time buffer += 2; currentMasterHeader = *(dmaBuffers[currentDMABufferIndex]); lastCycleUsecTime = (uint32)currentMasterHeader; } else { currentDMABufferIndex = GetLatestBufferIndex(); } }else{ int32 *header = dmaBuffers[currentDMABufferIndex]; int32 *footer = header + NumberOfInputChannels() + HEADER_LENGTH; if(*header != currentMasterHeader){ CStaticAssertErrorCondition(FatalError, "SingleATCAModule (slot=%d)::GetData: h (=%d) different from master h(=%d)", moduleIdentifier, *header, currentMasterHeader); return False; } if(*header != *footer){ CStaticAssertErrorCondition(FatalError, "SingleATCAModule (slot=%d)::GetData: The header (=%d) is different from the footer(=%d)", moduleIdentifier, *header, *footer); return False; } } // Skip the Header in the DMA Buffer int32 *src = (int32 *)dmaBuffers[currentDMABufferIndex] + 1; int32 *dest = buffer; memcpy(dest, src, NumberOfInputChannels()*sizeof(int32)); //This is introducing a huge delay (~1.5us per board). To be solved. /*for(int i=0; i\n"); hStream.Printf("\n"); hStream.Printf("Module Identifier%d\n", moduleIdentifier); hStream.Printf("\n"); hStream.Printf("\n"); hStream.Printf("Master%s\n", isMaster ? "True" : "False"); hStream.Printf("\n"); hStream.Printf("\n"); hStream.Printf("\n"); hStream.Printf("\n"); int i=0; for(i=0; i\n", i + 1, channelStatistics[i].LastValue(), channelStatistics[i].Mean(10), channelStatistics[i].Variance(10), channelStatistics[i].AbsMax(), channelStatistics[i].AbsMin(), channelStatistics[i].RelMax(), channelStatistics[i].RelMin()); } hStream.Printf("
ChannelLastMeanVarianceAbs MaxAbs MinRel MaxRel Min
%d%.3e%.3e%.3e%.3e%.3e%.3e%.3e
"); return True; } bool SingleATCAModule::ResetStatistics(){ int i=0; for(i=0; i 0); if(autoSoftwareTrigger){ CStaticAssertErrorCondition(Information, "ATCAadcDrv::ObjectLoadSetup: %s the system will be automatically triggered after %d us", Name(), autoSoftwareTriggerAfterUs); } // Get buffer address from the driver exported function GetBufferAddress (only works in RTAI!) #ifdef _RTAI numberOfBoards = GetNumberOfBoards(); #elif defined(_LINUX) int ret = ioctl(fileDescriptor, PCIE_ATCA_ADC_IOCT_NUM_BOARDS, &numberOfBoards); if(ret != 0){ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Could not query the number of boards. ioctl returned : %d",Name(), ret); return False; } mappedDmaMemorySize = numberOfBoards * DMA_BUFFS * pageSize; mappedDmaMemoryLocation = (int32 *)mmap(0, mappedDmaMemorySize, PROT_READ, MAP_FILE | MAP_SHARED | MAP_LOCKED | MAP_POPULATE | MAP_NONBLOCK, fileDescriptor, 0); if(mappedDmaMemoryLocation == MAP_FAILED) { AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: MAP_FAILED",Name()); return False; } #else numberOfBoards = -1; #endif if(!cdb->Move( "Modules")){ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: No Module has been specified",Name()); return False; } int32 nOfATCAModules = cdb->NumberOfChildren(); if(nOfATCAModules!= numberOfBoards){ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Number of installed boards [%d] differs from the number of specified boards [%d].",Name(),numberOfBoards,nOfATCAModules); return False; } if(modules != NULL) delete[] modules; modules = new SingleATCAModule[nOfATCAModules]; if(modules == NULL){ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Failed allocating space for %d modules.",Name(),nOfATCAModules); return False; } masterBoardIdx = -1; for(int i = 0; i < nOfATCAModules; i++){ cdb->MoveToChildren(i); cdb.WriteFString(syncMethod,"SynchronizationMethod"); if(!modules[i].ObjectLoadSetup(cdb,err)){ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Failed initialising module %d.",Name(),i); delete[] modules; return False; } if(modules[i].isMaster){ if(masterBoardIdx == -1){ masterBoardIdx = i; }else{ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Failed initialising module %d. A master board was already specified at index: %d",Name(),i,masterBoardIdx); return False; } } cdb->MoveToFather(); } for(int i = 0; i < nOfATCAModules; i++){ #ifdef _LINUX if(!modules[i].InstallDMABuffers(mappedDmaMemoryLocation)){ #else if(!modules[i].InstallDMABuffers()){ #endif AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Board %d failed to initialise DMA buffers",Name(), i); return False; } } cdb->MoveToFather(); int32 extTriggerAndClock = 0; if(!cdb.ReadInt32(extTriggerAndClock, "ExtTriggerAndClock",1)){ AssertErrorCondition(Warning,"ATCAadcDrv::ObjectLoadSetup: %s: ExtTriggerAndClock not specified, using default = %d",Name(), extTriggerAndClock); } #ifdef _LINUX ret = ioctl(fileDescriptor, PCIE_ATCA_ADC_IOCT_SET_EXT_CLK_TRG, &extTriggerAndClock); if(ret != 0){ AssertErrorCondition(InitialisationError,"ATCAadcDrv::ObjectLoadSetup: %s: Could not SetATCApcieExternalTriggerAndClock. ioctl returned : %d",Name(), ret); return False; } #else SetATCApcieExternalTriggerAndClock(extTriggerAndClock); #endif // Setup OK AssertErrorCondition(Information,"ATCAadcDrv::ObjectLoadSetup: %s: initialized correctly ",Name()); EnableAcquisition(); return True; } bool ATCAadcDrv::ObjectDescription(StreamInterface &s,bool full,StreamInterface *err){ s.Printf("%s %s\n",ClassName(),Version()); return True; } bool ATCAadcDrv::WriteData(uint32 usecTime, const int32 *buffer){ if(buffer == NULL) return False; const int32 *lBuffer = buffer; for(int i = 0; i < numberOfBoards; i++){ modules[i].WriteData(lBuffer); } return True; } int32 ATCAadcDrv::GetData(uint32 usecTime, int32 *buffer, int32 bufferNum){ //Check buffer existence if(buffer == NULL){ AssertErrorCondition(FatalError,"ATCAadcDrv::GetData: %s. The DDInterface buffer is NULL.",Name()); return -1; } int32 *lBuffer = buffer; for(int i = 0; i < numberOfBoards; i++){ if(!modules[i].GetData(lBuffer)){ AssertErrorCondition(FatalError,"ATCAadcDrv::GetData: %s. Module %d failed acquiring data",Name(),i); return -1; } } return 1; } bool ATCAadcDrv::Poll(){ if(autoSoftwareTrigger){ if(lastCycleUsecTime > autoSoftwareTriggerAfterUs){ SoftwareTrigger(); } } bool ok = modules[masterBoardIdx].Poll(); if(!ok){ return ok; } // If the module is the timingATMDrv call the Trigger() method of // the time service object lastCycleUsecTime = modules[masterBoardIdx].lastCycleUsecTime; for(int i = 0; i < nOfTriggeringServices; i++){ triggerService[i].Trigger(); } return ok; } bool ATCAadcDrv::ProcessHttpMessage(HttpStream &hStream) { hStream.SSPrintf("OutputHttpOtions.Content-Type","text/html"); hStream.keepAlive = False; //copy to the client hStream.Printf("%s", Name()); hStream.Printf( "\n" ); hStream.Printf("\n"); int i=0; hStream.Printf("\n"); for(i=0; i%d\n", modules[i].BoardIdentifier()); } hStream.Printf("\n"); hStream.Printf("\n"); for(i=0; i%s\n", modules[i].isMaster ? "M" : ""); } hStream.Printf("\n"); hStream.Printf("\n"); for(i=0; i%s\n", modules[i].NumberOfOutputChannels() > 0 ? "R" : ""); } hStream.Printf("\n"); hStream.Printf("\n"); hStream.Printf("\n"); for(i=0; i\n", modules[i].BoardIdentifier()); } hStream.Printf("\n"); hStream.Printf("\n"); hStream.Printf("
\n"); hStream.Printf("
\n"); hStream.Printf("\n"); hStream.Printf("
\n"); FString reqBoardID; reqBoardID.SetSize(0); if (hStream.Switch("InputCommands.boardID")){ hStream.Seek(0); hStream.GetToken(reqBoardID, ""); hStream.Switch((uint32)0); } FString reqReset; reqReset.SetSize(0); if (hStream.Switch("InputCommands.reset")){ hStream.Seek(0); hStream.GetToken(reqReset, ""); hStream.Switch((uint32)0); } if(reqReset.Size() > 0){ for(i=0; i 0){ int32 boardID = atoi(reqBoardID.Buffer()); for(i=0; iWorst polling jitter (us): %f\n", modules[masterBoardIdx].worstPollSleepJitter * 1e6); hStream.Printf("

Last polling sleep time (us): %f", modules[masterBoardIdx].pollSleepTime * 1e6); hStream.Printf(""); hStream.WriteReplyHeader(True); return True; } OBJECTLOADREGISTER(ATCAadcDrv,"$Id: ATCAadcDrv.cpp,v 1.48 2010/02/09 14:50:59 ppcc_dev Exp $")