Transient Recorder Framework
TRBaseDriver.h
Go to the documentation of this file.
1 /* This file is part of the Transient Recorder Framework.
2  * It is subject to the license terms in the LICENSE.txt file found in the
3  * top-level directory of this distribution and at
4  * https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. No part
5  * of the Transient Recorder Framework, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms
7  * contained in the LICENSE.txt file.
8  */
9 
16 #ifndef TRANSREC_BASE_DRIVER_H
17 #define TRANSREC_BASE_DRIVER_H
18 
19 #include <stddef.h>
20 
21 #include <vector>
22 
23 #include <epicsEvent.h>
24 #include <epicsMutex.h>
25 #include <epicsTime.h>
26 #include <epicsMemory.h>
27 
28 #include <asynPortDriver.h>
29 
30 #include "TRArmInfo.h"
31 #include "TRBaseConfig.h"
32 #include "TRBurstMetaInfo.h"
33 #include "TRChannelDataSubmit.h"
34 #include "TRChannelsDriver.h"
35 #include "TRConfigParam.h"
36 #include "TRNonCopyable.h"
37 #include "TRTimeArrayDriver.h"
38 
55 class TRBaseDriver : public asynPortDriver,
56  private TRNonCopyable
57 {
58  template <typename, typename>
59  friend class TRConfigParam;
60 
61  friend class TRChannelsDriver;
62  friend class TRChannelDataSubmit;
63 
64 public:
76  TRBaseDriver (TRBaseConfig const &cfg);
77 
94  template <typename ValueType, typename EffectiveValueType>
96  char const *base_name, EffectiveValueType invalid_value = EffectiveValueType())
97  {
98  param.init(this, base_name, invalid_value, false);
99  }
100 
116  template <typename ValueType, typename EffectiveValueType>
118  char const *base_name, EffectiveValueType invalid_value = EffectiveValueType())
119  {
120  param.init(this, base_name, invalid_value, true);
121  }
122 
133  void completeInit ();
134 
144  {
145  return *m_channels_driver;
146  }
147 
161  void setDigitizerName (char const *name);
162 
174  double getRequestedSampleRate ();
175 
187  void setAchievableSampleRate (double value);
188 
203  inline int getNumBurstsSnapshot ()
204  {
205  return m_param_num_bursts.getSnapshot();
206  }
207 
221  {
222  return m_param_num_post_samples.getSnapshot();
223  }
224 
238  {
239  return m_param_num_pre_post_samples.getSnapshot();
240  }
241 
253  {
254  return m_param_requested_sample_rate.getSnapshot();
255  }
256 
268  {
269  return m_param_achievable_sample_rate.getSnapshot();
270  }
271 
302 
324  void publishBurstMetaInfo (TRBurstMetaInfo const &info);
325 
341  void maybeSleepForTesting ();
342 
355  bool isArmed ();
356 
357 protected:
377 
395  virtual void requestedSampleRateChanged ();
396 
420  virtual bool waitForPreconditions ();
421 
454  virtual bool checkSettings (TRArmInfo &arm_info) = 0;
455 
477  virtual bool startAcquisition (bool overflow) = 0;
478 
506  virtual bool readBurst ();
507 
545  virtual bool checkOverflow (bool *had_overflow, int *num_buffer_bursts);
546 
570  virtual bool processBurstData ();
571 
595  virtual void interruptReading ();
596 
612  virtual void stopAcquisition () = 0;
613 
644  virtual void onDisarmed ();
645 
646 public:
666  virtual asynStatus writeInt32 (asynUser *pasynUser, epicsInt32 value);
667 
677  virtual asynStatus writeFloat64 (asynUser *pasynUser, epicsFloat64 value);
678 
679 private:
680  // Enumeration of asyn parameters of this class, excluding
681  // those managed by TRConfigParam.
682  enum Params {
683  ARM_REQUEST,
684  ARM_STATE,
685  EFFECTIVE_SAMPLE_RATE,
686  BURST_ID,
687  BURST_TIME_BURST,
688  BURST_TIME_READ,
689  BURST_TIME_PROCESS,
690  SLEEP_AFTER_BURST,
691  DIGITIZER_NAME,
692  TIME_ARRAY_UNIT_INV,
693  NUM_BASE_ASYN_PARAMS
694  };
695 
696  // Possible arm states
697  enum ArmState {
698  ArmStateDisarm,
699  ArmStatePostTrigger,
700  ArmStatePrePostTrigger,
701  ArmStateBusy,
702  ArmStateError
703  };
704 
705 private:
706  // Number of channels supported (as passed to constructor).
707  int m_num_channels;
708 
709  // Whether the driver supports pre-samples.
710  bool m_supports_pre_samples;
711 
712  // Whether copies of submitted NDArrays are kept in the TRChannelsDriver
713  // (initial value only used by TRChannelsDriver constructor).
714  bool m_update_arrays;
715 
716  // Flag whether completeInit has been called.
717  bool m_init_completed;
718 
719  // Whether we allow data to be submitted.
720  bool m_allowing_data;
721 
722  // Parameters remembered for the TRChannelsDriver constructor.
723  int m_max_ad_buffers;
724  size_t m_max_ad_memory;
725 
726  // Total number of configuration parameters.
727  int m_num_config_params;
728 
729  // Array of framework-managed asyn params' indices
730  int m_asyn_params[NUM_BASE_ASYN_PARAMS];
731 
732  // Every config parameter is added to this list.
733  std::vector<TRConfigParamBase *> m_config_params;
734 
735  // List of asyn parameter IDs which are not allowed to be modified.
736  std::vector<int> m_protected_params;
737 
738  // Base configuration perameters.
739  // NOTE: Update NumBaseConfigParams below on every change!
740  // There doesn't seem to be a nice way to avoid having to manually
741  // maintain the parameter count, so long as the parameters are
742  // defined like this as members of the class.
743  TRConfigParam<int, double> m_param_num_bursts;
744  TRConfigParam<int, double> m_param_num_post_samples;
745  TRConfigParam<int, double> m_param_num_pre_post_samples;
746  TRConfigParam<double> m_param_requested_sample_rate;
747  TRConfigParam<double> m_param_achievable_sample_rate;
748  static int const NumBaseConfigParams = 5;
749 
750  // Arm state maintained internally.
751  ArmState m_arm_state;
752 
753  // A simplified armed state useful for drivers.
754  bool m_armed;
755 
756  // When arming, the requested arm state (ArmStatePostTrigger or ArmStatePrePostTrigger).
757  ArmState m_requested_arm_state;
758 
759  // This flag is set to true when disarming is requested.
760  bool m_disarm_requested;
761 
762  // This flag indicates whether a new arming has been requested
763  // during an existing arming, that is we need to re-start arming
764  // after disarming.
765  ArmState m_requested_rearm_state;
766 
767  // This flag indicates whether we are inside the read loop.
768  bool m_in_read_loop;
769 
770  // Sample rate for display (time array and NDArrray attributes).
771  // This is set during arming to the value provided by checkSettings.
772  double m_rate_for_display;
773 
774  // This event is raised from handleArmRequest to the
775  // read_thread in order to start the arming.
776  epicsEvent m_start_arming_event;
777 
778  // This event is raised from handleArmRequest to the
779  // read_thread to allow disarming to proceed after an error,
780  // and also to allow the default readBurst to wait until
781  // disarming is requested.
782  epicsEvent m_disarm_requested_event;
783 
784  // AreaDetector port for the channel data.
785  epics_auto_ptr<TRChannelsDriver> m_channels_driver;
786 
787  // Asyn port for the time array.
788  TRTimeArrayDriver m_time_array_driver;
789 
790 private:
791  // Add this parameter index to m_protected_params.
792  void addProtectedParam (int param);
793 
794  // Cheks is a parameter is allowed to be written and prints an error if not.
795  bool checkProtectedParamWrite (int param);
796 
797  // Called from writeInt32 when ARM_REQUEST is being written.
798  asynStatus handleArmRequest (int armRequest);
799 
800  // Starts arming, must be currently locked and in ArmStateDisarm.
801  void startArming (ArmState requested_arm_state);
802 
803  // Requests disarming, must be currently locked and not in ArmStateDisarm.
804  void requestDisarming (ArmState requested_rearm_state);
805 
806  // Waits until disarming is reqested.
807  void waitUntilDisarming ();
808 
809  // Read thread.
810  static void readThreadTrampoline (void *obj);
811  void readThread ();
812 
813  // One iteration of the read thread (one arming and disarming).
814  void readThreadIteration ();
815 
816  // Set effective-value parameters, during arming.
817  void setEffectiveParams ();
818 
819  // Clear effective-value parameters, during disarming.
820  void clearEffectiveParams ();
821 
822  // Calls the given function on all configuration parameters.
823  void processConfigParams (void (TRConfigParamBase::*func) ());
824 
825  // Sets m_arm_state and updates the asyn parameter.
826  void setArmState (ArmState armState);
827 
828  // Reads the m_stop_requested, locking and unlocking the port.
829  bool checkDisarmRequestedUnlocked ();
830 
831  // Check basic settings before proceeding with arming.
832  bool checkBasicSettings ();
833 
834  // Check values provided by checkSettings in TRArmInfo.
835  bool checkArmInfo (TRArmInfo const &arm_info);
836 
837  // Sets up the time array based on snapshot settings and m_rate_for_display.
838  void setupTimeArray (TRArmInfo const &arm_info);
839 };
840 
841 #endif
Defines the TRChannelDataSubmit class, used for submitting burst data to the framework.
void setAchievableSampleRate(double value)
Sets the achievable sample rate corresponding to the requested sample rate.
double getRequestedSampleRateSnapshot()
Returns the snapshot value of the requested sample rate.
Definition: TRBaseDriver.h:252
virtual void requestedSampleRateChanged()
Reports that the requested sample rate has changed.
void maybeSleepForTesting()
Possibly sleep for testing if enabled.
Class for submitting burst data.
Definition: TRChannelDataSubmit.h:38
double getRequestedSampleRate()
Returns the requested sample rate.
Structure for burst meta-information.
Definition: TRBurstMetaInfo.h:26
Defines the TRChannelsDriver class, used for submitting data into AreaDetector.
Defines the TRBurstMetaInfo class, used for passing information to TRBaseDriver::publishBurstMetaInfo...
Information provided by the driver to the framework at the start of arming.
Definition: TRArmInfo.h:31
void initConfigParam(TRConfigParam< ValueType, EffectiveValueType > &param, char const *base_name, EffectiveValueType invalid_value=EffectiveValueType())
Initialize a configuration parameter.
Definition: TRBaseDriver.h:95
void initInternalParam(TRConfigParam< ValueType, EffectiveValueType > &param, char const *base_name, EffectiveValueType invalid_value=EffectiveValueType())
Initialize an internal configration parameter.
Definition: TRBaseDriver.h:117
TRChannelsDriver & getChannelsDriver()
Return a reference to the channels driver.
Definition: TRBaseDriver.h:143
int getNumPostSamplesSnapshot()
Returns the snapshot value of the number of post-trigger samples per event.
Definition: TRBaseDriver.h:220
int getNumBurstsSnapshot()
Returns the snapshot value of the number of bursts to capture.
Definition: TRBaseDriver.h:203
void completeInit()
Complete initialization of the class.
void publishBurstMetaInfo(TRBurstMetaInfo const &info)
Publish meta-information about a burst.
Central class of the Transient Recorder framework for transient recorders (digitizers).
Definition: TRBaseDriver.h:55
virtual bool startAcquisition(bool overflow)=0
Configure the hardware to start acquisition.
An asynNDArrayDriver-based class though which burst data is submitted into the AreaDetector framework...
Definition: TRChannelsDriver.h:114
void requestDisarmingFromDriver()
Request disarming of acquisition.
ValueType getSnapshot()
Return the current snapshot value of the parameter.
Definition: TRConfigParam.h:107
TRBaseDriver(TRBaseConfig const &cfg)
Constructor for TRBaseDriver, to be used from constructors of derived classes.
Defines the TRBaseConfig class, used for configuring TRBaseDriver.
Defines the TRConfigParam class, representing an acquisition configuration parameter.
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value)
Overridden asyn parameter write handler.
virtual void stopAcquisition()=0
Configure the hardware to stop acquisition.
virtual bool checkOverflow(bool *had_overflow, int *num_buffer_bursts)
Check if there has been a buffer overlow.
virtual bool waitForPreconditions()
Wait for preconditions for arming to be satisifed.
Transient Recorder configuration parameter.
Definition: TRConfigParam.h:65
virtual void interruptReading()
Interrupt reading of data.
void setDigitizerName(char const *name)
Set the name of the digitizer, which will appear as the value of the "name" PV.
bool isArmed()
Check if acquisition is currently armed.
virtual TRChannelsDriver * createChannelsDriver()
Create the channels driver.
Construction parameters for TRBaseDriver.
Definition: TRBaseConfig.h:29
int getNumPrePostSamplesSnapshot()
Returns the snapshot value for the total number of samples per event (counting pre-trigger and post-t...
Definition: TRBaseDriver.h:237
virtual void onDisarmed()
Called when isArmed() changes from true to false.
double getAchievableSampleRateSnapshot()
Returns the snapshot value of the achievable sample rate.
Definition: TRBaseDriver.h:267
Defines the TRArmInfo class, used for passing information to the framework during arming...
virtual bool processBurstData()
Process the read that has just been read by readBurst.
virtual bool checkSettings(TRArmInfo &arm_info)=0
Check preconditions for arming and report the sample freq rate for display.
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value)
Overridden asyn parameter write handler.
virtual bool readBurst()
This is called in a loop to wait for and read a burst of data.