409 lines
12 KiB
C++
409 lines
12 KiB
C++
//******************************************************************************
|
|
// MARTe Library
|
|
// $Log: ATCAadcDrv.h,v $
|
|
// Revision 1.32 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.31 2009/08/07 09:31:47 aneto
|
|
// Allow the autoSoftwareTrigger to work even if the softwareTrigger flag
|
|
// is set to false
|
|
//
|
|
// Revision 1.30 2009/05/21 15:18:37 ppcc_dev
|
|
// DigIO does not have outputMap
|
|
//
|
|
// Revision 1.29 2009/04/14 09:06:10 aneto
|
|
// Allow the system to auto-trigger after a specified amount of time
|
|
//
|
|
// Revision 1.28 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.27 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.26 2009/03/16 11:42:16 aneto
|
|
// Corrected the polling mode in order to allow different acquisition frequencies
|
|
//
|
|
// Revision 1.25 2009/03/11 12:31:54 aneto
|
|
// Support an html output with information about the driver
|
|
//
|
|
// Revision 1.24 2009/01/26 17:26:20 ppcc_dev
|
|
// Small bugs solved
|
|
//
|
|
// Revision 1.23 2009/01/26 09:20:38 aneto
|
|
// linux support
|
|
//
|
|
// Revision 1.22 2008/11/28 12:03:13 aneto
|
|
// Added bufferNumber
|
|
//
|
|
// Revision 1.21 2008/11/21 14:16:52 ppcc_dev
|
|
// This version works with the new firmware: jet clock+trigger
|
|
//
|
|
// Revision 1.19 2008/09/30 11:24:49 rvitelli
|
|
// Added non-synchronous operating mode.
|
|
//
|
|
// Revision 1.18 2008/09/22 17:20:36 fpiccolo
|
|
// Solved minor bugs
|
|
//
|
|
// Revision 1.17 2008/09/15 16:51:45 ppcc_dev
|
|
// Solved few bugs
|
|
//
|
|
// Revision 1.16 2008/09/09 09:29:15 fpiccolo
|
|
// Modified driver structure.
|
|
// Added SingleATCAModule class
|
|
// Added Writing facilities
|
|
//
|
|
// Revision 1.15 2008/08/20 16:34:36 ppcc_dev
|
|
// Added PulseStart to reset the internal counter to 0 when using the SoftTrigger option
|
|
//
|
|
// Revision 1.14 2008/08/15 10:41:35 fpiccolo
|
|
// Minor stylish modifications.
|
|
// Added TimeModule Interface
|
|
//
|
|
// Revision 1.13 2008/08/01 14:09:28 rvitelli
|
|
// First working version
|
|
//
|
|
//******************************************************************************
|
|
|
|
#ifndef ATCAADCDRV_H_
|
|
#define ATCAADCDRV_H_
|
|
|
|
#include "System.h"
|
|
#include "GenericAcqModule.h"
|
|
#include "FString.h"
|
|
#include "pcieAdc.h"
|
|
#include "pcieAdc_ioctl.h"
|
|
#ifdef _LINUX
|
|
#include <sys/mman.h>
|
|
#endif
|
|
#include "WebStatisticGAM.h"
|
|
|
|
class SingleATCAModule{
|
|
private:
|
|
/** Module Identifier */
|
|
int32 moduleIdentifier;
|
|
|
|
/** Number of Analogue Input channels for this module (Maximum 32)*/
|
|
int32 numberOfAnalogueInputChannels;
|
|
|
|
/** Number of Digital Input channels for this module (1 or 0) */
|
|
int32 numberOfDigitalInputChannels;
|
|
|
|
/** Number of Analogue Output channels (Maximum 8) */
|
|
int32 numberOfAnalogueOutputChannels;
|
|
|
|
/** Number of Digital Output channels () */
|
|
int32 numberOfDigitalOutputChannels;
|
|
|
|
/** Output Map. Used to map the output to a specific physical
|
|
output channel. Channels are identified from 1 to 8. */
|
|
int32 outputMap[8];
|
|
|
|
|
|
////////////////////////////
|
|
// Analogue Input Section //
|
|
////////////////////////////
|
|
|
|
/** If true synchronize on data arrival, if false return latest completed buffer */
|
|
bool synchronizing;
|
|
|
|
/** Pointers to the DMA memory allocated for data acquisition.
|
|
The number of buffers is fixed to 4.
|
|
*/
|
|
int32 *dmaBuffers[DMA_BUFFS];
|
|
|
|
/** Current DMA buffer index [0-3]. */
|
|
static int32 currentDMABufferIndex;
|
|
|
|
/** The current master header (must be the same in all the boards) */
|
|
static int32 currentMasterHeader;
|
|
|
|
/** Estimated time of the next expected arrival in CPU Ticks of the acquired buffer.
|
|
It is computed by adding a delay specified @param periodUsecSleep to
|
|
the time of the previous completed acquisition. The system will sleep
|
|
till this time elapses.
|
|
*/
|
|
int64 nextExpectedAcquisitionCPUTicks;
|
|
|
|
/** Specifies how long to sleep between acquisitions. It is specified in microseconds
|
|
but it is internally converted in CPU ticks to avoid unecessary computations during
|
|
realtime activities.
|
|
*/
|
|
int64 boardInternalCycleTicks;
|
|
|
|
/** Amount of time in microseconds after which the data stops waiting for data arrival
|
|
and reports an acquisition error.
|
|
*/
|
|
int64 dataAcquisitionUsecTimeOut;
|
|
|
|
/** Length of a "Short Sleep" in seconds. It is used to monitor
|
|
the data arrival on the master board and specifies a sleep time
|
|
between checks of the data datagram arrival.
|
|
*/
|
|
float datagramArrivalFastMonitorSecSleep;
|
|
|
|
/** The number of micro seconds incremented by the board in each cycle. It gives the board acquisition frequency.
|
|
*/
|
|
int32 boardInternalCycleTime;
|
|
|
|
/**
|
|
* The statistics info for these channels
|
|
*/
|
|
StatSignalInfo *channelStatistics;
|
|
|
|
/** Find the currentDMABufferIndex and synchronize on data arrival
|
|
|
|
*/
|
|
int32 CurrentBufferIndex();
|
|
|
|
/** Find the latest completed buffer without synchronization*/
|
|
int32 GetLatestBufferIndex();
|
|
|
|
public:
|
|
|
|
SingleATCAModule();
|
|
|
|
/** Initialises the SingleModule Parameter*/
|
|
bool ObjectLoadSetup(ConfigurationDataBase &info,StreamInterface *err = NULL);
|
|
|
|
/** Reads NumberOfInputChannels() from the DMA Buffer.
|
|
The first module must be the master board to assure
|
|
correct data transfer.
|
|
*/
|
|
bool GetData(int32 *&buffer);
|
|
|
|
bool WriteData(const int32 *&buffer);
|
|
|
|
/** Copies the pointers to the DMA Buffers */
|
|
#ifdef _LINUX
|
|
bool InstallDMABuffers(int32 *mappedDmaMemoryLocation);
|
|
#else
|
|
/** Copies the pointers to the DMA Buffers */
|
|
bool InstallDMABuffers();
|
|
#endif
|
|
|
|
/////////////////
|
|
// Time Module //
|
|
/////////////////
|
|
|
|
int64 lastCycleUsecTime;
|
|
|
|
int32 packetCounter;
|
|
|
|
/** Is Master Board */
|
|
bool isMaster;
|
|
|
|
|
|
/** Returns the sum of analogue and digital input channels */
|
|
int32 NumberOfInputChannels(){
|
|
return numberOfDigitalInputChannels + numberOfAnalogueInputChannels;
|
|
}
|
|
|
|
/** Returns the sum of analogue and digital output channels */
|
|
int32 NumberOfOutputChannels(){
|
|
return numberOfDigitalOutputChannels + numberOfAnalogueOutputChannels;
|
|
}
|
|
|
|
/** Returns the module Identifier */
|
|
int32 BoardIdentifier(){return moduleIdentifier;}
|
|
|
|
/**
|
|
* Output an HTML table with the current value in mV of the acquired signals for this board
|
|
*/
|
|
virtual bool ProcessHttpMessage(HttpStream &hStream);
|
|
/**
|
|
* Resets the statistics
|
|
*/
|
|
bool ResetStatistics();
|
|
/**
|
|
* Polling method
|
|
*/
|
|
virtual bool Poll();
|
|
/**
|
|
* Allow sleeping, when enough time is available, before start polling
|
|
*/
|
|
bool allowPollSleeping;
|
|
/**
|
|
* Time to sleep before hard polling: pollSleepTime = CycleTime - time left to cycle time - pollSleepTimeWakeBeforeUs - worstPollSleepJitter;
|
|
*/
|
|
float pollSleepTime;
|
|
/**
|
|
* Actually we want to start polling some us before reaching the cycle time
|
|
*/
|
|
float pollSleepTimeWakeBeforeUs;
|
|
/**
|
|
* The worst jitter calculated in realtime of the actual time slept before polling and time meant to sleep
|
|
*/
|
|
float worstPollSleepJitter;
|
|
/**
|
|
* The worst jitter will try to be recovered with a certain rate
|
|
*/
|
|
float worstPollSleepJitterDecayRate;
|
|
};
|
|
|
|
|
|
|
|
|
|
OBJECT_DLL(ATCAadcDrv)
|
|
/** The high level driver for the ATCA ADC module */
|
|
class ATCAadcDrv:public GenericAcqModule{
|
|
private:
|
|
|
|
/** Number of boards in the crate. Read during Initialisation */
|
|
int32 numberOfBoards;
|
|
|
|
/** Pointers to the ATCA modules */
|
|
SingleATCAModule *modules;
|
|
|
|
/** Last cycle usec time */
|
|
int64 lastCycleUsecTime;
|
|
|
|
/** */
|
|
bool synchronizing;
|
|
|
|
/** Software triggered acquisition.
|
|
0, which is the default value, means hardware trigger.
|
|
*/
|
|
int32 softwareTrigger;
|
|
|
|
/** The master board index
|
|
*/
|
|
int32 masterBoardIdx;
|
|
|
|
/** If set to true the a software trigger will be sent every
|
|
* AutoSoftwareTriggerAfterUs microseconds. For this to be
|
|
* true the value of AutoSoftwareTriggerAfterUs in the configuration file
|
|
* must be > 1
|
|
*/
|
|
bool autoSoftwareTrigger;
|
|
int32 autoSoftwareTriggerAfterUs;
|
|
|
|
#ifdef _LINUX
|
|
/** Used only in Linux. The mmapped memory location.*/
|
|
int32 *mappedDmaMemoryLocation;
|
|
int32 mappedDmaMemorySize;
|
|
#endif
|
|
/** The css for this page
|
|
*/
|
|
const char *css;
|
|
|
|
public:
|
|
|
|
#ifdef _LINUX
|
|
/**The page size*/
|
|
static int32 pageSize;
|
|
|
|
/**The file descriptor to access the driver*/
|
|
static int32 fileDescriptor;
|
|
#endif
|
|
|
|
// (De)Constructor
|
|
ATCAadcDrv();
|
|
|
|
virtual ~ATCAadcDrv(){
|
|
if(modules != NULL) delete[] modules;
|
|
#ifdef _LINUX
|
|
munmap(mappedDmaMemoryLocation, mappedDmaMemorySize);
|
|
close(fileDescriptor);
|
|
#endif
|
|
}
|
|
|
|
// Standard GAM methods
|
|
/* Load setup from CDB.
|
|
This IOGAM peculiar parameters are PeriodSleep_usec and FastSleep_usec.
|
|
@param info: CDB from which load data
|
|
@param err: not used
|
|
@returns true if all ok*/
|
|
virtual bool ObjectLoadSetup(ConfigurationDataBase &info,StreamInterface *err);
|
|
|
|
/* Print internal GAM informations
|
|
@param s: StreamInterface in which print infos
|
|
@param full: not used
|
|
@param err: not used
|
|
@returns true if all ok*/
|
|
virtual bool ObjectDescription(StreamInterface &s,bool full = False, StreamInterface *err=NULL);
|
|
|
|
/* Saves the data into the DDB
|
|
@param usecTime: not used
|
|
@param buffer: pointer to the data buffer to be filled
|
|
@returns 1 if all ok*/
|
|
int32 GetData(uint32 usecTime, int32 *buffer, int32 bufferNum = 0);
|
|
|
|
bool WriteData(uint32 usecTime, const int32 *buffer);
|
|
|
|
// Set board used as input
|
|
virtual bool SetInputBoardInUse(bool on = False){
|
|
if(inputBoardInUse && on){
|
|
AssertErrorCondition(InitialisationError, "ATCAadcDrv::SetInputBoardInUse: Board %s is already in use", Name());
|
|
return False;
|
|
}
|
|
inputBoardInUse = on;
|
|
return True;
|
|
}
|
|
|
|
virtual bool SetOutputBoardInUse(bool on = False){
|
|
if(outputBoardInUse && on){
|
|
AssertErrorCondition(InitialisationError, "ATCAadcDrv::SetOutputBoardInUse: Board %s is already in use", Name());
|
|
return False;
|
|
}
|
|
outputBoardInUse = on;
|
|
return True;
|
|
}
|
|
|
|
virtual bool EnableAcquisition();
|
|
|
|
virtual bool DisableAcquisition();
|
|
|
|
//////////////////////
|
|
// From Time Module //
|
|
//////////////////////
|
|
|
|
// Get the Time
|
|
int64 GetUsecTime(){return lastCycleUsecTime;}
|
|
|
|
bool SoftwareTrigger(){
|
|
if(modules == NULL)return False;
|
|
#ifdef _RTAI
|
|
SendSoftwareTrigger();
|
|
#elif defined(_LINUX)
|
|
int ret = ioctl(fileDescriptor, PCIE_ATCA_ADC_IOCT_SEND_SOFT_TRG);
|
|
if(ret != 0){
|
|
AssertErrorCondition(InitialisationError,"ATCAadcDrv::PulseStart: Could send software trigger. ioctl returned : %d",ret);
|
|
return False;
|
|
}
|
|
#endif
|
|
return True;
|
|
}
|
|
|
|
|
|
//////////////////////////////////
|
|
// Simulation Purpose Functions //
|
|
//////////////////////////////////
|
|
|
|
bool PulseStart(){
|
|
if(modules == NULL)return False;
|
|
if(softwareTrigger == 1){
|
|
return SoftwareTrigger();
|
|
}
|
|
return True;
|
|
}
|
|
|
|
/**
|
|
* Output an HTML page with the current value in mV of the acquired signals
|
|
*/
|
|
virtual bool ProcessHttpMessage(HttpStream &hStream);
|
|
/**
|
|
* Polling method
|
|
*/
|
|
virtual bool Poll();
|
|
private:
|
|
|
|
OBJECT_DLL_STUFF(ATCAadcDrv);
|
|
};
|
|
#endif /*ATCAADCDRV_H_*/
|