RSS Git Download  Clone
Raw Blame History
/*******************************************************************************
 *	Gens.cpp	Signal Generator classes
 *			T.Barnaby,	BEAM Ltd,	2006-09-12
 *******************************************************************************
 */

#include <Gen.h>
#include <BArray.h>
#include <math.h>

#define AVG_PRINT	0

BList<Gen*>	genAll;

BList<Gen*>&	genInit(){
	genAll.append(new GenBeam1());
	genAll.append(new GenBeam2());
	genAll.append(new GenBeam3());
	
	return genAll;
}




BString NameValueList::getValue(BString name){
	BString*	s;
	
	if(s = find(name)){
		return *s;
	}
	return "";
}

void NameValueList::setValue(BString name, BString value){
	BString*	s;
	
	if(s = find(name)){
		*s = value;
		return;
	}
	else {
		append(NameValue(name, value));
//		BList<GenParam>::append(GenParam(name, value));
	}
}

Gen::Gen(BString name){
	oname = name;
	osampleRate = 125000000.0;
	ofref = 437000.0;
	ophaseTableFile = 0;
	ouseMsbFref = 0;
	opllInitialFrequencyDelay = 0;
}

Gen::~Gen(){
}

BError Gen::init(NameValueList& params){
	BError	err;
	BString	s;
	
	oparams = params;
	
	if((s = params.getValue("fileName")) != "")
		ofileName = s;

	if((s = params.getValue("sampleRate")) != "")
		osampleRate = atof(s);

	if((s = params.getValue("fref")) != "")
		ofref = atof(s);

	if((s = params.getValue("phaseTableFile")) != "")
		ophaseTableFile = 1;

	if((s = params.getValue("useMsbFref")) != "")
		ouseMsbFref = atoi(s);

	if((s = params.getValue("pllInitialFrequencyDelay")) != "")
		opllInitialFrequencyDelay = atoi(s);

	if((s = params.getValue("name")) != "")
		oname = s;

	return ofile.open(ofileName, "w");
}

void Gen::close(){
	ofile.close();
}

BString Gen::name(){
	return oname;
}

BString Gen::info(){
	return oinfo;
}

BError Gen::run(){
	BError	err;

	return err;
}

BError Gen::output(){
	BIter	i;
	BError	err;
	BString	name;
	
	for(ooutput.start(i); !ooutput.isEnd(i); ooutput.next(i)){
		name = ooutput[i].getName() + ":";
		ofile.printf("%s\t%s\n", name.retStr(), ooutput[i].getValue().retStr());
	}
	return err;
}

void Gen::outputPhaseDelay(){
	int		num = 40;
	double		phase;
	int		v;
	int		n;
	
	for(n = 0; n < num; n++){
		phase = double(512 * n) / num;
		v = int(phase);
		ooutput.append(NameValue(BString("frefPhaseDelay") + n, v));
	}
}

