/*******************************************************************************
* 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);
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){
state.pllLO1FromAddress = 1;
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();
}