kicad/eeschema/dialogs/dialog_sim_settings.cpp

235 lines
7.1 KiB
C++
Raw Normal View History

2016-08-11 12:41:29 +00:00
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "dialog_sim_settings.h"
#include <sim/netlist_exporter_pspice_sim.h>
2016-08-11 12:41:29 +00:00
/// @todo ngspice offers more types of analysis,
//so there are a few tabs missing (e.g. pole-zero, distortion, sensitivity)
DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent )
: DIALOG_SIM_SETTINGS_BASE( aParent ), m_exporter( nullptr )
{
m_posFloatValidator.SetMin( 0 );
m_posFloatValidator.SetPrecision( 6 );
2016-08-11 12:41:29 +00:00
m_posIntValidator.SetMin( 1 );
m_acPointsNumber->SetValidator( m_posIntValidator );
m_acFreqStart->SetValidator( m_posFloatValidator );
m_acFreqStop->SetValidator( m_posFloatValidator );
m_dcStart1->SetValidator( m_posFloatValidator );
m_dcStop1->SetValidator( m_posFloatValidator );
m_dcIncr1->SetValidator( m_posFloatValidator );
m_dcStart2->SetValidator( m_posFloatValidator );
m_dcStop2->SetValidator( m_posFloatValidator );
m_dcIncr2->SetValidator( m_posFloatValidator );
m_noisePointsNumber->SetValidator( m_posIntValidator );
m_noiseFreqStart->SetValidator( m_posFloatValidator );
m_noiseFreqStop->SetValidator( m_posFloatValidator );
m_transStep->SetValidator( m_posFloatValidator );
m_transFinal->SetValidator( m_posFloatValidator );
m_transInitial->SetValidator( m_posFloatValidator );
}
bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
{
if( !wxDialog::TransferDataFromWindow() )
return false;
wxWindow* page = m_simPages->GetCurrentPage();
// AC analysis
if( page == m_pgAC )
{
if( m_acPointsNumber->IsEmpty() || m_acFreqStart->IsEmpty() || m_acFreqStop->IsEmpty() )
return false;
2016-08-11 12:41:29 +00:00
m_simCommand = wxString::Format( ".ac %s %s %s %s",
scaleToString( m_acScale->GetSelection() ),
m_acPointsNumber->GetValue(), m_acFreqStart->GetValue(), m_acFreqStop->GetValue() );
}
// DC transfer analysis
else if( page == m_pgDC )
{
// At least one source has to be enabled
if( !m_dcEnable1->IsChecked() && !m_dcEnable1->IsChecked() )
return false;
wxString simCmd = wxString( ".dc " );
if( m_dcEnable1->IsChecked() )
{
if( m_dcSource1->GetValue().IsEmpty() || m_dcStart1->IsEmpty() ||
m_dcStop1->IsEmpty() || m_dcIncr1->IsEmpty() )
2016-08-11 12:41:29 +00:00
return false;
simCmd += wxString::Format( "%s %s %s %s",
m_dcSource1->GetValue(), m_dcStart1->GetValue(),
m_dcStop1->GetValue(), m_dcIncr1->GetValue() );
}
if( m_dcEnable2->IsChecked() )
{
if( m_dcSource2->GetValue().IsEmpty() || m_dcStart2->IsEmpty() ||
m_dcStop2->IsEmpty() || m_dcIncr2->IsEmpty() )
2016-08-11 12:41:29 +00:00
return false;
simCmd += wxString::Format( "%s %s %s %s",
m_dcSource2->GetValue(), m_dcStart2->GetValue(),
m_dcStop2->GetValue(), m_dcIncr2->GetValue() );
}
m_simCommand = simCmd;
}
// Noise analysis
else if( page == m_pgNoise )
{
if( m_noiseMeas->GetValue().IsEmpty() || m_noiseSrc->GetValue().IsEmpty() ||
m_noisePointsNumber->IsEmpty() || m_noiseFreqStart->IsEmpty() ||
m_noiseFreqStop->IsEmpty() )
2016-08-11 12:41:29 +00:00
return false;
// TODO missing node number
wxString ref = m_noiseRef->GetValue().IsEmpty() ? wxString() : wxString::Format( ", %d", 42 );
m_simCommand = wxString::Format( ".noise v(%d%s) %s %s %s %s %s",
42, ref, m_noiseSrc->GetValue(), scaleToString( m_noiseScale->GetSelection() ),
m_noisePointsNumber->GetValue(), m_noiseFreqStart->GetValue(), m_noiseFreqStop->GetValue() );
}
// DC operating point analysis
else if( page == m_pgOP )
{
m_simCommand = wxString( ".op" );
}
// Transient analysis
else if( page == m_pgTransient )
{
if( m_transStep->IsEmpty() || m_transFinal->IsEmpty() )
return false;
2016-08-11 12:41:29 +00:00
m_simCommand = wxString::Format( ".trans %s %s %s",
m_transStep->GetValue(), m_transFinal->GetValue(), m_transInitial->GetValue() );
}
// Custom directives
else if( page == m_pgCustom )
{
m_simCommand = m_customTxt->GetValue();
}
else
{
return false;
}
return true;
}
bool DIALOG_SIM_SETTINGS::TransferDataToWindow()
{
/// @todo one day it could interpret the sim command and fill out appropriate fields..
return true;
}
int DIALOG_SIM_SETTINGS::ShowModal()
{
// Fill out comboboxes that allow to select nets
// Map comoboxes to their current values
std::map<wxComboBox*, wxString> cmbNet = {
{ m_noiseMeas, m_noiseMeas->GetStringSelection() },
{ m_noiseRef, m_noiseRef->GetStringSelection() }
};
for( auto c : cmbNet )
c.first->Clear();
for( auto net : m_exporter->GetNetIndexMap() )
{
for( auto c : cmbNet )
c.first->Append( net.first );
}
// Try to restore the previous selection, if possible
for( auto c : cmbNet )
{
int idx = c.first->FindString( c.second );
if( idx != wxNOT_FOUND )
c.first->SetSelection( idx );
}
// Fill out comboboxes that allow to select power sources
std::map<wxComboBox*, wxString> cmbSrc = {
{ m_dcSource1, m_dcSource1->GetStringSelection() },
{ m_dcSource2, m_dcSource2->GetStringSelection() },
{ m_noiseSrc, m_noiseSrc->GetStringSelection() },
};
for( auto c : cmbSrc )
c.first->Clear();
for( auto item : m_exporter->GetSpiceItems() )
{
if( item.m_primitive == 'V' )
{
for( auto c : cmbSrc )
c.first->Append( item.m_refName );
}
}
// Try to restore the previous selection, if possible
for( auto c : cmbSrc )
{
int idx = c.first->FindString( c.second );
if( idx != wxNOT_FOUND )
c.first->SetSelection( idx );
}
return DIALOG_SIM_SETTINGS_BASE::ShowModal();
}
2016-08-11 12:41:29 +00:00
void DIALOG_SIM_SETTINGS::onLoadDirectives( wxCommandEvent& event )
{
if( m_exporter )
m_customTxt->SetValue( m_exporter->GetSheetSimCommand() );
2016-08-11 12:41:29 +00:00
}