void Gen::outputState(int num, Tms::TmsState state, int lo1, int bunchSet0, int lo2, int bunchSet1, int capture){
	int		numSamples = 512;
	int		numSigSamples = numSamples * 2;
	BArray<Sample>	signal0(numSigSamples);
	BArray<Sample>	signal1(numSigSamples);
	BArray<Sample>	signalFull0(numSigSamples);
	BArray<Sample>	signalFull1(numSigSamples);
	SigGenBeam	sigGenBeam;
	SigGenSquare	sigGenFref;
	int		s;
	BString		str;
	BString		strPhaseTable;
	Tms::TmsPhase	p;
	Sample		sig;
	Sample		sigLast;
	int		bunch = 0;
	BFile		f;
	int		meanFilter1 = 0;
	int		meanFilter2 = 0;
	int		i;
	int		numBunches0 = 0;
	int		numBunches1 = 0;
	int		phase0 = 0;
	int		phase1 = 0;
	int		avg = 0;

	if(ouseMsbFref){
		if(state.pllReference1 == 0)
			state.pllLO1FromAddress = 1;
		if(state.pllReference2 == 0)
			state.pllLO2FromAddress = 1;
	}

	for(i = 0; i < lo1; i++){
		if(bunchSet0 & (1 << i)){
			numBunches0++;
		}
	}
	for(i = 0; i < lo2; i++){
		if(bunchSet1 & (1 << i)){
			numBunches1++;
		}
	}

	if(ophaseTableFile)
		f.open(BString("phaseTable") + num + ".txt", "w");
	
	str.printf("0x%x", state.value);
	ooutput.append(NameValue(BString("stateTable") + num + ".state", str));
	if(state.pllFeedbackSelect)
		ooutput.append(NameValue(BString("stateTable") + num + ".numBunches", numBunches1));
	else
		ooutput.append(NameValue(BString("stateTable") + num + ".numBunches", numBunches0));

	if(lo1){
		sigGenBeam.config(osampleRate, ofref, lo1, bunchSet0, 0, 1, 1.0);
		sigGenBeam.generate(signal0.data(), numSigSamples);
		sigGenBeam.config(osampleRate, ofref, lo1, 0xFFFFFFFF, 0, 1, 1.0);
		sigGenBeam.generate(signalFull0.data(), numSigSamples);
		phase0 = numSamples - numSamples / (4 * lo1);
	}
	else {
		sigGenFref.config(osampleRate, ofref, 1.0);
		sigGenFref.generate(signalFull0.data(), numSigSamples);
		phase0 = numSamples - numSamples / 4;
	}

	if(lo2){
		sigGenBeam.config(osampleRate, ofref, lo2, bunchSet1, 0, 1, 1.0);
		sigGenBeam.generate(signal1.data(), numSigSamples);
		sigGenBeam.config(osampleRate, ofref, lo2, 0xFFFFFFFF, 0, 1, 1.0);
		sigGenBeam.generate(signalFull1.data(), numSigSamples);
		phase1 = numSamples - numSamples / (4 * lo2);
	}
	else {
		sigGenFref.config(osampleRate, ofref, 1.0);
		sigGenFref.generate(signalFull1.data(), numSigSamples);
		phase1 = numSamples - numSamples / 4;
	}

	if(state.pllFeedbackSelect)
		sigLast = signal1[0];
	else
		sigLast = signal0[0];

	for(s = 0, bunch = 0; s < numSamples; s++){
		p.value = 0;

		if(state.pllFeedbackSelect)
			sig = signal1[s];
		else
			sig = signal0[s];
			
		if(sig > 0.01){
			if(capture){
				p.gate = 1;
				avg += int(8192 * signal1[s]);
			}
		}
		else {
			if(sigLast > 0.01){
				meanFilter1 = 4;
				if(bunch == 0)
					meanFilter2 = 4;
				bunch++;
			}
			p.blr = 1;
#if AVG_PRINT
			if(capture && avg){
				printf("Avg: Sample: %d %d\n", s, avg);
				avg = 0;
			}
#endif
		}
		
		if(meanFilter1){
			p.meanFilter1 = 1;
			meanFilter1--;
		}
		if(meanFilter2){
			p.meanFilter2 = 1;
			meanFilter2--;
		}
		
		if(signalFull0[phase0 + s] > 0.20){
			p.lo1 = 1;
		}
		if(signalFull1[phase1 + s] > 0.20){
			p.lo2 = 1;
		}
		

		str.printf("0x%x", p.value);
		if(strPhaseTable.len())
			strPhaseTable = strPhaseTable + ",";
		strPhaseTable = strPhaseTable + str;

		if(ophaseTableFile){
			f.printf("%f ", sig);
			f.printf("%d ", p.lo1);
			f.printf("%d ", p.blr);
			f.printf("%d ", p.gate);
			f.printf("%d ", p.lo2);
			f.printf("%d ", p.meanFilter1);
			f.printf("%d\n", p.meanFilter2);
		}

		sigLast = sig;
	}
	ooutput.append(NameValue(BString("stateTable") + num + ".phaseTable", strPhaseTable));
}

GenBeam1::GenBeam1() : Gen("Beam1") {
	oinfo = "Beam with 4 particle bunches at harmonic 8.";
}

BError GenBeam1::run(){
	BError		err;
	Tms::TmsState	state;
	double		f;
	
	f = pow(2.0, 32) / (62.5e6 / ofref);

	// Output General Info	
	ooutput.append(NameValue("cycleType", oname));
	ooutput.append(NameValue("info", oinfo));
	ooutput.append(NameValue("channel", "0"));
	ooutput.append(NameValue("pllInitialFrequency", int(f)));
	ooutput.append(NameValue("pllInitialFrequencyDelay", opllInitialFrequencyDelay));
	ooutput.append(NameValue("pllFrefGain", 4096));
	ooutput.append(NameValue("pllGain", 9));
	ooutput.append(NameValue("pllDdsMinimum", "0"));
	ooutput.append(NameValue("pllDdsMaximum", "0"));
	
	outputPhaseDelay();

	// First Cycle Period, await calibration or injection
	state.value = 0x0;
	state.calStart = 1;		// Goto state 1
	state.calStop = 14;		// Goto state 14
	state.injection = 3;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(0, state, 0, 0, 8, 0x3C, 0);

	// Second Cycle period, calibration
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 2;		// Goto state 2
	state.injection = 14;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 1;
	outputState(1, state, 0, 0, 8, 0x3C, 1);
	
	// Third Cycle period, await injection
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 3;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(2, state, 0, 0, 8, 0x3C, 0);

	// Second Cycle period, data capture harmonic 8
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 14;		// Goto state 14
	state.hchange = 03;		// Goto state 03, ie ignore these events
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 1;
	outputState(3, state, 0, 0, 8, 0x3C, 1);

	return output();
}


