Files
drs4eb/software/drsosc/ConfigDialog.cpp
T

582 lines
19 KiB
C++

/*
* ConfigDialog.cpp
* Modeless Configuration Dialog class
* $Id: ConfigDialog.cpp 22325 2016-10-07 14:05:49Z ritt $
*/
#include "DRSOscInc.h"
ConfigDialog::ConfigDialog( wxWindow* parent )
:
ConfigDialog_fb( parent )
{
m_frame = (DOFrame *)parent;
m_osci = m_frame->GetOsci();
fCalMode = 0;
m_board = 0;
m_firstChannel = 0;
m_chnSection = m_frame->GetOsci()->GetChnSection();
if (m_frame->GetMultiBoard()) {
m_cbMulti->SetValue(true);
m_cbTrgCorr->SetValue(false);
m_cbTrgCorr->Enable(false);
m_frame->SetDisplayTrgCorr(false);
}
m_cbClkOn->SetValue(m_frame->GetClkOn());
if (m_osci->GetNumberOfBoards() == 0) {
m_cbClkOn->SetLabel(wxT("Connect reference clock to channel #4"));
} else {
if (m_frame->GetOsci()->GetBoard(0)->GetBoardType() == 9)
m_cbClkOn->SetLabel(wxT("Connect reference clock to all channels"));
else
m_cbClkOn->SetLabel(wxT("Connect reference clock to channel #4"));
}
if (m_frame->GetRange() == 0) {
m_rbRange->SetSelection(0);
m_slCal->SetRange(-500, 500);
} else if (m_frame->GetRange() == 0.45) {
m_rbRange->SetSelection(1);
m_slCal->SetRange(-50, 950);
} else if (m_frame->GetRange() == 0.5) {
m_rbRange->SetSelection(2);
m_slCal->SetRange(-0, 1000);
}
if (m_chnSection == 2)
m_rbChHalf->SetSelection(2);
wxString wxstr;
wxstr.Printf(wxT("%1.4lg"), m_frame->GetReqSamplingSpeed());
m_tbFreq->SetValue(wxstr);
wxstr.Printf(wxT("%1.4lg GSPS"), m_frame->GetActSamplingSpeed());
m_stActFreq->SetLabel(wxstr);
m_cbLocked->SetValue(m_frame->IsFreqLocked());
m_cbSpikes->SetValue(m_frame->GetSpikeRemovel());
if (m_osci->GetNumberOfBoards() == 0) {
m_cbTCalOn->SetValue(true);
m_cbTCalOn->Enable(true);
} else {
m_cbTCalOn->SetValue(m_frame->GetOsci()->IsTCalibrated());
m_cbTCalOn->Enable(m_frame->GetOsci()->IsTCalibrated());
}
PopulateBoards();
}
void ConfigDialog::PopulateBoards()
{
wxString wxstr;
m_cbBoard->Clear();
for (int i=0 ; i<m_osci->GetNumberOfBoards() ; i++) {
DRSBoard *b = m_osci->GetBoard(i);
#ifdef HAVE_VME
if (b->GetTransport() == 1)
wxstr.Printf(wxT("VME DRS%d slot %2d%s serial %d"),
b->GetDRSType(), (b->GetSlotNumber() >> 1)+2,
((b->GetSlotNumber() & 1) == 0) ? "up" : "lo",
b->GetBoardSerialNumber());
else
#endif
wxstr.Printf(wxT("USB DRS%d serial %d"), b->GetDRSType(), b->GetBoardSerialNumber());
m_cbBoard->Append(wxstr);
}
m_cbBoard->Select(m_board);
UpdateControls();
}
void ConfigDialog::UpdateControls()
{
if (m_osci->GetNumberOfBoards() < 2) {
m_cbMulti->Enable(false);
} else
m_cbMulti->Enable(true);
if (m_osci->GetNumberOfBoards() == 0 ||
m_osci->GetBoard(m_board)->GetBoardType() == 5 ||
m_osci->GetBoard(m_board)->GetBoardType() == 7 ||
m_osci->GetBoard(m_board)->GetBoardType() == 8 ||
m_osci->GetBoard(m_board)->GetBoardType() == 9) {
if (m_osci->GetNumberOfBoards() > 0) {
m_cbExtRefclk->Enable(m_osci->GetBoard(m_board)->GetBoardType() == 8 || m_osci->GetBoard(m_board)->GetBoardType() == 9);
m_cbExtRefclk->Show(m_osci->GetBoard(m_board)->GetBoardType() == 8 || m_osci->GetBoard(m_board)->GetBoardType() == 9);
}
} else {
m_cbExtRefclk->Enable(true);
m_cbExtRefclk->Show(true);
}
if (m_osci->GetNumberOfBoards() > 0) {
if (m_osci->GetBoard(m_board)->GetBoardType() == 5 ||
m_osci->GetBoard(m_board)->GetBoardType() == 6 ||
m_osci->GetBoard(m_board)->Is2048ModeCapable()) {
m_rbChHalf->Enable(true);
} else {
if (m_osci->GetBoard(m_board)->GetBoardSerialNumber() == 2146 ||
m_osci->GetBoard(m_board)->GetBoardSerialNumber() == 2205 ||
m_osci->GetBoard(m_board)->GetBoardSerialNumber() == 2208 ||
m_osci->GetBoard(m_board)->GetBoardSerialNumber() == 2253 ||
m_osci->GetBoard(m_board)->GetBoardSerialNumber() == 2287) {
m_rbChHalf->Enable(true); // special boards modified for RFBeta & Slow Muons
} else {
m_rbChHalf->Enable(false);
}
}
} else {
m_rbChHalf->Enable(false);
}
if (m_osci->GetNumberOfBoards() == 0) {
m_cbTCalOn->SetValue(true);
m_cbTCalOn->Enable(true);
} else {
m_cbCalibrated->SetValue(m_frame->GetOsci()->IsVCalibrated());
m_cbCalibrated->Enable(m_frame->GetOsci()->IsVCalibrated());
m_cbCalibrated2->SetValue(m_frame->GetOsci()->IsVCalibrated());
m_cbCalibrated2->Enable(m_frame->GetOsci()->IsVCalibrated());
m_cbTCalOn->SetValue(m_frame->GetOsci()->IsTCalibrated());
m_cbTCalOn->Enable(m_frame->GetOsci()->IsTCalibrated());
m_cbExtRefclk->SetValue(m_osci->GetBoard(m_board)->GetRefclk() == 1);
if ((m_osci->GetBoard(m_board)->GetBoardType() == 8 || m_osci->GetBoard(m_board)->GetBoardType() == 9)
&& !(m_osci->IsMultiBoard() && !m_frame->IsTranspTrigger() && m_board > 0))
m_frame->EnableTriggerConfig(true);
else
m_frame->EnableTriggerConfig(false);
}
}
void ConfigDialog::OnBoardSelect( wxCommandEvent& event )
{
if (event.GetId() == ID_MULTI) {
if (m_cbMulti->IsChecked()) {
wxString str;
str.Printf(wxT("In a multi-board configuration, the Trigger and Clock singals must be conected. Please read the manual for details. Turn on multi-board mode?"));
if (wxMessageBox(str, wxT("DRS Oscilloscope Info"), wxOK | wxCANCEL | wxICON_EXCLAMATION) == wxOK) {
m_osci->Enable(false);
m_osci->SetMultiBoard(true);
for (int i=1 ; i<m_osci->GetNumberOfBoards() ; i++) {
DRSBoard *b = m_frame->GetOsci()->GetBoard(i);
m_frame->SetTriggerConfig(i, (1<<4)); // select external trigger
m_frame->SetTriggerPolarity(i, false); // positive trigger
if (b->GetFirmwareVersion() < 21260) {
wxMessageBox(wxT("For this operation V5 boards with firmware revision >= 21260 is required"),
wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
} else {
if (b->GetScaler(5) < 300000) {
str.Printf(wxT("No clock signal connected to CLK IN of board #%d. Keeping internal clock."), m_frame->GetOsci()->GetBoard(i)->GetBoardSerialNumber());
wxMessageBox(str, wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
m_frame->SetRefclk(i, false);
} else {
m_frame->SetRefclk(i, true);
}
}
}
m_osci->Enable(true);
m_osci->SelectBoard(m_board);
m_osci->SelectChannel(m_firstChannel, m_chnSection);
m_frame->SetDisplayTrgCorr(false);
m_cbTrgCorr->SetValue(false);
m_cbTrgCorr->Enable(false);
} else {
m_cbMulti->SetValue(false);
}
} else {
m_osci->Enable(false);
m_osci->SetMultiBoard(false);
m_osci->Enable(true);
m_osci->SelectBoard(m_board);
m_osci->SelectChannel(m_firstChannel, m_chnSection);
m_cbTrgCorr->Enable(true);
}
m_frame->SetMultiBoard(m_cbMulti->IsChecked());
m_frame->SelectBoard(m_board); // cause control update
if (!m_cbMulti->IsChecked())
m_frame->SetSplitMode(false);
} else {
m_board = m_cbBoard->GetSelection();
m_osci->SelectBoard(m_board);
m_osci->SelectChannel(m_firstChannel, m_chnSection);
m_frame->SelectBoard(m_board);
UpdateControls();
}
}
// called from DOFrame if one selects another board
void ConfigDialog::SelectBoard(int i)
{
m_board = i;
m_cbBoard->SetSelection(i);
m_osci->SelectBoard(m_board);
m_osci->SelectChannel(m_firstChannel, m_chnSection);
m_frame->UpdateStatusBar();
UpdateControls();
}
void ConfigDialog::OnRescan( wxCommandEvent& event )
{
m_frame->EnableEPThread(false);
m_osci->ScanBoards();
PopulateBoards();
if (m_board >= m_osci->GetNumberOfBoards())
m_board = m_firstChannel = m_chnSection = 0;
m_osci->SelectBoard(m_board);
m_frame->EnableEPThread(true);
m_frame->UpdateStatusBar();
}
void ConfigDialog::OnInfo( wxCommandEvent& event )
{
InfoDialog id(m_frame);
id.ShowModal();
}
void ConfigDialog::OnChannelHalf( wxCommandEvent& event )
{
if (event.GetId() == ID_CH_HALF)
m_chnSection = m_rbChHalf->GetSelection();
m_frame->SetSource(m_board, m_firstChannel, m_chnSection);
m_osci->SelectBoard(m_board);
m_osci->SelectChannel(m_firstChannel, m_chnSection);
}
void ConfigDialog::OnInputRange( wxCommandEvent& event )
{
if (m_rbRange->GetSelection() == 0) {
m_frame->GetOsci()->SetInputRange(0);
m_frame->SetRange(0);
m_slCal->SetRange(-500, 500);
} else if (m_rbRange->GetSelection() == 1) {
m_frame->GetOsci()->SetInputRange(0.45);
m_frame->SetRange(0.45);
m_slCal->SetRange(-50, 950);
} else if (m_rbRange->GetSelection() == 2) {
m_frame->GetOsci()->SetInputRange(0.5);
m_frame->SetRange(0.5);
m_slCal->SetRange(0, 1000);
}
OnCalEnter(event);
}
void ConfigDialog::OnCalOn( wxCommandEvent& event )
{
if (event.IsChecked()) {
m_frame->GetOsci()->SetCalibVoltage(true, m_slCal->GetValue()/1000.0);
} else {
m_frame->GetOsci()->SetCalibVoltage(false, 0);
}
}
void ConfigDialog::OnCalEnter( wxCommandEvent& event )
{
if (!m_teCal->IsEmpty()) {
long value;
m_teCal->GetValue().ToLong(&value);
if (m_frame->GetRange() == 0) {
if (value < -500)
value = -500;
if (value > 500)
value = 500;
} else if (m_frame->GetRange() == 0.45) {
if (value < -50)
value = -50;
if (value > 950)
value = 950;
} else if (m_frame->GetRange() == 0.5) {
if (value < 0)
value = 0;
if (value > 1000)
value = 1000;
}
m_slCal->SetValue(value);
m_teCal->SetValue(wxString::Format(wxT("%ld"), value));
if (m_cbCalOn->IsChecked())
m_frame->GetOsci()->SetCalibVoltage(true, value/1000.0);
}
/* check for calibration */
if (m_osci->GetNumberOfBoards() > 0 &&
fabs(m_frame->GetRange() - m_frame->GetOsci()->GetCalibratedInputRange()) > 0.001) {
wxString str;
str.Printf(wxT("This board was calibrated for an input range of\n %1.2lg V ... %1.2lg V\nYou must execute a new voltage calibration to use this board for the new input range"),
m_frame->GetOsci()->GetCalibratedInputRange()-0.5, m_frame->GetOsci()->GetCalibratedInputRange()+0.5);
wxMessageBox(str, wxT("DRS Oscilloscope Warning"), wxOK | wxICON_EXCLAMATION, this);
}
}
void ConfigDialog::OnCalSlider( wxScrollEvent& event )
{
m_teCal->SetValue(wxString::Format(wxT("%d"), m_slCal->GetValue()));
if (m_cbCalOn->IsChecked())
m_frame->GetOsci()->SetCalibVoltage(true, m_slCal->GetValue()/1000.0);
}
void ConfigDialog::Progress(int prog)
{
if (fCalMode == 1)
m_gaugeCalVolt->SetValue(prog);
else {
m_gaugeCalTime->SetValue(prog);
m_frame->SetProgress(prog);
m_frame->Refresh();
m_frame->Update();
}
/* produces flickers with V 2.9.2
this->Refresh();
this->Update(); */
}
void ConfigDialog::OnButtonCalVolt( wxCommandEvent& event )
{
fCalMode = 1;
if (m_frame->GetOsci()->GetNumberOfBoards()) {
m_frame->GetTimer()->Stop();
m_frame->GetOsci()->Enable(false); // turn off readout thread
DRSBoard *b = m_frame->GetOsci()->GetCurrentBoard();
if (b->GetTransport() == TR_USB2 && b->GetBoardType() == 6) {
wxMessageBox(wxT("Voltage calibration not possible with Mezzanine Board through USB"),
wxT("DRS Oscilloscope Error"), wxOK | wxICON_STOP, this);
return;
}
wxMessageBox(wxT("Please disconnect any signal from input to continue calibration"),
wxT("DRS Oscilloscope Info"), wxOK | wxICON_INFORMATION, this);
m_frame->Refresh();
m_frame->Update();
/* remember current settings */
double acalVolt = b->GetAcalVolt();
int acalMode = b->GetAcalMode();
int tcalFreq = b->GetTcalFreq();
int tcalLevel = b->GetTcalLevel();
int tcalSource = b->GetTcalSource();
int flag1 = b->GetTriggerEnable(0);
int flag2 = b->GetTriggerEnable(1);
int trgConfig = b->GetTriggerConfig();
int trgDelay = b->GetTriggerDelay();
double range = b->GetInputRange();
int config = b->GetReadoutChannelConfig();
int casc = b->GetChannelCascading();
wxBusyCursor cursor;
b->CalibrateVolt(this);
/* restore old values */
b->EnableAcal(acalMode, acalVolt);
b->EnableTcal(tcalFreq, tcalLevel);
b->SelectClockSource(tcalSource);
b->EnableTrigger(flag1, flag2);
b->SetTriggerConfig(trgConfig);
b->SetTriggerDelayPercent(trgDelay);
b->SetInputRange(range);
if (casc == 2)
b->SetChannelConfig(config, 8, 4);
else
b->SetChannelConfig(config, 8, 8);
if (b->GetBoardType() == 5)
b->SetTranspMode(1); // Evaluation board with build-in trigger
else
b->SetTranspMode(1); // VPC Mezzanine board
UpdateControls();
m_frame->GetTimer()->Start(100);
m_frame->GetOsci()->Start();
m_frame->GetOsci()->Enable(true);
}
Progress(0);
}
void ConfigDialog::OnButtonCalTime( wxCommandEvent& event )
{
fCalMode = 2;
if (m_frame->GetOsci()->GetNumberOfBoards()) {
if (m_frame->GetOsci()->GetCurrentBoard()->GetFirmwareVersion() < 13279)
wxMessageBox(wxT("Firmware revision 13279 or later\nrequired for timing calibration"),
wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
else if (m_frame->GetOsci()->GetInputRange() != 0)
wxMessageBox(wxT("Timing calibration can only be done\nat the -0.5V to +0.5V input range"),
wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
else {
DRSBoard *b = m_frame->GetOsci()->GetCurrentBoard();
m_frame->GetOsci()->Enable(false); // turn off readout thread
/* remember current settings */
double acalVolt = b->GetAcalVolt();
int acalMode = b->GetAcalMode();
int tcalFreq = b->GetTcalFreq();
int tcalLevel = b->GetTcalLevel();
int tcalSource = b->GetTcalSource();
int flag1 = b->GetTriggerEnable(0);
int flag2 = b->GetTriggerEnable(1);
int trgConfig = b->GetTriggerConfig();
int trgDelay = b->GetTriggerDelay();
double range = b->GetInputRange();
int config = b->GetReadoutChannelConfig();
m_frame->SetPaintMode(kPMTimeCalibration);
wxBusyCursor cursor;
int status = b->CalibrateTiming(this);
if (!status)
wxMessageBox(wxT("Error performing timing calibration, please check waveforms and redo voltage calibration."),
wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
else
wxMessageBox(wxT("Timing calibration successfully finished."),
wxT("DRS Oscilloscope"), wxOK, this);
m_frame->SetPaintMode(kPMWaveform);
/* restore old values */
b->EnableAcal(acalMode, acalVolt);
b->EnableTcal(tcalFreq, tcalLevel);
b->SelectClockSource(tcalSource);
b->EnableTrigger(flag1, flag2);
b->SetTriggerConfig(trgConfig);
b->SetTriggerDelayPercent(trgDelay);
b->SetInputRange(range);
b->SetChannelConfig(config, 8, 8);
if (b->GetBoardType() == 5)
b->SetTranspMode(1); // Evaluation board with build-in trigger
else
b->SetTranspMode(1); // VPC Mezzanine board
FreqChange(); // update enable flag for timing calibration check box
m_frame->GetTimer()->Start(100);
m_frame->GetOsci()->Start();
m_frame->GetOsci()->Enable(true);
}
Progress(0);
}
}
void ConfigDialog::OnClkOn( wxCommandEvent& event )
{
m_frame->SetClkOn(event.IsChecked());
}
void ConfigDialog::OnDateTime( wxCommandEvent& event )
{
m_frame->SetDisplayDateTime(event.IsChecked());
}
void ConfigDialog::OnShowGrid( wxCommandEvent& event )
{
m_frame->SetDisplayShowGrid(event.IsChecked());
}
void ConfigDialog::OnDisplayWaveforms( wxCommandEvent& event )
{
if (event.GetId() == ID_DISP_CALIBRATED)
m_frame->SetDisplayCalibrated(event.IsChecked());
if (event.GetId() == ID_DISP_CALIBRATED2)
m_frame->SetDisplayCalibrated2(event.IsChecked());
if (event.GetId() == ID_DISP_ROTATED)
m_frame->SetDisplayRotated(event.IsChecked());
if (event.GetId() == ID_DISP_TCALIBRATED)
m_frame->SetDisplayTCalOn(event.IsChecked());
if (event.GetId() == ID_DISP_TRGCORR)
m_frame->SetDisplayTrgCorr(event.IsChecked());
if (event.GetId() == ID_REFCLK) {
if (event.IsChecked()) {
// check if clock is connected to CLK in
if (m_frame->GetOsci()->GetNumberOfBoards() > 0) {
if (m_frame->GetOsci()->GetCurrentBoard()->GetFirmwareVersion() < 21260) {
wxMessageBox(wxT("For this operation a V5 board with firmware revision >= 21260 is required"),
wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
m_cbExtRefclk->SetValue(false);
} else {
if (m_frame->GetOsci()->GetScaler(5) < 300000) {
wxMessageBox(wxT("No clock signal connected to CLK IN"),
wxT("DRS Oscilloscope"), wxOK | wxICON_STOP, this);
m_cbExtRefclk->SetValue(false);
} else
m_frame->SetRefclk(m_board, true);
}
}
} else
m_frame->SetRefclk(m_board, false);
FreqChange();
}
}
void ConfigDialog::OnRemoveSpikes( wxCommandEvent& event )
{
m_frame->SetSpikeRemoval(event.IsChecked());
}
void ConfigDialog::FreqChange()
{
wxString wxstr;
wxstr.Printf(wxT("%1.4lg"), m_frame->GetReqSamplingSpeed());
m_tbFreq->SetValue(wxstr);
wxstr.Printf(wxT("%1.4lg GSPS"), m_frame->GetActSamplingSpeed());
m_stActFreq->SetLabel(wxstr);
if (m_osci->GetNumberOfBoards() == 0) {
m_cbTCalOn->SetValue(true);
m_cbTCalOn->Enable(true);
} else {
m_cbTCalOn->SetValue(m_frame->GetOsci()->IsTCalibrated());
m_cbTCalOn->Enable(m_frame->GetOsci()->IsTCalibrated());
}
}
void ConfigDialog::OnFreq( wxCommandEvent& event )
{
wxString wxstr = m_tbFreq->GetValue();
double freq = 0;
wxstr.ToDouble(&freq);
m_frame->SetSamplingSpeed(freq);
wxstr.Printf(wxT("%1.4lg GSPS"), m_frame->GetActSamplingSpeed());
m_stActFreq->SetLabel(wxstr);
if (m_osci->GetNumberOfBoards() == 0) {
m_cbTCalOn->SetValue(true);
m_cbTCalOn->Enable(true);
} else {
m_cbTCalOn->SetValue(m_frame->GetOsci()->IsTCalibrated());
m_cbTCalOn->Enable(m_frame->GetOsci()->IsTCalibrated());
}
}
void ConfigDialog::OnLock( wxCommandEvent& event )
{
m_frame->SetFreqLock(event.IsChecked());
}
void ConfigDialog::OnClose( wxCommandEvent& event )
{
this->Hide();
}