/******************************************************************************* * Gen.cpp Signal Generator classes * T.Barnaby, BEAM Ltd, 2006-09-12 ******************************************************************************* */ #include <Gen.h> #include <BArray.h> #include <math.h> #define AVG_PRINT 0 const int defaultFrefGain = 4096; // The default PLL FREF gain const int defaultPllGain = 9; // The default PLL feedback gain (In shifts to the right) BList<Gen*> genAll; BList<Gen*>& genInit(){ genAll.append(new GenBeam1()); genAll.append(new GenBeam2()); genAll.append(new GenBeam3()); genAll.append(new GenTest1()); 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)); } } /// This function will generate the phase tables for a given state. /// It is passed the parameters for the LO1 reference and the LO2 reference. /// If lo?Harmonic is 0, then FREF is generated, otherwise a lo?Harmonic harmonic reference is generated. /// The bunchSet? parameters are bit masks defining the locations of the particle bunches within the harmonic loactions. /// The capture boolean is used to enable data capture within this state. void Gen::outputState(int num, Tms::TmsState state, int lo1Harmonic, int bunchSet1, int lo2Harmonic, int bunchSet2, int capture){ int numSamples = 512; int numSigSamples = numSamples * 2; BArray<Sample> signal1(numSigSamples); ///< Bunch signal1 BArray<Sample> signal2(numSigSamples); ///< Bunch signal2 BArray<Sample> signalFull1(numSigSamples); ///< Harmonic signal1 BArray<Sample> signalFull2(numSigSamples); ///< Harmonic signal2 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 numBunches1 = 0; int numBunches2 = 0; int phase0 = 0; int phase1 = 0; int avg = 0; if(ouseMsbFref){ // If configured to use the PLL's address counters MSB as FREF, set the appropriate state table bits // In this case the appropriate LO1/LO2 phase table signal will not be used. if(state.pllReference1 == 0) state.pllLO1FromAddress = 1; if(state.pllReference2 == 0) state.pllLO2FromAddress = 1; } // Calculate the number of particle bunches for(i = 0; i < lo1Harmonic; i++){ if(bunchSet1 & (1 << i)){ numBunches1++; } } for(i = 0; i < lo2Harmonic; i++){ if(bunchSet2 & (1 << i)){ numBunches2++; } } if(ophaseTableFile) f.open(BString("phaseTable") + num + ".txt", "w"); // Generate the main state table entrys str.printf("0x%x", state.value); ooutput.append(NameValue(BString("stateTable") + num + ".state", str)); if(state.pllFeedbackSelect) ooutput.append(NameValue(BString("stateTable") + num + ".numBunches", numBunches2)); else ooutput.append(NameValue(BString("stateTable") + num + ".numBunches", numBunches1)); // Generate the LO1 reference if(lo1Harmonic){ sigGenBeam.config(osampleRate, ofref, lo1Harmonic, bunchSet1, 0, 1, 1.0); sigGenBeam.generate(signal1.data(), numSigSamples); sigGenBeam.config(osampleRate, ofref, lo1Harmonic, 0xFFFFFFFF, 0, 1, 1.0); sigGenBeam.generate(signalFull1.data(), numSigSamples); phase0 = numSamples - numSamples / (4 * lo1Harmonic); } else { sigGenFref.config(osampleRate, ofref, 1.0); sigGenFref.generate(signalFull1.data(), numSigSamples); phase0 = numSamples - numSamples / 4; } // Generate the LO2 reference if(lo2Harmonic){ sigGenBeam.config(osampleRate, ofref, lo2Harmonic, bunchSet2, 0, 1, 1.0); sigGenBeam.generate(signal2.data(), numSigSamples); sigGenBeam.config(osampleRate, ofref, lo2Harmonic, 0xFFFFFFFF, 0, 1, 1.0); sigGenBeam.generate(signalFull2.data(), numSigSamples); phase1 = numSamples - numSamples / (4 * lo2Harmonic); } else { sigGenFref.config(osampleRate, ofref, 1.0); sigGenFref.generate(signalFull2.data(), numSigSamples); phase1 = numSamples - numSamples / 4; } if(state.pllFeedbackSelect) sigLast = signal2[0]; else sigLast = signal1[0]; // Generate the phase table entries for(s = 0, bunch = 0; s < numSamples; s++){ p.value = 0; if(state.pllFeedbackSelect) sig = signal2[s]; else sig = signal1[s]; if(sig > 0.01){ if(capture){ p.gate = 1; avg += int(8192 * signal2[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(signalFull1[phase0 + s] > 0.20){ p.lo1 = 1; } if(signalFull2[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", defaultFrefGain)); ooutput.append(NameValue("pllGain", defaultPllGain)); 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", defaultFrefGain)); ooutput.append(NameValue("pllGain", defaultPllGain)); 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", defaultFrefGain)); ooutput.append(NameValue("pllGain", defaultPllGain)); 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 = 15; // Goto state 15 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(); } GenTest1::GenTest1() : Gen("Test1") { oinfo = "Test Beam settings."; } BError GenTest1::run(){ BError err; Tms::TmsState state; double f; // Calculate PLL initial frequency 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", defaultFrefGain)); ooutput.append(NameValue("pllGain", defaultPllGain)); 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 = 15; // Goto state 15 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(); }