GenBeam2::GenBeam2() : Gen("Beam2") {
	oinfo = "Beam with 4 particle bunches at harmonic 8.";
	oinfo += "Beam then moves to 4 particle bunches at harmonic 16.";
}

BError GenBeam2::run(){
	BError		err;
	Tms::TmsState	state;
	double		f;
	
	f = pow(2.0, 32) / (62.5e6 / ofref);

	// Output General Info	
	ooutput.append(NameValue("cycleType", oname));
	ooutput.append(NameValue("info", oinfo));
	ooutput.append(NameValue("channel", "0"));
	ooutput.append(NameValue("pllInitialFrequency", int(f)));
	ooutput.append(NameValue("pllInitialFrequencyDelay", opllInitialFrequencyDelay));
	ooutput.append(NameValue("pllFrefGain", 4096));
	ooutput.append(NameValue("pllGain", 9));
	ooutput.append(NameValue("pllDdsMinimum", "0"));
	ooutput.append(NameValue("pllDdsMaximum", "0"));
	
	outputPhaseDelay();

	// First Cycle Period, await calibration or injection
	state.value = 0x0;
	state.calStart = 1;		// Goto state 1
	state.calStop = 14;		// Goto state 14
	state.injection = 3;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(0, state, 0, 0, 8, 0x3C, 0);

	// Second Cycle period, calibration
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 2;		// Goto state 2
	state.injection = 14;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 1;
	outputState(1, state, 0, 0, 8, 0x3C, 1);
	
	// Third Cycle period, await injection
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 3;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(2, state, 0, 0, 8, 0x3C, 0);

	// Second Cycle period, data capture harmonic 8
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 14;		// Goto state 14
	state.hchange = 4;		// Goto state 4
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 1;
	outputState(3, state, 16, 0x03C0, 8, 0x3C, 1);

	// Second Cycle period, data capture harmonic 16
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 14;		// Goto state 14
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(4, state, 16, 0x03C0, 0, 0, 1);

	return output();
}

GenBeam3::GenBeam3() : Gen("Beam3") {
	oinfo = "Beam with 4 particle bunches at harmonic 8.";
	oinfo += "Beam then moves to 8 particle bunches at harmonic 16.";
}

BError GenBeam3::run(){
	BError		err;
	Tms::TmsState	state;
	double		f;
	
	f = pow(2.0, 32) / (62.5e6 / ofref);

	// Output General Info	
	ooutput.append(NameValue("cycleType", oname));
	ooutput.append(NameValue("info", oinfo));
	ooutput.append(NameValue("channel", "0"));
	ooutput.append(NameValue("pllInitialFrequency", int(f)));
	ooutput.append(NameValue("pllInitialFrequencyDelay", opllInitialFrequencyDelay));
	ooutput.append(NameValue("pllFrefGain", 4096));
	ooutput.append(NameValue("pllGain", 9));
	ooutput.append(NameValue("pllDdsMinimum", "0"));
	ooutput.append(NameValue("pllDdsMaximum", "0"));
	
	outputPhaseDelay();

	// First Cycle Period, await calibration or injection
	state.value = 0x0;
	state.calStart = 1;		// Goto state 1
	state.calStop = 14;		// Goto state 14
	state.injection = 3;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(0, state, 0, 0, 8, 0x3C, 0);

	// Second Cycle period, calibration
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 2;		// Goto state 2
	state.injection = 14;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 1;
	outputState(1, state, 0, 0, 8, 0x3C, 1);
	
	// Third Cycle period, await injection
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 3;		// Goto state 3
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(2, state, 0, 0, 8, 0x3C, 0);

	// Second Cycle period, data capture harmonic 8
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 14;		// Goto state 14
	state.hchange = 4;		// Goto state 4
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 1;
	outputState(3, state, 16, 0x0FF0, 8, 0x3C, 1);

	// Second Cycle period, data capture harmonic 16
	state.value = 0x0;
	state.calStart = 14;		// Goto state 14
	state.calStop = 14;		// Goto state 14
	state.injection = 14;		// Goto state 14
	state.hchange = 14;		// Goto state 14
	state.cycleStop = 15;		// Goto state 15
	state.aquireData = 1;
	state.pllReference1 = 0;
	state.pllReference2 = 1;
	state.pllFeedbackSelect = 0;
	outputState(4, state, 16, 0x0FF0, 0, 0, 1);

	return output();
}