Skip to content
Snippets Groups Projects
AWG.h 5.47 KiB
Newer Older
xiyehu2's avatar
xiyehu2 committed
#pragma once
xiyehu2's avatar
xiyehu2 committed
#include "driver_header/dlltyp.h"
#include "driver_header/regs.h"
#include "driver_header/spcerr.h"
#include "driver_header/spcm_drv.h"
#include <string>
#include <set>
#include <map>
xiyehu2's avatar
xiyehu2 committed

class AWG {
	/**
	 * Class for handling AWG M4i.6622-x8 .
	 * Manual can be found at
	 * https://spectrum-instrumentation.com/products/details/M4i6622-x8.php
	 */

	// collection of card status for printouts
	const std::map<int, std::string> STATUS_NAMES = {
		{M2STAT_CARD_TRIGGER,	 "card received trigger"},
		{M2STAT_CARD_READY,		 "card ready"},
		{M2STAT_DATA_BLOCKREADY, "data block ready"},
		{M2STAT_DATA_END,		 "data transfer ended"},
		{M2STAT_DATA_OVERRUN,	 "data transfer overrun"},
		{M2STAT_DATA_ERROR,		 "data transfer error"},
	};

private:
	// card information
	drv_handle	pCardHandle;
	int32	    cardIdx;
	int32	    serialNumber;
	int64	    instMemSize;
	int32	    bytesPerSample;
	int64	    maxSampleRate;

	// setting information
	std::set<int> activeChannels;
	void		  checkError();

public:
xiyehu2's avatar
xiyehu2 committed
	class CardException : std::exception {
		private:
		char* exceptionMsg;
		public:
		CardException(char* msg) : exceptionMsg(msg) {}
		const char* what() const throw() { return exceptionMsg; }
	};
// collection of special constants to help with setting options
	enum class CHANNEL_STOPLVL : int32 {
xiyehu2's avatar
xiyehu2 committed
		ZERO	 = SPCM_STOPLVL_ZERO,
		LOW		 = SPCM_STOPLVL_LOW,
		HIGH	 = SPCM_STOPLVL_HIGH,
		HOLDLAST = SPCM_STOPLVL_HOLDLAST,
	};
xiyehu2's avatar
xiyehu2 committed
		SINGLE		  = SPC_REP_STD_SINGLE,
		MULTI		  = SPC_REP_STD_MULTI,
		GATE		  = SPC_REP_STD_GATE,
		SINGLERESTART = SPC_REP_STD_SINGLERESTART,
		SEQUENCE	  = SPC_REP_STD_SEQUENCE,
		FIFO_SINGLE	  = SPC_REP_FIFO_SINGLE,
		FIFO_MULTI	  = SPC_REP_FIFO_MULTI,
		FIFO_GATE	  = SPC_REP_FIFO_GATE,
	};
xiyehu2's avatar
xiyehu2 committed
		DATA	  = SPCM_BUF_DATA,
		ABA		  = SPCM_BUF_ABA,
		TIMESTAMP = SPCM_BUF_TIMESTAMP,
	};
	enum class TRANSFER_DIR : int32 {
xiyehu2's avatar
xiyehu2 committed
		PCTOCARD  = SPCM_DIR_PCTOCARD,
		CARDTOPC  = SPCM_DIR_CARDTOPC,
		CARDTOGPU = SPCM_DIR_CARDTOGPU,
		GPUTOCARD = SPCM_DIR_GPUTOCARD,
	};
