/*
* Title: PupeDiagnosticsWin.cpp
* Author: M.Thomas BEAM Ltd
* Date: 2007-02-13
*
* Contents: Status Display
*
* Mod Rec:
*
*/
#include <PupeDiagnosticsWin.h>
#include <qlayout.h>
#include <qvbox.h>
#include <qlabel.h>
#include <qtable.h>
#include <BError.h>
#include <TmsD.h>
#include <qvalidator.h>
#include <qmessagebox.h>
#include <BFile.h>
#include <BQComboBox.h>
using namespace std;
using namespace Tms;
#define BIT(v,b) ((v >> b) & 1)
static ComboDefinition sourceDef[] = {
{ 0, "Source 0", 0, 1 },
{ 1, "Source 1", 1, 0 },
{ 2, "Source 2", 2, 0 },
{ 3, "Source 3", 3, 0 },
{ 0,0,0,0 }
};
static ComboDefinition clockDef[] = {
{ 0, "ADC Clock", ClkAdcDiv_1, 1 },
{ 1, "ADC Clock/2", ClkAdcDiv_2, 0 },
{ 2, "ADC Clock/5", ClkAdcDiv_5, 0 },
{ 3, "ADC Clock/10", ClkAdcDiv_10, 0 },
{ 4, "ADC Clock/20", ClkAdcDiv_20, 0 },
{ 5, "ADC Clock/50", ClkAdcDiv_50, 0 },
{ 6, "ADC Clock/100", ClkAdcDiv_100, 0 },
{ 7, "ADC Clock/200", ClkAdcDiv_200, 0 },
{ 8, "ADC Clock/500", ClkAdcDiv_500, 0 },
{ 9, "ADC Clock/1000", ClkAdcDiv_1000, 0 },
{ 10, "ADC Clock/2000", ClkAdcDiv_2000, 0 },
{ 11, "ADC Clock/5000", ClkAdcDiv_5000, 0 },
{ 12, "ADC Clock/10000", ClkAdcDiv_10000, 0 },
{ 13, "ADC Clock/20000", ClkAdcDiv_20000, 0 },
{ 14, "ADC Clock/50000", ClkAdcDiv_50000, 0 },
{ 15, "ADC Clock/100000", ClkAdcDiv_100000, 0 },
{ 16, "FREF", ClkFref, 0 },
{ 17, "Ms", ClkMs, 0 },
{ 0,0,0,0 }
};
PupeDiagnosticsWin::PupeDiagnosticsWin(QWidget* w,Control& c) : ocontrol(c) {
QVBox* mv = new QVBox(this);
oplotA= new BQwtPlot(mv);
oplotB = new BQwtPlot(mv);
BQwtPlotControlBasic* controls = new BQwtPlotControlBasic(mv,oplotA);
QValidator* validator = new QIntValidator(0, (int)pow(2,31), this );
QRegExpValidator* validatorHex = new QRegExpValidator(this);
QRegExp rx;
QWidget* t = new QWidget(mv);
QGridLayout* v = new QGridLayout(t);
int row = 0;
int col = 0;
QPen pen;
BList<BString> colours;
controls->addPlot(oplotB);
rx.setPattern("0x[0-9,a-f][0-9,a-f]");
validatorHex->setRegExp(rx);
QHBox* h = new QHBox(mv);
QPushButton* refreshButton = new QPushButton("Refresh Data",h,"refreshButton");
QPushButton* saveButton = new QPushButton("Save To File",h,"saveButton");
ochannel = new QSpinBox(1,60,1,t,"");
osource = new BQComboBox(sourceDef,t,"");
oclock = new BQComboBox(clockDef,t,"");
ostartTime = new QLineEdit(t,"");ostartTime->setValidator(validator);
ostartTime->setText("0");
opostTriggerDelay = new QLineEdit(t,"");opostTriggerDelay->setValidator(validator);
opostTriggerDelay->setText("0");
otriggerMask = new QLineEdit(t,"");otriggerMask->setValidator(validatorHex);
otriggerMask->setText("0x02");
otriggerSourceData = new QCheckBox(t,"");
otriggerAnd = new QCheckBox(t,"");
otriggerStore = new QCheckBox(t,"");
ochannel->setWrapping(true);
h->setMargin(4);
refreshButton->setMaximumWidth(200);
saveButton->setMaximumWidth(200);
oplotA->setLegendPosition(QwtPlot::Right);
oplotB->setLegendPosition(QwtPlot::Right);
oplotA->setMaximumHeight(100);
oplotB->setMaximumHeight(450);
oplotA->enableXBottomAxis(0);
oplotB->enableXBottomAxis(1);
int width = 200;
ochannel->setMaximumWidth(width);
osource->setMaximumWidth(width);
oclock->setMaximumWidth(width);
ostartTime->setMaximumWidth(width);
opostTriggerDelay->setMaximumWidth(width);
otriggerMask->setMaximumWidth(width);
otriggerAnd->setMaximumWidth(width);
otriggerStore->setMaximumWidth(width);
otriggerSourceData->setMaximumWidth(width);
otriggerStore->setChecked(true);
col = 0;row = 0;
v->addWidget(new QLabel("Channel",t,""),row,col); v->addWidget(ochannel,row,col+1); row++;
v->addWidget(new QLabel("Source",t,""),row,col); v->addWidget(osource,row,col+1); row++;
v->addWidget(new QLabel("Clock",t,""),row,col); v->addWidget(oclock,row,col+1); row++;
v->addWidget(new QLabel("StartTime",t,""),row,col); v->addWidget(ostartTime,row,col+1); row++;
v->addWidget(new QLabel("Post Trigger Delay",t,""),row,col); v->addWidget(opostTriggerDelay,row,col+1); row++;
col = 2;row = 0;
v->addWidget(new QLabel("Trigger Src Data",t,""),row,col); v->addWidget(otriggerSourceData,row,col+1); row++;
v->addWidget(new QLabel("Trigger And",t,""),row,col); v->addWidget(otriggerAnd,row,col+1); row++;
v->addWidget(new QLabel("Trigger Store",t,""),row,col); v->addWidget(otriggerStore,row,col+1); row++;
v->addWidget(new QLabel("Trigger Mask Data Hex (eg 0x3c)",t,""),row,col); v->addWidget(otriggerMask ,row,col+1); row++;
v->setSpacing(5);
connect(refreshButton,SIGNAL(clicked()),this,SLOT(refresh()));
connect(saveButton,SIGNAL(clicked()),this,SLOT(saveFile()));
connect(oplotA,SIGNAL(plotEvent(QWheelEvent*)),this,SLOT(slotPlotEvent(QWheelEvent*)));
connect(oplotB,SIGNAL(plotEvent(QWheelEvent*)),this,SLOT(slotPlotEvent(QWheelEvent*)));
}
PupeDiagnosticsWin::~PupeDiagnosticsWin() {}
void PupeDiagnosticsWin::show() {
QWidget::show();
}
void PupeDiagnosticsWin::update() {
}
void PupeDiagnosticsWin::refresh() {
BError err;
Tms::TestCaptureInfo captureInfo;
Tms::PuChannel puPhysChannel;
// Build request
if (err = ocontrol.getPuChannel (ochannel->value(),puPhysChannel)) {
warningDialog("Reading Test Data",err);
return;
}
captureInfo.source = (int)osource->getValue();
captureInfo.clock = (int)oclock->getValue();
captureInfo.startTime = ostartTime->text().toUInt();
captureInfo.postTriggerDelay = opostTriggerDelay->text().toUInt();
captureInfo.triggerSourceData = otriggerSourceData->isChecked();
captureInfo.triggerAnd = otriggerAnd->isChecked();
captureInfo.triggerStore = otriggerStore->isChecked();
sscanf(otriggerMask->text().ascii(),"%i",&captureInfo.triggerMask);
if (err = ocontrol.getTestData(puPhysChannel,captureInfo,odata)) {
warningDialog("Reading Test Data",err);
return;
}
setPlotData();
plot();
}
void PupeDiagnosticsWin::setPlotData() {
unsigned int n = 0;
BIter i;
int size = odata.size();
CurveInfo info;
// Bit Pattern Source 0
int source = (int)osource->getValue();
int offset = 0x3FFF/6;
int gain = 0x3FFF/8;
if (source == 0) {
ox.data.resize(size);
if (ocurves.number() == 0) {
int n = 12;
ocurves.append(CurveInfo("dds_freq ","blue",oplotA));
ocurves.append(CurveInfo("sigma ", "blue",oplotB,1,offset * n--));
ocurves.append(CurveInfo("gate ","white", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("blr ","read", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("selFilter","green", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("rfSelect2","cyan", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("rfSelect1","magenta", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("fref ","yellow", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("mean2 ","darkRed", oplotB,gain,offset * n--));
ocurves.append(CurveInfo("mean1 ","darkGreen",oplotB,gain,offset * n--));
ocurves.append(CurveInfo("lo2 ","dartBlue",oplotB,gain,offset * n--));
ocurves.append(CurveInfo("lo1 ","darkCyan",oplotB,gain,offset * n--));
ocurves.append(CurveInfo("top " ,"darkMagenta",oplotB,gain,offset * n--));
}
for (ocurves.start(i);! ocurves.isEnd(i);ocurves.next(i)) {
ocurves[i].data.resize(size);
}
for(n = 0; n < odata.size(); n++){
UInt32 dds_freq, gate, blr, selFilter, rfSelect2, rfSelect1, fref;
UInt32 mean2, mean1, lo2, lo1, top;
Int16 sigma;
dds_freq = odata[n] & 0xFFFFFFFF;
sigma = (odata[n] >> 32) & 0x3FFF;
sigma = sigma | ((sigma & 0x2000) ? 0xC000 : 0);
gate = (odata[n] & (1ULL << 47)) ? 1 : 0;
blr = (odata[n] & (1ULL << 46)) ? 1 : 0;
selFilter = (odata[n] & (1ULL << 55)) ? 1 : 0;
rfSelect2 = (odata[n] & (1ULL << 54)) ? 1 : 0;
rfSelect1 = (odata[n] & (1ULL << 53)) ? 1 : 0;
fref = (odata[n] & (1ULL << 52)) ? 1 : 0;
mean2 = (odata[n] & (1ULL << 51)) ? 1 : 0;
mean1 = (odata[n] & (1ULL << 50)) ? 1 : 0;
lo2 = (odata[n] & (1ULL << 49)) ? 1 : 0;
lo1 = (odata[n] & (1ULL << 48)) ? 1 : 0;
top = (odata[n] >> 56) & 0xFF;
ox.data[n] = n;
ocurves[0].data[n] = dds_freq;
ocurves[1].data[n] = sigma;
ocurves[2].data[n] = gate;
ocurves[3].data[n] = blr;
ocurves[4].data[n] = selFilter;
ocurves[5].data[n] = rfSelect2;
ocurves[6].data[n] = rfSelect1;
ocurves[7].data[n] = fref;
ocurves[8].data[n] = mean2;
ocurves[9].data[n] = mean1;
ocurves[10].data[n] = lo2;
ocurves[11].data[n] = lo1;
ocurves[12].data[n] = BIT(top,0);
}
for (ocurves.start(i);! ocurves.isEnd(i);ocurves.next(i)) {
QPen pen;
pen.setColor(ocurves[i].colour.retStr());
ocurves[i].applyGainAndOffset();
if (ocurves[i].curve == 0) {
ocurves[i].curve = ocurves[i].plot->insertCurve(ocurves[i].title.retStr());
ocurves[i].plot->setCurveTitle(ocurves[i].curve,ocurves[i].title.retStr());
ocurves[i].plot->setCurvePen(ocurves[i].curve,pen);
ocurves[i].plot->enableLegend(true,ocurves[i].curve);
}
ocurves[i].plot->setCurveData(ocurves[i].curve,ox.data.data(),ocurves[i].data.data(),size);
}
oplotA->enableYLeftAxis(0);
oplotB->enableYLeftAxis(0);
oplotA->setRange(size);
oplotB->setRange(size);
}
else {
BError err;
err.set(1,"Only data of source type 0 can be viewed");
warningDialog("Viewing Pupe Diagnostics",err);
}
}
void PupeDiagnosticsWin::plot() {
oplotA->replot();
oplotB->replot();
}
void PupeDiagnosticsWin::slotPlotEvent(QWheelEvent* e) {
// Graph Linkage
oplotA->syntheticWheelEvent(e);
oplotB->syntheticWheelEvent(e);
}
void PupeDiagnosticsWin::saveFile() {
BError err;
unsigned int n;
BFile f;
if (osource->getValue() == 0) {
BString fname = "pupeSource0.dat";
if (f.open(fname,"w+")) {
warningDialog("PupeDiagnostics",BString("Cannot open save file (") + fname + ")");
return;
}
f.printf("# tmsControlGui - Saved data file\n");
f.printf("# Pupe Diagnostics Source 0\n");
f.printf("# fref,sigma,lo1,lo2,gate,blr,mean1,mean2,dds_freq,rfSelect2,selFilter,");
f.printf("# top_bit7,top_bit6,top_bit5,top_bit4,top_bit3,top_bit2,top_bit1,top_bit0\n");
f.printf("#\n");
for (n = 0;n < odata.size();n++) {
UInt32 dds_freq, gate, blr, selFilter, rfSelect2, rfSelect1, fref;
UInt32 mean2, mean1, lo2, lo1, top;
Int16 sigma;
dds_freq = odata[n] & 0xFFFFFFFF;
sigma = (odata[n] >> 32) & 0x3FFF;
sigma = sigma | ((sigma & 0x2000) ? 0xC000 : 0);
gate = (odata[n] & (1ULL << 47)) ? 1 : 0;
blr = (odata[n] & (1ULL << 46)) ? 1 : 0;
selFilter = (odata[n] & (1ULL << 55)) ? 1 : 0;
rfSelect2 = (odata[n] & (1ULL << 54)) ? 1 : 0;
rfSelect1 = (odata[n] & (1ULL << 53)) ? 1 : 0;
fref = (odata[n] & (1ULL << 52)) ? 1 : 0;
mean2 = (odata[n] & (1ULL << 51)) ? 1 : 0;
mean1 = (odata[n] & (1ULL << 50)) ? 1 : 0;
lo2 = (odata[n] & (1ULL << 49)) ? 1 : 0;
lo1 = (odata[n] & (1ULL << 48)) ? 1 : 0;
top = (odata[n] >> 56) & 0xFF;
f.printf("%d %d %d %d %d %d %d %d %u %d %d %d %d %d %d %d %d %d %d %d\n",
fref, sigma, lo1, lo2, gate, blr, mean1, mean2, dds_freq, rfSelect1, rfSelect2, selFilter,
BIT(top,7), BIT(top,6), BIT(top,5), BIT(top,4), BIT(top,3), BIT(top,2), BIT(top,1), BIT(top,0));
}
f.close();
}
else {
err.set(1,"Only data of source type 0 can be saved");
warningDialog("Attempting file Save",err);
}
}
void PupeDiagnosticsWin::warningDialog(BString title, BError err){
BString m;
m = BString("<h5>") + title + "</h5><p>" + err.getString() + "</p>";
QMessageBox::warning(this, "Warning", m.retStr());
}