xiyehu2's avatar
xiyehu2 committed
		INTPLL	  = SPC_CM_INTPLL,
		EXTREFCLK = SPC_CM_EXTREFCLOCK,
	};
	enum class TRIGGER_MASK : int32 {
xiyehu2's avatar
xiyehu2 committed
		NONE	 = SPC_TMASK_NONE,
		SOFTWARE = SPC_TMASK_SOFTWARE,
		EXT0	 = SPC_TMASK_EXT0,
		EXT1	 = SPC_TMASK_EXT1,
	};
	enum class TRIGGER_MODE : int32 {
xiyehu2's avatar
xiyehu2 committed
		NONE	   = SPC_TM_NONE,
		POS		   = SPC_TM_POS,
		NEG		   = SPC_TM_NEG,
		POS_REARM  = SPC_TM_POS | SPC_TM_REARM,
		NEG_REARM  = SPC_TM_NEG | SPC_TM_REARM,
		BOTH	   = SPC_TM_BOTH,
		HIGH	   = SPC_TM_HIGH,
		LOW		   = SPC_TM_LOW,
		WINENTER   = SPC_TM_WINENTER,
		WINLEAVE   = SPC_TM_WINLEAVE,
		INWIN	   = SPC_TM_INWIN,
		OUTSIDEWIN = SPC_TM_OUTSIDEWIN,
	};
	enum class SEQ_LOOPCONDITION : int64 {
xiyehu2's avatar
xiyehu2 committed
		ALWAYS = SPCSEQ_ENDLOOPALWAYS,
		ONTRIG = SPCSEQ_ENDLOOPONTRIG,
		END	   = SPCSEQ_END,
	};

	// functions
	AWG() noexcept;
	~AWG();

	// basic card setting
	void  open(int openIndex);
	bool  isOpen();
	void  close();
	void  reset();
	int   getCardIdx();
	int   getSerialNumber();
	int64 getInstMemSize();
	int   getBytesPerSample();
	int64 getMaxSampleRate();
	void  setSampleRate(int64 sampleRate);
	int64 getSampleRate();

	// channel output control
	void setActiveChannels(std::set<int> channels);
	void setChannelAmp(int ch, int amp);
	void setChannelStopLvl(int ch, CHANNEL_STOPLVL stopLvl);
	void toggleChannelOutput(int ch, bool enable);
	void setChannel(int ch, int amp, CHANNEL_STOPLVL stopLvl, bool enable);
	int	 getChannelCount();
	std::set<int> getChannelActivated();
	void setChannelDiffMode(int chPair, bool enable);
	void setChannelDoubleMode(int chPair, bool enable);

	// card status control
	void writeSetup();
	void cardRun();
	void cardStop();
	void waitReady();
	void setTimeOut(int time); // ms
	int  getTimeOut();
	void printCardStatus();

	// card trigger control
	void   toggleTrigger(bool enable);
	void   forceTrigger();
	void   waitTrigger();
	void   setTrigMaskOr(std::initializer_list<TRIGGER_MASK> trigMasks);
	void   setTrigMaskOr(std::vector<TRIGGER_MASK> trigMasks);
xiyehu2's avatar
xiyehu2 committed
	void   setTrigMaskAnd(std::initializer_list<TRIGGER_MASK> trigMasks);
	void   setTrigMaskAnd(std::vector<TRIGGER_MASK> trigMasks);
xiyehu2's avatar
xiyehu2 committed
	void   setTrigMode(int trigChannel, TRIGGER_MODE trigMode);
	void   setTrigTerm(int term);
	int    getTrigTerm();
	void   setTrigCoupling(int channel, int coupling);
	int    getTrigCoupling(int channel);
	void   setTrigLvl(int channel, int level);
	int    getTrigLvl(int channel);
	void   setTrigRearmLvl(int channel, int level);
	int64  getTrigRearmLvl(int channel);

	// replay mode control
	//void  setReplayMode(REPLAY_MODE mode);
	//void  setMemSize(int64 sampleSize);
	//int64 getMemsize();
	//void  setLoop(int nLoop);
	//int64 getLoop();
	void initReplayModeSeq(int nSeg);
	void setSeqModeStep(
xiyehu2's avatar
xiyehu2 committed
		uint32 step,
xiyehu2's avatar
xiyehu2 committed
		uint64 segment,
		uint64 nextStep,
		uint64 nLoop,
		SEQ_LOOPCONDITION condition
	);
	void writeSeqModeSegment(
		void* pDataBuffer, 
		int size,
		int segment
	);

	// data transfer
	void prepDataTransfer(
		void* dataBuffer,
		uint64 bufferLen,
		BUFFER_TYPE bufType = BUFFER_TYPE::DATA,
		TRANSFER_DIR dir = TRANSFER_DIR::PCTOCARD,
		uint32 notifySize = 0,
		uint64 brdMemOffs = 0
	);
	void startDataTransfer();
	void waitDataTransfer();
	void stopDataTransfer();

	// clock control
	void  setClockMode(CLOCK_MODE cm);
	int32 getClockMode();
	void  setRefClkFreq(int64 frequency);
	void  setClockOut(bool enable);
	int64 getClockOutFreq();

    // memory management functions
	void*		  getPageAlignedMem(uint64 memSize);
	void		  freePageAlignedMem(void* pMem, uint64 memSize);
xiyehu2's avatar
xiyehu2 committed
};